adde table and editor components
This commit is contained in:
279
src/components/AppEntriesTable.vue
Normal file
279
src/components/AppEntriesTable.vue
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { BButton, BCol, BContainer, BFormGroup, BFormInput, BFormSelect, BInputGroup, BInputGroupText, BPagination, BRow, BSpinner, BTable, type TableFieldRaw, type TableItem } from 'bootstrap-vue-next'
|
||||||
|
import type { GlossaryItem } from '@/types/GlossaryItem'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useGlossaryEntryStore } from '@/stores/glossaryEntry'
|
||||||
|
import { onMounted, ref, type Ref } from 'vue'
|
||||||
|
|
||||||
|
// use global scope
|
||||||
|
const { t } = useI18n({
|
||||||
|
useScope: 'global',
|
||||||
|
inheritLocale: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const glossaryEntryStore = useGlossaryEntryStore()
|
||||||
|
|
||||||
|
const isLoading = ref(false)
|
||||||
|
const filter = ref('')
|
||||||
|
const glossaryEntries: Ref<TableItem<GlossaryItem>[]> = ref([])
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const perPage = ref (5)
|
||||||
|
const totalRows = ref(glossaryEntries.value.length)
|
||||||
|
const pageOptions = [
|
||||||
|
{value: 5, text: '5'},
|
||||||
|
{value: 10, text: '10'},
|
||||||
|
{value: 15, text: '15'},
|
||||||
|
{value: 100, text: '100'},
|
||||||
|
]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the passed table item (a GlossaryItem object) to the
|
||||||
|
* glossaryEntry store and routes the user to the edit page
|
||||||
|
* @param item GlossaryItem object from the table
|
||||||
|
* @param index Row index of the GlossaryItem object in the table
|
||||||
|
*/
|
||||||
|
const goToEdit = (item: TableItem<GlossaryItem>, index: number) => {
|
||||||
|
glossaryEntryStore.setGlossaryEntry({
|
||||||
|
uuid: item.uuid,
|
||||||
|
title: item.title,
|
||||||
|
description: item.description,
|
||||||
|
source: item.source,
|
||||||
|
})
|
||||||
|
router.push({ path: '/edit' })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the results displayed in the table only against certain
|
||||||
|
* columns. This avoid the default filter function, which will
|
||||||
|
* filter on UUID.
|
||||||
|
* @param item Item from the table
|
||||||
|
*/
|
||||||
|
const filterFuntion = (item: Readonly<GlossaryItem>): boolean => {
|
||||||
|
if (typeof filter == undefined) return false
|
||||||
|
if (
|
||||||
|
filter.value == '' ||
|
||||||
|
item.title.includes(filter.value) ||
|
||||||
|
item.description.includes(filter.value) ||
|
||||||
|
item.source.includes(filter.value)
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const onFiltered = (filteredItems: TableItem<GlossaryItem>[]) => {
|
||||||
|
// Trigger pagination to update the number of buttons/pages due to filtering
|
||||||
|
totalRows.value = filteredItems.length
|
||||||
|
currentPage.value = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
const fields: Exclude<TableFieldRaw<GlossaryItem>, string>[] = [
|
||||||
|
{
|
||||||
|
key: 'title',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'description',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'source',
|
||||||
|
sortable: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'actions',
|
||||||
|
label: '',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
isLoading.value = true
|
||||||
|
// TODO add APi call here
|
||||||
|
glossaryEntries.value = [
|
||||||
|
{
|
||||||
|
uuid: 'trzsdgres4',
|
||||||
|
title: 'Example 1',
|
||||||
|
description: 'Description for Exmaple 1.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'nhtsgrzg4y',
|
||||||
|
title: 'Example 2',
|
||||||
|
description: 'Description for Exmaple 2.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'gnrdu908ty945e',
|
||||||
|
title: 'Example 3',
|
||||||
|
description: 'Description for Exmaple 3.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'u67ej7tewu',
|
||||||
|
title: 'Example f453q',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'y456wj64w',
|
||||||
|
title: 'Example htgxdfy54',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: '654w',
|
||||||
|
title: 'Example f4j76ro36753q',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'y563je',
|
||||||
|
title: 'Example gfdj67',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'jkuy09o7ie',
|
||||||
|
title: 'Example f4fgewar3 53q',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: '98o8fjgh',
|
||||||
|
title: 'Example vfaf321',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: '5y4286',
|
||||||
|
title: 'Example vgdfsaghtsh',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'hj7649i',
|
||||||
|
title: 'Example grayh4',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uuid: 'j79',
|
||||||
|
title: 'Example jyayf34',
|
||||||
|
description: 'Description for Exmaple.',
|
||||||
|
source: 'https://ccascoe.org',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
// TODO remove fake delay
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||||
|
isLoading.value = false
|
||||||
|
totalRows.value = glossaryEntries.value.length
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BContainer>
|
||||||
|
<BRow>
|
||||||
|
<BCol
|
||||||
|
lg="6"
|
||||||
|
class="my-1"
|
||||||
|
>
|
||||||
|
<BFormGroup
|
||||||
|
label="Filter"
|
||||||
|
label-for="filter-input"
|
||||||
|
label-cols-sm="3"
|
||||||
|
label-align-sm="right"
|
||||||
|
label-size="sm"
|
||||||
|
class="mb-0"
|
||||||
|
>
|
||||||
|
<BInputGroup size="sm">
|
||||||
|
<BFormInput
|
||||||
|
id="filter-input"
|
||||||
|
v-model="filter"
|
||||||
|
type="search"
|
||||||
|
placeholder="Type to Search"
|
||||||
|
/>
|
||||||
|
<BInputGroupText>
|
||||||
|
<BButton
|
||||||
|
:disabled="!filter"
|
||||||
|
@click="filter = ''"
|
||||||
|
>Clear</BButton
|
||||||
|
>
|
||||||
|
</BInputGroupText>
|
||||||
|
</BInputGroup>
|
||||||
|
</BFormGroup>
|
||||||
|
</BCol>
|
||||||
|
</BRow>
|
||||||
|
<BTable
|
||||||
|
sticky-header
|
||||||
|
striped
|
||||||
|
hover
|
||||||
|
bordered
|
||||||
|
:sort-by="[{ key: 'title', order: 'asc' }]"
|
||||||
|
:filter="filter"
|
||||||
|
:filter-function="filterFuntion"
|
||||||
|
@filtered="onFiltered"
|
||||||
|
:current-page="currentPage"
|
||||||
|
:per-page="perPage"
|
||||||
|
:busy="isLoading"
|
||||||
|
variant="primary"
|
||||||
|
:items="glossaryEntries"
|
||||||
|
:fields="fields"
|
||||||
|
>
|
||||||
|
<template #cell(actions)="row">
|
||||||
|
<BButton size="sm" @click="goToEdit(row.item, row.index)">{{
|
||||||
|
t('table.edit')
|
||||||
|
}}</BButton>
|
||||||
|
</template>
|
||||||
|
<template #table-busy>
|
||||||
|
<div class="text-center text-primary my-2">
|
||||||
|
<BSpinner variant="primary" class="align-middle" />
|
||||||
|
<strong class="ms-2">Loading...</strong>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</BTable>
|
||||||
|
<BRow>
|
||||||
|
<BCol
|
||||||
|
sm="7"
|
||||||
|
md="6"
|
||||||
|
class="my-1"
|
||||||
|
>
|
||||||
|
<BPagination
|
||||||
|
v-model="currentPage"
|
||||||
|
:total-rows="totalRows"
|
||||||
|
:per-page="perPage"
|
||||||
|
:align="'fill'"
|
||||||
|
size="sm"
|
||||||
|
class="my-0"
|
||||||
|
/>
|
||||||
|
</BCol>
|
||||||
|
<BCol
|
||||||
|
sm="5"
|
||||||
|
md="6"
|
||||||
|
class="my-1"
|
||||||
|
>
|
||||||
|
<BFormGroup
|
||||||
|
label="Per page"
|
||||||
|
label-for="per-page-select"
|
||||||
|
label-cols-sm="6"
|
||||||
|
label-cols-md="4"
|
||||||
|
label-cols-lg="3"
|
||||||
|
label-align-sm="right"
|
||||||
|
label-size="sm"
|
||||||
|
class="mb-0"
|
||||||
|
>
|
||||||
|
<BFormSelect
|
||||||
|
id="per-page-select"
|
||||||
|
v-model="perPage"
|
||||||
|
:options="pageOptions"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</BFormGroup>
|
||||||
|
</BCol>
|
||||||
|
</BRow>
|
||||||
|
</BContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
115
src/components/AppEntryEditor.vue
Normal file
115
src/components/AppEntryEditor.vue
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useGlossaryEntryStore } from '@/stores/glossaryEntry'
|
||||||
|
import type { GlossaryItem } from '@/types/GlossaryItem'
|
||||||
|
import { BButton, BCol, BContainer, BForm, BFormFloatingLabel, BFormGroup, BFormInput, BRow } from 'bootstrap-vue-next'
|
||||||
|
import { nextTick, reactive, ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const glossaryEntryStore = useGlossaryEntryStore()
|
||||||
|
const router = useRouter()
|
||||||
|
// use global scope
|
||||||
|
const { t } = useI18n({
|
||||||
|
useScope: 'global',
|
||||||
|
inheritLocale: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const form = reactive<GlossaryItem>({
|
||||||
|
uuid: glossaryEntryStore.glossaryEntry.uuid,
|
||||||
|
title: glossaryEntryStore.glossaryEntry.title,
|
||||||
|
description: glossaryEntryStore.glossaryEntry.description,
|
||||||
|
source: glossaryEntryStore.glossaryEntry.source,
|
||||||
|
})
|
||||||
|
|
||||||
|
const show = ref(true)
|
||||||
|
const saveSuccess = ref(false)
|
||||||
|
|
||||||
|
const toListView = () => {
|
||||||
|
router.push({ path: '/list' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = (event: Event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
//on save:
|
||||||
|
// 1. send update API call to server
|
||||||
|
// 2. Wait for success response
|
||||||
|
saveSuccess.value = true
|
||||||
|
// 3. router push back to list
|
||||||
|
// router.push({ path: '/list' })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the values of the form back to empty strings
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
const onReset = (event: Event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
// Reset our form values
|
||||||
|
// form.uuid = ''
|
||||||
|
form.title = ''
|
||||||
|
form.description = ''
|
||||||
|
form.source = ''
|
||||||
|
// Trick to reset/clear native browser form validation state
|
||||||
|
show.value = false
|
||||||
|
nextTick(() => {
|
||||||
|
show.value = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<BContainer>
|
||||||
|
<BForm v-if="show" @submit="onSubmit" @reset="onReset">
|
||||||
|
<BFormGroup id="input-group-1" :label="t('editForm.title')" label-for="input-1">
|
||||||
|
<BFormInput
|
||||||
|
id="input-1"
|
||||||
|
v-model="form.title"
|
||||||
|
type="text"
|
||||||
|
:placeholder="t('editForm.titlePlaceholder')"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</BFormGroup>
|
||||||
|
|
||||||
|
<BFormFloatingLabel id="input-group-2" :label="t('editForm.description')" label-for="input-2" class="my-2">
|
||||||
|
<BFormInput
|
||||||
|
id="input-2"
|
||||||
|
v-model="form.description"
|
||||||
|
type="text"
|
||||||
|
:placeholder="t('editForm.descriptionPlaceholder')"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</BFormFloatingLabel>
|
||||||
|
|
||||||
|
<BFormGroup
|
||||||
|
id="input-group-3"
|
||||||
|
:label="t('editForm.source')"
|
||||||
|
label-for="input-3"
|
||||||
|
:description="t('editForm.sourceDescription')"
|
||||||
|
>
|
||||||
|
<BFormInput
|
||||||
|
id="input-3"
|
||||||
|
v-model="form.source"
|
||||||
|
type="url"
|
||||||
|
:placeholder="t('editForm.sourcePlaceholder')"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</BFormGroup>
|
||||||
|
<BContainer>
|
||||||
|
<BRow>
|
||||||
|
<BCol>
|
||||||
|
<BButton type="submit" variant="primary">{{ t('editForm.submit') }}</BButton>
|
||||||
|
<BButton type="reset" variant="danger">{{ t('editForm.reset') }}</BButton>
|
||||||
|
</BCol>
|
||||||
|
<BCol>
|
||||||
|
<BButton variant="secondary" @click="toListView">{{ t('editForm.back') }}</BButton>
|
||||||
|
</BCol>
|
||||||
|
</BRow>
|
||||||
|
</BContainer>
|
||||||
|
</BForm>
|
||||||
|
<BContainer v-if="saveSuccess">
|
||||||
|
Entry Saved!
|
||||||
|
</BContainer>
|
||||||
|
</BContainer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { BContainer } from 'bootstrap-vue-next';
|
import { BContainer } from 'bootstrap-vue-next'
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<!-- <div class="bg-dark text-white text-center py-3 fixed-bottom">Footer</div> -->
|
<!-- <div class="bg-dark text-white text-center py-3 fixed-bottom">Footer</div> -->
|
||||||
<BContainer fluid class="bg-dark text-white fixed-bottom py-3">
|
<BContainer fluid class="bg-dark text-white fixed-bottom py-3"> Footer </BContainer>
|
||||||
Footer
|
|
||||||
</BContainer>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
BButton,
|
BButton,
|
||||||
BCollapse,
|
BCollapse,
|
||||||
BDropdownItem,
|
BDropdownItem,
|
||||||
BNavbar,
|
BNavbar,
|
||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
BNavbarToggle,
|
BNavbarToggle,
|
||||||
BNavItem,
|
BNavItem,
|
||||||
BNavItemDropdown,
|
BNavItemDropdown,
|
||||||
vBColorMode
|
vBColorMode,
|
||||||
} from 'bootstrap-vue-next'
|
} from 'bootstrap-vue-next'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ const { t } = useI18n({
|
|||||||
>
|
>
|
||||||
</b-nav-item-dropdown>
|
</b-nav-item-dropdown>
|
||||||
</b-navbar-nav>
|
</b-navbar-nav>
|
||||||
<b-button type="button">{{ t('navbar.login') }}</b-button>
|
<b-button type="button">{{ t('navbar.login') }}</b-button>
|
||||||
</b-collapse>
|
</b-collapse>
|
||||||
</b-navbar>
|
</b-navbar>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,5 +8,20 @@
|
|||||||
"language": "Language",
|
"language": "Language",
|
||||||
"logout": "logout",
|
"logout": "logout",
|
||||||
"login": "login"
|
"login": "login"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"edit": "Edit"
|
||||||
|
},
|
||||||
|
"editForm": {
|
||||||
|
"title": "Title",
|
||||||
|
"titlePlaceholder": "Enter title",
|
||||||
|
"description": "Description",
|
||||||
|
"descriptionPlaceholder": "Enter description",
|
||||||
|
"source": "Source",
|
||||||
|
"sourcePlaceholder": "Enter source URL",
|
||||||
|
"sourceDescription": "Ensure the source is a valid URL.",
|
||||||
|
"submit": "Submit",
|
||||||
|
"reset": "Reset",
|
||||||
|
"back": "Back"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,20 @@
|
|||||||
"language": "Language",
|
"language": "Language",
|
||||||
"logout": "se déconnecter",
|
"logout": "se déconnecter",
|
||||||
"login": "se connecter"
|
"login": "se connecter"
|
||||||
|
},
|
||||||
|
"table": {
|
||||||
|
"edit": "Modifier "
|
||||||
|
},
|
||||||
|
"editForm": {
|
||||||
|
"title": "Titre",
|
||||||
|
"titlePlaceholder": "Entrez le titre",
|
||||||
|
"description": "Description",
|
||||||
|
"descriptionPlaceholder": "Entrer la description",
|
||||||
|
"source": "Source",
|
||||||
|
"sourcePlaceholder": "Entrer l'URL source",
|
||||||
|
"sourceDescription": "Assurez-vous que la source est une URL valide.",
|
||||||
|
"submit": "Soumettre",
|
||||||
|
"reset": "Réinitialiser",
|
||||||
|
"back": "Retour"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import Home from '@/views/Home.vue'
|
import Home from '@/views/Home.vue'
|
||||||
import List from '@/views/List.vue'
|
import List from '@/views/List.vue'
|
||||||
|
import Edit from '@/views/Edit.vue'
|
||||||
|
|
||||||
import DefaultLayout from '@/layout/DefaultLayout.vue'
|
import DefaultLayout from '@/layout/DefaultLayout.vue'
|
||||||
|
|
||||||
@@ -22,6 +23,11 @@ const router = createRouter({
|
|||||||
name: 'List',
|
name: 'List',
|
||||||
component: List,
|
component: List,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/edit',
|
||||||
|
name: 'Edit',
|
||||||
|
component: Edit,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
import { ref, computed } from 'vue'
|
|
||||||
import { defineStore } from 'pinia'
|
|
||||||
|
|
||||||
export const useCounterStore = defineStore('counter', () => {
|
|
||||||
const count = ref(0)
|
|
||||||
const doubleCount = computed(() => count.value * 2)
|
|
||||||
function increment() {
|
|
||||||
count.value++
|
|
||||||
}
|
|
||||||
|
|
||||||
return { count, doubleCount, increment }
|
|
||||||
})
|
|
||||||
21
src/stores/glossaryEntry.ts
Normal file
21
src/stores/glossaryEntry.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { ref, computed, type Ref } from 'vue'
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import type { GlossaryItem } from '@/types/GlossaryItem'
|
||||||
|
|
||||||
|
export const useGlossaryEntryStore = defineStore('glossaryEntry', () => {
|
||||||
|
const glossaryEntry: Ref<GlossaryItem> = ref({
|
||||||
|
uuid: '',
|
||||||
|
title: '',
|
||||||
|
description: '',
|
||||||
|
source: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const setGlossaryEntry = (passedGlossaryEntry: GlossaryItem) => {
|
||||||
|
glossaryEntry.value.uuid = passedGlossaryEntry.uuid
|
||||||
|
glossaryEntry.value.title = passedGlossaryEntry.title
|
||||||
|
glossaryEntry.value.description = passedGlossaryEntry.description
|
||||||
|
glossaryEntry.value.source = passedGlossaryEntry.source
|
||||||
|
}
|
||||||
|
|
||||||
|
return { glossaryEntry, setGlossaryEntry }
|
||||||
|
})
|
||||||
6
src/types/GlossaryItem.ts
Normal file
6
src/types/GlossaryItem.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export type GlossaryItem = {
|
||||||
|
uuid: string
|
||||||
|
title: string
|
||||||
|
description: string
|
||||||
|
source: string
|
||||||
|
}
|
||||||
12
src/views/Edit.vue
Normal file
12
src/views/Edit.vue
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import AppEntryEditor from '@/components/AppEntryEditor.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
Edit view
|
||||||
|
<AppEntryEditor />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import AppEntriesTable from '@/components/AppEntriesTable.vue'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>This is List</div>
|
<div>This is List</div>
|
||||||
|
<AppEntriesTable />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="css" scoped></style>
|
<style lang="css" scoped></style>
|
||||||
|
|||||||
19
src/vue-i18n.d.ts
vendored
19
src/vue-i18n.d.ts
vendored
@@ -18,9 +18,24 @@ declare module 'vue-i18n' {
|
|||||||
home: string
|
home: string
|
||||||
list: string
|
list: string
|
||||||
language: string
|
language: string
|
||||||
logout: string
|
logout: string
|
||||||
login: string
|
login: string
|
||||||
}
|
}
|
||||||
|
table: {
|
||||||
|
edit: string
|
||||||
|
}
|
||||||
|
editForm: {
|
||||||
|
title: string
|
||||||
|
titlePlaceholder: stirng
|
||||||
|
description: string
|
||||||
|
descriptionPlaceholder: string
|
||||||
|
source: string
|
||||||
|
sourcePlaceholder: string
|
||||||
|
sourceDescription: string
|
||||||
|
submit: string
|
||||||
|
reset: string
|
||||||
|
back: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // define the datetime format schema
|
// // define the datetime format schema
|
||||||
|
|||||||
Reference in New Issue
Block a user