Skip to content

Commit e2c1f31

Browse files
feat: Display only resources questions (#2831)
AB#122462 --------- Co-authored-by: Antoine Hurard <[email protected]>
1 parent 9db2512 commit e2c1f31

4 files changed

Lines changed: 115 additions & 65 deletions

File tree

libs/shared/src/lib/components/form-builder/form-builder.component.ts

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -590,14 +590,35 @@ export class FormBuilderComponent
590590
});
591591
}
592592
if (['resource', 'resources'].includes(question.getType())) {
593-
if (question.relatedName) {
594-
question.relatedName = this.formHelpersService.toSnakeCase(
595-
question.relatedName
596-
);
597-
if (this.relatedNames.includes(question.relatedName)) {
593+
// Check that relatedName is set and not duplicated
594+
if (!question.displayOnly) {
595+
// Skip check if display only
596+
if (question.relatedName) {
597+
question.relatedName = this.formHelpersService.toSnakeCase(
598+
question.relatedName
599+
);
600+
if (this.relatedNames.includes(question.relatedName)) {
601+
this.snackBar.openSnackBar(
602+
this.translate.instant(
603+
'components.formBuilder.errors.duplicatedRelatedName',
604+
{
605+
question: question.name,
606+
page: page.name,
607+
}
608+
),
609+
{
610+
error: true,
611+
duration: 15000,
612+
}
613+
);
614+
return false;
615+
} else {
616+
this.relatedNames.push(question.relatedName);
617+
}
618+
} else {
598619
this.snackBar.openSnackBar(
599620
this.translate.instant(
600-
'components.formBuilder.errors.duplicatedRelatedName',
621+
'components.formBuilder.errors.missingRelatedName',
601622
{
602623
question: question.name,
603624
page: page.name,
@@ -609,25 +630,10 @@ export class FormBuilderComponent
609630
}
610631
);
611632
return false;
612-
} else {
613-
this.relatedNames.push(question.relatedName);
614633
}
615-
} else {
616-
this.snackBar.openSnackBar(
617-
this.translate.instant(
618-
'components.formBuilder.errors.missingRelatedName',
619-
{
620-
question: question.name,
621-
page: page.name,
622-
}
623-
),
624-
{
625-
error: true,
626-
duration: 15000,
627-
}
628-
);
629-
return false;
630634
}
635+
636+
// Error if the user selected Add Record without adding a template.
631637
if (question.addRecord && !question.addTemplate) {
632638
this.snackBar.openSnackBar(
633639
this.translate.instant(

libs/shared/src/lib/survey/components/resources.ts

Lines changed: 78 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import {
66
FilterDescriptor,
77
} from '@progress/kendo-data-query';
88
import { Apollo } from 'apollo-angular';
9-
import { isNil } from 'lodash';
9+
import { isEqual, isNil } from 'lodash';
1010
import get from 'lodash/get';
1111
import {
1212
ComponentCollection,
1313
JsonObject,
1414
Serializer,
1515
SurveyModel,
1616
SvgRegistry,
17+
surveyLocalization,
1718
} from 'survey-core';
1819
import { CoreGridComponent } from '../../components/ui/core-grid/core-grid.component';
1920
import { ResourceQueryResponse } from '../../models/resource.model';
@@ -178,6 +179,13 @@ export const init = (
178179
},
179180
resourceFieldsName: [] as any[],
180181
onInit: (): void => {
182+
Serializer.addProperty('resources', {
183+
name: 'displayOnly:boolean',
184+
category: 'general',
185+
displayName: surveyLocalization.getString('oort:displayOnly'),
186+
visibleIndex: 7,
187+
default: false,
188+
});
181189
Serializer.addProperty('resources', {
182190
name: 'resource',
183191
category: 'Custom Questions',
@@ -218,7 +226,7 @@ export const init = (
218226
dependsOn: 'resource',
219227
required: true,
220228
description: 'unique name for this resource question',
221-
visibleIf: visibleIfResource,
229+
visibleIf: (obj: any) => visibleIfResource(obj) && !obj.displayOnly,
222230
visibleIndex: 4,
223231
});
224232

@@ -447,39 +455,10 @@ export const init = (
447455
}
448456
});
449457
if (question.customFilter && question.customFilter.trim().length > 0) {
450-
/**
451-
* Get question filters value
452-
*
453-
* @param question Current question
454-
*/
455-
const getQuestionFilters = (question: any) => {
456-
const surveyData = question.survey?.data;
457-
458-
const customFilter = JSON.parse(question.customFilter);
459-
if (Array.isArray(customFilter)) {
460-
question.filters = {
461-
logic: 'and',
462-
filters: customFilter
463-
.map((x) => updateFilter(surveyData, x))
464-
.filter((x) => !isNil(x)),
465-
};
466-
} else {
467-
question.filters = updateFilter(surveyData, customFilter);
468-
}
469-
470-
// Load question choices
471-
if (!question.displayAsGrid) {
472-
this.populateChoices(question);
473-
}
474-
};
475-
476458
// Subscribe to survey value changes
477459
question.survey?.onValueChanged.add(() => {
478-
getQuestionFilters(question);
460+
this.getQuestionFilters(question);
479461
});
480-
481-
// Initial load
482-
getQuestionFilters(question);
483462
} else {
484463
// Load question choices
485464
if (!question.displayAsGrid) {
@@ -514,7 +493,37 @@ export const init = (
514493
question.prefillWithCurrentRecord = false;
515494
}
516495
},
517-
onAfterRender: (question: QuestionResource, el: any): void => {
496+
/**
497+
* Get question filters
498+
*
499+
* @param question Current question
500+
*/
501+
getQuestionFilters(question: QuestionResource): void {
502+
const surveyData = (question.survey as SurveyModel).data;
503+
const customFilter = JSON.parse(question.customFilter);
504+
if (Array.isArray(customFilter)) {
505+
question.filters = {
506+
logic: 'and',
507+
filters: customFilter
508+
.map((x) => updateFilter(surveyData, x))
509+
.filter((x) => !isNil(x)),
510+
};
511+
} else {
512+
question.filters = updateFilter(surveyData, customFilter);
513+
}
514+
515+
// Load question choices
516+
if (!question.displayAsGrid) {
517+
this.populateChoices(question);
518+
}
519+
},
520+
/**
521+
* On After render callback
522+
*
523+
* @param question Current question
524+
* @param el Element
525+
*/
526+
onAfterRender(question: QuestionResource, el: any): void {
518527
const parentElement = el.querySelector('.sd-question__content');
519528
// Display the add button | grid for resources question
520529
const actionsButtons = setUpActionsButtonWrapper();
@@ -529,6 +538,13 @@ export const init = (
529538
}
530539
}, 500);
531540

541+
if (question.resource) {
542+
if (question.customFilter && question.customFilter.trim().length > 0) {
543+
// Initial load
544+
this.getQuestionFilters(question);
545+
}
546+
}
547+
532548
const searchBtn = buildSearchButton(
533549
question,
534550
question.gridFieldsSettings,
@@ -540,14 +556,14 @@ export const init = (
540556
);
541557
searchBtn.style.display = 'none';
542558
if (question.resource) {
543-
searchBtn.style.display = 'block';
559+
searchBtn.style.display = question.displayOnly ? 'none' : 'block';
544560
if (parentElement) {
545561
if (question.displayAsGrid) {
546562
gridComponentRef = buildGridDisplay(question, parentElement);
547563
}
548564

549565
if ((question.survey as SurveyModel).mode !== 'display') {
550-
searchBtn.style.display = 'block';
566+
searchBtn.style.display = question.displayOnly ? 'none' : 'block';
551567
const addBtn = buildAddButton(
552568
question,
553569
true,
@@ -579,15 +595,16 @@ export const init = (
579595
actionsButtons.appendChild(searchBtn);
580596
parentElement.insertBefore(actionsButtons, parentElement.firstChild);
581597
question.registerFunctionOnPropertyValueChanged('resource', () => {
582-
if (question.resource && question.canSearch) {
598+
if (question.resource && question.canSearch && !question.displayOnly) {
583599
searchBtn.style.display = 'block';
584600
}
585601
});
586602
question.registerFunctionOnPropertyValueChanged('canSearch', () => {
587603
if (question.displayAsGrid) {
588604
setGridInputs(gridComponentRef.instance, question);
589605
} else {
590-
searchBtn.style.display = question.canSearch ? 'block' : 'none';
606+
searchBtn.style.display =
607+
question.canSearch && !question.displayOnly ? 'block' : 'none';
591608
}
592609
});
593610
question.registerFunctionOnPropertyValueChanged(
@@ -614,7 +631,7 @@ export const init = (
614631
if (element) {
615632
element.style.display = 'block';
616633
}
617-
if (question.canSearch) {
634+
if (question.canSearch && !question.displayOnly) {
618635
searchBtn.style.display = 'block';
619636
}
620637
}
@@ -679,7 +696,7 @@ export const init = (
679696
);
680697
setGridInputs(grid.instance, question);
681698
question.survey?.onValueChanged.add((_: any, options: any) => {
682-
if (options.name === question.name) {
699+
if (question.displayOnly || options.name === question.name) {
683700
setGridInputs(grid.instance, question);
684701
}
685702
});
@@ -693,7 +710,8 @@ export const init = (
693710
* @param question survey question.
694711
*/
695712
const setGridInputs = async (instance: CoreGridComponent, question: any) => {
696-
instance.multiSelect = true;
713+
instance.multiSelect = !question.displayOnly;
714+
instance.selectable = !question.displayOnly;
697715
const promises: any[] = [];
698716
const settings = await processNewCreatedRecords(question, true, promises);
699717
if (
@@ -718,9 +736,27 @@ export const init = (
718736
if (question.canSearch) {
719737
temporaryRecordsForm.setValue(settings.query.temporaryRecords);
720738
}
721-
instance.settings = settings;
739+
if (question.displayOnly) {
740+
const filters: any[] = [];
741+
742+
if (question.filters) {
743+
filters.push(question.filters);
744+
}
745+
if (question.gridFieldsSettings?.filter) {
746+
filters.push(question.gridFieldsSettings.filter);
747+
}
748+
749+
settings.query.filter = {
750+
logic: 'and',
751+
filters: filters,
752+
};
753+
}
722754
Promise.allSettled(promises).then(() => {
723-
instance.configureGrid();
755+
// Only update grid if needed
756+
if (!isEqual(instance.settings, settings)) {
757+
instance.settings = settings;
758+
instance.configureGrid();
759+
}
724760
});
725761
};
726762
};

libs/shared/src/lib/survey/localization.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ const SURVEY_LOCALIZABLE_STRINGS = [
99
fr: 'Ajouter un enregistrement',
1010
},
1111
},
12+
{
13+
key: 'displayOnly',
14+
locales: {
15+
en: 'Display only',
16+
fr: 'Affichage seul',
17+
},
18+
},
1219
{
1320
key: 'fileLimitations',
1421
locales: {

libs/shared/src/lib/survey/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export interface QuestionResource
8282
staticValue: string;
8383
customFilter: string;
8484
displayAsGrid: boolean;
85+
displayOnly?: boolean;
8586
remove?: boolean;
8687
template?: string;
8788
draftData?: any;

0 commit comments

Comments
 (0)