From fcd9c488b9de8060914e677499d37b870971066e Mon Sep 17 00:00:00 2001 From: Ashish Sam Date: Thu, 5 Oct 2023 00:37:52 +0530 Subject: [PATCH] Create Fields for changing head of family - Change Head of Family - Change relation of famiy members when head of family is changed - Add mutation for changing head of family - Add query for getting persons in a family --- Tithe-Vue/src/components/AddressForm.vue | 83 +++-- Tithe-Vue/src/components/FormControl.vue | 2 + .../components/MultiSelectBox/Multiselect.vue | 4 +- .../FamilyByParishSingleSelectBox.vue | 8 +- .../SearchBoxes/SingleSelectBox.vue | 7 + .../src/externalized-data/graphqlMutations.js | 16 + .../src/externalized-data/graphqlQueries.js | 35 ++ Tithe-Vue/src/views/FamilyView.vue | 342 ++++++++++++++++++ 8 files changed, 461 insertions(+), 36 deletions(-) diff --git a/Tithe-Vue/src/components/AddressForm.vue b/Tithe-Vue/src/components/AddressForm.vue index 5612b7a..ea1d6ef 100644 --- a/Tithe-Vue/src/components/AddressForm.vue +++ b/Tithe-Vue/src/components/AddressForm.vue @@ -52,6 +52,7 @@ const { }, () => ({ enabled: streetListQueryEnabled, + fetchPolicy: "no-cache", }) ); @@ -118,17 +119,19 @@ const { onError: createStreetError, } = useMutation(CREATE_STREET_MUTATION); -const createStreetOption = (option, setSelected) => { +const createStreetOption = async (option, select$) => { createStreet({ streetName: option.label }); // Not using loading for now - createStreetDone((mutationResult) => { - setSelected({ - id: mutationResult.data?.createOneStreet?.streetId ?? "", - label: mutationResult.data?.createOneStreet?.streetName ?? "", + await new Promise((resolve, reject) => { + createStreetDone(() => { + select$.clear(); + resolve("Success"); }); }); + + return false; }; // City Search Box @@ -150,6 +153,7 @@ const { }, () => ({ enabled: cityListQueryEnabled, + fetchPolicy: "no-cache", }) ); @@ -216,17 +220,17 @@ const { onError: createCityError, } = useMutation(CREATE_CITY_MUTATION); -const createCityOption = (option, setSelected) => { +const createCityOption = async (option, select$) => { createCity({ cityName: option.label }); - // Not using loading for now - - createCityDone((mutationResult) => { - setSelected({ - id: mutationResult.data?.createOneCity?.cityId ?? "", - label: mutationResult.data?.createOneCity?.cityName ?? "", + await new Promise((resolve, reject) => { + createCityDone(() => { + select$.clear(); + resolve("Success"); }); }); + + return false; }; // District Search Box @@ -248,6 +252,7 @@ const { }, () => ({ enabled: districtListQueryEnabled, + fetchPolicy: "no-cache", }) ); @@ -297,17 +302,17 @@ const { onError: createDistrictError, } = useMutation(CREATE_DISTRICT_MUTATION); -const createDistrictOption = (option, setSelected) => { +const createDistrictOption = async (option, select$) => { createDistrict({ districtName: option.label }); - // Not using loading for now - - createDistrictDone((mutationResult) => { - setSelected({ - id: mutationResult.data?.createOneDistrict?.districtId ?? "", - label: mutationResult.data?.createOneDistrict?.districtName ?? "", + await new Promise((resolve, reject) => { + createDistrictDone(() => { + select$.clear(); + resolve("Success"); }); }); + + return false; }; // State Search Box @@ -329,6 +334,7 @@ const { }, () => ({ enabled: stateListQueryEnabled, + fetchPolicy: "no-cache", }) ); @@ -378,17 +384,17 @@ const { onError: createStateError, } = useMutation(CREATE_STATE_MUTATION); -const createStateOption = (option, setSelected) => { +const createStateOption = async (option, select$) => { createState({ stateName: option.label }); - // Not using loading for now - - createStateDone((mutationResult) => { - setSelected({ - id: mutationResult.data?.createOneState?.stateId ?? "", - label: mutationResult.data?.createOneState?.stateName ?? "", + await new Promise((resolve, reject) => { + createStateDone(() => { + select$.clear(); + resolve("Success"); }); }); + + return false; }; // Pincode Search Box @@ -410,6 +416,7 @@ const { }, () => ({ enabled: pincodeListQueryEnabled, + fetchPolicy: "no-cache", }) ); @@ -459,17 +466,17 @@ const { onError: createPincodeError, } = useMutation(CREATE_PINCODE_MUTATION); -const createPincodeOption = (option, setSelected) => { +const createPincodeOption = async (option, select$) => { createPincode({ pincode: option.label }); - // Not using loading for now - - createPincodeDone((mutationResult) => { - setSelected({ - id: mutationResult.data?.createOnePincode?.pincodeId ?? "", - label: mutationResult.data?.createOnePincode?.pincode ?? "", + await new Promise((resolve, reject) => { + createPincodeDone(() => { + select$.clear(); + resolve("Success"); }); }); + + return false; }; const addressRef = ref(null); @@ -517,8 +524,10 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" + :create-option="true" :resolve-on-load="false" :min-chars="1" + :on-create="createStreetOption" class="multipleSelectAddressBox" @search-change="streetSearchChange" @value-change="changeInStreet" @@ -531,8 +540,10 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" + :create-option="true" :resolve-on-load="false" :min-chars="1" + :on-create="createCityOption" class="multipleSelectAddressBox" @search-change="citySearchChange" @value-change="changeInCity" @@ -545,8 +556,10 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" + :create-option="true" :resolve-on-load="false" :min-chars="1" + :on-create="createDistrictOption" class="multipleSelectAddressBox" @search-change="districtSearchChange" @value-change="changeInDistrict" @@ -559,8 +572,10 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" + :create-option="true" :resolve-on-load="false" :min-chars="1" + :on-create="createStateOption" class="multipleSelectAddressBox" @search-change="stateSearchChange" @value-change="changeInState" @@ -573,8 +588,10 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" + :create-option="true" :resolve-on-load="false" :min-chars="1" + :on-create="createPincodeOption" class="multipleSelectAddressBox" @search-change="pincodeSearchChange" @value-change="changeInPincode" diff --git a/Tithe-Vue/src/components/FormControl.vue b/Tithe-Vue/src/components/FormControl.vue index 5f3c5b3..bd82941 100644 --- a/Tithe-Vue/src/components/FormControl.vue +++ b/Tithe-Vue/src/components/FormControl.vue @@ -48,6 +48,7 @@ const props = defineProps({ borderless: Boolean, transparent: Boolean, ctrlKFocus: Boolean, + disabled: Boolean, }); const emit = defineEmits(["update:modelValue", "setRef"]); @@ -163,6 +164,7 @@ if (props.ctrlKFocus) { :autocomplete="autocomplete" :required="required" :placeholder="placeholder" + :disabled="disabled" :type="computedType" :class="inputElClass" /> diff --git a/Tithe-Vue/src/components/MultiSelectBox/Multiselect.vue b/Tithe-Vue/src/components/MultiSelectBox/Multiselect.vue index bec7d03..7bb527d 100644 --- a/Tithe-Vue/src/components/MultiSelectBox/Multiselect.vue +++ b/Tithe-Vue/src/components/MultiSelectBox/Multiselect.vue @@ -259,9 +259,9 @@ :is-pointed="isPointed" :search="search" > - {{ localize(option[label]) }} + {{ localize(option[label]) }} {{ Object.values(option?.meta ?? {}).join(",") }} + >{{ Object.values(option?.meta ?? {}).join(", ") }} diff --git a/Tithe-Vue/src/components/SearchBoxes/FamilyByParishSingleSelectBox.vue b/Tithe-Vue/src/components/SearchBoxes/FamilyByParishSingleSelectBox.vue index bdf60c4..86cbd0d 100644 --- a/Tithe-Vue/src/components/SearchBoxes/FamilyByParishSingleSelectBox.vue +++ b/Tithe-Vue/src/components/SearchBoxes/FamilyByParishSingleSelectBox.vue @@ -42,6 +42,12 @@ const loadFamilies = computed((query, setOptions) => { value: { id: entity.familyId, label: entity.familyName, + headOfFamily: entity.headOfFamily, + persons: entity.persons, + }, + meta: { + headOfFamily: entity.headOfFamily?.personName ?? "", + address: entity.address?.street?.streetName ?? "", }, }; }) ?? [] @@ -74,7 +80,7 @@ defineExpose({ :can-deselect="false" :can-clear="false" :searchable="true" - :meta-label-enabled="false" + :meta-label-enabled="true" @value-change="changeInFamily" /> diff --git a/Tithe-Vue/src/components/SearchBoxes/SingleSelectBox.vue b/Tithe-Vue/src/components/SearchBoxes/SingleSelectBox.vue index 99f1303..547e9c6 100644 --- a/Tithe-Vue/src/components/SearchBoxes/SingleSelectBox.vue +++ b/Tithe-Vue/src/components/SearchBoxes/SingleSelectBox.vue @@ -13,7 +13,12 @@ defineProps({ canClear: Boolean, searchable: Boolean, metaLabelEnabled: Boolean, + createOption: Boolean, resolveOnLoad: Boolean, + onCreate: { + type: Function, + default: () => {}, + }, }); const emit = defineEmits(["valueChange", "searchChange"]); @@ -46,6 +51,8 @@ defineExpose({ :can-clear="canClear" :searchable="searchable" :meta-label-enabled="metaLabelEnabled" + :create-option="createOption" + :on-create="onCreate" :resolve-on-load="resolveOnLoad" class="multiselect-theme" @search-change="searchChange" diff --git a/Tithe-Vue/src/externalized-data/graphqlMutations.js b/Tithe-Vue/src/externalized-data/graphqlMutations.js index 2e9fe82..0d78228 100644 --- a/Tithe-Vue/src/externalized-data/graphqlMutations.js +++ b/Tithe-Vue/src/externalized-data/graphqlMutations.js @@ -86,6 +86,22 @@ export const createFamilyMutation = `mutation createFamily ($family: FamilyMutat } `; +export const createFamilyMembers = `mutation createFamilyMembers ($familyId: ID!, $persons: [PersonMutationThroughFamilyInput]!){ + createManyPersonsInOneFamily (familyId: $familyId, persons: $persons){ + personId + personName + } +} +`; + +export const changeHeadOfFamily = `mutation changeHeadOfFamily ($familyId: ID!, $newHeadOfFamily: PersonRelationSchema!, $persons: [PersonRelationSchema]){ + changeHeadOfFamily (familyId: $familyId, newHeadOfFamily: $newHeadOfFamily, persons: $persons){ + familyId + familyName + } +} +`; + export const deactivateFamilyMutation = `mutation removeFamily ($familyId: ID!){ deactivateOneFamily (familyId: $familyId){ familyId diff --git a/Tithe-Vue/src/externalized-data/graphqlQueries.js b/Tithe-Vue/src/externalized-data/graphqlQueries.js index bd43e51..608ad7c 100644 --- a/Tithe-Vue/src/externalized-data/graphqlQueries.js +++ b/Tithe-Vue/src/externalized-data/graphqlQueries.js @@ -292,6 +292,29 @@ export const familyAllFamilyListQuery = `query familyPageActiveFamily ($parishId getAllFamiliesByParish (parishId: $parishId){ familyId familyName + headOfFamily{ + personId + personName + baptismName + relation{ + relationId + relationName + } + } + address{ + street{ + streetName + } + } + persons{ + personId + personName + baptismName + relation{ + relationId + relationName + } + } } }`; @@ -301,6 +324,18 @@ export const familyPageActiveEnityCountQuery = `query activeCountByFamily ($id: getPersonCountByFamily (familyId: $id) }`; +export const familyPagePersonsQuery = `query familyMembersQuery ($id: ID!){ + getAllPersonsByFamily (familyId: $id) { + personId + personName + baptismName + relation{ + relationId + relationName + } + } +}`; + export const familyPageActivePersonTableQuery = `query activePersonByFamily ($familyId: ID!){ getAllPersonsByFamily (familyId: $familyId) { personId diff --git a/Tithe-Vue/src/views/FamilyView.vue b/Tithe-Vue/src/views/FamilyView.vue index f72b716..61cdfea 100644 --- a/Tithe-Vue/src/views/FamilyView.vue +++ b/Tithe-Vue/src/views/FamilyView.vue @@ -18,10 +18,12 @@ import { import PersonForm from "@/components/Forms/PersonForm.vue"; import AddPersonInFamilyForm from "@/components/Forms/AddPersonInFamilyForm.vue"; +import SingleSelectBox from "@/components/SearchBoxes/SingleSelectBox.vue"; import ForaneSingleSelectBox from "@/components/SearchBoxes/ForaneSingleSelectBox.vue"; import ParishByForaneSingleSelectBox from "@/components/SearchBoxes/ParishByForaneSingleSelectBox.vue"; import FamilyByParishSingleSelectBox from "@/components/SearchBoxes/FamilyByParishSingleSelectBox.vue"; import KoottaymaByParishSingleSelectBox from "@/components/SearchBoxes/KoottaymaByParishSingleSelectBox.vue"; +import RelationSingleSelectBox from "@/components/SearchBoxes/RelationSingleSelectBox.vue"; import LayoutAuthenticated from "@/layouts/LayoutAuthenticated.vue"; import SectionMain from "@/components/SectionMain.vue"; import FormField from "@/components/FormField.vue"; @@ -43,10 +45,13 @@ import TableTabs from "@/components/TableTabs.vue"; import { familyPageActiveEnityCountQuery, familyPageActivePersonTableQuery, + familyPagePersonsQuery, } from "@/externalized-data/graphqlQueries"; import { createFamilyMutation, deactivateFamilyMutation, + createFamilyMembers, + changeHeadOfFamily, } from "@/externalized-data/graphqlMutations"; import { familyPageTableTabTitle, @@ -112,8 +117,156 @@ const activePersonCount = computed( () => activeEntityByFamilyCount.value?.getPersonCountByFamily ?? 0 ); +const createFamilyMembersForm = reactive({ + familyId: "", + persons: [], +}); + +// Change in Head of Family +const changeHeadOfFamilyForm = reactive({ + familyId: "", + newHeadOfFamily: {}, + persons: [], +}); + +// Members in a family +const personsByFamilyEnabled = ref(false); + +const PERSONS_BY_FAMILY_QUERY = gql` + ${familyPagePersonsQuery} +`; + +const { + result: personsByFamilyResult, + onResult: personsByFamilyOnResult, + refetch: personsByFamilyRefetch, +} = useQuery( + PERSONS_BY_FAMILY_QUERY, + () => ({ id: family.value.id }), + () => ({ enabled: personsByFamilyEnabled }) +); +const personsByFamily = computed( + () => + personsByFamilyResult.value?.getAllPersonsByFamily?.map((entity) => { + return { + id: entity.personId, + label: entity.personName, + value: { + id: entity.personId, + label: entity.personName, + relationName: entity.relation?.relationName ?? "", + }, + meta: { + baptismName: entity.baptismName, + relation: entity.relation?.relationName ?? "", + }, + }; + }) ?? [] +); + +const personsByFamilyExcludingOldHeadOfFamily = computed(() => + personsByFamily.value.filter( + (person) => person.id !== family.value?.headOfFamily?.personId + ) +); +const personsByFamilyExcludingNewHeadOfFamily = computed(() => + personsByFamily.value.filter( + (person) => person.id !== changeHeadOfFamilyForm.newHeadOfFamily?.personId + ) +); + +const changeInHeadOfFamily = (entity) => { + if (entity !== null && entity !== undefined) { + changeHeadOfFamilyForm.newHeadOfFamily.personId = entity?.id ?? ""; + } +}; +const changeInHeadOfFamilyRelation = (relation) => { + if (relation !== null && relation !== undefined) { + changeHeadOfFamilyForm.newHeadOfFamily.relationId = relation?.id ?? ""; + } +}; +const changeInHeadOfFamily_MemberRelation = (personId, personRelationId) => { + let personIdAlreadyExists = false; + changeHeadOfFamilyForm.persons = changeHeadOfFamilyForm.persons.map((obj) => { + if (obj.personId === personId) { + personIdAlreadyExists = true; + return { ...obj, relationId: personRelationId }; + } + return obj; + }); + + if (!personIdAlreadyExists) { + changeHeadOfFamilyForm.persons.push({ + personId: personId, + relationId: personRelationId, + }); + } +}; + +const newHeadOfFamilySelectBoxRef = ref(null); +const newHeadOfFamilyFormRelationRef = ref(null); + +// Change of Head of Family Mutation +const CHANGE_HEAD_OF_FAMILY_MUTATION = gql` + ${changeHeadOfFamily} +`; + +const { + mutate: changeHeadOfFamilyMutate, + loading: changeHeadOfFamilyLoading, + onDone: changeHeadOfFamilyDone, + onError: changeHeadOfFamilyError, +} = useMutation(CHANGE_HEAD_OF_FAMILY_MUTATION); + +const submitChangeHeadOfFamilyForm = () => { + if (hasEmptyValues(createFamilyMembersForm, ["persons"])) { + console.log("Empty Values: " + createFamilyMembersForm); + } else { + console.log("Complete Values: " + createFamilyMembersForm); + changeHeadOfFamilyMutate({ + familyId: changeHeadOfFamilyForm.familyId, + newHeadOfFamily: changeHeadOfFamilyForm.newHeadOfFamily, + persons: changeHeadOfFamilyForm.persons, + }); + } +}; + +watch(changeHeadOfFamilyLoading, (value) => { + infoNotificationEnabled.value = changeHeadOfFamilyLoading.value; + if (value === true) { + infoNotificationHeading.value = "Changing Head of Family."; + infoNotificationContent.value = "Please Wait..."; + } else { + infoNotificationHeading.value = ""; + infoNotificationContent.value = ""; + } +}); + +changeHeadOfFamilyDone(() => { + console.log("onDone called"); + successNotificationEnabled.value = true; + successNotificationHeading.value = "Changed Head of Family."; + successNotificationContent.value = ""; + + setTimeout(() => { + successNotificationEnabled.value = false; + successNotificationHeading.value = ""; + successNotificationContent.value = ""; + }, 3000); + + location.reload(); +}); + watch(family, () => { activeEntityByFamilyCountEnabled.value = true; + createFamilyMembersForm.familyId = family.value?.id ?? ""; + + personsByFamilyEnabled.value = true; + changeHeadOfFamilyForm.familyId = family.value?.id ?? ""; + newHeadOfFamilySelectBoxRef.value?.clearField(); + newHeadOfFamilyFormRelationRef.value?.clearRelation(); + changeHeadOfFamilyForm.newHeadOfFamily = {}; + changeHeadOfFamilyForm.persons = []; }); const createFamilyForm = reactive({ @@ -259,6 +412,65 @@ createFamilyDone(() => { }, 3000); }); +// Add Family Members of selected Family +const addFamilyMembersAloneRef = ref(null); + +const changeInFamilyMembersAlone = (value) => { + createFamilyMembersForm.persons = value; +}; + +const ADD_FAMILY_MEMBERS_ALONE_MUTATION = gql` + ${createFamilyMembers} +`; + +const { + mutate: addFamilyMembersAlone, + loading: addFamilyMembersAloneLoading, + onDone: addFamilyMembersAloneDone, + onError: addFamilyMembersAloneError, +} = useMutation(ADD_FAMILY_MEMBERS_ALONE_MUTATION); + +const submitAddFamilyMembersForm = () => { + if (hasEmptyValues(createFamilyMembersForm, ["buildingName", "phone"])) { + console.log("Empty Values: " + createFamilyMembersForm); + } else { + console.log("Complete Values: " + createFamilyMembersForm); + addFamilyMembersAlone({ + familyId: family.value?.id, + persons: createFamilyMembersForm.persons, + }); + } +}; + +watch(addFamilyMembersAloneLoading, (value) => { + infoNotificationEnabled.value = addFamilyMembersAloneLoading.value; + if (value === true) { + infoNotificationHeading.value = "Adding Family Members."; + infoNotificationContent.value = "Please Wait..."; + } else { + infoNotificationHeading.value = ""; + infoNotificationContent.value = ""; + } +}); + +addFamilyMembersAloneDone(() => { + console.log("onDone called"); + successNotificationEnabled.value = true; + successNotificationHeading.value = "Added Family Members."; + successNotificationContent.value = ""; + + addFamilyMembersAloneRef.value.clearFamilyMembersForm(); + + createFamilyMembersForm.familyId = ""; + createFamilyMembersForm.persons = []; + + setTimeout(() => { + successNotificationEnabled.value = false; + successNotificationHeading.value = ""; + successNotificationContent.value = ""; + }, 3000); +}); + // Remove Family const DEACTIVATE_FAMILY_MUTATION = gql` ${deactivateFamilyMutation} @@ -435,6 +647,128 @@ const getActivePersonRows = computed(() => { /> + + + Add New Family Members + + + + + + + + + + Change Head of Family + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ +
+
{ --ms-py: 0.757rem; } + +.multiselect-theme { + --ms-bg: #1e293b; + --ms-dropdown-bg: #1e293b; + --ms-dropdown-border-color: #1e293b; + + --ms-py: 0.757rem; +}