@muraai/mnl-form 0.0.1-alpha-2edbad0 → 0.0.1-alpha-10829d9
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.
- package/esm2022/lib/formly-lib/formly-lib.component.mjs +6 -3
- package/esm2022/lib/services/scoring.service.mjs +19 -7
- package/esm2022/lib/types/mu-helper-text.type.mjs +78 -26
- package/fesm2022/muraai-mnl-form.mjs +98 -31
- package/fesm2022/muraai-mnl-form.mjs.map +1 -1
- package/lib/formly-lib/formly-lib.component.d.ts +2 -1
- package/lib/types/mu-helper-text.type.d.ts +7 -0
- package/package.json +1 -1
|
@@ -4524,14 +4524,44 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4524
4524
|
get defaultHelperText() {
|
|
4525
4525
|
return this.to['helperProps']?.['defaultHelperText'] || '';
|
|
4526
4526
|
}
|
|
4527
|
+
// Get value from primary model (answers)
|
|
4528
|
+
get originalValue() {
|
|
4529
|
+
const fieldKey = this.field.key;
|
|
4530
|
+
return this.field.model?.[fieldKey];
|
|
4531
|
+
}
|
|
4532
|
+
// Get/Set value from secondary model (helper)
|
|
4533
|
+
get helperModel() {
|
|
4534
|
+
return (this.to['helperModel'] ||
|
|
4535
|
+
this.props['helperModel'] ||
|
|
4536
|
+
this.options?.formState?.['helperModel']);
|
|
4537
|
+
}
|
|
4538
|
+
get helperKey() {
|
|
4539
|
+
return this.to['helperKey'] || this.field.key;
|
|
4540
|
+
}
|
|
4541
|
+
get currentHelperValue() {
|
|
4542
|
+
if (this.helperModel && this.helperKey) {
|
|
4543
|
+
return this.helperModel[this.helperKey];
|
|
4544
|
+
}
|
|
4545
|
+
return '';
|
|
4546
|
+
}
|
|
4547
|
+
set currentHelperValue(value) {
|
|
4548
|
+
if (this.helperModel && this.helperKey) {
|
|
4549
|
+
this.helperModel[this.helperKey] = value;
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4527
4552
|
constructor(cdr) {
|
|
4528
4553
|
super();
|
|
4529
4554
|
this.cdr = cdr;
|
|
4530
4555
|
this.checked = false;
|
|
4531
4556
|
}
|
|
4532
4557
|
ngOnInit() {
|
|
4558
|
+
// Initialize helper form control with value from helper model
|
|
4559
|
+
this.helperFormControl = new FormControl(this.currentHelperValue || '');
|
|
4560
|
+
// Subscribe to changes in helper form control and update helper model
|
|
4561
|
+
this.helperFormControl.valueChanges.subscribe((value) => {
|
|
4562
|
+
this.currentHelperValue = value;
|
|
4563
|
+
});
|
|
4533
4564
|
this.setupDefaultField();
|
|
4534
|
-
// If mode is helper, set up the initial state based on scoring
|
|
4535
4565
|
if (this.to['enableHelper']) {
|
|
4536
4566
|
this.setCorrectValue();
|
|
4537
4567
|
this.determineInitialState();
|
|
@@ -4539,6 +4569,16 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4539
4569
|
}
|
|
4540
4570
|
toggleSlide() {
|
|
4541
4571
|
this.checked = !this.checked;
|
|
4572
|
+
if (this.checked) {
|
|
4573
|
+
// When toggle is opened, check if helper field is empty
|
|
4574
|
+
const currenthelper = this.helperFormControl.value;
|
|
4575
|
+
if (!currenthelper || currenthelper.trim() === '') {
|
|
4576
|
+
this.helperFormControl.setValue(this.defaultHelperText);
|
|
4577
|
+
}
|
|
4578
|
+
}
|
|
4579
|
+
else {
|
|
4580
|
+
this.helperFormControl.setValue('');
|
|
4581
|
+
}
|
|
4542
4582
|
this.cdr.detectChanges();
|
|
4543
4583
|
}
|
|
4544
4584
|
setupDefaultField() {
|
|
@@ -4548,7 +4588,6 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4548
4588
|
...fieldConfig,
|
|
4549
4589
|
key: this.field.key || fieldConfig.key || 'defaultKey',
|
|
4550
4590
|
formControl: this.formControl,
|
|
4551
|
-
// Add required properties that formly expects
|
|
4552
4591
|
modelOptions: fieldConfig.modelOptions || this.field.modelOptions || {},
|
|
4553
4592
|
validators: fieldConfig.validators || this.field.validators || {},
|
|
4554
4593
|
asyncValidators: fieldConfig.asyncValidators || this.field.asyncValidators || {},
|
|
@@ -4559,7 +4598,6 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4559
4598
|
fieldGroupClassName: fieldConfig.fieldGroupClassName ||
|
|
4560
4599
|
this.field.fieldGroupClassName ||
|
|
4561
4600
|
'',
|
|
4562
|
-
// Inherit parent field's form and model
|
|
4563
4601
|
parent: this.field.parent,
|
|
4564
4602
|
options: this.field.options,
|
|
4565
4603
|
model: this.field.model,
|
|
@@ -4572,12 +4610,12 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4572
4610
|
switch (this.to['scoring']?.['criteria']) {
|
|
4573
4611
|
case 'exactMatch':
|
|
4574
4612
|
if (Array.isArray(this.to['scoring']?.['answer']) &&
|
|
4575
|
-
!this.to['scoring']?.['answer'].includes(this.
|
|
4613
|
+
!this.to['scoring']?.['answer'].includes(this.originalValue)) {
|
|
4576
4614
|
this.checked = true;
|
|
4577
4615
|
}
|
|
4578
4616
|
break;
|
|
4579
4617
|
case 'range':
|
|
4580
|
-
const answer = this.
|
|
4618
|
+
const answer = this.originalValue;
|
|
4581
4619
|
const num = typeof answer === 'number' ? answer : Number(answer);
|
|
4582
4620
|
const correct = Number.isFinite(num) &&
|
|
4583
4621
|
num >= this.to['scoring']?.['answer'].min &&
|
|
@@ -4589,28 +4627,44 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4589
4627
|
}
|
|
4590
4628
|
}
|
|
4591
4629
|
setCorrectValue() {
|
|
4630
|
+
const currentHelperValue = this.currentHelperValue;
|
|
4631
|
+
// If helper already has a value (user edited), don't override
|
|
4632
|
+
if (currentHelperValue && currentHelperValue.trim() !== '') {
|
|
4633
|
+
return;
|
|
4634
|
+
}
|
|
4592
4635
|
switch (this.to['scoring']?.['criteria']) {
|
|
4593
4636
|
case 'attempted':
|
|
4594
|
-
|
|
4637
|
+
// For attempted, set defaultHelperText
|
|
4638
|
+
this.helperFormControl.setValue('');
|
|
4595
4639
|
break;
|
|
4596
4640
|
case 'exactMatch':
|
|
4597
|
-
if (Array.isArray(this.to['scoring']?.['answer'])
|
|
4598
|
-
|
|
4599
|
-
|
|
4641
|
+
if (Array.isArray(this.to['scoring']?.['answer'])) {
|
|
4642
|
+
if (this.to['scoring']?.['answer'].includes(this.originalValue)) {
|
|
4643
|
+
// Answer is correct - set empty value in helper
|
|
4644
|
+
this.helperFormControl.setValue('');
|
|
4645
|
+
}
|
|
4646
|
+
else {
|
|
4647
|
+
// Answer is incorrect - set defaultHelperText in helper
|
|
4648
|
+
this.helperFormControl.setValue(this.defaultHelperText);
|
|
4649
|
+
}
|
|
4600
4650
|
}
|
|
4601
4651
|
break;
|
|
4602
4652
|
case 'range':
|
|
4603
|
-
const answer = this.
|
|
4653
|
+
const answer = this.originalValue;
|
|
4604
4654
|
const num = typeof answer === 'number' ? answer : Number(answer);
|
|
4605
4655
|
const correct = Number.isFinite(num) &&
|
|
4606
4656
|
num >= this.to['scoring']?.['answer'].min &&
|
|
4607
4657
|
num <= this.to['scoring']?.['answer'].max;
|
|
4608
|
-
if (
|
|
4609
|
-
|
|
4658
|
+
if (correct) {
|
|
4659
|
+
// Answer is correct - set empty value in helper
|
|
4660
|
+
this.helperFormControl.setValue('');
|
|
4661
|
+
}
|
|
4662
|
+
else {
|
|
4663
|
+
// Answer is incorrect - set defaultHelperText in helper
|
|
4664
|
+
this.helperFormControl.setValue(this.defaultHelperText);
|
|
4610
4665
|
}
|
|
4611
4666
|
break;
|
|
4612
4667
|
default:
|
|
4613
|
-
this.formControl?.setValue(this.defaultHelperText);
|
|
4614
4668
|
break;
|
|
4615
4669
|
}
|
|
4616
4670
|
}
|
|
@@ -4620,20 +4674,19 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4620
4674
|
<!-- Helper Mode - Show toggle and conditional content -->
|
|
4621
4675
|
<div *ngIf="to['enableHelper']">
|
|
4622
4676
|
<mat-label>{{ to.label }}</mat-label>
|
|
4623
|
-
<div *ngIf="
|
|
4624
|
-
<span class="answer">{{
|
|
4677
|
+
<div *ngIf="originalValue" class="flex-row">
|
|
4678
|
+
<span class="answer">{{ originalValue }}</span>
|
|
4625
4679
|
<mat-slide-toggle
|
|
4626
4680
|
[(ngModel)]="checked"
|
|
4627
4681
|
(toggleChange)="toggleSlide()"
|
|
4628
|
-
>{{helperLabel}}</mat-slide-toggle
|
|
4682
|
+
>{{ helperLabel }}</mat-slide-toggle
|
|
4629
4683
|
>
|
|
4630
4684
|
</div>
|
|
4631
4685
|
|
|
4632
4686
|
<mat-form-field class="textarea" appearance="outline" *ngIf="checked">
|
|
4633
4687
|
<textarea
|
|
4634
4688
|
matInput
|
|
4635
|
-
[formControl]="
|
|
4636
|
-
[formlyAttributes]="field"
|
|
4689
|
+
[formControl]="helperFormControl"
|
|
4637
4690
|
[readonly]="to['readonly']"
|
|
4638
4691
|
>
|
|
4639
4692
|
</textarea>
|
|
@@ -4646,7 +4699,7 @@ class MnlFormHelperTextInputComponent extends FieldType$1 {
|
|
|
4646
4699
|
</formly-field>
|
|
4647
4700
|
</div>
|
|
4648
4701
|
</div>
|
|
4649
|
-
`, isInline: true, styles: [".helper-text-container{display:flex;flex-direction:column}.answer{font-size:12px}.textarea{margin:0!important;width:100%}.flex-row{display:flex;flex-direction:row;justify-content:space-between}.w-full{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i3$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2$1.FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "
|
|
4702
|
+
`, isInline: true, styles: [".helper-text-container{display:flex;flex-direction:column}.answer{font-size:12px}.textarea{margin:0!important;width:100%}.flex-row{display:flex;flex-direction:row;justify-content:space-between}.w-full{width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i3$3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3$3.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2$1.FormlyField, selector: "formly-field", inputs: ["field"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i6$3.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "ngmodule", type: MatDatepickerModule }, { kind: "ngmodule", type: MatNativeDateModule }] }); }
|
|
4650
4703
|
}
|
|
4651
4704
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MnlFormHelperTextInputComponent, decorators: [{
|
|
4652
4705
|
type: Component,
|
|
@@ -4666,20 +4719,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
4666
4719
|
<!-- Helper Mode - Show toggle and conditional content -->
|
|
4667
4720
|
<div *ngIf="to['enableHelper']">
|
|
4668
4721
|
<mat-label>{{ to.label }}</mat-label>
|
|
4669
|
-
<div *ngIf="
|
|
4670
|
-
<span class="answer">{{
|
|
4722
|
+
<div *ngIf="originalValue" class="flex-row">
|
|
4723
|
+
<span class="answer">{{ originalValue }}</span>
|
|
4671
4724
|
<mat-slide-toggle
|
|
4672
4725
|
[(ngModel)]="checked"
|
|
4673
4726
|
(toggleChange)="toggleSlide()"
|
|
4674
|
-
>{{helperLabel}}</mat-slide-toggle
|
|
4727
|
+
>{{ helperLabel }}</mat-slide-toggle
|
|
4675
4728
|
>
|
|
4676
4729
|
</div>
|
|
4677
4730
|
|
|
4678
4731
|
<mat-form-field class="textarea" appearance="outline" *ngIf="checked">
|
|
4679
4732
|
<textarea
|
|
4680
4733
|
matInput
|
|
4681
|
-
[formControl]="
|
|
4682
|
-
[formlyAttributes]="field"
|
|
4734
|
+
[formControl]="helperFormControl"
|
|
4683
4735
|
[readonly]="to['readonly']"
|
|
4684
4736
|
>
|
|
4685
4737
|
</textarea>
|
|
@@ -4811,11 +4863,21 @@ class ScoringService {
|
|
|
4811
4863
|
calculateScore(model, fields) {
|
|
4812
4864
|
let totalScore = 0;
|
|
4813
4865
|
let categoryResults = {};
|
|
4814
|
-
|
|
4815
|
-
const categoryLabel = category.props?.label
|
|
4816
|
-
const categoryWeight = category.props?.weight
|
|
4817
|
-
|
|
4818
|
-
|
|
4866
|
+
const processCategory = (category) => {
|
|
4867
|
+
const categoryLabel = category.props?.label;
|
|
4868
|
+
const categoryWeight = category.props?.weight ?? 0;
|
|
4869
|
+
// Only treat as scoring category if it has a label + weight
|
|
4870
|
+
if (!categoryLabel || !categoryWeight) {
|
|
4871
|
+
// Still need to go deeper in case children have categories
|
|
4872
|
+
if (category.fieldGroup?.length) {
|
|
4873
|
+
category.fieldGroup.forEach(processCategory);
|
|
4874
|
+
}
|
|
4875
|
+
return;
|
|
4876
|
+
}
|
|
4877
|
+
const questions = (category.fieldGroup || []).filter(q => q.props?.scoring);
|
|
4878
|
+
if (questions.length === 0)
|
|
4879
|
+
return;
|
|
4880
|
+
const perQuestionWeight = categoryWeight / questions.length;
|
|
4819
4881
|
let categoryScore = 0;
|
|
4820
4882
|
for (const q of questions) {
|
|
4821
4883
|
const parentKey = category.key;
|
|
@@ -4856,7 +4918,9 @@ class ScoringService {
|
|
|
4856
4918
|
score: categoryScore,
|
|
4857
4919
|
weight: categoryWeight,
|
|
4858
4920
|
};
|
|
4859
|
-
}
|
|
4921
|
+
};
|
|
4922
|
+
// start recursive walk
|
|
4923
|
+
fields.forEach(processCategory);
|
|
4860
4924
|
return {
|
|
4861
4925
|
totalScore,
|
|
4862
4926
|
categoryResults,
|
|
@@ -4900,6 +4964,7 @@ class MnlFormLibComponent {
|
|
|
4900
4964
|
...this.options.formState,
|
|
4901
4965
|
showOldValues: this.showOldValues,
|
|
4902
4966
|
oldValues: this.oldValues,
|
|
4967
|
+
helperModel: this.helperModel,
|
|
4903
4968
|
},
|
|
4904
4969
|
};
|
|
4905
4970
|
}
|
|
@@ -5005,7 +5070,7 @@ class MnlFormLibComponent {
|
|
|
5005
5070
|
});
|
|
5006
5071
|
}
|
|
5007
5072
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MnlFormLibComponent, deps: [{ token: i1$2.TranslateService }, { token: ScoringService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5008
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MnlFormLibComponent, isStandalone: true, selector: "mnl-form", inputs: { readonly: "readonly", form: "form", fields: "fields", model: "model", options: "options", userRoles: "userRoles", userCountries: "userCountries", oldValues: "oldValues", showOldValues: "showOldValues" }, outputs: { noOfTabs: "noOfTabs", scoreChange: "scoreChange" }, ngImport: i0, template: "@if(formPrepared) {\n<formly-form\n [form]=\"form\"\n [fields]=\"fields\"\n [model]=\"model\"\n [options]=\"options\"\n (modelChange)=\"onModelChange($event)\"\n class=\"mnl-formly-form\"\n></formly-form>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CommonsModule }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: FormlyMatTextAreaModule }, { kind: "ngmodule", type: FormlyMatInputModule }, { kind: "ngmodule", type: FormlyMatCheckboxModule }, { kind: "ngmodule", type: FormlyMatRadioModule }] }); }
|
|
5073
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: MnlFormLibComponent, isStandalone: true, selector: "mnl-form", inputs: { readonly: "readonly", form: "form", fields: "fields", model: "model", helperModel: "helperModel", options: "options", userRoles: "userRoles", userCountries: "userCountries", oldValues: "oldValues", showOldValues: "showOldValues" }, outputs: { noOfTabs: "noOfTabs", scoreChange: "scoreChange" }, ngImport: i0, template: "@if(formPrepared) {\n<formly-form\n [form]=\"form\"\n [fields]=\"fields\"\n [model]=\"model\"\n [options]=\"options\"\n (modelChange)=\"onModelChange($event)\"\n class=\"mnl-formly-form\"\n></formly-form>\n}\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CommonsModule }, { kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i2$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: FormlyMatTextAreaModule }, { kind: "ngmodule", type: FormlyMatInputModule }, { kind: "ngmodule", type: FormlyMatCheckboxModule }, { kind: "ngmodule", type: FormlyMatRadioModule }] }); }
|
|
5009
5074
|
}
|
|
5010
5075
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: MnlFormLibComponent, decorators: [{
|
|
5011
5076
|
type: Component,
|
|
@@ -5029,6 +5094,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
5029
5094
|
type: Input
|
|
5030
5095
|
}], model: [{
|
|
5031
5096
|
type: Input
|
|
5097
|
+
}], helperModel: [{
|
|
5098
|
+
type: Input
|
|
5032
5099
|
}], options: [{
|
|
5033
5100
|
type: Input
|
|
5034
5101
|
}], userRoles: [{
|