Merge branch '161-fix-ordering-filter-social-action-type' into 'master'

Export: Fix vue app in "filter action by type, goals and result"

Closes #219, #141, and #161

See merge request Chill-Projet/chill-bundles!616
This commit is contained in:
Julien Fastré 2023-11-23 15:50:57 +00:00
commit c704ffa379
10 changed files with 117 additions and 60 deletions

View File

@ -0,0 +1,6 @@
kind: Feature
body: 'Export: in filter "Filter accompanying period work (social action) by type,
goal and result", order the items alphabetically or with the defined order'
time: 2023-11-16T11:53:15.32989153+01:00
custom:
Issue: "161"

View File

@ -0,0 +1,6 @@
kind: Fixed
body: 'Export: on filter "action by type goals, and results", restore the fields when
editing a saved export'
time: 2023-11-16T14:22:07.968973002+01:00
custom:
Issue: "141"

View File

@ -0,0 +1,5 @@
kind: Fixed
body: 'Export: fix the list of accompanying period work, when the "calc date" is null'
time: 2023-11-23T14:45:02.839510554+01:00
custom:
Issue: "219"

View File

@ -206,6 +206,7 @@ class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements L
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{ {
$centers = array_map(static fn ($el) => $el['center'], $acl); $centers = array_map(static fn ($el) => $el['center'], $acl);
$calcDate = $data['calc_date'] ?? new RollingDate(RollingDate::T_TODAY);
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
@ -220,7 +221,7 @@ class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements L
->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL') ->andWhere('acppart.startDate != acppart.endDate OR acppart.endDate IS NULL')
// get participants at the given date // get participants at the given date
->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)') ->andWhere('acppart.startDate <= :calc_date AND (acppart.endDate > :calc_date OR acppart.endDate IS NULL)')
->setParameter('calc_date', $this->rollingDateConverter->convert($data['calc_date'])); ->setParameter('calc_date', $this->rollingDateConverter->convert($calcDate));
if ($this->filterStatsByCenters) { if ($this->filterStatsByCenters) {
$qb $qb
@ -236,7 +237,7 @@ class ListAccompanyingPeriodWorkAssociatePersonOnAccompanyingPeriod implements L
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
$this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); $this->addSelectClauses($qb, $this->rollingDateConverter->convert($calcDate));
return $qb; return $qb;
} }

View File

@ -206,6 +206,7 @@ class ListAccompanyingPeriodWorkAssociatePersonOnWork implements ListInterface,
public function initiateQuery(array $requiredModifiers, array $acl, array $data = []) public function initiateQuery(array $requiredModifiers, array $acl, array $data = [])
{ {
$centers = array_map(static fn ($el) => $el['center'], $acl); $centers = array_map(static fn ($el) => $el['center'], $acl);
$calcDate = $data['calc_date'] ?? new RollingDate(RollingDate::T_TODAY);
$qb = $this->entityManager->createQueryBuilder(); $qb = $this->entityManager->createQueryBuilder();
@ -231,7 +232,7 @@ class ListAccompanyingPeriodWorkAssociatePersonOnWork implements ListInterface,
AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb); AccompanyingCourseExportHelper::addClosingMotiveExclusionClause($qb);
$this->addSelectClauses($qb, $this->rollingDateConverter->convert($data['calc_date'])); $this->addSelectClauses($qb, $this->rollingDateConverter->convert($calcDate));
return $qb; return $qb;
} }

View File

@ -144,6 +144,9 @@ class SocialWorkTypeFilter implements FilterInterface
$ids = []; $ids = [];
foreach ($asIterable as $value) { foreach ($asIterable as $value) {
if (null === $value) {
continue;
}
$ids[] = $value->getId(); $ids[] = $value->getId();
} }

View File

