Skip to content

Commit

Permalink
improve index templates, fixes #242
Browse files Browse the repository at this point in the history
  • Loading branch information
cars10 committed Jul 14, 2024
1 parent 2741835 commit 2dbda62
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 48 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 1.0.9

* improve index templates, fixes [#242](https://github.com/cars10/elasticvue/issues/242)
* dependency updates

## 1.0.8
Expand Down
17 changes: 10 additions & 7 deletions src/components/indextemplates/IndexTemplateRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,32 @@
<q-icon :name="expand ? 'expand_less' : 'expand_more'" />
</td>
<td>{{ row.name }}</td>
<td>{{ row.index_patterns }}</td>
<td>{{ row.order }}</td>
<td>{{ row.version }}</td>
<td>{{ row.index_patterns || row.template || row.index_template?.index_patterns }}</td>
</tr>

<tr v-if="expand">
<td colspan="100%">
<div class="q-pa-md">
<resizable-container>
<code-viewer :value="JSON.stringify(row)" />
<code-viewer :value="JSON.stringify(cleanedRow)" />
</resizable-container>
</div>
</td>
</tr>
</template>

<script setup lang="ts">
import { ref, defineAsyncComponent } from 'vue'
import { ref, defineAsyncComponent, computed } from 'vue'
import ResizableContainer from '../shared/ResizableContainer.vue'
import { EsIndexTemplate } from '../../composables/components/indextemplates/IndexTemplatesTable.ts'
import { GenericIndexTemplate } from '../../composables/components/indextemplates/IndexTemplates.ts'
const CodeViewer = defineAsyncComponent(() => import('../shared/CodeViewer.vue'))
defineProps<{ row: EsIndexTemplate }>()
const props = defineProps<{ row: GenericIndexTemplate }>()
const expand = ref(false)
const cleanedRow = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { indexPatterns, ...rest } = props.row
return rest
})
</script>
8 changes: 4 additions & 4 deletions src/components/indextemplates/IndexTemplates.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<q-separator />

<loader-status :request-state="requestState">
<index-templates-table :index-templates="data || {}" />
<index-templates-table :index-templates="data || []" />
</loader-status>
</q-card>
</template>
Expand All @@ -20,12 +20,12 @@
import ReloadButton from '../shared/ReloadButton.vue'
import LoaderStatus from '../shared/LoaderStatus.vue'
import IndexTemplatesTable from './IndexTemplatesTable.vue'
import { useElasticsearchRequest } from '../../composables/CallElasticsearch'
import { useTranslation } from '../../composables/i18n.ts'
import { EsIndexTemplates } from '../../composables/components/indextemplates/IndexTemplatesTable.ts'
import { useIndexTemplates } from '../../composables/components/indextemplates/IndexTemplates.ts'
const t = useTranslation()
const { requestState, data, load } = useElasticsearchRequest<EsIndexTemplates>('catIndexTemplates')
const { data, requestState, load } = useIndexTemplates()
onMounted(load)
</script>
57 changes: 44 additions & 13 deletions src/components/indextemplates/IndexTemplatesTable.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
<template>
<div class="flex justify-end q-pa-md">
<div class="flex">
<filter-input v-model="filter" />
<filter-input v-model="indexTemplatesStore.filter" />

<q-btn icon="settings" round flat class="q-ml-sm">
<q-menu style="white-space: nowrap" anchor="bottom right" self="top end">
<q-list dense>
<q-item style="padding-left: 0">
<q-checkbox v-model="indexTemplatesStore.showHiddenIndices" size="32px"
:label="t('indices.indices_table.show_hidden_indices.label')" />
</q-item>

<q-item style="padding-left: 0">
<q-checkbox v-model="indexTemplatesStore.stickyTableHeader" size="32px"
:label="t('indices.indices_table.sticky_table_header.label')" />
</q-item>
</q-list>
</q-menu>
</q-btn>
</div>
</div>

