diff --git a/aleksis/core/frontend/components/person/PersonActions.vue b/aleksis/core/frontend/components/person/PersonActions.vue index 5bad55e08cc3a86271cb58ed57265152b0f0d572..0929fde34b3d918f9fd23df8e381a74b32182934 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 cae913842328e206d54ee4767b223160385027c6..fef7aff504596b15e49fb433e6a06accca079aab 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 048df5b9fc9a1d3460578444fc2ee5bf3ea0c97b..e7fa45bd6349e3b2ae29a65d9167ad90797b531d 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 0000000000000000000000000000000000000000..0913ba77f4ecbd6a247ca00a5a70ab35fec83a38 --- /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 b041afd028112049abe19c316668dc7a2a256c5a..209671ae30481c5af003ae60e55146e55c49c293 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 0000000000000000000000000000000000000000..5be70d5146419979abe5a6dadd8e204664119e91 --- /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 048272f56950762b065df8572323b834a97a1733..f604de3b534a88c517e27311fbebd9f8ba042ded 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: {