From c48e5786a87959d8a2bad5226b96536dfdf62e41 Mon Sep 17 00:00:00 2001 From: Hangzhi Yu <hangzhi@protonmail.com> Date: Thu, 6 Mar 2025 01:16:58 +0100 Subject: [PATCH] Restructure components --- .../components/person/PersonActions.vue | 192 +++++++----------- .../frontend/components/person/PersonForm.vue | 59 +++++- .../frontend/components/person/PersonList.vue | 12 +- .../components/person/PersonListWrapper.vue | 22 ++ .../components/person/PersonOverview.vue | 1 - .../person/PersonOverviewWrapper.vue | 33 +++ aleksis/core/frontend/routes.js | 4 +- 7 files changed, 189 insertions(+), 134 deletions(-) create mode 100644 aleksis/core/frontend/components/person/PersonListWrapper.vue create mode 100644 aleksis/core/frontend/components/person/PersonOverviewWrapper.vue diff --git a/aleksis/core/frontend/components/person/PersonActions.vue b/aleksis/core/frontend/components/person/PersonActions.vue index 5bad55e08..0929fde34 100644 --- a/aleksis/core/frontend/components/person/PersonActions.vue +++ b/aleksis/core/frontend/components/person/PersonActions.vue @@ -4,107 +4,89 @@ import PersonForm from "./PersonForm.vue"; <template> <div> - <person-form - v-if="$route.query.action === 'edit'" - :i18n-key="i18nKey" - :gql-query="gqlQuery" - :gql-delete-mutation="gqlDeleteMutation" - :gql-patch-mutation="gqlPatchMutation" - :gql-create-mutation="gqlCreateMutation" - :edit-item="editItem" - :is-create="false" - :fallback-url="{ name: 'core.personById', params: { id: person.id } }" - :success-redirect-url="{ + <v-btn + v-if="person.canEdit" + color="primary" + :to="{ name: 'core.personById', params: { id: person.id }, + query: { _ui_action: 'edit' }, }" - v-on="$listeners" - /> - <template v-else-if="person && person.id"> - <v-btn - v-if="person.canEdit" - color="primary" + > + <v-icon left>$edit</v-icon> + {{ $t("actions.edit") }} + </v-btn> + <v-btn + v-if="person.canChangePersonPreferences" + color="secondary" + outlined + text + :to="{ + name: 'core.preferencesPersonByPk', + params: { pk: person.id }, + }" + > + <v-icon left>$preferences</v-icon> + {{ $t("preferences.person.change_preferences") }} + </v-btn> + + <button-menu + v-if=" + person.canImpersonatePerson || + person.canInvitePerson || + person.canDelete + " + > + <v-list-item + v-if="person.canImpersonatePerson" :to="{ - name: 'core.personById', - params: { id: person.id }, - query: { action: 'edit' }, + name: 'impersonate.impersonateByUserPk', + params: { uid: person.userid }, + query: { next: $route.path }, }" > - <v-icon left>$edit</v-icon> - {{ $t("actions.edit") }} - </v-btn> - <v-btn - v-if="person.canChangePersonPreferences" - color="secondary" - outlined - text + <v-list-item-icon> + <v-icon>mdi-account-box-outline</v-icon> + </v-list-item-icon> + <v-list-item-content> + <v-list-item-title> + {{ $t("person.impersonation.impersonate") }} + </v-list-item-title> + </v-list-item-content> + </v-list-item> + + <v-list-item + v-if="person.canInvitePerson" :to="{ - name: 'core.preferencesPersonByPk', - params: { pk: person.id }, + name: 'core.invitePerson', + params: { id: person.id }, }" > - <v-icon left>$preferences</v-icon> - {{ $t("preferences.person.change_preferences") }} - </v-btn> + <v-list-item-icon> + <v-icon>mdi-account-plus-outline</v-icon> + </v-list-item-icon> + <v-list-item-content> + <v-list-item-title> + {{ $t("person.invite") }} + </v-list-item-title> + </v-list-item-content> + </v-list-item> - <button-menu - v-if=" - person.canImpersonatePerson || - person.canInvitePerson || - person.canDelete - " + <v-list-item + v-if="person.canDelete" + @click="showDeleteConfirm = true" + class="error--text" > - <v-list-item - v-if="person.canImpersonatePerson" - :to="{ - name: 'impersonate.impersonateByUserPk', - params: { uid: person.userid }, - query: { next: $route.path }, - }" - > - <v-list-item-icon> - <v-icon>mdi-account-box-outline</v-icon> - </v-list-item-icon> - <v-list-item-content> - <v-list-item-title> - {{ $t("person.impersonation.impersonate") }} - </v-list-item-title> - </v-list-item-content> - </v-list-item> - - <v-list-item - v-if="person.canInvitePerson" - :to="{ - name: 'core.invitePerson', - params: { id: person.id }, - }" - > - <v-list-item-icon> - <v-icon>mdi-account-plus-outline</v-icon> - </v-list-item-icon> - <v-list-item-content> - <v-list-item-title> - {{ $t("person.invite") }} - </v-list-item-title> - </v-list-item-content> - </v-list-item> - - <v-list-item - v-if="person.canDelete" - @click="showDeleteConfirm = true" - class="error--text" - > - <v-list-item-icon> - <v-icon color="error">$deleteContent</v-icon> - </v-list-item-icon> - <v-list-item-content> - <v-list-item-title> - {{ $t("person.delete") }} - </v-list-item-title> - </v-list-item-content> - </v-list-item> - </button-menu> - </template> + <v-list-item-icon> + <v-icon color="error">$deleteContent</v-icon> + </v-list-item-icon> + <v-list-item-content> + <v-list-item-title> + {{ $t("person.delete") }} + </v-list-item-title> + </v-list-item-content> + </v-list-item> + </button-menu> <delete-dialog v-model="showDeleteConfirm" :gql-delete-mutation="deleteMutation" @@ -127,12 +109,9 @@ import PersonForm from "./PersonForm.vue"; import { deletePersons } from "./personList.graphql"; import DeleteDialog from "../generic/dialogs/DeleteDialog.vue"; -import personCRUDMixin from "../../mixins/personCRUDMixin.js"; - export default { name: "PersonActions", components: { DeleteDialog }, - mixins: [personCRUDMixin], props: { person: { type: Object, @@ -145,33 +124,6 @@ export default { deleteMutation: deletePersons, }; }, - computed: { - editItem() { - return { - id: this.person.id, - firstName: this.person.firstName, - additionalName: this.person.additionalName, - lastName: this.person.lastName, - shortName: this.person.shortName, - user: this.person.userid, - description: this.person.description, - sex: this.person.sex, - street: this.person.street, - housenumber: this.person.housenumber, - postalCode: this.person.postalCode, - place: this.person.place, - phoneNumber: this.person.phoneNumber, - mobileNumber: this.person.mobileNumber, - email: this.person.email, - dateOfBirth: this.person.dateOfBirth, - placeOfBirth: this.person.placeOfBirth, - photo: this.person.photo, - avatar: this.person.avatar, - guardians: this.person.guardians.map((g) => g.id), - primaryGroup: this.person?.primaryGroup?.id, - }; - }, - }, }; </script> diff --git a/aleksis/core/frontend/components/person/PersonForm.vue b/aleksis/core/frontend/components/person/PersonForm.vue index cae913842..fef7aff50 100644 --- a/aleksis/core/frontend/components/person/PersonForm.vue +++ b/aleksis/core/frontend/components/person/PersonForm.vue @@ -12,11 +12,17 @@ import AdditionalImage from "./AdditionalImage.vue"; <fullscreen-dialog-object-form v-bind="$attrs" v-on="$listeners" + :i18n-key="i18nKey" + :gql-query="gqlQuery" + :gql-delete-mutation="gqlDeleteMutation" + :gql-patch-mutation="gqlPatchMutation" + :gql-create-mutation="gqlCreateMutation" full-width :fields="filteredFields" :create-item-i18n-key="createItemI18nKey" :edit-item-i18n-key="editItemI18nKey" :get-patch-data="getPatchData" + :edit-item="editItem" > <!-- eslint-disable-next-line vue/valid-v-slot --> <template #firstName.field="{ attrs, on }"> @@ -132,12 +138,15 @@ import AdditionalImage from "./AdditionalImage.vue"; <script> import formRulesMixin from "../../mixins/formRulesMixin.js"; import permissionsMixin from "../../mixins/permissions.js"; +import personCRUDMixin from "../../mixins/personCRUDMixin.js"; import { gqlEditableFieldsPreference, gqlUsers } from "./personForm.graphql"; +import gqlPersonOverview from "./personOverview.graphql"; + export default { name: "PersonForm", - mixins: [formRulesMixin, permissionsMixin], + mixins: [formRulesMixin, permissionsMixin, personCRUDMixin], data() { return { fields: [ @@ -256,13 +265,33 @@ export default { ], createItemI18nKey: "person.form.create", editItemI18nKey: "person.form.edit", + person: null, }; }, + props: { + id: { + type: String, + required: false, + default: null, + }, + }, apollo: { users: gqlUsers, systemProperties: { query: gqlEditableFieldsPreference, }, + person: { + query: gqlPersonOverview, + variables() { + return { + id: this.id, + }; + }, + skip() { + return !this.id; + }, + update: (data) => data.object, + } }, computed: { editPersonID() { @@ -299,6 +328,34 @@ export default { } return this.fields; }, + editItem() { + if (this.person) { + return { + id: this.person.id, + firstName: this.person.firstName, + additionalName: this.person.additionalName, + lastName: this.person.lastName, + shortName: this.person.shortName, + user: this.person.userid, + description: this.person.description, + sex: this.person.sex, + street: this.person.street, + housenumber: this.person.housenumber, + postalCode: this.person.postalCode, + place: this.person.place, + phoneNumber: this.person.phoneNumber, + mobileNumber: this.person.mobileNumber, + email: this.person.email, + dateOfBirth: this.person.dateOfBirth, + placeOfBirth: this.person.placeOfBirth, + photo: this.person.photo, + avatar: this.person.avatar, + guardians: this.person.guardians.map((g) => g.id), + primaryGroup: this.person?.primaryGroup?.id, + }; + } + return null; + }, }, methods: { handleNameInput(input, itemModel, setter) { diff --git a/aleksis/core/frontend/components/person/PersonList.vue b/aleksis/core/frontend/components/person/PersonList.vue index 048df5b9f..e7fa45bd6 100644 --- a/aleksis/core/frontend/components/person/PersonList.vue +++ b/aleksis/core/frontend/components/person/PersonList.vue @@ -65,17 +65,9 @@ export default { color="secondary" :to="{ name: 'core.persons', - query: { action: 'create' }, + query: { _ui_action: 'create' }, }" - :disabled="$route.query.action === 'create'" - /> - - <person-form - v-if="$route.query.action === 'create'" - v-bind="attrs" - v-on="on" - :fallback-url="{ name: 'core.persons' }" - :success-redirect-url="{ name: 'core.persons' }" + :disabled="$route.query._ui_action === 'create'" /> </template> diff --git a/aleksis/core/frontend/components/person/PersonListWrapper.vue b/aleksis/core/frontend/components/person/PersonListWrapper.vue new file mode 100644 index 000000000..0913ba77f --- /dev/null +++ b/aleksis/core/frontend/components/person/PersonListWrapper.vue @@ -0,0 +1,22 @@ +<template> + <component :is="currentComponent" v-bind="componentProps"/> +</template> + +<script> +import PersonForm from "./PersonForm.vue"; +import PersonList from "./PersonList.vue"; + +export default { + computed: { + currentComponent() { + return this.$route.query._ui_action === "create" ? PersonForm : PersonList; + }, + componentProps() { + return this.$route.query._ui_action === "create" ? { + fallbackUrl: { name: 'core.persons' }, + successRedirectUrl: { name: 'core.persons' }, + } : {}; + }, + } +}; +</script> diff --git a/aleksis/core/frontend/components/person/PersonOverview.vue b/aleksis/core/frontend/components/person/PersonOverview.vue index b041afd02..209671ae3 100644 --- a/aleksis/core/frontend/components/person/PersonOverview.vue +++ b/aleksis/core/frontend/components/person/PersonOverview.vue @@ -43,7 +43,6 @@ <person-actions :class="classes" :person="person" - @save="$refs.overview.$apollo.queries.object.refresh()" /> </template> diff --git a/aleksis/core/frontend/components/person/PersonOverviewWrapper.vue b/aleksis/core/frontend/components/person/PersonOverviewWrapper.vue new file mode 100644 index 000000000..5be70d514 --- /dev/null +++ b/aleksis/core/frontend/components/person/PersonOverviewWrapper.vue @@ -0,0 +1,33 @@ +<template> + <component :is="currentComponent" v-bind="componentProps"/> +</template> + +<script> +import PersonForm from "./PersonForm.vue"; +import PersonOverview from "./PersonOverview.vue"; + +export default { + computed: { + currentComponent() { + return this.$route.query._ui_action === "edit" ? PersonForm : PersonOverview; + }, + componentProps() { + return this.$route.query._ui_action === "edit" ? { + fallbackUrl: { name: "core.personById", params: { id: this.id } }, + successRedirectUrl: { name: "core.personById", params: { id: this.id } }, + isCreate: false, + id: this.id, + } : { + id: this.id, + }; + }, + }, + props: { + id: { + type: String, + required: false, + default: null, + }, + }, +}; +</script> diff --git a/aleksis/core/frontend/routes.js b/aleksis/core/frontend/routes.js index 048272f56..f604de3b5 100644 --- a/aleksis/core/frontend/routes.js +++ b/aleksis/core/frontend/routes.js @@ -114,7 +114,7 @@ const routes = [ children: [ { path: "/persons/", - component: () => import("./components/person/PersonList.vue"), + component: () => import("./components/person/PersonListWrapper.vue"), name: "core.persons", meta: { inMenu: true, @@ -126,7 +126,7 @@ const routes = [ }, { path: "/persons/:id(\\d+)", - component: () => import("./components/person/PersonOverview.vue"), + component: () => import("./components/person/PersonOverviewWrapper.vue"), name: "core.personById", props: true, meta: { -- GitLab