<q-table flat
dense
row-key="name"
:columns="columns"
:rows="filteredItems"
:pagination="{sortBy: 'name'}"
:rows-per-page-options="DEFAULT_ROWS_PER_PAGE">
<template #body="{row}">
<index-template-row :row="row" />
</template>
</q-table>
<div :class="{'table--sticky-header': indexTemplatesStore.stickyTableHeader, 'q-pb-md': true}">
<resizable-container v-model="resizeStore.indexTemplatesTable" :active="indexTemplatesStore.stickyTableHeader">
<q-table v-model:pagination="indexTemplatesStore.pagination"
flat
dense
row-key="name"
:columns="columns"
:virtual-scroll="indexTemplatesStore.stickyTableHeader"
:virtual-scroll-item-size="14"
:rows="filteredItems"
:rows-per-page-options="DEFAULT_ROWS_PER_PAGE">
<template #body="{row}">
<index-template-row :row="row" />
</template>
</q-table>
</resizable-container>
</div>
</template>

<script setup lang="ts">
Expand All @@ -26,7 +48,16 @@
useIndexTemplatesTable
} from '../../composables/components/indextemplates/IndexTemplatesTable'
import IndexTemplateRow from './IndexTemplateRow.vue'
import { useIndexTemplatesStore } from '../../store/index_templates.ts'
import { useTranslation } from '../../composables/i18n.ts'
import ResizableContainer from '../shared/ResizableContainer.vue'
import { useResizeStore } from '../../store/resize.ts'
const props = defineProps<IndexTemplatesTableProps>()
const { filter, filteredItems, columns } = useIndexTemplatesTable(props)
const indexTemplatesStore = useIndexTemplatesStore()
const resizeStore = useResizeStore()
const t = useTranslation()
const { filteredItems, columns } = useIndexTemplatesTable(props)
</script>
2 changes: 1 addition & 1 deletion src/components/indices/IndicesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="flex justify-between q-pa-md">
<div>
<new-index @reload="emit('reload')" />
<router-link v-if="connectionStore.activeCluster && parseInt(connectionStore.activeCluster.majorVersion) > 6"
<router-link v-if="connectionStore.activeCluster && parseInt(connectionStore.activeCluster.majorVersion) >= 5"
to="index_templates" class="q-ml-md">
{{ t('index_templates.heading') }}
</router-link>
Expand Down
73 changes: 73 additions & 0 deletions src/composables/components/indextemplates/IndexTemplates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { useElasticsearchAdapter } from '../../CallElasticsearch.ts'
import { ref, Ref } from 'vue'
import { useConnectionStore } from '../../../store/connection.ts'

export type GenericIndexTemplate = {
name: string,
order?: string,
version?: string,
priority?: string,
template?: string,
index_patterns?: string[],
indexPatterns?: string,
index_template?: {
index_patterns?: string[],
}
}

type IndexTemplates = {
index_templates?: Record<string, { index_patterns: string[] }>,
component_templates?: Record<string, { index_patterns: string[] }>
} | Record<string, { template: string }>

export const useIndexTemplates = () => {
const { requestState, callElasticsearch } = useElasticsearchAdapter()
const data: Ref<GenericIndexTemplate[] | null> = ref(null)
const connectionStore = useConnectionStore()

const load = async () => {
if (!connectionStore.activeCluster) return
const majorVersion = parseInt(connectionStore.activeCluster.majorVersion)
const method = templateEndpoint(majorVersion)
if (!method) return

return callElasticsearch(method)
.then(body => (data.value = enrich(body)))
.catch(() => (data.value = null))
}

return {
data,
requestState,
load
}
}

const enrich = (data: IndexTemplates) => {
const templates = data.index_templates || data.component_templates || data
const results: GenericIndexTemplate[] = []
Object.entries(templates).map(([name, template]) => {
const indexPatterns = template.index_patterns?.join('') || template.index_template?.index_patterns?.join('') || template.component_template?.index_patterns?.join('') || template.template
results.push({
name,
indexPatterns,
...template,
})
})
return results
}

