| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <!--
- A data table for the parameters page
- -->
- <template>
- <div class="container">
- <UiLoadingPanel v-if="pending" />
- <div v-else>
- <LayoutParametersTable
- :items="items"
- :title="title"
- :columns-definitions="columns"
- :actions="actions"
- :actions-route="actionsRoute"
- @edit-clicked="onEditClicked"
- @delete-clicked="onDeleteClicked"
- @add-clicked="goToCreatePage"
- />
- <UiFormDeletionConfirmationDialog
- v-model="showDeletionConfirmationDialog"
- @delete-clicked="onDeleteConfirmed"
- @cancel-clicked="onCancelClicked"
- />
- </div>
- </div>
- </template>
- <script setup lang="ts">
- import { TABLE_ACTION } from '~/types/enum/enums'
- import UrlUtils from '~/services/utils/urlUtils'
- import type ApiResource from '~/models/ApiResource'
- import { useEntityFetch } from '~/composables/data/useEntityFetch'
- import type { AssociativeArray } from '~/types/data'
- import type { ColumnDefinition } from '~/types/interfaces'
- import { useDeleteItem } from '~/composables/form/useDeleteItem'
- import { useEntityManager } from '~/composables/data/useEntityManager'
- const props = defineProps({
- /**
- * The model whom entities shall be to fetch
- */
- model: {
- type: Object as PropType<typeof ApiResource>,
- required: true,
- },
- /** Titre du tableau */
- title: {
- type: String,
- required: false,
- default: null,
- },
- /**
- * If provided, define the columns to show.
- * Else, all the entity's props are shown.
- *
- * Ex: [
- * { property: 'id', label : 'Identifier'},
- * { property: 'name', label : 'Full name'},
- * ]
- */
- columnsDefinitions: {
- type: Array as PropType<Array<ColumnDefinition> | null>,
- required: false,
- default: null,
- },
- /**
- * List of the actions available for each record
- */
- actions: {
- type: Array as PropType<Array<TABLE_ACTION>>,
- required: false,
- default: () => [TABLE_ACTION.EDIT, TABLE_ACTION.DELETE, TABLE_ACTION.ADD],
- },
- /**
- * The base URL for the edit / create pages
- * The resulting url will be constructed this way :
- *
- * Edition : ({baseUrl}/){apiResource.entity}/{id}
- * Creation : ({baseUrl}/){apiResource.entity}/new
- */
- baseActionsRoute: {
- type: String,
- required: false,
- default: '/parameters',
- },
- /**
- * If provided, sort the record by the given property
- */
- sortBy: {
- type: String as PropType<string>,
- required: false,
- default: 'id',
- },
- })
- const i18n = useI18n()
- const { em } = useEntityManager()
- const { fetchCollection } = useEntityFetch()
- const { data: collection, pending } = fetchCollection(props.model)
- const { deleteItem } = useDeleteItem()
- const pageStore = usePageStore()
- /**
- * Return the properties to display in the table, or all the
- * props of the model if not specified.
- */
- const columns: ComputedRef<Array<ColumnDefinition>> = computed(() => {
- return (
- props.columnsDefinitions ??
- Object.getOwnPropertyNames(new props.model()).map((prop) => {
- return { property: prop }
- })
- )
- })
- /**
- * Fetch the collection of ApiResources of the given model, then
- * map it according to the configuration.
- */
- const items: ComputedRef<Array<ApiResource> | null> = computed(() => {
- if (pending.value || collection.value === null) {
- return null
- }
- let items: Array<ApiResource> = collection.value!.items
- if (props.columnsDefinitions !== null) {
- // Filter the columns to show
- items = items.map((item) => {
- const newItem: ApiResource = { id: item.id }
- for (const col of props.columnsDefinitions!) {
- newItem[col.property] = item[col.property]
- }
- return newItem
- })
- }
- if (props.sortBy) {
- items = items.sort((a: AssociativeArray, b: AssociativeArray) => {
- return a[props.sortBy as keyof typeof a] >
- b[props.sortBy as keyof typeof b]
- ? 1
- : -1
- })
- }
- return items
- })
- const actionsRoute = computed(() => {
- return UrlUtils.join(props.baseActionsRoute, props.model.entity)
- })
- const showDeletionConfirmationDialog: Ref<boolean> = ref(false)
- const itemToDelete: Ref<ApiResource | null> = ref(null)
- /**
- * Redirect to the edition page for the given item
- * @param item
- */
- const onEditClicked = (item: ApiResource) => {
- navigateTo(UrlUtils.join(actionsRoute.value, item.id))
- }
- /**
- * Show the deletion confirmation dialog
- * @param item
- */
- const onDeleteClicked = (item: ApiResource) => {
- itemToDelete.value = em.cast(props.model, item)
- showDeletionConfirmationDialog.value = true
- }
- const onCancelClicked = () => {
- itemToDelete.value = null
- }
- /**
- * Deletion has be confirmed, perform
- */
- const onDeleteConfirmed = async () => {
- pageStore.loading = true
- await deleteItem(itemToDelete.value)
- pageStore.loading = false
- }
- /**
- * Redirect to the creation page for this model
- */
- const goToCreatePage = () => {
- navigateTo(UrlUtils.join(actionsRoute.value, 'new'))
- }
- </script>
- <style scoped lang="scss"></style>
|