valtech-components 4.0.1014 → 4.0.1016

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,7 +70,7 @@ import fixWebmDuration from 'fix-webm-duration';
70
70
  * Current version of valtech-components.
71
71
  * This is automatically updated during the publish process.
72
72
  */
73
- const VERSION = '4.0.1014';
73
+ const VERSION = '4.0.1016';
74
74
 
75
75
  function evaluateValtechAccess(rule, context, features = {}, visitedFeatures = new Set()) {
76
76
  if (rule == null)
@@ -40368,7 +40368,7 @@ class SurveyResponseComponent {
40368
40368
  }
40369
40369
  }
40370
40370
  }
40371
- `, isInline: true, styles: [":host{display:block}.survey-response{display:flex;flex-direction:column;gap:16px}.survey-response__header-image,.survey-response__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-response__success{align-items:center;text-align:center}.survey-response__success-image{max-width:320px}.survey-response__success-note{margin:0;color:var(--ion-color-medium, #92949c);font-size:.95rem;font-weight:600}.survey-response__steps{display:flex;gap:6px}.survey-response__step{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;color:var(--ion-color-medium, #92949c);font-size:.8125rem;font-weight:700}.survey-response__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-response__actions{display:flex;justify-content:flex-end;gap:8px}.survey-response__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}.survey-response__hint{display:block;margin-top:4px;font-size:.8125rem;color:var(--ion-color-medium, #92949c)}.survey-response__loading{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["preset", "props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: EmptyStateComponent, selector: "val-empty-state", inputs: ["props"] }, { kind: "component", type: FormComponent, selector: "val-form", inputs: ["props"], outputs: ["onSubmit", "onValueChange", "onInvalid", "onSelectChange"] }, { kind: "component", type: SkeletonLayoutComponent, selector: "val-skeleton-layout", inputs: ["props"] }] }); }
40371
+ `, isInline: true, styles: [":host{display:block}.survey-response{display:flex;flex-direction:column;gap:16px}.survey-response__header-image,.survey-response__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-response__success{align-items:center;text-align:center}.survey-response__success-image{max-width:320px}.survey-response__success-note{margin:0;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.95rem;font-weight:600}.survey-response__steps{display:flex;gap:6px}.survey-response__step{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700}.survey-response__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-response__actions{display:flex;justify-content:flex-end;gap:8px}.survey-response__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}.survey-response__hint{display:block;margin-top:4px;font-size:.8125rem;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72)}.survey-response__loading{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["preset", "props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: EmptyStateComponent, selector: "val-empty-state", inputs: ["props"] }, { kind: "component", type: FormComponent, selector: "val-form", inputs: ["props"], outputs: ["onSubmit", "onValueChange", "onInvalid", "onSelectChange"] }, { kind: "component", type: SkeletonLayoutComponent, selector: "val-skeleton-layout", inputs: ["props"] }] }); }
40372
40372
  }
40373
40373
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SurveyResponseComponent, decorators: [{
40374
40374
  type: Component,
@@ -40473,7 +40473,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
40473
40473
  }
40474
40474
  }
40475
40475
  }