@ -1,5 +1,4 @@
<template> <template>
<teleport to="#export_filters_social_work_type_filter_form">
<fieldset class="mb-3" id="actionType"> <fieldset class="mb-3" id="actionType">
<div class="row"> <div class="row">
@ -14,7 +13,7 @@
:multiple="true" :multiple="true"
:close-on-select="false" :close-on-select="false"
:placeholder="$t('action.placeholder')" :placeholder="$t('action.placeholder')"
label="text" :custom-label="formatSocialAction"
track-by="id" track-by="id"
:searchable="true" :searchable="true"
></VueMultiselect> ></VueMultiselect>
@ -68,8 +67,6 @@
</div> </div>
</div> </div>
</fieldset> </fieldset>
</teleport>
</template> </template>
<script> <script>
@ -150,72 +147,118 @@ export default {
} }
}, },
}, },
mounted() { async mounted() {
this.getSocialActionsList(); await this.getSocialActionsList();
this.actions.hiddenField.value = ''; if ('' !== this.actions.hiddenField.value) {
this.goals.hiddenField.value = ''; const actionIds = this.actions.hiddenField.value.split(',');
this.results.hiddenField.value = ''; for (const aid of actionIds) {
let action = this.actions.options.find(a => Number.parseInt(aid) === a.id);
if (undefined !== action) {
this.action.push(action);
await this.selectAction(action);
}
}
}
//console.log(this.actions.hiddenField, this.goals.hiddenField, this.results.hiddenField); if ('' !== this.goals.hiddenField.value) {
const goalsIds = this.goals.hiddenField.value.split(',').map(s => Number.parseInt(s));
for (const gid of goalsIds) {
let goal = this.goals.options.find(g => gid === g.id);
if (undefined !== goal) {
this.goal.push(goal);
await this.selectGoal(goal);
}
}
}
if ('' !== this.results.hiddenField.value) {
const resultsIds = this.results.hiddenField.value.split(',').map(s => Number.parseInt(s));
for (const rid of resultsIds) {
let result = this.results.options.find(r => rid === r.id);
if (undefined !== result) {
this.result.push(result);
}
}
}
}, },
methods: { methods: {
async getSocialActionsList() { async getSocialActionsList() {
this.actions.options = await getSocialActions(); let actions = await getSocialActions();
this.actions.options = actions.toSorted(function (a, b) {
if (a.issue.ordering === b.issue.ordering) {
if (a.ordering === b.ordering) {
return 0;
}
if (a.ordering < b.ordering) {
return -1;
}
return 1;
}
if (a.issue.ordering < b.issue.ordering) {
return -1;
}
return 1;
})
return Promise.resolve();
},
formatSocialAction({text, issue}) {
return text + ' (' + issue.text + ')';
}, },
/** /**
* Select/unselect in Action Multiselect * Select/unselect in Action Multiselect
* @param value * @param value
*/ */
selectAction(value) { async selectAction(value) {
//console.log('----'); console.log('select action', value.id); //console.log('----'); console.log('select action', value.id);
let children = this.getChildrensFromParent(value); let children = this.getChildrensFromParent(value);
this.addSelectedElement('actions', children); this.addSelectedElement('actions', children);
let parentAndChildren = [...[value], ...children]; let parentAndChildren = [...[value], ...children];
const promises = [];
parentAndChildren.forEach(elem => { parentAndChildren.forEach(elem => {
getGoalByAction(elem.id).then(response => new Promise((resolve, reject) => { promises.push(getGoalByAction(elem.id).then(goals => {
this.addElementInData('goals', response.results); this.addElementInData('goals', goals);
resolve(); return Promise.resolve();
})).catch; }));
getResultByAction(elem.id).then(response => new Promise((resolve, reject) => { promises.push(getResultByAction(elem.id).then(results => {
this.addElementInData('results', response.results); this.addElementInData('results', results);
resolve(); return Promise.resolve();
})).catch; }));
}); });
await Promise.all(promises);
return Promise.resolve();
}, },
unselectAction(value) { unselectAction(value) {
//console.log('----'); console.log('unselect action', value.id); getGoalByAction(value.id).then(goals => {
getGoalByAction(value.id).then(response => new Promise((resolve, reject) => { [this.results.options, this.results.value ] = this.removeElementInData('goals', goals);
[ this.goals.options, this.goals.value ] = this.removeElementInData('goals', response.results); });
resolve(); getResultByAction(value.id).then(results => {
})).catch; [this.results.options, this.results.value ] = this.removeElementInData('results', results);
getResultByAction(value.id).then(response => new Promise((resolve, reject) => { });
[ this.results.options, this.results.value ] = this.removeElementInData('results', response.results);
resolve();
})).catch;
}, },
/** /**
* Select/unselect in Goal Multiselect * Select/unselect in Goal Multiselect
* @param value * @param value
*/ */
selectGoal(value) { async selectGoal(value) {
//console.log('----'); console.log('select goal', value.id); return getResultByGoal(value.id).then(results => {
getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { this.addElementInData('results', results);
this.addElementInData('results', response.results); })
resolve();
})).catch;
}, },
unselectGoal(value) { unselectGoal(value) {
//console.log('----'); console.log('unselect goal', value.id); getResultByGoal(value.id).then(results => {
getResultByGoal(value.id).then(response => new Promise((resolve, reject) => { [ this.results.options, this.results.value ] = this.removeElementInData('results', results);
[ this.results.options, this.results.value ] = this.removeElementInData('results', response.results); }).catch;
resolve();
})).catch;
}, },
/** /**
@ -263,6 +306,7 @@ export default {
if (dump.length > 0) { if (dump.length > 0) {
//console.log('push ' + dump.length + ' elems in', target, dump); //console.log('push ' + dump.length + ' elems in', target, dump);
} }
data.options.sort();
}, },
/** /**

View File

@ -8,29 +8,17 @@ const getSocialActions = () => fetchResults(
const getGoalByAction = (id) => { const getGoalByAction = (id) => {
let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`; let url = `/api/1.0/person/social-work/goal/by-social-action/${id}.json`;
return fetch(url) return fetchResults(url);
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
}; };
const getResultByAction = (id) => { const getResultByAction = (id) => {
let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`; let url = `/api/1.0/person/social-work/result/by-social-action/${id}.json`;
return fetch(url) return fetchResults(url);
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
}; };
const getResultByGoal = (id) => { const getResultByGoal = (id) => {
let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`; let url = `/api/1.0/person/social-work/result/by-goal/${id}.json`;
return fetch(url) return fetchResults(url);
.then(response => {
if (response.ok) { return response.json(); }
throw Error('Error with request resource response');
});
}; };
export { export {

View File

@ -4,11 +4,13 @@ import App from './App.vue';
if (null !== document.getElementById('export_filters_social_work_type_filter_enabled')) { if (null !== document.getElementById('export_filters_social_work_type_filter_enabled')) {
const i18n = _createI18n({}); const i18n = _createI18n({});
const form = document.getElementById('export_filters_social_work_type_filter_form');
const after = form.appendChild(document.createElement('div'));
const app = createApp({ const app = createApp({
template: `<app></app>`, template: `<app></app>`,
}) })
.use(i18n) .use(i18n)
.component('app', App) .component('app', App)
.mount('#export_export'); .mount(after);
} }

View File

@ -35,6 +35,7 @@ class SocialIssueNormalizer implements ContextAwareNormalizerInterface, Normaliz
'children_ids' => $socialIssue->getChildren()->map(static fn (SocialIssue $si) => $si->getId()), 'children_ids' => $socialIssue->getChildren()->map(static fn (SocialIssue $si) => $si->getId()),
'title' => $socialIssue->getTitle(), 'title' => $socialIssue->getTitle(),
'text' => $this->render->renderString($socialIssue, []), 'text' => $this->render->renderString($socialIssue, []),
'ordering' => $socialIssue->getOrdering(),
]; ];
case 'docgen': case 'docgen':