From e5905902cc5b02c337a6694c93149c8a57e3f2aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 4 Jun 2021 21:24:11 +0200 Subject: [PATCH] add confirm button for move --- .../Controller/HouseholdMemberController.php | 43 +++++++ .../vuejs/HouseholdMembersEditor/App.vue | 3 + .../vuejs/HouseholdMembersEditor/api.js | 47 ++++++++ .../components/Confirmation.vue | 32 +++++ .../HouseholdMembersEditor/store/index.js | 111 ++++++++++++++++-- .../ChillPersonBundle/chill.api.specs.yaml | 42 +++++++ 6 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/api.js create mode 100644 src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/components/Confirmation.vue diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php index 24d77467d..e60deea8e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php @@ -50,6 +50,49 @@ class HouseholdMemberController extends ApiController return $this->json($editor->getHousehold(), Response::HTTP_OK, ["groups" => ["read"]]); } + /** + * @Route( + * "/api/1.0/person/household/members/move/test.{_format}", + * name="chill_api_person_household_members_move_test" + * ) + */ + public function test(Request $request, $_format): Response + { + try { + $editor = $this->getSerializer() + ->deserialize($request->getContent(), MembersEditor::class, + $_format, ['groups' => [ "read" ]]); + } catch (Exception\InvalidArgumentException | Exception\UnexpectedValueException $e) { + throw new BadRequestException("Deserialization error: {$e->getMessage()}", 45896, $e); + } + // TODO ACL + // + // TODO validation + // temporary, to have at least one problem for testing purpose + /*$violations = [ + new \Symfony\Component\Validator\ConstraintViolation( + "This is a fake message", + null, + [], + $editor->getHousehold(), + 'household.members.startDate', + new \DateTime('10 years ago') + ), + new \Symfony\Component\Validator\ConstraintViolation( + "This is another fake message", + null, + [], + $editor->getHousehold(), + 'household.members.endDate', + new \DateTime('10 years ago') + ) + ]; + $violationsList = new \Symfony\Component\Validator\ConstraintViolationList($violations); + */ + + return $this->json($editor->getHousehold(), Response::HTTP_OK, ["groups" => ["read"]]); + } + /** * @Route( * "/{_locale}/person/household/members/editor", diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue index 939dc6119..7fc138ee9 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/App.vue @@ -2,6 +2,7 @@ + diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js index 74cab3b1d..447bac285 100644 --- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js +++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/HouseholdMembersEditor/store/index.js @@ -1,4 +1,6 @@ import { createStore } from 'vuex'; +import { householdMove, householdMoveTest } from './../api.js'; +import { datetimeToISO } from 'ChillMainAssets/js/date.js'; const debug = process.env.NODE_ENV !== 'production'; @@ -7,6 +9,7 @@ const concerned = window.household_members_editor_data.persons.map(p => { person: p, position: null, allowRemove: false, + holder: false }; }); @@ -21,7 +24,7 @@ const store = createStore({ allowHouseholdSearch: window.household_members_editor_data.allowHouseholdSearch, allowLeaveWithoutHousehold: window.household_members_editor_data.allowLeaveWithoutHousehold, forceLeaveWithoutHousehold: false, - + warnings: [], }, getters: { isHouseholdNew(state) { @@ -63,13 +66,51 @@ const store = createStore({ .find(conc => conc.person.id === person_id) ; }, + buildPayload: (state) => { + let + conc, + payload = { + concerned: [], + destination: { + id: state.household.id, + type: state.household.type + } + } + ; + + for (let i in state.concerned) { + conc = state.concerned[i]; + console.log('loop', conc); + payload.concerned.push({ + person: { + id: conc.person.id, + type: conc.person.type + }, + position: { + id: conc.position.id, + type: conc.position.type + }, + holder: conc.holder, + comment: "", + start_date: { + datetime: datetimeToISO(state.startDate) + } + }); + } + + return payload; + }, }, mutations: { addConcerned(state, person) { let persons = state.concerned.map(conc => conc.person.id); if (!persons.includes(person.id)) { - state.concerned.push({ person, position: null, - allowRemove: true }); + state.concerned.push({ + person, + position: null, + allowRemove: true, + holder: false + }); } else { console.err("person already included"); } @@ -107,39 +148,89 @@ const store = createStore({ state.forceLeaveWithoutHousehold = true; }, setStartDate(state, dateI) { - state.startDate = dateI + state.startDate = dateI; + }, + setWarnings(state, warnings) { + state.warnings = warnings; }, }, actions: { - addConcerned({ commit }, person) { + addConcerned({ commit, dispatch }, person) { console.log('from actions addConcerned'); commit('addConcerned', person); + dispatch('computeWarnings'); }, - markPosition({ commit, state }, { person_id, position_id }) { + markPosition({ commit, state, dispatch }, { person_id, position_id }) { console.log('from action markPosition'); console.log('person_id', person_id); console.log('position_id', position_id); commit('markPosition', { person_id, position_id }); + dispatch('computeWarnings'); }, toggleHolder({ commit }, conc) { commit('toggleHolder', conc); }, - removePosition({ commit }, conc) { + removePosition({ commit, dispatch }, conc) { commit('removePosition', conc); + dispatch('computeWarnings'); }, - removeConcerned({ commit }, conc) { + removeConcerned({ commit, dispatch }, conc) { commit('removeConcerned', conc); + dispatch('computeWarnings'); }, - createHousehold({ commit }) { + createHousehold({ commit, dispatch }) { commit('createHousehold'); + dispatch('computeWarnings'); }, - forceLeaveWithoutHousehold({ commit }) { + forceLeaveWithoutHousehold({ commit, dispatch }) { commit('forceLeaveWithoutHousehold'); + dispatch('computeWarnings'); }, setStartDate({ commit }, date) { commit('setStartDate', date); }, + computeWarnings({ commit, state, getters }) { + let warnings = [], + payload; + + if (!getters.hasHousehold && !state.forceLeaveWithoutHousehold) { + warnings.push({ m: 'household_member_editor.add_destination', a: {} }); + } + + if (state.concerned.length === 0) { + warnings.push({ m: 'household_member_editor.add_at_least_onePerson', a: {} }); + } + + if (getters.concUnpositionned.length > 0 + && !state.forceLeaveWithoutHousehold) { + warnings.push({ m: 'household_member_editor.give_a_position_to_every_person', a: {} }) + } + + if (warnings.length === 0) { + payload = getters.buildPayload; + householdMoveTest(payload).then(errors => { + for (let i in errors.violations) { + console.log('error from server', errors.violations[i]); + warnings.push({ m: errors.violations[i].title, a: {} }); + } + commit('setWarnings', warnings); + }); + } else { + commit('setWarnings', warnings); + } + }, + confirm({ getters }) { + let payload = getters.buildPayload; + householdMove(payload).then(household => { + console.log('move success', household); + let id = household.id; + // nothing to do anymore here, bye-bye ! + window.location.replace(`/fr/person/household/{id}/members`); + }); + }, } }); +store.dispatch('computeWarnings'); + export { store }; diff --git a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml index 0fac8e6ce..30178e385 100644 --- a/src/Bundle/ChillPersonBundle/chill.api.specs.yaml +++ b/src/Bundle/ChillPersonBundle/chill.api.specs.yaml @@ -826,3 +826,45 @@ paths: 400: description: "transition cannot be applyed" + /1.0/person/household/members/move/test.json: + post: + tags: + - household + summary: test the move of one or more person, without persisting changes in database + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + concerned: + type: array + items: + type: object + properties: + person: + $ref: '#/components/schemas/PersonById' + start_date: + $ref: '#/components/schemas/Date' + position: + $ref: '#/components/schemas/HouseholdPosition' + holder: + type: boolean + comment: + type: string + destination: + oneOf: + - $ref: '#/components/schemas/Household' + responses: + 401: + description: "Unauthorized" + 404: + description: "Not found" + 200: + description: "OK" + 422: + description: "Unprocessable entity (validation errors)" + 400: + description: "transition cannot be applyed" +