40476
- `, styles: [":host{display:block}.survey-response{display:flex;flex-direction:column;gap:16px}.survey-response__header-image,.survey-response__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-response__success{align-items:center;text-align:center}.survey-response__success-image{max-width:320px}.survey-response__success-note{margin:0;color:var(--ion-color-medium, #92949c);font-size:.95rem;font-weight:600}.survey-response__steps{display:flex;gap:6px}.survey-response__step{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;color:var(--ion-color-medium, #92949c);font-size:.8125rem;font-weight:700}.survey-response__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-response__actions{display:flex;justify-content:flex-end;gap:8px}.survey-response__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}.survey-response__hint{display:block;margin-top:4px;font-size:.8125rem;color:var(--ion-color-medium, #92949c)}.survey-response__loading{display:block}\n"] }]
40476
+ `, styles: [":host{display:block}.survey-response{display:flex;flex-direction:column;gap:16px}.survey-response__header-image,.survey-response__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-response__success{align-items:center;text-align:center}.survey-response__success-image{max-width:320px}.survey-response__success-note{margin:0;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.95rem;font-weight:600}.survey-response__steps{display:flex;gap:6px}.survey-response__step{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700}.survey-response__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-response__actions{display:flex;justify-content:flex-end;gap:8px}.survey-response__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}.survey-response__hint{display:block;margin-top:4px;font-size:.8125rem;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72)}.survey-response__loading{display:block}\n"] }]
40477
40477
  }], ctorParameters: () => [], propDecorators: { props: [{
40478
40478
  type: Input
40479
40479
  }], submitted: [{
@@ -40819,9 +40819,11 @@ class FieldSchemaEditorComponent {
40819
40819
  </val-form-field>
40820
40820
  }
40821
40821
 
40822
- <val-form-field [label]="t('sectionLabel')">
40823
- <val-text-input [props]="{ control: sectionControl, placeholder: t('sectionPlaceholder'), state: state() }" />
40824
- </val-form-field>
40822
+ @if (props.showSection !== false) {
40823
+ <val-form-field [label]="t('sectionLabel')">
40824
+ <val-text-input [props]="{ control: sectionControl, placeholder: t('sectionPlaceholder'), state: state() }" />
40825
+ </val-form-field>
40826
+ }
40825
40827
 
40826
40828
  <val-toggle-input
40827
40829
  [props]="{
@@ -40895,9 +40897,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
40895
40897
  </val-form-field>
40896
40898
  }
40897
40899
 
40898
- <val-form-field [label]="t('sectionLabel')">
40899
- <val-text-input [props]="{ control: sectionControl, placeholder: t('sectionPlaceholder'), state: state() }" />
40900
- </val-form-field>
40900
+ @if (props.showSection !== false) {
40901
+ <val-form-field [label]="t('sectionLabel')">
40902
+ <val-text-input [props]="{ control: sectionControl, placeholder: t('sectionPlaceholder'), state: state() }" />
40903
+ </val-form-field>
40904
+ }
40901
40905
 
40902
40906
  <val-toggle-input
40903
40907
  [props]="{
@@ -41383,6 +41387,7 @@ const SURVEY_BUILDER_I18N = {
41383
41387
  questionLabelPlaceholder: 'Escribe la pregunta',
41384
41388
  addQuestion: 'Agregar pregunta',
41385
41389
  addQuestionToSection: 'Agregar aquí',
41390
+ addSection: 'Agregar sección',
41386
41391
  removeQuestion: 'Quitar pregunta',
41387
41392
  editQuestion: 'Editar pregunta',
41388
41393
  duplicateQuestion: 'Duplicar pregunta',
@@ -41395,13 +41400,18 @@ const SURVEY_BUILDER_I18N = {
41395
41400
  save: 'Guardar encuesta',
41396
41401
  noTitle: 'Ponle un título a la encuesta',
41397
41402
  noQuestions: 'Agrega al menos una pregunta',
41403
+ noQuestionsInSection: 'Agrega al menos una pregunta a esta sección',
41404
+ noSectionName: 'Ponle nombre a la sección',
41398
41405
  emptyQuestionLabel: 'Todas las preguntas necesitan texto',
41399
41406
  saveError: 'No pudimos guardar la encuesta. Inténtalo de nuevo en un rato.',
41400
41407
  loadError: 'No pudimos cargar la encuesta para editar.',
41401
41408
  stepStart: 'Inicio',
41402
41409
  stepQuestions: 'Preguntas',
41410
+ sectionNameLabel: 'Nombre de la sección',
41411
+ sectionNamePlaceholder: 'Ej: Información personal',
41403
41412
  sectionSubtitleLabel: 'Subtítulo',
41404
41413
  sectionSubtitlePlaceholder: 'Escribe un subtítulo para esta sección',
41414
+ sectionTabsLabel: 'Secciones de la encuesta',
41405
41415
  stepClose: 'Cierre',
41406
41416
  stepReview: 'Revisar',
41407
41417
  wizardStepsLabel: 'Pasos para crear la encuesta',
@@ -41449,6 +41459,7 @@ const SURVEY_BUILDER_I18N = {
41449
41459
  questionLabelPlaceholder: 'Write the question',
41450
41460
  addQuestion: 'Add question',
41451
41461
  addQuestionToSection: 'Add here',
41462
+ addSection: 'Add section',
41452
41463
  removeQuestion: 'Remove question',
41453
41464
  editQuestion: 'Edit question',
41454
41465
  duplicateQuestion: 'Duplicate question',
@@ -41461,13 +41472,18 @@ const SURVEY_BUILDER_I18N = {
41461
41472
  save: 'Save survey',
41462
41473
  noTitle: 'Give the survey a title',
41463
41474
  noQuestions: 'Add at least one question',
41475
+ noQuestionsInSection: 'Add at least one question to this section',
41476
+ noSectionName: 'Give the section a name',
41464
41477
  emptyQuestionLabel: 'Every question needs text',
41465
41478
  saveError: "We couldn't save the survey. Please try again in a while.",
41466
41479
  loadError: "We couldn't load the survey to edit.",
41467
41480
  stepStart: 'Start',
41468
41481
  stepQuestions: 'Questions',
41482
+ sectionNameLabel: 'Section name',
41483
+ sectionNamePlaceholder: 'E.g: Personal information',
41469
41484
  sectionSubtitleLabel: 'Subtitle',
41470
41485
  sectionSubtitlePlaceholder: 'Add a subtitle for this section',
41486
+ sectionTabsLabel: 'Survey sections',
41471
41487
  stepClose: 'Close',
41472
41488
  stepReview: 'Review',
41473
41489
  wizardStepsLabel: 'Survey builder steps',
@@ -41550,7 +41566,7 @@ class SurveyPreviewModalComponent {
41550
41566
  </section>
41551
41567
  </div>
41552
41568
  </val-modal-layout>
41553
- `, isInline: true, styles: [":host{display:block}.survey-preview{display:flex;flex-direction:column;gap:16px}.survey-preview__image,.survey-preview__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-preview__section{display:flex;flex-direction:column;gap:10px}.survey-preview__section-title{color:var(--ion-text-color, #000);font-size:1rem}.survey-preview__question,.survey-preview__success{display:flex;flex-direction:column;gap:4px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-preview__question span,.survey-preview__success span{color:var(--ion-color-medium, #92949c);font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ModalLayoutComponent, selector: "val-modal-layout", inputs: ["title", "subtitle", "closeLabel", "showClose", "actions", "actionsAlign", "footer", "footerClass"], outputs: ["close", "actionClick"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }] }); }
41569
+ `, isInline: true, styles: [":host{display:block}.survey-preview{display:flex;flex-direction:column;gap:16px}.survey-preview__image,.survey-preview__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-preview__section{display:flex;flex-direction:column;gap:10px}.survey-preview__section-title{color:var(--ion-text-color, #000);font-size:1rem}.survey-preview__question,.survey-preview__success{display:flex;flex-direction:column;gap:4px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-preview__question span,.survey-preview__success span{color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ModalLayoutComponent, selector: "val-modal-layout", inputs: ["title", "subtitle", "closeLabel", "showClose", "actions", "actionsAlign", "footer", "footerClass"], outputs: ["close", "actionClick"] }, { kind: "component", type: DisplayComponent, selector: "val-display", inputs: ["props"] }, { kind: "component", type: TitleComponent, selector: "val-title", inputs: ["props"] }] }); }
41554
41570
  }
41555
41571
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SurveyPreviewModalComponent, decorators: [{
41556
41572
  type: Component,
@@ -41586,7 +41602,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
41586
41602
  </section>
41587
41603
  </div>
41588
41604
  </val-modal-layout>
41589
- `, styles: [":host{display:block}.survey-preview{display:flex;flex-direction:column;gap:16px}.survey-preview__image,.survey-preview__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-preview__section{display:flex;flex-direction:column;gap:10px}.survey-preview__section-title{color:var(--ion-text-color, #000);font-size:1rem}.survey-preview__question,.survey-preview__success{display:flex;flex-direction:column;gap:4px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-preview__question span,.survey-preview__success span{color:var(--ion-color-medium, #92949c);font-size:.875rem}\n"] }]
41605
+ `, styles: [":host{display:block}.survey-preview{display:flex;flex-direction:column;gap:16px}.survey-preview__image,.survey-preview__success-image{display:block;width:100%;max-height:220px;object-fit:contain;border-radius:var(--val-radius-md, 12px)}.survey-preview__section{display:flex;flex-direction:column;gap:10px}.survey-preview__section-title{color:var(--ion-text-color, #000);font-size:1rem}.survey-preview__question,.survey-preview__success{display:flex;flex-direction:column;gap:4px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-preview__question span,.survey-preview__success span{color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem}\n"] }]
41590
41606
  }], propDecorators: { modalTitle: [{
41591
41607
  type: Input
41592
41608
  }], closeLabel: [{
@@ -41632,23 +41648,29 @@ let rowUid = 0;
41632
41648
  */
41633
41649
  class SurveyBuilderComponent {
41634
41650
  groupQuestions(rows) {
41635
- const groups = [];
41651
+ const groups = this.sectionIds().map(id => ({
41652
+ id,
41653
+ label: this.sectionNames()[id] ?? '',
41654
+ subtitle: this.sectionSubtitles()[id] ?? '',
41655
+ rows: [],
41656
+ }));
41636
41657
  const index = new Map();
41658
+ groups.forEach((group, position) => index.set(group.id, position));
41637
41659
  rows.forEach(question => {
41638
41660
  const section = (question.sectionLabel ?? '').trim();
41639
41661
  const sectionKey = question.sectionId || (section ? this.formBuilder.toToken(section) : '__default__');
41640
- const label = section;
41662
+ const label = this.sectionNames()[sectionKey] ?? section;
41641
41663
  let position = index.get(sectionKey);
41642
41664
  if (position == null) {
41643
41665
  position = groups.length;
41644
41666
  index.set(sectionKey, position);
41645
- groups.push({ id: sectionKey, label, rows: [] });
41667
+ groups.push({ id: sectionKey, label, subtitle: this.sectionSubtitles()[sectionKey] ?? '', rows: [] });
41646
41668
  }
41647
41669
  groups[position].rows.push(question);
41648
41670
  });
41649
41671
  if (!groups.length) {
41650
41672
  const defaultId = '__default__';
41651
- groups.push({ id: defaultId, label: '', rows: [] });
41673
+ groups.push({ id: defaultId, label: this.sectionNames()[defaultId] ?? '', subtitle: this.sectionSubtitles()[defaultId] ?? '', rows: [] });
41652
41674
  }
41653
41675
  return groups;
41654
41676
  }
@@ -41658,6 +41680,21 @@ class SurveyBuilderComponent {
41658
41680
  questionGroupById(sectionId) {
41659
41681
  return this.questionGroups().find(group => group.id === sectionId);
41660
41682
  }
41683
+ sectionNameControl(sectionId) {
41684
+ const normalized = this.normalizeSectionId(sectionId);
41685
+ if (!this.sectionNameControls[normalized]) {
41686
+ const control = new FormControl(this.sectionNames()[normalized] ?? '', { nonNullable: true });
41687
+ control.valueChanges.subscribe(value => {
41688
+ const label = (value ?? '').trim();
41689
+ this.sectionNames.update(values => ({ ...values, [normalized]: value }));
41690
+ this.questions.update(rows => rows.map(row => this.normalizeSectionId(row.sectionId) === normalized
41691
+ ? { ...row, sectionId: normalized, sectionLabel: label || undefined }
41692
+ : row));
41693
+ });
41694
+ this.sectionNameControls[normalized] = control;
41695
+ }
41696
+ return this.sectionNameControls[normalized];
41697
+ }
41661
41698
  sectionSubtitleControl(sectionId) {
41662
41699
  const normalized = this.normalizeSectionId(sectionId);
41663
41700
  if (!this.sectionSubtitleControls[normalized]) {
@@ -41697,19 +41734,20 @@ class SurveyBuilderComponent {
41697
41734
  this.validationError = signal('');
41698
41735
  this.saving = signal(false);
41699
41736
  this.uploadingImage = signal('');
41737
+ this.sectionIds = signal(['__default__']);
41738
+ this.sectionNames = signal({});
41700
41739
  this.sectionSubtitles = signal({});
41740
+ this.activeSectionId = signal('__default__');
41741
+ this.sectionNameControls = {};
41701
41742
  this.sectionSubtitleControls = {};
41702
41743
  this.questionGroups = computed(() => this.groupQuestions(this.questions()));
41703
41744
  this.wizardSteps = computed(() => {
41704
- const groups = this.questionGroups();
41705
- const steps = [{ id: 'start', label: this.t('stepStart') }];
41706
- groups.forEach((group, index) => {
41707
- const sectionLabel = group.label || `${this.t('sectionQuestionsLabel')} ${index + 1}`;
41708
- steps.push({ id: `section-${group.id}`, label: `${index + 1}. ${sectionLabel}` });
41709
- });
41710
- steps.push({ id: 'close', label: this.t('stepClose') });
41711
- steps.push({ id: 'review', label: this.t('stepReview') });
41712
- return steps;
41745
+ return [
41746
+ { id: 'start', label: this.t('stepStart') },
41747
+ { id: 'questions', label: this.t('stepQuestions') },
41748
+ { id: 'close', label: this.t('stepClose') },
41749
+ { id: 'review', label: this.t('stepReview') },
41750
+ ];
41713
41751
  });
41714
41752
  this.allowedImageTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
41715
41753
  this.maxImageBytes = 10 * 1024 * 1024;
@@ -41825,22 +41863,24 @@ class SurveyBuilderComponent {
41825
41863
  };
41826
41864
  }
41827
41865
  closeStep() {
41828
- return Math.max(this.wizardSteps().length - 2, 0);
41866
+ return 2;
41829
41867
  }
41830
41868
  reviewStep() {
41831
- return Math.max(this.wizardSteps().length - 1, 0);
41869
+ return 3;
41832
41870
  }
41833
- sectionStepIndex(sectionIndex) {
41834
- return sectionIndex + 1;
41871
+ currentSectionId() {
41872
+ if (!this.isWizard())
41873
+ return this.questionGroups()[0]?.id;
41874
+ return this.activeSectionId();
41835
41875
  }
41836
- showCurrentSectionQuestionStep() {
41837
- return this.isWizard() && this.wizardStep() >= 1 && this.wizardStep() < this.reviewStep();
41876
+ selectSection(sectionId) {
41877
+ this.activeSectionId.set(this.normalizeSectionId(sectionId));
41838
41878
  }
41839
41879
  interpolate(template, values) {
41840
41880
  return Object.entries(values).reduce((text, [key, value]) => text.replaceAll(`{${key}}`, String(value)), template);
41841
41881
  }
41842
41882
  editorProps(row) {
41843
- return { mode: 'edit', field: row, allowedTypes: this.questionTypes() };
41883
+ return { mode: 'edit', field: row, allowedTypes: this.questionTypes(), showSection: false };
41844
41884
  }
41845
41885
  iconAction(token, icon, label, disabled = false, color = 'dark') {
41846
41886
  return {
@@ -41866,6 +41906,7 @@ class SurveyBuilderComponent {
41866
41906
  addQuestion(sectionId) {
41867
41907
  const normalizedSectionId = this.normalizeSectionId(sectionId);
41868
41908
  const targetGroup = this.questionGroupById(normalizedSectionId);
41909
+ const sectionLabel = this.sectionNameControl(normalizedSectionId).value.trim() || targetGroup?.label || '';
41869
41910
  const row = {
41870
41911
  id: `row-${rowUid++}`,
41871
41912
  name: '',
@@ -41875,7 +41916,7 @@ class SurveyBuilderComponent {
41875
41916
  type: this.questionTypes()[0],
41876
41917
  required: true,
41877
41918
  sectionId: normalizedSectionId,
41878
- sectionLabel: targetGroup?.label || undefined,
41919
+ sectionLabel: sectionLabel || undefined,
41879
41920
  };
41880
41921
  this.questions.update(rows => {
41881
41922
  const next = [...rows];
@@ -41887,6 +41928,18 @@ class SurveyBuilderComponent {
41887
41928
  // siguiente posible, y dejarla cerrada la haría ver como una fila rota.
41888
41929
  this.editingId.set(row.id);
41889
41930
  }
41931
+ addSection() {
41932
+ const id = `section-${rowUid++}`;
41933
+ this.sectionIds.update(ids => [...ids, id]);
41934
+ this.sectionNames.update(values => ({ ...values, [id]: '' }));
41935
+ this.sectionSubtitles.update(values => ({ ...values, [id]: '' }));
41936
+ this.sectionNameControl(id);
41937
+ this.sectionSubtitleControl(id);
41938
+ this.validationError.set('');
41939
+ this.activeSectionId.set(id);
41940
+ if (this.isWizard())
41941
+ this.wizardStep.set(1);
41942
+ }
41890
41943
  rowGlobalIndex(sectionId, groupRowIndex) {
41891
41944
  const normalized = this.normalizeSectionId(sectionId);
41892
41945
  let index = 0;
@@ -41972,10 +42025,10 @@ class SurveyBuilderComponent {
41972
42025
  withResolvedSection(field) {
41973
42026
  const label = (field.sectionLabel ?? '').trim();
41974
42027
  const id = this.normalizeSectionId(field.sectionId);
41975
- if (id !== '__default__' || !label) {
41976
- return { ...field, sectionId: id, sectionLabel: label || undefined };
42028
+ if (!this.isWizard() && id === '__default__' && label) {
42029
+ return { ...field, sectionId: this.formBuilder.toToken(label), sectionLabel: label };
41977
42030
  }
41978
- return { ...field, sectionId: this.formBuilder.toToken(label), sectionLabel: label };
42031
+ return { ...field, sectionId: id, sectionLabel: label || undefined };
41979
42032
  }
41980
42033
  async onPresentationFileSelected(slot, event) {
41981
42034
  const input = event.target;
@@ -42024,7 +42077,7 @@ class SurveyBuilderComponent {
42024
42077
  if (this.saving())
42025
42078
  return;
42026
42079
  this.validationError.set('');
42027
- if (!this.validateWizardStep(0) || !this.validateWizardStep(1))
42080
+ if (!this.validateBeforeSave())
42028
42081
  return;
42029
42082
  const title = this.titleControl.value.trim();
42030
42083
  const rows = this.questions();
@@ -42037,8 +42090,8 @@ class SurveyBuilderComponent {
42037
42090
  type: row.type,
42038
42091
  required: row.required,
42039
42092
  sectionId: row.sectionId,
42040
- sectionLabel: row.sectionLabel,
42041
- sectionSubtitle: this.sectionSubtitles()[this.normalizeSectionId(row.sectionId)] ?? '',
42093
+ sectionLabel: this.sectionNameControl(row.sectionId).value.trim() || row.sectionLabel,
42094
+ sectionSubtitle: this.sectionSubtitleControl(row.sectionId).value.trim() || row.sectionSubtitle,
42042
42095
  sectionOrder: this.sectionOrderFor(row.sectionId, rows),
42043
42096
  placeholderText: row.placeholderText,
42044
42097
  hintText: row.hintText,
@@ -42103,14 +42156,21 @@ class SurveyBuilderComponent {
42103
42156
  this.successMessageControl.setValue(presentation?.successMessage || this.defaultSuccessMessage());
42104
42157
  this.successImageControl.setValue(presentation?.successImageUrl ?? '');
42105
42158
  const rows = [...(questions ?? [])].sort((a, b) => a.order - b.order).map(f => this.rowFromField(f));
42159
+ const ids = [...new Set(rows.map(row => this.normalizeSectionId(row.sectionId)))];
42160
+ this.sectionIds.set(ids.length ? ids : ['__default__']);
42161
+ const names = {};
42106
42162
  const subtitles = {};
42107
42163
  rows.forEach(row => {
42108
42164
  const id = this.normalizeSectionId(row.sectionId);
42165
+ if (row.sectionLabel && names[id] === undefined)
42166
+ names[id] = row.sectionLabel;
42109
42167
  if (row.sectionSubtitle && subtitles[id] === undefined)
42110
42168
  subtitles[id] = row.sectionSubtitle;
42111
42169
  });
42170
+ this.sectionNames.set(names);
42112
42171
  this.sectionSubtitles.set(subtitles);
42113
42172
  this.questions.set(rows);
42173
+ this.activeSectionId.set(this.sectionIds()[0] ?? '__default__');
42114
42174
  }
42115
42175
  presentationPayload() {
42116
42176
  const presentation = {
@@ -42144,25 +42204,61 @@ class SurveyBuilderComponent {
42144
42204
  }
42145
42205
  return true;
42146
42206
  }
42147
- if (step === 1) {
42148
- const rows = this.questions();
42149
- if (!rows.length) {
42207
+ if (this.isWizard() && step === 1) {
42208
+ if (!this.questions().length) {
42150
42209
  this.validationError.set(this.t('noQuestions'));
42151
42210
  return false;
42152
42211
  }
42153
- if (rows.some(r => !r.label.trim())) {
42154
- this.validationError.set(this.t('emptyQuestionLabel'));
42212
+ if (!this.validateRows(this.questions()))
42213
+ return false;
42214
+ const emptySection = this.questionGroups().find(group => group.id !== '__default__' && !group.rows.length);
42215
+ if (emptySection) {
42216
+ this.activeSectionId.set(emptySection.id);
42217
+ this.validationError.set(this.t('noQuestionsInSection'));
42155
42218
  return false;
42156
42219
  }
42157
- // El editor ya lo valida al cerrar cada pregunta, pero una pregunta abierta
42158
- // (o cargada de una encuesta vieja) puede llegar acá sin opciones.
42159
- if (rows.some(r => FIELD_TYPES_WITH_OPTIONS.includes(r.type) && !r.options?.length)) {
42160
- this.validationError.set(this.t('missingOptions'));
42220
+ return true;
42221
+ }
42222
+ if (!this.isWizard() && step === 1) {
42223
+ return this.validateRows(this.questions());
42224
+ }
42225
+ return true;
42226
+ }
42227
+ validateBeforeSave() {
42228
+ if (!this.validateWizardStep(0))
42229
+ return false;
42230
+ if (!this.questions().length) {
42231
+ this.validationError.set(this.t('noQuestions'));
42232
+ return false;
42233
+ }
42234
+ if (!this.validateRows(this.questions()))
42235
+ return false;
42236
+ if (this.isWizard()) {
42237
+ const emptySection = this.questionGroups().find(group => group.id !== '__default__' && !group.rows.length);
42238
+ if (emptySection) {
42239
+ this.validationError.set(this.t('noQuestionsInSection'));
42161
42240
  return false;
42162
42241
  }
42163
42242
  }
42164
42243
  return true;
42165
42244
  }
42245
+ validateRows(rows) {
42246
+ if (!rows.length) {
42247
+ this.validationError.set(this.t('noQuestions'));
42248
+ return false;
42249
+ }
42250
+ if (rows.some(r => !r.label.trim())) {
42251
+ this.validationError.set(this.t('emptyQuestionLabel'));
42252
+ return false;
42253
+ }
42254
+ // El editor ya lo valida al cerrar cada pregunta, pero una pregunta abierta
42255
+ // (o cargada de una encuesta vieja) puede llegar acá sin opciones.
42256
+ if (rows.some(r => FIELD_TYPES_WITH_OPTIONS.includes(r.type) && !r.options?.length)) {
42257
+ this.validationError.set(this.t('missingOptions'));
42258
+ return false;
42259
+ }
42260
+ return true;
42261
+ }
42166
42262
  rowFromField(f) {
42167
42263
  return {
42168
42264
  id: `row-${rowUid++}`,
@@ -42215,7 +42311,8 @@ class SurveyBuilderComponent {
42215
42311
  name: question.name || this.formBuilder.toToken(question.label),
42216
42312
  typeLabel: this.typeLabel(question.type),
42217
42313
  sectionId: this.normalizeSectionId(question.sectionId),
42218
- sectionSubtitle: this.sectionSubtitles()[this.normalizeSectionId(question.sectionId)] ?? '',
42314
+ sectionLabel: this.sectionNameControl(question.sectionId).value.trim() || question.sectionLabel,
42315
+ sectionSubtitle: this.sectionSubtitleControl(question.sectionId).value.trim() || question.sectionSubtitle,
42219
42316
  sectionOrder: this.sectionOrderFor(question.sectionId, this.questions()),
42220
42317
  })),
42221
42318
  },
@@ -42386,7 +42483,7 @@ class SurveyBuilderComponent {
42386
42483
  </div>
42387
42484
  }
42388
42485
 
42389
- @if (showWizardSection(closeStep())) {
42486
+ @if (showWizardSection(2)) {
42390
42487
  <section class="survey-builder__section">
42391
42488
  <span class="survey-builder__questions-label">{{ t('stepClose') }}</span>
42392
42489
  <p class="survey-builder__optional-note">{{ t('successOptionalNote') }}</p>
@@ -42433,7 +42530,7 @@ class SurveyBuilderComponent {
42433
42530
  </section>
42434
42531
  }
42435
42532
 
42436
- @if (showCurrentSectionQuestionStep()) {
42533
+ @if (showWizardSection(1)) {
42437
42534
  <div class="survey-builder__questions">
42438
42535
  <span class="survey-builder__questions-label">{{ t('questionsLabel') }}</span>
42439
42536
 
@@ -42441,12 +42538,35 @@ class SurveyBuilderComponent {
42441
42538
  <p class="survey-builder__empty">{{ t('noQuestions') }}</p>
42442
42539
  }
42443
42540
 
42541
+ @if (questionGroups().length > 1) {
42542
+ <div class="survey-builder__section-tabs" [attr.aria-label]="t('sectionTabsLabel')">
42543
+ @for (group of questionGroups(); track group.id; let sectionIndex = $index) {
42544
+ <button
42545
+ type="button"
42546
+ class="survey-builder__section-tab"
42547
+ [class.survey-builder__section-tab--active]="activeSectionId() === group.id"
42548
+ [attr.aria-current]="activeSectionId() === group.id ? 'true' : null"
42549
+ (click)="selectSection(group.id)"
42550
+ >
42551
+ {{ group.label || t('sectionQuestionsLabel') + ' ' + (sectionIndex + 1) }}
42552
+ </button>
42553
+ }
42554
+ </div>
42555
+ }
42556
+
42444
42557
  @for (group of questionGroups(); track group.id; let sectionIndex = $index) {
42445
- @if (wizardStep() === sectionStepIndex(sectionIndex)) {
42558
+ @if (activeSectionId() === group.id) {
42446
42559
  <section class="survey-builder__question-section">
42447
42560
  <div class="survey-builder__section-head">
42448
- <div>
42449
- <strong>{{ group.label || t('sectionQuestionsLabel') }}</strong>
42561
+ <div class="survey-builder__section-fields">
42562
+ <val-form-field [label]="t('sectionNameLabel')">
42563
+ <val-text-input
42564
+ [props]="{
42565
+ control: sectionNameControl(group.id),
42566
+ placeholder: t('sectionNamePlaceholder'),
42567
+ }"
42568
+ />
42569
+ </val-form-field>
42450
42570
  <div class="survey-builder__section-subtitle">
42451
42571
  <val-form-field [label]="t('sectionSubtitleLabel')">
42452
42572
  <val-text-input
@@ -42483,8 +42603,7 @@ class SurveyBuilderComponent {
42483
42603
  <span>
42484
42604
  {{
42485
42605
  typeLabel(row.type) +
42486
- (row.required ? ' · ' + t('requiredTag') : '') +
42487
- (row.sectionLabel ? ' · ' + row.sectionLabel : '')
42606
+ (row.required ? ' · ' + t('requiredTag') : '')
42488
42607
  }}
42489
42608
  </span>
42490
42609
  </div>
@@ -42559,12 +42678,28 @@ class SurveyBuilderComponent {
42559
42678
  state: 'ENABLED',
42560
42679
  icon: { name: 'add-outline', slot: 'start' },
42561
42680
  }"
42562
- (onClick)="addQuestion(questionGroups()[0]?.id)"
42681
+ (onClick)="addQuestion(currentSectionId())"
42563
42682
  />
42683
+ @if (isWizard()) {
42684
+ <val-button
42685
+ [props]="{
42686
+ token: 'survey-builder-add-section',
42687
+ text: t('addSection'),
42688
+ color: 'dark',
42689
+ fill: 'outline',
42690
+ shape: 'round',
42691
+ size: 'default',
42692
+ type: 'button',
42693
+ state: 'ENABLED',
42694
+ icon: { name: 'add-outline', slot: 'start' },
42695
+ }"
42696
+ (onClick)="addSection()"
42697
+ />
42698
+ }
42564
42699
  </div>
42565
42700
  }
42566
42701
 
42567
- @if (showWizardSection(reviewStep())) {
42702
+ @if (showWizardSection(3)) {
42568
42703
  <section class="survey-builder__review">
42569
42704
  <span class="survey-builder__questions-label">{{ t('reviewTitle') }}</span>
42570
42705
  <strong>{{ titleControl.value || t('untitledQuestion') }}</strong>
@@ -42597,7 +42732,7 @@ class SurveyBuilderComponent {
42597
42732
  <val-button [props]="saveProps()" (onClick)="save()" />
42598
42733
  }
42599
42734
  </div>
42600
- `, isInline: true, styles: [":host{display:block}.survey-builder{display:flex;flex-direction:column;gap:16px}.survey-builder__questions{display:flex;flex-direction:column;gap:12px}.survey-builder__question-section{display:flex;flex-direction:column;gap:10px;padding:10px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-sm, 10px)}.survey-builder__section-head{display:flex;justify-content:space-between;align-items:center;gap:8px}.survey-builder__section-head strong{color:var(--ion-text-color, #000);font-size:.875rem}.survey-builder__presentation{display:flex;flex-direction:column;gap:12px;padding-top:4px}.survey-builder__section,.survey-builder__review{display:flex;flex-direction:column;gap:12px}.survey-builder__steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-top:16px;margin-bottom:12px}.survey-builder__step{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:8px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:var(--ion-color-medium-shade, #6b6675);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__step span{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:999px;background:var(--ion-color-light, #f4f5f8);color:inherit;font-size:.75rem}.survey-builder__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__wizard-actions{display:flex;justify-content:flex-end;gap:8px}.survey-builder__review{padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__review strong{color:var(--ion-text-color, #000)}.survey-builder__review span:not(.survey-builder__questions-label){color:var(--ion-color-medium, #92949c);font-size:.875rem}.survey-builder__image-field{display:flex;flex-direction:column;gap:10px}.survey-builder__image-preview{position:relative;width:100%}.survey-builder__image-preview img{display:block;width:100%;aspect-ratio:16 / 9;object-fit:contain;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:8px;background:var(--ion-color-light, #f4f5f8)}.survey-builder__image-clear{position:absolute;top:8px;right:8px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:999px;background:#0009;color:#fff;cursor:pointer}.survey-builder__image-upload{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:10px 18px;border:2px dashed var(--ion-color-dark, #2f2c3a);border-radius:20px;color:var(--ion-color-dark, #2f2c3a);font-size:.875rem;font-weight:600;cursor:pointer}.survey-builder__image-upload:hover{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__image-upload--loading{opacity:.7;cursor:default}.survey-builder__image-upload ion-spinner{width:16px;height:16px}.survey-builder__image-upload input{display:none}.survey-builder__questions-label{font-size:.8125rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ion-color-medium, #92949c)}.survey-builder__empty{margin:0;font-size:.875rem;color:var(--ion-color-medium, #92949c)}.survey-builder__optional-note{margin:0;color:var(--ion-color-medium, #92949c);font-size:.875rem;line-height:1.35}.survey-builder__row{display:flex;flex-direction:column;gap:12px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__row-head{display:flex;flex-direction:column;gap:8px}.survey-builder__row-text{display:flex;flex-direction:column;gap:2px;min-width:0}.survey-builder__row-text strong{color:var(--ion-text-color, #000);font-size:.9375rem}.survey-builder__row-text span{color:var(--ion-color-medium, #92949c);font-size:.8125rem}.survey-builder__row-actions{display:flex;gap:4px;flex-wrap:wrap}.survey-builder__row-editor{display:flex;flex-direction:column;gap:12px;padding-top:12px;border-top:1px solid var(--ion-border-color, rgba(0, 0, 0, .1))}.survey-builder__row-editor-actions{display:flex;justify-content:flex-end}.survey-builder__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}@media (min-width: 576px){.survey-builder__row-head{flex-direction:row;align-items:flex-start;justify-content:space-between}.survey-builder__row-text{flex:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["preset", "props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: FormFieldComponent, selector: "val-form-field", inputs: ["label"] }, { kind: "component", type: FieldSchemaEditorComponent, selector: "val-field-schema-editor", inputs: ["props"], outputs: ["save", "changed"] }] }); }
42735
+ `, isInline: true, styles: [":host{display:block}.survey-builder{display:flex;flex-direction:column;gap:16px}.survey-builder__questions{display:flex;flex-direction:column;gap:12px}.survey-builder__question-section{display:flex;flex-direction:column;gap:10px;padding:10px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-sm, 10px)}.survey-builder__section-head{display:flex;justify-content:space-between;align-items:center;gap:8px}.survey-builder__section-head strong{color:var(--ion-text-color, #000);font-size:.875rem}.survey-builder__section-tabs{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px}.survey-builder__section-tab{flex:0 0 auto;min-height:36px;padding:7px 12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__section-tab--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__presentation{display:flex;flex-direction:column;gap:12px;padding-top:4px}.survey-builder__section,.survey-builder__review{display:flex;flex-direction:column;gap:12px}.survey-builder__steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-top:16px;margin-bottom:12px}.survey-builder__step{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:8px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__step span{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:999px;background:var(--ion-color-light, #f4f5f8);color:inherit;font-size:.75rem}.survey-builder__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__wizard-actions{display:flex;justify-content:flex-end;gap:8px}.survey-builder__review{padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__review strong{color:var(--ion-text-color, #000)}.survey-builder__review span:not(.survey-builder__questions-label){color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem}.survey-builder__image-field{display:flex;flex-direction:column;gap:10px}.survey-builder__image-preview{position:relative;width:100%}.survey-builder__image-preview img{display:block;width:100%;aspect-ratio:16 / 9;object-fit:contain;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:8px;background:var(--ion-color-light, #f4f5f8)}.survey-builder__image-clear{position:absolute;top:8px;right:8px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:999px;background:#0009;color:#fff;cursor:pointer}.survey-builder__image-upload{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:10px 18px;border:2px dashed var(--ion-color-dark, #2f2c3a);border-radius:20px;color:var(--ion-color-dark, #2f2c3a);font-size:.875rem;font-weight:600;cursor:pointer}.survey-builder__image-upload:hover{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__image-upload--loading{opacity:.7;cursor:default}.survey-builder__image-upload ion-spinner{width:16px;height:16px}.survey-builder__image-upload input{display:none}.survey-builder__questions-label{font-size:.8125rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ion-text-color, #000)}.survey-builder__empty{margin:0;font-size:.875rem;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72)}.survey-builder__optional-note{margin:0;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem;line-height:1.35}.survey-builder__row{display:flex;flex-direction:column;gap:12px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__row-head{display:flex;flex-direction:column;gap:8px}.survey-builder__row-text{display:flex;flex-direction:column;gap:2px;min-width:0}.survey-builder__row-text strong{color:var(--ion-text-color, #000);font-size:.9375rem}.survey-builder__row-text span{color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.68);font-size:.8125rem}.survey-builder__row-actions{display:flex;gap:4px;flex-wrap:wrap}.survey-builder__row-editor{display:flex;flex-direction:column;gap:12px;padding-top:12px;border-top:1px solid var(--ion-border-color, rgba(0, 0, 0, .1))}.survey-builder__row-editor-actions{display:flex;justify-content:flex-end}.survey-builder__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}@media (min-width: 576px){.survey-builder__row-head{flex-direction:row;align-items:flex-start;justify-content:space-between}.survey-builder__row-text{flex:1}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }, { kind: "component", type: TextInputComponent, selector: "val-text-input", inputs: ["preset", "props"] }, { kind: "component", type: ButtonComponent, selector: "val-button", inputs: ["preset", "props"], outputs: ["onClick"] }, { kind: "component", type: FormFieldComponent, selector: "val-form-field", inputs: ["label"] }, { kind: "component", type: FieldSchemaEditorComponent, selector: "val-field-schema-editor", inputs: ["props"], outputs: ["save", "changed"] }] }); }
42601
42736
  }
42602
42737
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SurveyBuilderComponent, decorators: [{
42603
42738
  type: Component,
@@ -42768,7 +42903,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42768
42903
  </div>
42769
42904
  }
42770
42905
 
42771
- @if (showWizardSection(closeStep())) {
42906
+ @if (showWizardSection(2)) {
42772
42907
  <section class="survey-builder__section">
42773
42908
  <span class="survey-builder__questions-label">{{ t('stepClose') }}</span>
42774
42909
  <p class="survey-builder__optional-note">{{ t('successOptionalNote') }}</p>
@@ -42815,7 +42950,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42815
42950
  </section>
42816
42951
  }
42817
42952
 
42818
- @if (showCurrentSectionQuestionStep()) {
42953
+ @if (showWizardSection(1)) {
42819
42954
  <div class="survey-builder__questions">
42820
42955
  <span class="survey-builder__questions-label">{{ t('questionsLabel') }}</span>
42821
42956
 
@@ -42823,12 +42958,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42823
42958
  <p class="survey-builder__empty">{{ t('noQuestions') }}</p>
42824
42959
  }
42825
42960
 
42961
+ @if (questionGroups().length > 1) {
42962
+ <div class="survey-builder__section-tabs" [attr.aria-label]="t('sectionTabsLabel')">
42963
+ @for (group of questionGroups(); track group.id; let sectionIndex = $index) {
42964
+ <button
42965
+ type="button"
42966
+ class="survey-builder__section-tab"
42967
+ [class.survey-builder__section-tab--active]="activeSectionId() === group.id"
42968
+ [attr.aria-current]="activeSectionId() === group.id ? 'true' : null"
42969
+ (click)="selectSection(group.id)"
42970
+ >
42971
+ {{ group.label || t('sectionQuestionsLabel') + ' ' + (sectionIndex + 1) }}
42972
+ </button>
42973
+ }
42974
+ </div>
42975
+ }
42976
+
42826
42977
  @for (group of questionGroups(); track group.id; let sectionIndex = $index) {
42827
- @if (wizardStep() === sectionStepIndex(sectionIndex)) {
42978
+ @if (activeSectionId() === group.id) {
42828
42979
  <section class="survey-builder__question-section">
42829
42980
  <div class="survey-builder__section-head">
42830
- <div>
42831
- <strong>{{ group.label || t('sectionQuestionsLabel') }}</strong>
42981
+ <div class="survey-builder__section-fields">
42982
+ <val-form-field [label]="t('sectionNameLabel')">
42983
+ <val-text-input
42984
+ [props]="{
42985
+ control: sectionNameControl(group.id),
42986
+ placeholder: t('sectionNamePlaceholder'),
42987
+ }"
42988
+ />
42989
+ </val-form-field>
42832
42990
  <div class="survey-builder__section-subtitle">
42833
42991
  <val-form-field [label]="t('sectionSubtitleLabel')">
42834
42992
  <val-text-input
@@ -42865,8 +43023,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42865
43023
  <span>
42866
43024
  {{
42867
43025
  typeLabel(row.type) +
42868
- (row.required ? ' · ' + t('requiredTag') : '') +
42869
- (row.sectionLabel ? ' · ' + row.sectionLabel : '')
43026
+ (row.required ? ' · ' + t('requiredTag') : '')
42870
43027
  }}
42871
43028
  </span>
42872
43029
  </div>
@@ -42941,12 +43098,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42941
43098
  state: 'ENABLED',
42942
43099
  icon: { name: 'add-outline', slot: 'start' },
42943
43100
  }"
42944
- (onClick)="addQuestion(questionGroups()[0]?.id)"
43101
+ (onClick)="addQuestion(currentSectionId())"
42945
43102
  />
43103
+ @if (isWizard()) {
43104
+ <val-button
43105
+ [props]="{
43106
+ token: 'survey-builder-add-section',
43107
+ text: t('addSection'),
43108
+ color: 'dark',
43109
+ fill: 'outline',
43110
+ shape: 'round',
43111
+ size: 'default',
43112
+ type: 'button',
43113
+ state: 'ENABLED',
43114
+ icon: { name: 'add-outline', slot: 'start' },
43115
+ }"
43116
+ (onClick)="addSection()"
43117
+ />
43118
+ }
42946
43119
  </div>
42947
43120
  }
42948
43121
 
42949
- @if (showWizardSection(reviewStep())) {
43122
+ @if (showWizardSection(3)) {
42950
43123
  <section class="survey-builder__review">
42951
43124
  <span class="survey-builder__questions-label">{{ t('reviewTitle') }}</span>
42952
43125
  <strong>{{ titleControl.value || t('untitledQuestion') }}</strong>
@@ -42979,7 +43152,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
42979
43152
  <val-button [props]="saveProps()" (onClick)="save()" />
42980
43153
  }
42981
43154
  </div>
42982
- `, styles: [":host{display:block}.survey-builder{display:flex;flex-direction:column;gap:16px}.survey-builder__questions{display:flex;flex-direction:column;gap:12px}.survey-builder__question-section{display:flex;flex-direction:column;gap:10px;padding:10px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-sm, 10px)}.survey-builder__section-head{display:flex;justify-content:space-between;align-items:center;gap:8px}.survey-builder__section-head strong{color:var(--ion-text-color, #000);font-size:.875rem}.survey-builder__presentation{display:flex;flex-direction:column;gap:12px;padding-top:4px}.survey-builder__section,.survey-builder__review{display:flex;flex-direction:column;gap:12px}.survey-builder__steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-top:16px;margin-bottom:12px}.survey-builder__step{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:8px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:var(--ion-color-medium-shade, #6b6675);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__step span{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:999px;background:var(--ion-color-light, #f4f5f8);color:inherit;font-size:.75rem}.survey-builder__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__wizard-actions{display:flex;justify-content:flex-end;gap:8px}.survey-builder__review{padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__review strong{color:var(--ion-text-color, #000)}.survey-builder__review span:not(.survey-builder__questions-label){color:var(--ion-color-medium, #92949c);font-size:.875rem}.survey-builder__image-field{display:flex;flex-direction:column;gap:10px}.survey-builder__image-preview{position:relative;width:100%}.survey-builder__image-preview img{display:block;width:100%;aspect-ratio:16 / 9;object-fit:contain;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:8px;background:var(--ion-color-light, #f4f5f8)}.survey-builder__image-clear{position:absolute;top:8px;right:8px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:999px;background:#0009;color:#fff;cursor:pointer}.survey-builder__image-upload{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:10px 18px;border:2px dashed var(--ion-color-dark, #2f2c3a);border-radius:20px;color:var(--ion-color-dark, #2f2c3a);font-size:.875rem;font-weight:600;cursor:pointer}.survey-builder__image-upload:hover{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__image-upload--loading{opacity:.7;cursor:default}.survey-builder__image-upload ion-spinner{width:16px;height:16px}.survey-builder__image-upload input{display:none}.survey-builder__questions-label{font-size:.8125rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ion-color-medium, #92949c)}.survey-builder__empty{margin:0;font-size:.875rem;color:var(--ion-color-medium, #92949c)}.survey-builder__optional-note{margin:0;color:var(--ion-color-medium, #92949c);font-size:.875rem;line-height:1.35}.survey-builder__row{display:flex;flex-direction:column;gap:12px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__row-head{display:flex;flex-direction:column;gap:8px}.survey-builder__row-text{display:flex;flex-direction:column;gap:2px;min-width:0}.survey-builder__row-text strong{color:var(--ion-text-color, #000);font-size:.9375rem}.survey-builder__row-text span{color:var(--ion-color-medium, #92949c);font-size:.8125rem}.survey-builder__row-actions{display:flex;gap:4px;flex-wrap:wrap}.survey-builder__row-editor{display:flex;flex-direction:column;gap:12px;padding-top:12px;border-top:1px solid var(--ion-border-color, rgba(0, 0, 0, .1))}.survey-builder__row-editor-actions{display:flex;justify-content:flex-end}.survey-builder__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}@media (min-width: 576px){.survey-builder__row-head{flex-direction:row;align-items:flex-start;justify-content:space-between}.survey-builder__row-text{flex:1}}\n"] }]
43155
+ `, styles: [":host{display:block}.survey-builder{display:flex;flex-direction:column;gap:16px}.survey-builder__questions{display:flex;flex-direction:column;gap:12px}.survey-builder__question-section{display:flex;flex-direction:column;gap:10px;padding:10px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-sm, 10px)}.survey-builder__section-head{display:flex;justify-content:space-between;align-items:center;gap:8px}.survey-builder__section-head strong{color:var(--ion-text-color, #000);font-size:.875rem}.survey-builder__section-tabs{display:flex;gap:8px;overflow-x:auto;padding-bottom:2px}.survey-builder__section-tab{flex:0 0 auto;min-height:36px;padding:7px 12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:999px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__section-tab--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__presentation{display:flex;flex-direction:column;gap:12px;padding-top:4px}.survey-builder__section,.survey-builder__review{display:flex;flex-direction:column;gap:12px}.survey-builder__steps{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin-top:16px;margin-bottom:12px}.survey-builder__step{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:40px;padding:8px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .12));border-radius:8px;background:var(--ion-card-background, var(--ion-background-color, #fff));color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.8125rem;font-weight:700;cursor:pointer}.survey-builder__step span{display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:999px;background:var(--ion-color-light, #f4f5f8);color:inherit;font-size:.75rem}.survey-builder__step--active{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__wizard-actions{display:flex;justify-content:flex-end;gap:8px}.survey-builder__review{padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__review strong{color:var(--ion-text-color, #000)}.survey-builder__review span:not(.survey-builder__questions-label){color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem}.survey-builder__image-field{display:flex;flex-direction:column;gap:10px}.survey-builder__image-preview{position:relative;width:100%}.survey-builder__image-preview img{display:block;width:100%;aspect-ratio:16 / 9;object-fit:contain;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:8px;background:var(--ion-color-light, #f4f5f8)}.survey-builder__image-clear{position:absolute;top:8px;right:8px;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:999px;background:#0009;color:#fff;cursor:pointer}.survey-builder__image-upload{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:44px;padding:10px 18px;border:2px dashed var(--ion-color-dark, #2f2c3a);border-radius:20px;color:var(--ion-color-dark, #2f2c3a);font-size:.875rem;font-weight:600;cursor:pointer}.survey-builder__image-upload:hover{border-color:var(--ion-color-primary);color:var(--ion-color-primary)}.survey-builder__image-upload--loading{opacity:.7;cursor:default}.survey-builder__image-upload ion-spinner{width:16px;height:16px}.survey-builder__image-upload input{display:none}.survey-builder__questions-label{font-size:.8125rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ion-text-color, #000)}.survey-builder__empty{margin:0;font-size:.875rem;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72)}.survey-builder__optional-note{margin:0;color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.72);font-size:.875rem;line-height:1.35}.survey-builder__row{display:flex;flex-direction:column;gap:12px;padding:12px;border:1px solid var(--ion-border-color, rgba(0, 0, 0, .1));border-radius:var(--val-radius-md, 12px);background:var(--ion-card-background, var(--ion-background-color, #fff))}.survey-builder__row-head{display:flex;flex-direction:column;gap:8px}.survey-builder__row-text{display:flex;flex-direction:column;gap:2px;min-width:0}.survey-builder__row-text strong{color:var(--ion-text-color, #000);font-size:.9375rem}.survey-builder__row-text span{color:rgba(var(--ion-text-color-rgb, 0, 0, 0),.68);font-size:.8125rem}.survey-builder__row-actions{display:flex;gap:4px;flex-wrap:wrap}.survey-builder__row-editor{display:flex;flex-direction:column;gap:12px;padding-top:12px;border-top:1px solid var(--ion-border-color, rgba(0, 0, 0, .1))}.survey-builder__row-editor-actions{display:flex;justify-content:flex-end}.survey-builder__error{margin:0;color:var(--ion-color-danger);font-size:.875rem;font-weight:700}@media (min-width: 576px){.survey-builder__row-head{flex-direction:row;align-items:flex-start;justify-content:space-between}.survey-builder__row-text{flex:1}}\n"] }]
42983
43156
  }], ctorParameters: () => [], propDecorators: { props: [{
42984
43157
  type: Input
42985
43158
  }], saved: [{