const templateEndpoint = (majorVersion: number) => {
switch (majorVersion) {
case 5:
return 'templates'
case 6:
return 'templates'
case 7:
return 'templates'
case 8:
return 'indexTemplates'
default:
return null
}
}
35 changes: 13 additions & 22 deletions src/composables/components/indextemplates/IndexTemplatesTable.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,36 @@
import { useTranslation } from '../../i18n'
import { computed, ref } from 'vue'
import { computed } from 'vue'
import { genColumns } from '../../../helpers/tableColumns'
import { filterItems } from '../../../helpers/filters.ts'

export type EsIndexTemplate = {
name: string,
index_patterns: string[],
order: string,
version: string,
}

export type EsIndexTemplates = Record<string, EsIndexTemplate>
import { GenericIndexTemplate } from './IndexTemplates.ts'
import { useIndexTemplatesStore } from '../../../store/index_templates.ts'
import { DEFAULT_HIDE_INDICES_REGEX } from '../../../consts.ts'

export type IndexTemplatesTableProps = {
indexTemplates: EsIndexTemplates
indexTemplates: GenericIndexTemplate[]
}

export const useIndexTemplatesTable = (props: IndexTemplatesTableProps) => {
const t = useTranslation()

const filter = ref('')
const enrichedIndexTemplates = computed(() => {
return Object.entries(props.indexTemplates).map(([name, template]) => {
return Object.assign({}, { name }, { indexPatterns: template.index_patterns?.join('') }, template)
})
})
const indexTemplatesStore = useIndexTemplatesStore()

const filteredItems = computed(() => {
return filterItems(enrichedIndexTemplates.value, filter.value, ['name', 'indexPatterns'])
let results = props.indexTemplates
if (results.length === 0) return []

if (!indexTemplatesStore.showHiddenIndices) {
results = results.filter((item: any) => !item.name.match(new RegExp(DEFAULT_HIDE_INDICES_REGEX)))
}
return filterItems(results, indexTemplatesStore.filter, ['name', 'indexPatterns'])
})

const columns = genColumns([
{ label: '' },
{ label: t('index_templates.index_templates_table.table.headers.name'), field: 'name', },
{ label: t('index_templates.index_templates_table.table.headers.index_patterns') },
{ label: t('index_templates.index_templates_table.table.headers.priority') },
{ label: t('index_templates.index_templates_table.table.headers.version') },
])

return {
filter,
filteredItems,
columns
}
Expand Down
10 changes: 9 additions & 1 deletion src/services/ElasticsearchAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,18 @@ export default class ElasticsearchAdapter {
return this.request(`_cat/indices/${query}`, 'GET', params)
}

catIndexTemplates () {
templates () {
return this.request('_template', 'GET')
}

indexTemplates () {
return this.request('_index_template', 'GET')
}

componentTemplates () {
return this.request('_component_template', 'GET')
}

catShards (params: object, filter?: string) {
const query = filter ? `${filter}*` : ''
return this.request(`_cat/shards/${query}`, 'GET', params)
Expand Down
31 changes: 31 additions & 0 deletions src/store/index_templates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineStore } from 'pinia'

type IndexTemplatesState = {
filter: string,
showHiddenIndices: boolean,
stickyTableHeader: boolean,
pagination: any,
}

export const useIndexTemplatesStore = defineStore('indexTemplates', {
state: (): IndexTemplatesState => ({
filter: '',
showHiddenIndices: false,
stickyTableHeader: false,
pagination: {
sortBy: 'index',
descending: false,
rowsPerPage: 10
},
}),
persist: {
paths: [
'filter',
'showHiddenIndices',
'stickyTableHeader',
'pagination.sortBy',
'pagination.descending',
'pagination.rowsPerPage',
]
}
})
2 changes: 2 additions & 0 deletions src/store/resize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defineStore } from 'pinia'

type ResizeState = {
indicesTable: number,
indexTemplatesTable: number,
modalLoaderCodeViewer: number,
restForm: number,
searchQuery: number,
Expand All @@ -12,6 +13,7 @@ type ResizeState = {
export const useResizeStore = defineStore('resize', {
state: (): ResizeState => ({
indicesTable: 500,
indexTemplatesTable: 500,
modalLoaderCodeViewer: 600,
restForm: 400,
searchQuery: 400,
Expand Down

0 comments on commit 2dbda62

Please sign in to comment.