diff --git a/backend/go.mod b/backend/go.mod index 2f46216..686a2c9 100644 --- a/backend/go.mod +++ b/backend/go.mod @@ -4,7 +4,7 @@ go 1.24.5 require ( gitea.tecamino.com/paadi/access-handler v1.0.12 - gitea.tecamino.com/paadi/memberDB v1.0.4 + gitea.tecamino.com/paadi/memberDB v1.0.11 gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 gitea.tecamino.com/paadi/tecamino-logger v0.2.1 github.com/gin-contrib/cors v1.7.6 diff --git a/backend/go.sum b/backend/go.sum index 1d33899..2b89399 100644 --- a/backend/go.sum +++ b/backend/go.sum @@ -2,8 +2,8 @@ gitea.tecamino.com/paadi/access-handler v1.0.12 h1:lSmW0YrBJJvCqCg0ukTJHlFUNwd7q gitea.tecamino.com/paadi/access-handler v1.0.12/go.mod h1:w71lpnuu5MgAWG3oiI9vsY2dWi4njF/iPrM/xV/dbBQ= gitea.tecamino.com/paadi/dbHandler v1.0.4 h1:ctnaec0GDdtw3gRQdUISVDYLJ9x+vt50VW41OemfhD4= gitea.tecamino.com/paadi/dbHandler v1.0.4/go.mod h1:y/xn/POJg1DO++67uKvnO23lJQgh+XFQq7HZCS9Getw= -gitea.tecamino.com/paadi/memberDB v1.0.4 h1:2H7obSoMq4dW+VN8PsDOv1UK75hCtlF+NymU5NBGuw4= -gitea.tecamino.com/paadi/memberDB v1.0.4/go.mod h1:iLm7nunVRzqJK8CV4PJVuWIhgPlQjNIaeOkmtfK5fMg= +gitea.tecamino.com/paadi/memberDB v1.0.11 h1:Mwo86NVe7sLReRf+R4Z6hRxeEIgjjq6EPyiL1L1TlrA= +gitea.tecamino.com/paadi/memberDB v1.0.11/go.mod h1:iLm7nunVRzqJK8CV4PJVuWIhgPlQjNIaeOkmtfK5fMg= gitea.tecamino.com/paadi/tecamino-dbm v0.1.1 h1:vAq7mwUxlxJuLzCQSDMrZCwo8ky5usWi9Qz+UP+WnkI= gitea.tecamino.com/paadi/tecamino-dbm v0.1.1/go.mod h1:+tmf1rjPaKEoNeUcr1vdtoFIFweNG3aUGevDAl3NMBk= gitea.tecamino.com/paadi/tecamino-logger v0.2.1 h1:sQTBKYPdzn9mmWX2JXZBtGBvNQH7cuXIwsl4TD0aMgE= diff --git a/backend/main.go b/backend/main.go index 76b28eb..a1464bc 100644 --- a/backend/main.go +++ b/backend/main.go @@ -121,16 +121,22 @@ func main() { role := auth.Group("", accessHandler.AuthorizeRole("/api")) role.GET("/members", dbHandler.GetMember) + auth.GET("/events", dbHandler.GetEvent) auth.GET("/users", accessHandler.GetUser) auth.GET("/roles", accessHandler.GetRole) auth.POST("database/open", dbHandler.OpenDatabase) auth.POST("/members/add", dbHandler.AddNewMember) - auth.POST("/members/edit", dbHandler.EditMember) + auth.POST("/members/edit", dbHandler.UpdateMember) auth.POST("/members/delete", dbHandler.DeleteMember) auth.POST("/members/import/csv", dbHandler.ImportCSV) + auth.POST("/events/add", dbHandler.StartNewEvent) + auth.POST("/events/add/attendees", dbHandler.AddNewAttendees) + auth.POST("/events/delete/attendees", dbHandler.DeleteAttendee) + auth.POST("/events/delete", dbHandler.DeleteEvent) + auth.POST("/roles/add", accessHandler.AddRole) auth.POST("/roles/update", accessHandler.UpdateRole) auth.POST("/roles/delete", accessHandler.DeleteRole) diff --git a/backend/members.dba b/backend/members.dba index 5cd7f65..3bce730 100644 Binary files a/backend/members.dba and b/backend/members.dba differ diff --git a/package.json b/package.json index 44332c7..a7c3c1f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lightcontrol", - "version": "1.0.4", + "version": "1.0.5", "description": "A Tecamino App", "productName": "Member Database", "author": "A. Zuercher", diff --git a/quasar.config.ts b/quasar.config.ts index 90459c8..d370c53 100644 --- a/quasar.config.ts +++ b/quasar.config.ts @@ -11,7 +11,7 @@ export default defineConfig((/* ctx */) => { // app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli-vite/boot-files - boot: ['auth', 'axios', 'lang', 'quasar-global'], + boot: ['auth', 'axios', 'lang', 'quasar-global', 'restore-route'], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#css css: ['app.scss'], diff --git a/src/assets/lang/de-CH.yaml b/src/assets/lang/de-CH.yaml index 4612c97..4b35e87 100644 --- a/src/assets/lang/de-CH.yaml +++ b/src/assets/lang/de-CH.yaml @@ -61,7 +61,9 @@ emailIsRequired: Email isch erforderlich roleIsRequired: Rolle isch erforderlich permissions: Recht selectRoleOptions: Wähle Roue Optione +selectEventOptions: Wähle Verastautigs Optione addNewRole: Füeg neui Roue hinzue +addNewEvent: Füeg neui Verastautig hinzue veryWeak: sehr Schwach weak: Schwach fair: So so @@ -81,3 +83,25 @@ members: Mitglider attendanceTable: Anweseheits Tabelle excursionTable: Usflugs Tabelle updated: aktualisiert +events: Veranstalige +eventNameIsRequired: Verastatigsname isch erforderlich +eventName: Verastatigsname +attendees: Teilnähmer +now: Jetzt +addToEvent: Füge zu Veranstautig +add: Hinzuefüege +event: Verastautig +dateAndTime: Datum und Zyt +count: Anzau +selectAttendeesOptions: Wähle Teilnehmer Optionen +addNewAttendees: Füeg neue Teilnehmer hinzue +notAllRequiredFieldsFilled: Nid aui erforderliche Felder usgfüet +memberUpdated: Mitglied aktualisiert +membersUpdated: Mitglieder aktualisiert +deleteAttendee: Teilnehmer entfernt +deleteAttendees: Teilnehmer entfernt +deleteRoles: Rolen entfernt +attendeeAdded: Teilnämer hinzuegfüegt +attendeesAdded: Teilnämer hinzuegfüegt +eventAdded: Verastautig hinzuegfüegt +userUpdated: Benutzer aktualisiert diff --git a/src/assets/lang/de-DE.yaml b/src/assets/lang/de-DE.yaml index f45deb9..21709c0 100644 --- a/src/assets/lang/de-DE.yaml +++ b/src/assets/lang/de-DE.yaml @@ -60,8 +60,10 @@ userIsRequired: Benutzer ist erforderlich emailIsRequired: Email ist erforderlich roleIsRequired: Rolle ist erforderlich permissions: Rechte -selectRoleOptions: Wähle Rollen Option +selectRoleOptions: Wähle Rollen Optionen +selectEventOptions: Wähle Veranstaltungs Optionen addNewRole: Füge neue Rolle hinzu +addNewEvent: Füeg neue Veranstaltung hinzu veryWeak: sehr Schwach weak: Schwach fair: Ausreichend @@ -81,3 +83,25 @@ members: Mitglieder attendanceTable: Anwesenheits Tabelle excursionTable: Ausflugs Tabelle updated: aktualisiert +events: Veranstaltungen +eventNameIsRequired: Veranstaltungsname ist erforderlich +eventName: Veranstaltungsname +attendees: Teilnehmer +now: Jetzt +addToEvent: Füge zu Veranstaltung +add: Hinzufügen +event: Veranstaltung +dateAndTime: Datum und Zeit +count: Anzahl +selectAttendeesOptions: Wähle Teilnehmer Optionen +addNewAttendees: Füge neuen Teilnehmer hinzu +notAllRequiredFieldsFilled: Nicht alle erforderlichen Felder ausgefüllt +memberUpdated: Mitglied aktualisiert +membersUpdated: Mitglieder aktualisiert +deleteAttendee: Teilnehmer entfernt +deleteAttendees: Teilnehmer entfernt +deleteRoles: Rolen entfernt +attendeeAdded: Teilnehmer hinzugefügt +attendeesAdded: Teilnehmer hinzugefügt +eventAdded: Veranstaltung hinzugefügt +userUpdated: Benutzer aktualisiert diff --git a/src/assets/lang/en-US.yaml b/src/assets/lang/en-US.yaml index 706ffa8..bb70dcb 100644 --- a/src/assets/lang/en-US.yaml +++ b/src/assets/lang/en-US.yaml @@ -61,7 +61,9 @@ emailIsRequired: Email is required roleIsRequired: Role is required permissions: Permissions selectRoleOptions: Select Role Options +selectEventOptions: Select Event Options addNewRole: Add new Role +addNewEvent: Add new Event veryWeak: very Weak weak: Weak fair: Fair @@ -81,3 +83,25 @@ members: Members attendanceTable: Attendance Table excursionTable: Excursion Table updated: updated +events: Events +eventNameIsRequired: Eventname is required +eventName: Eventname +attendees: Attendees +now: Now +addToEvent: Add to event +add: Add +event: Event +dateAndTime: Date and Time +count: Count +selectAttendeesOptions: Select Attendees Options +addNewAttendees: Add new Attendee +notAllRequiredFieldsFilled: Not all required fields are filled in +memberUpdated: Member updated +membersUpdated: Members updated +deleteAttendee: Attendee deleted +deleteAttendees: Attendees deleted +deleteRoles: Roles deleted +attendeeAdded: Attendee added +attendeesAdded: Attendees added +eventAdded: Event added +userUpdated: User updated diff --git a/src/boot/auth.ts b/src/boot/auth.ts index 3bc8220..83db2aa 100644 --- a/src/boot/auth.ts +++ b/src/boot/auth.ts @@ -16,7 +16,7 @@ export default boot(async ({ app }) => { .then((resp) => { useStore .setUser({ id: resp.data.id, username: resp.data.username, role: resp.data.role }) - .catch((err) => console.log(err)); + .catch((err) => console.error(err)); login.refresh().catch((err) => console.error(err)); }) .catch(() => { diff --git a/src/boot/restore-route.js b/src/boot/restore-route.js new file mode 100644 index 0000000..b1cb255 --- /dev/null +++ b/src/boot/restore-route.js @@ -0,0 +1,32 @@ +import { boot } from 'quasar/wrappers'; +import { useUserStore } from 'src/vueLib/login/userStore'; + +export default boot(async ({ router }) => { + const userStore = useUserStore(); + + // Restore logic after router is ready but before navigation + router.isReady().then(() => { + const lastRoute = sessionStorage.getItem('lastRoute'); + const currentPath = router.currentRoute.value.fullPath; + + // Restore only if: + // - we’re on root ("/" or "/#/"), and + // - a last route exists, and + // - the user is authenticated + if ( + lastRoute && + ['/', '/#/', '/#/index.html'].includes(currentPath) && + userStore.isAuthenticated + ) { + router.replace(lastRoute).catch(() => {}); + } + }); + + // Save the route after every successful navigation + router.afterEach((to) => { + // Don't save login page as "last route" + if (to.path !== '/login' && to.path !== '/') { + sessionStorage.setItem('lastRoute', to.fullPath); + } + }); +}); diff --git a/src/components/AddToEvent.vue b/src/components/AddToEvent.vue new file mode 100644 index 0000000..b96c417 --- /dev/null +++ b/src/components/AddToEvent.vue @@ -0,0 +1,91 @@ + + + diff --git a/src/components/EditOneDialog.vue b/src/components/EditOneDialog.vue index 8da98e4..30425d3 100644 --- a/src/components/EditOneDialog.vue +++ b/src/components/EditOneDialog.vue @@ -1,17 +1,35 @@ @@ -22,6 +40,7 @@ import { ref } from 'vue'; import { appApi } from 'src/boot/axios'; import type { Member } from 'src/vueLib/models/member'; import { useNotify } from 'src/vueLib/general/useNotify'; +import { i18n } from 'src/boot/lang'; const dialog = ref(); const localMember = ref(); @@ -34,9 +53,6 @@ const props = defineProps({ type: String, required: true, }, - queryId: { - type: Boolean, - }, }); const emit = defineEmits(['update']); @@ -52,26 +68,24 @@ function open(label: string, field: string, member: Member) { } function save() { - let query = props.endpoint; - if (props.queryId) { - query += '?id=' + localMember.value.id; - } let payload = {}; if (value.value === localMember.value[localField.value]) { dialog.value.close(); return; } - payload = { - id: localMember.value.id, - [localField.value]: value.value, - }; + payload = [ + { + id: localMember.value.id, + [localField.value]: value.value, + }, + ]; appApi - .post(query, payload) - .then((resp) => { + .post(props.endpoint, payload) + .then(() => { emit('update'); - NotifyResponse(resp.data); + NotifyResponse(i18n.global.t('memberUpdated')); dialog.value.close(); }) .catch((err) => { @@ -79,5 +93,18 @@ function save() { }); } +function setTimeNow() { + const now = new Date(); + + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); // Months are 0-based + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + + value.value = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; +} + defineExpose({ open }); diff --git a/src/components/EventEditAllDialog.vue b/src/components/EventEditAllDialog.vue new file mode 100644 index 0000000..bfd2fd9 --- /dev/null +++ b/src/components/EventEditAllDialog.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/src/components/MemberEditAllDialog.vue b/src/components/MemberEditAllDialog.vue index 8df03d2..bd06dab 100644 --- a/src/components/MemberEditAllDialog.vue +++ b/src/components/MemberEditAllDialog.vue @@ -90,7 +90,7 @@
- Save + {{ $t('save') }}
@@ -101,6 +101,7 @@ import { ref } from 'vue'; import { appApi } from 'src/boot/axios'; import type { Member } from 'src/vueLib/models/member'; import { useNotify } from 'src/vueLib/general/useNotify'; +import { i18n } from 'src/boot/lang'; const { NotifyResponse } = useNotify(); const dialog = ref(); @@ -158,18 +159,21 @@ function open(member: Member | null) { async function save() { const valid = await form.value.validate(); + if (!valid) { + NotifyResponse(i18n.global.t('notAllRequiredFieldsFilled'), 'error'); + return; + } - if (!valid) return; - - let query = 'members/edit?id=' + localMember.value.id; + let query = 'members/edit'; if (newMember.value) { query = 'members/add'; } - appApi - .post(query, JSON.stringify(localMember.value)) + await appApi + .post(query, JSON.stringify([localMember.value])) .then(() => { emit('update-member'); + NotifyResponse(i18n.global.t('memberUpdated')); dialog.value.close(); }) .catch((err) => NotifyResponse(err, 'error')); diff --git a/src/components/RoleEditAllDialog.vue b/src/components/RoleEditAllDialog.vue index 861de59..8d49ef8 100644 --- a/src/components/RoleEditAllDialog.vue +++ b/src/components/RoleEditAllDialog.vue @@ -27,7 +27,7 @@
- Save + {{ $t('save') }}
diff --git a/src/components/UserEditAllDialog.vue b/src/components/UserEditAllDialog.vue index c207159..e9f16ff 100644 --- a/src/components/UserEditAllDialog.vue +++ b/src/components/UserEditAllDialog.vue @@ -100,7 +100,7 @@
- Save + {{ $t('save') }}
diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 32d4d05..9b1407c 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -31,7 +31,17 @@ v-ripple @click="closeDrawer" > - Members + {{ $t('members') }} + + + {{ $t('events') }} diff --git a/src/pages/EventsTable.vue b/src/pages/EventsTable.vue new file mode 100644 index 0000000..9b1a84b --- /dev/null +++ b/src/pages/EventsTable.vue @@ -0,0 +1,21 @@ + + + diff --git a/src/pages/LoginPage.vue b/src/pages/LoginPage.vue index 6f5cd6d..246b8ac 100644 --- a/src/pages/LoginPage.vue +++ b/src/pages/LoginPage.vue @@ -21,6 +21,7 @@ onMounted(() => { const forwardToPage = async () => { await nextTick(); - await router.push('/members'); + const lastRoute = sessionStorage.getItem('lastRoute') || '/members'; + await router.push(lastRoute); }; diff --git a/src/pages/MembersTable.vue b/src/pages/MembersTable.vue index 5bc23cb..dfa800d 100644 --- a/src/pages/MembersTable.vue +++ b/src/pages/MembersTable.vue @@ -9,9 +9,6 @@ Get Selected -
- Click Me -
@@ -20,15 +17,12 @@ import MembersTable from 'src/vueLib/tables/members/MembersTable.vue'; import DialogFrame from 'src/vueLib/dialog/DialogFrame.vue'; import { ref } from 'vue'; import type { MemberDialog } from 'src/vueLib/tables/members/MembersTable.vue'; +import type { Members } from 'src/vueLib/models/member'; const dialog = ref(); const memberDialog = ref(); -const open = () => dialog.value?.open(); - -function getSelection() { - const selected = memberDialog.value?.getSelected(); - if (selected === undefined) return; - console.log(65, selected[0]?.id); +function getSelection(): Members { + return memberDialog.value?.getSelected() || []; } diff --git a/src/pages/SettingsPage.vue b/src/pages/SettingsPage.vue index c2b63e0..3005b3a 100644 --- a/src/pages/SettingsPage.vue +++ b/src/pages/SettingsPage.vue @@ -139,11 +139,9 @@ import { reactive, ref, watch } from 'vue'; import { appApi } from 'src/boot/axios'; import { useNotify } from 'src/vueLib/general/useNotify'; import { type Settings } from 'src/vueLib/models/settings'; -import { useLogin } from 'src/vueLib/login/useLogin'; import { useUserStore } from 'src/vueLib/login/userStore'; const { NotifyResponse } = useNotify(); -const { getUser } = useLogin(); const colorGroup = ref(false); const user = useUserStore(); @@ -185,8 +183,12 @@ function save() { localStorage.setItem('secondaryColor', settings.secondaryColor); localStorage.setItem('secondaryColorText', settings.secondaryColorText); + const tempuser = user.user; + if (tempuser) { + tempuser.settings = settings; + } appApi - .post('settings/update', { user: getUser()?.username, settings }) + .post('users/update', tempuser) .then((resp) => NotifyResponse(resp.data.message)) .catch((err) => NotifyResponse(err, 'error')); } diff --git a/src/router/routes.ts b/src/router/routes.ts index bb94809..628444d 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -18,6 +18,11 @@ const routes: RouteRecordRaw[] = [ component: () => import('pages/MembersTable.vue'), meta: { requiresAuth: true, requiresAdmin: true }, }, + { + path: 'events', + component: () => import('pages/EventsTable.vue'), + meta: { requiresAuth: true, requiresAdmin: true }, + }, { path: 'settings', component: () => import('pages/SettingsPage.vue'), diff --git a/src/vueLib/checkboxes/CheckBoxGroupPermissions.vue b/src/vueLib/checkboxes/CheckBoxGroupPermissions.vue index 51c3c8c..7ee77f9 100644 --- a/src/vueLib/checkboxes/CheckBoxGroupPermissions.vue +++ b/src/vueLib/checkboxes/CheckBoxGroupPermissions.vue @@ -2,6 +2,7 @@ + {{ permission }}
{{ $t(permission.name) }}
diff --git a/src/vueLib/checkboxes/permissions.ts b/src/vueLib/checkboxes/permissions.ts index 65b38ca..2a3cfff 100644 --- a/src/vueLib/checkboxes/permissions.ts +++ b/src/vueLib/checkboxes/permissions.ts @@ -26,8 +26,8 @@ export const defaultPermissions = [ permission: 0, }, { - name: 'attendanceTable', - label: i18n.global.t('attendanceTable'), + name: 'events', + label: i18n.global.t('events'), permission: 0, }, { diff --git a/src/vueLib/login/LoginMenu.vue b/src/vueLib/login/LoginMenu.vue index eb366de..19e4ad2 100644 --- a/src/vueLib/login/LoginMenu.vue +++ b/src/vueLib/login/LoginMenu.vue @@ -3,9 +3,7 @@ - {{ - currentUser?.username - }} + {{ currentUser?.username }} {{ loginText }} @@ -47,23 +45,23 @@ + + diff --git a/src/vueLib/tables/events/EventsTable.ts b/src/vueLib/tables/events/EventsTable.ts new file mode 100644 index 0000000..8fd0602 --- /dev/null +++ b/src/vueLib/tables/events/EventsTable.ts @@ -0,0 +1,79 @@ +import { appApi } from 'src/boot/axios'; +import { ref, computed } from 'vue'; +import type { Events } from 'src/vueLib/models/event'; +import { useNotify } from 'src/vueLib/general/useNotify'; +import { i18n } from 'boot/lang'; + +export function useEventTable() { + const Events = ref([]); + + const pagination = ref({ + sortBy: 'firstName', + descending: false, + page: 1, + rowsPerPage: 20, + }); + + const columns = computed(() => [ + { + name: 'name', + align: 'left' as const, + label: i18n.global.t('name'), + field: 'name', + sortable: true, + }, + { + name: 'attendees', + align: 'center' as const, + label: i18n.global.t('attendees'), + field: 'attendees', + sortable: true, + }, + { + name: 'date', + align: 'left' as const, + label: i18n.global.t('dateAndTime'), + field: 'date', + sortable: true, + }, + { name: 'option', align: 'center' as const, label: '', field: 'option', icon: 'option' }, + ]); + + const { NotifyResponse } = useNotify(); + + const loading = ref(false); + + //updates Event list from database + function updateEvents() { + loading.value = true; + + appApi + .get('events') + .then((resp) => { + if (resp.data === null) { + Events.value = []; + return; + } + Events.value = resp.data as Events; + if (Events.value === null) { + Events.value = []; + return; + } + }) + + .catch((err) => { + NotifyResponse(err, 'error'); + }) + .finally(() => { + loading.value = false; + }); + } + + return { + Events, + pagination, + columns, + loading, + updateEvents, + }; +} diff --git a/src/vueLib/tables/events/EventsTable.vue b/src/vueLib/tables/events/EventsTable.vue new file mode 100644 index 0000000..b255915 --- /dev/null +++ b/src/vueLib/tables/events/EventsTable.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/src/vueLib/tables/members/MembersTable.ts b/src/vueLib/tables/members/MembersTable.ts index 09aacb0..7705325 100644 --- a/src/vueLib/tables/members/MembersTable.ts +++ b/src/vueLib/tables/members/MembersTable.ts @@ -16,101 +16,122 @@ export function useMemberTable() { rowsPerPage: 20, }); - const columns = computed(() => [ - { name: 'cake', align: 'center' as const, label: '', field: 'cake', icon: 'cake' }, - { - name: 'firstName', - align: 'left' as const, - label: i18n.global.t('prename'), - field: 'firstName', - sortable: true, - }, - { - name: 'lastName', - align: 'left' as const, - label: i18n.global.t('lastName'), - field: 'lastName', - sortable: true, - }, - { - name: 'birthday', - align: 'left' as const, - label: i18n.global.t('birthday'), - field: 'birthday', - sortable: true, - }, - { - name: 'age', - align: 'left' as const, - label: i18n.global.t('age'), - field: 'age', - sortable: true, - }, - { - name: 'address', - align: 'left' as const, - label: i18n.global.t('address'), - field: 'address', - sortable: true, - }, - { - name: 'town', - align: 'left' as const, - label: i18n.global.t('town'), - field: 'town', - sortable: true, - }, - { - name: 'zip', - align: 'left' as const, - label: i18n.global.t('zipCode'), - field: 'zip', - sortable: true, - }, - { - name: 'phone', - align: 'left' as const, - label: i18n.global.t('phone'), - field: 'phone', - sortable: true, - }, - { - name: 'email', - align: 'left' as const, - label: i18n.global.t('email'), - field: 'email', - sortable: true, - }, - { - name: 'group', - align: 'left' as const, - label: i18n.global.t('group'), - field: 'group', - sortable: true, - }, - { - name: 'responsiblePerson', - align: 'left' as const, - label: i18n.global.t('responsible'), - field: 'responsiblePerson', - sortable: true, - }, - { - name: 'firstVisit', - align: 'left' as const, - label: i18n.global.t('firstVisit'), - field: 'firstVisit', - sortable: true, - }, - { - name: 'lastVisit', - align: 'left' as const, - label: i18n.global.t('lastVisit'), - field: 'lastVisit', - sortable: true, - }, - { name: 'option', align: 'center' as const, label: '', field: 'option', icon: 'option' }, - ]); + //add enabling of each columns + const enabledColumns = ref>({ + cake: true, + firstName: true, + lastName: true, + birthday: true, + age: true, + address: false, + town: true, + zip: true, + phone: true, + email: true, + group: true, + responsiblePerson: true, + firstVisit: true, + lastVisit: true, + option: true, + }); + + const columns = computed(() => + [ + { name: 'cake', align: 'center' as const, label: '', field: 'cake', icon: 'cake' }, + { + name: 'firstName', + align: 'left' as const, + label: i18n.global.t('prename'), + field: 'firstName', + sortable: true, + }, + { + name: 'lastName', + align: 'left' as const, + label: i18n.global.t('lastName'), + field: 'lastName', + sortable: true, + }, + { + name: 'birthday', + align: 'left' as const, + label: i18n.global.t('birthday'), + field: 'birthday', + sortable: true, + }, + { + name: 'age', + align: 'left' as const, + label: i18n.global.t('age'), + field: 'age', + sortable: true, + }, + { + name: 'address', + align: 'left' as const, + label: i18n.global.t('address'), + field: 'address', + sortable: true, + }, + { + name: 'town', + align: 'left' as const, + label: i18n.global.t('town'), + field: 'town', + sortable: true, + }, + { + name: 'zip', + align: 'left' as const, + label: i18n.global.t('zipCode'), + field: 'zip', + sortable: true, + }, + { + name: 'phone', + align: 'left' as const, + label: i18n.global.t('phone'), + field: 'phone', + sortable: true, + }, + { + name: 'email', + align: 'left' as const, + label: i18n.global.t('email'), + field: 'email', + sortable: true, + }, + { + name: 'group', + align: 'left' as const, + label: i18n.global.t('group'), + field: 'group', + sortable: true, + }, + { + name: 'responsiblePerson', + align: 'left' as const, + label: i18n.global.t('responsible'), + field: 'responsiblePerson', + sortable: true, + }, + { + name: 'firstVisit', + align: 'left' as const, + label: i18n.global.t('firstVisit'), + field: 'firstVisit', + sortable: true, + }, + { + name: 'lastVisit', + align: 'left' as const, + label: i18n.global.t('lastVisit'), + field: 'lastVisit', + sortable: true, + }, + { name: 'option', align: 'center' as const, label: '', field: 'option', icon: 'option' }, + ].filter((c) => enabledColumns.value[c.name]), + ); const { NotifyResponse } = useNotify(); @@ -197,6 +218,13 @@ export function useMemberTable() { }); } + function disableColumns(...columns: string[]) { + columns.forEach((col) => { + if (col in enabledColumns.value) { + enabledColumns.value[col] = false; + } + }); + } return { members, pagination, @@ -205,5 +233,6 @@ export function useMemberTable() { getRowClass, updateMembers, isXDaysBeforeAnnualDate, + disableColumns, }; } diff --git a/src/vueLib/tables/members/MembersTable.vue b/src/vueLib/tables/members/MembersTable.vue index 7ef8f07..8958598 100644 --- a/src/vueLib/tables/members/MembersTable.vue +++ b/src/vueLib/tables/members/MembersTable.vue @@ -9,7 +9,7 @@ :no-data-label="$t('noDataAvailable')" :loading-label="$t('loading')" :rows-per-page-label="$t('recordsPerPage')" - :selected-rows-label="(val) => val + $t('recordSelected')" + :selected-rows-label="(val) => val + ' ' + $t('recordSelected')" :rows="members" :columns="columns" row-key="id" @@ -24,7 +24,7 @@ @@ -79,9 +92,9 @@ @@ -100,10 +113,7 @@