frontend/src/components/ConfigMapsList.vue
<script lang="ts">
import { defineComponent, ref, computed, PropType, onBeforeUnmount } from 'vue';
import { KubernetesCluster, KubernetesConfigMap } from '../types/kubernetes';
import SearchBar from './SearchBar.vue';
import { formatAge } from '../lib/format';
export default defineComponent({
name: 'ConfigMapsList',
components: {
SearchBar
},
props: {
selectedCluster: {
type: Object as PropType<KubernetesCluster>,
required: false,
default: null
},
configMaps: {
type: Array as PropType<KubernetesConfigMap[]>,
required: false,
default: () => []
}
},
emits: ['configmap-selected'],
data() {
return {
selectedConfigMap: null as KubernetesConfigMap | null
};
},
setup(props, { emit }) {
const searchQuery = ref('');
const filteredConfigMaps = computed(() => {
if (!searchQuery.value) {
return props.configMaps;
}
const query = searchQuery.value.toLowerCase();
const nameSpecificMatch = query.match(/^name:(.+)$/);
if (nameSpecificMatch) {
const nameQuery = nameSpecificMatch[1].trim();
return props.configMaps.filter(configMap => {
const name = configMap.metadata.name.toLowerCase();
return name.includes(nameQuery);
});
}
const namespaceSpecificMatch = query.match(/^namespace:(.+)$/);
if (namespaceSpecificMatch) {
const namespaceQuery = namespaceSpecificMatch[1].trim();
return props.configMaps.filter(configMap => {
const namespace = configMap.metadata.namespace.toLowerCase();
return namespace.includes(namespaceQuery);
});
}
return props.configMaps.filter(configMap => {
const name = configMap.metadata.name.toLowerCase();
return name.includes(query);
});
});
return {
searchQuery,
filteredConfigMaps,
formatAge
};
},
methods: {
isSelected(configMap: KubernetesConfigMap): boolean {
if (!this.selectedConfigMap) return false;
return this.selectedConfigMap.metadata.name === configMap.metadata.name &&
this.selectedConfigMap.metadata.namespace === configMap.metadata.namespace &&
this.selectedConfigMap.metadata.uid === configMap.metadata.uid;
},
selectConfigMap(configMap: KubernetesConfigMap): void {
const configMapToEmit = { ...configMap }
if (!configMapToEmit.kind) {
configMapToEmit.kind = 'ConfigMap';
}
this.selectedConfigMap = configMapToEmit;
this.$emit('configmap-selected', configMapToEmit);
},
getUniqueKey(configMap: KubernetesConfigMap): string {
const namespace = configMap.metadata.namespace || 'default';
let key;
key = namespace + '-' + configMap.metadata.name + '-' + (configMap.metadata.uid || '');
return key;
}
},
});
</script>
<template>
<div class="configmaps-container">
<div class="search-bar-container">
<SearchBar
:value="searchQuery"
@update:value="searchQuery = $event"
placeholder="Search configmaps..."
/>
</div>
<div class="table-scroll-container">
<table>
<thead>
<tr>
<th>Name</th>
<th>Namespace</th>
<th>Age</th>
</tr>
</thead>
<tbody>
<tr
v-for="configMap in filteredConfigMaps"
:key="getUniqueKey(configMap)"
:class="{ selected: isSelected(configMap) }"
@click="selectConfigMap(configMap)"
>
<td>{{ configMap.metadata.name }}</td>
<td>{{ configMap.metadata.namespace || 'default' }}</td>
<td>{{ formatAge(configMap.metadata.creationTimestamp) }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</template>
<style src="@/assets/css/ConfigMapsList.css" scoped></style>