@memberjunction/ng-base-forms 1.7.1 → 1.8.1

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.
@@ -33,6 +33,10 @@ export declare class MJFormField extends BaseRecordComponent implements AfterVie
33
33
  * valid when the FieldName field is a foreign key field to another entity.
34
34
  */
35
35
  LinkType: 'Email' | 'URL' | 'Record' | 'None';
36
+ /**
37
+ * Optional, when the field type is a linked field, you can specify if a search box is shown or a dropdown component is shown. The default is 'search'.
38
+ */
39
+ LinkComponentType: 'Search' | 'Dropdown';
36
40
  /**
37
41
  * If set to false, the label for the field will not be shown. The default is true.
38
42
  */
@@ -65,6 +69,6 @@ export declare class MJFormField extends BaseRecordComponent implements AfterVie
65
69
  constructor(renderer: Renderer2, cdr: ChangeDetectorRef);
66
70
  ngAfterViewInit(): void;
67
71
  static ɵfac: i0.ɵɵFactoryDeclaration<MJFormField, never>;
68
- static ɵcmp: i0.ɵɵComponentDeclaration<MJFormField, "mj-form-field", never, { "record": { "alias": "record"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; "FieldName": { "alias": "FieldName"; "required": false; }; "Type": { "alias": "Type"; "required": false; }; "LinkType": { "alias": "LinkType"; "required": false; }; "ShowLabel": { "alias": "ShowLabel"; "required": false; }; "DisplayName": { "alias": "DisplayName"; "required": false; }; "PossibleValues": { "alias": "PossibleValues"; "required": false; }; "Value": { "alias": "Value"; "required": false; }; }, { "ValueChange": "ValueChange"; }, never, never, false, never>;
72
+ static ɵcmp: i0.ɵɵComponentDeclaration<MJFormField, "mj-form-field", never, { "record": { "alias": "record"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; "FieldName": { "alias": "FieldName"; "required": false; }; "Type": { "alias": "Type"; "required": false; }; "LinkType": { "alias": "LinkType"; "required": false; }; "LinkComponentType": { "alias": "LinkComponentType"; "required": false; }; "ShowLabel": { "alias": "ShowLabel"; "required": false; }; "DisplayName": { "alias": "DisplayName"; "required": false; }; "PossibleValues": { "alias": "PossibleValues"; "required": false; }; "Value": { "alias": "Value"; "required": false; }; }, { "ValueChange": "ValueChange"; }, never, never, false, never>;
69
73
  }
70
74
  //# sourceMappingURL=base-field-component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base-field-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-field-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAyB,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3I,OAAO,EAAE,UAAU,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;;AAGjD;;;;;GAKG;AACH,qBAKa,WAAY,SAAQ,mBAAoB,YAAW,aAAa;IA8GzE,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IA9Gb;;OAEG;IACM,MAAM,EAAG,UAAU,CAAC;IAC7B;;OAEG;IACM,QAAQ,EAAE,OAAO,CAAS;IACnC;;OAEG;IACM,SAAS,EAAE,MAAM,CAAM;IAChC;;OAEG;IACM,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,gBAAgB,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,GAAG,MAAM,CAAa;IACxI;;;OAGG;IACM,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAU;IAEhE;;OAEG;IACM,SAAS,EAAE,OAAO,CAAQ;IAEnC,SAAS,uDAAa;IAEtB,OAAO,CAAC,YAAY,CAAuB;IAC3C;;OAEG;IACH,IACW,WAAW,IAAI,MAAM,CAO/B;IAED,IAAW,WAAW,CAAC,QAAQ,EAAE,MAAM,EAEtC;IAED,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,OAAO,CAAC,eAAe,CAAyB;IAChD;;;OAGG;IACH,IAAa,cAAc,IAAI,MAAM,EAAE,CAOtC;IAED,IAAI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAEpC;IAED,IACW,KAAK,IAAI,GAAG,CAUtB;IACD,IAAW,KAAK,CAAC,QAAQ,EAAE,GAAG,EAM7B;IACS,WAAW,oBAA2B;IAEhD;;OAEG;IACH,IAAW,eAAe,IAAI,OAAO,CAIpC;IAED,IAAW,SAAS,IAAI,eAAe,CAItC;IAEyC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAClF,OAAO,CAAC,QAAQ,CAA+B;gBAGrC,QAAQ,EAAE,SAAS,EACnB,GAAG,EAAE,iBAAiB;IAKhC,eAAe,IAAI,IAAI;yCApHZ,WAAW;2CAAX,WAAW;CA2LvB"}
1
+ {"version":3,"file":"base-field-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-field-component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAyB,aAAa,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC3I,OAAO,EAAE,UAAU,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;;AAGjD;;;;;GAKG;AACH,qBAKa,WAAY,SAAQ,mBAAoB,YAAW,aAAa;IAmHzE,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,GAAG;IAnHb;;OAEG;IACM,MAAM,EAAG,UAAU,CAAC;IAC7B;;OAEG;IACM,QAAQ,EAAE,OAAO,CAAS;IACnC;;OAEG;IACM,SAAS,EAAE,MAAM,CAAM;IAChC;;OAEG;IACM,IAAI,EAAE,SAAS,GAAG,UAAU,GAAG,gBAAgB,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,GAAG,MAAM,CAAa;IACxI;;;OAGG;IACM,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAU;IAEhE;;OAEG;IACM,iBAAiB,EAAE,QAAQ,GAAG,UAAU,CAAc;IAE/D;;OAEG;IACM,SAAS,EAAE,OAAO,CAAQ;IAEnC,SAAS,uDAAa;IAEtB,OAAO,CAAC,YAAY,CAAuB;IAC3C;;OAEG;IACH,IACW,WAAW,IAAI,MAAM,CAO/B;IAED,IAAW,WAAW,CAAC,QAAQ,EAAE,MAAM,EAEtC;IAED,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,OAAO,CAAC,eAAe,CAAyB;IAChD;;;OAGG;IACH,IAAa,cAAc,IAAI,MAAM,EAAE,CAOtC;IAED,IAAI,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,EAEpC;IAED,IACW,KAAK,IAAI,GAAG,CAUtB;IACD,IAAW,KAAK,CAAC,QAAQ,EAAE,GAAG,EAM7B;IACS,WAAW,oBAA2B;IAEhD;;OAEG;IACH,IAAW,eAAe,IAAI,OAAO,CAIpC;IAED,IAAW,SAAS,IAAI,eAAe,CAItC;IAEyC,QAAQ,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAClF,OAAO,CAAC,QAAQ,CAA+B;gBAGrC,QAAQ,EAAE,SAAS,EACnB,GAAG,EAAE,iBAAiB;IAKhC,eAAe,IAAI,IAAI;yCAzHZ,WAAW;2CAAX,WAAW;CAgMvB"}
@@ -105,40 +105,41 @@ function MJFormField_Conditional_0_div_1_Conditional_2_Template(rf, ctx) { if (r
105
105
  i0.ɵɵelement(0, "mj-link-field", 9);
106
106
  } if (rf & 2) {
107
107
  const ctx_r0 = i0.ɵɵnextContext(3);
108
- i0.ɵɵproperty("record", ctx_r0.record)("FieldName", ctx_r0.FieldName);
108
+ i0.ɵɵproperty("record", ctx_r0.record)("FieldName", ctx_r0.FieldName)("LinkComponentType", ctx_r0.LinkComponentType);
109
109
  } }
110
110
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_0_Template(rf, ctx) { if (rf & 1) {
111
111
  const _r2 = i0.ɵɵgetCurrentView();
112
- i0.ɵɵelementStart(0, "kendo-textbox", 16);
113
- i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_0_Template_kendo_textbox_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
112
+ i0.ɵɵelementStart(0, "mj-code-editor", 17);
113
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_0_Template_mj_code_editor_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
114
114
  i0.ɵɵelementEnd();
115
115
  } if (rf & 2) {
116
116
  const ctx_r0 = i0.ɵɵnextContext(4);
117
117
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
118
+ i0.ɵɵproperty("languages", ctx_r0.languages)("language", "JavaScript");
118
119
  } }
119
120
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_1_Template(rf, ctx) { if (rf & 1) {
120
121
  const _r3 = i0.ɵɵgetCurrentView();
121
- i0.ɵɵelementStart(0, "kendo-textarea", 17);
122
- i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_1_Template_kendo_textarea_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
122
+ i0.ɵɵelementStart(0, "kendo-textbox", 18);
123
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_1_Template_kendo_textbox_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
123
124
  i0.ɵɵelementEnd();
124
125
  } if (rf & 2) {
125
126
  const ctx_r0 = i0.ɵɵnextContext(4);
126
127
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
127
- i0.ɵɵproperty("fillWidth", ctx_r0.ShowLabel ? false : true)("fillHeight", ctx_r0.ShowLabel ? false : true);
128
128
  } }
129
129
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_2_Template(rf, ctx) { if (rf & 1) {
130
130
  const _r4 = i0.ɵɵgetCurrentView();
131
- i0.ɵɵelementStart(0, "kendo-numerictextbox", 18);
132
- i0.ɵɵtwoWayListener("valueChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_2_Template_kendo_numerictextbox_valueChange_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
131
+ i0.ɵɵelementStart(0, "kendo-textarea", 19);
132
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_2_Template_kendo_textarea_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
133
133
  i0.ɵɵelementEnd();
134
134
  } if (rf & 2) {
135
135
  const ctx_r0 = i0.ɵɵnextContext(4);
136
- i0.ɵɵtwoWayProperty("value", ctx_r0.Value);
136
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
137
+ i0.ɵɵproperty("fillWidth", ctx_r0.ShowLabel ? false : true)("fillHeight", ctx_r0.ShowLabel ? false : true);
137
138
  } }
138
139
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template(rf, ctx) { if (rf & 1) {
139
140
  const _r5 = i0.ɵɵgetCurrentView();
140
- i0.ɵɵelementStart(0, "kendo-datepicker", 18);
141
- i0.ɵɵtwoWayListener("valueChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template_kendo_datepicker_valueChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
141
+ i0.ɵɵelementStart(0, "kendo-numerictextbox", 20);
142
+ i0.ɵɵtwoWayListener("valueChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template_kendo_numerictextbox_valueChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
142
143
  i0.ɵɵelementEnd();
143
144
  } if (rf & 2) {
144
145
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -146,27 +147,36 @@ function MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template(rf, ctx)
146
147
  } }
147
148
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_4_Template(rf, ctx) { if (rf & 1) {
148
149
  const _r6 = i0.ɵɵgetCurrentView();
149
- i0.ɵɵelementStart(0, "input", 19);
150
- i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_4_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
150
+ i0.ɵɵelementStart(0, "kendo-datepicker", 20);
151
+ i0.ɵɵtwoWayListener("valueChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_4_Template_kendo_datepicker_valueChange_0_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
151
152
  i0.ɵɵelementEnd();
152
153
  } if (rf & 2) {
153
154
  const ctx_r0 = i0.ɵɵnextContext(4);
154
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
155
+ i0.ɵɵtwoWayProperty("value", ctx_r0.Value);
155
156
  } }
156
157
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_5_Template(rf, ctx) { if (rf & 1) {
157
158
  const _r7 = i0.ɵɵgetCurrentView();
158
- i0.ɵɵelementStart(0, "kendo-dropdownlist", 20);
159
- i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_5_Template_kendo_dropdownlist_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
159
+ i0.ɵɵelementStart(0, "input", 21);
160
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_5_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
160
161
  i0.ɵɵelementEnd();
161
162
  } if (rf & 2) {
162
163
  const ctx_r0 = i0.ɵɵnextContext(4);
163
- i0.ɵɵproperty("data", ctx_r0.PossibleValues);
164
164
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
165
165
  } }
166
166
  function MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template(rf, ctx) { if (rf & 1) {
167
167
  const _r8 = i0.ɵɵgetCurrentView();
168
- i0.ɵɵelementStart(0, "kendo-combobox", 21);
169
- i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template_kendo_combobox_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
168
+ i0.ɵɵelementStart(0, "kendo-dropdownlist", 22);
169
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template_kendo_dropdownlist_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r8); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
170
+ i0.ɵɵelementEnd();
171
+ } if (rf & 2) {
172
+ const ctx_r0 = i0.ɵɵnextContext(4);
173
+ i0.ɵɵproperty("data", ctx_r0.PossibleValues);
174
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
175
+ } }
176
+ function MJFormField_Conditional_0_div_1_Conditional_3_Case_7_Template(rf, ctx) { if (rf & 1) {
177
+ const _r9 = i0.ɵɵgetCurrentView();
178
+ i0.ɵɵelementStart(0, "kendo-combobox", 23);
179
+ i0.ɵɵtwoWayListener("ngModelChange", function MJFormField_Conditional_0_div_1_Conditional_3_Case_7_Template_kendo_combobox_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r0 = i0.ɵɵnextContext(4); i0.ɵɵtwoWayBindingSet(ctx_r0.Value, $event) || (ctx_r0.Value = $event); return i0.ɵɵresetView($event); });
170
180
  i0.ɵɵelementEnd();
171
181
  } if (rf & 2) {
172
182
  const ctx_r0 = i0.ɵɵnextContext(4);
@@ -174,15 +184,15 @@ function MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template(rf, ctx)
174
184
  i0.ɵɵtwoWayProperty("ngModel", ctx_r0.Value);
175
185
  } }
176
186
  function MJFormField_Conditional_0_div_1_Conditional_3_Template(rf, ctx) { if (rf & 1) {
177
- i0.ɵɵtemplate(0, MJFormField_Conditional_0_div_1_Conditional_3_Case_0_Template, 1, 1, "kendo-textbox", 10)(1, MJFormField_Conditional_0_div_1_Conditional_3_Case_1_Template, 1, 3, "kendo-textarea", 11)(2, MJFormField_Conditional_0_div_1_Conditional_3_Case_2_Template, 1, 1, "kendo-numerictextbox", 12)(3, MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template, 1, 1, "kendo-datepicker", 12)(4, MJFormField_Conditional_0_div_1_Conditional_3_Case_4_Template, 1, 1, "input", 13)(5, MJFormField_Conditional_0_div_1_Conditional_3_Case_5_Template, 1, 2, "kendo-dropdownlist", 14)(6, MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template, 1, 3, "kendo-combobox", 15);
187
+ i0.ɵɵtemplate(0, MJFormField_Conditional_0_div_1_Conditional_3_Case_0_Template, 1, 3, "mj-code-editor", 10)(1, MJFormField_Conditional_0_div_1_Conditional_3_Case_1_Template, 1, 1, "kendo-textbox", 11)(2, MJFormField_Conditional_0_div_1_Conditional_3_Case_2_Template, 1, 3, "kendo-textarea", 12)(3, MJFormField_Conditional_0_div_1_Conditional_3_Case_3_Template, 1, 1, "kendo-numerictextbox", 13)(4, MJFormField_Conditional_0_div_1_Conditional_3_Case_4_Template, 1, 1, "kendo-datepicker", 13)(5, MJFormField_Conditional_0_div_1_Conditional_3_Case_5_Template, 1, 1, "input", 14)(6, MJFormField_Conditional_0_div_1_Conditional_3_Case_6_Template, 1, 2, "kendo-dropdownlist", 15)(7, MJFormField_Conditional_0_div_1_Conditional_3_Case_7_Template, 1, 3, "kendo-combobox", 16);
178
188
  } if (rf & 2) {
179
189
  let tmp_3_0;
180
190
  const ctx_r0 = i0.ɵɵnextContext(3);
181
- i0.ɵɵconditional((tmp_3_0 = ctx_r0.Type) === "textbox" ? 0 : tmp_3_0 === "textarea" ? 1 : tmp_3_0 === "numerictextbox" ? 2 : tmp_3_0 === "datepicker" ? 3 : tmp_3_0 === "checkbox" ? 4 : tmp_3_0 === "dropdownlist" ? 5 : tmp_3_0 === "combobox" ? 6 : -1);
191
+ i0.ɵɵconditional((tmp_3_0 = ctx_r0.Type) === "code" ? 0 : tmp_3_0 === "textbox" ? 1 : tmp_3_0 === "textarea" ? 2 : tmp_3_0 === "numerictextbox" ? 3 : tmp_3_0 === "datepicker" ? 4 : tmp_3_0 === "checkbox" ? 5 : tmp_3_0 === "dropdownlist" ? 6 : tmp_3_0 === "combobox" ? 7 : -1);
182
192
  } }
183
193
  function MJFormField_Conditional_0_div_1_Template(rf, ctx) { if (rf & 1) {
184
194
  i0.ɵɵelementStart(0, "div", 2);
185
- i0.ɵɵtemplate(1, MJFormField_Conditional_0_div_1_Conditional_1_Template, 2, 1, "label")(2, MJFormField_Conditional_0_div_1_Conditional_2_Template, 1, 2, "mj-link-field", 9)(3, MJFormField_Conditional_0_div_1_Conditional_3_Template, 7, 1);
195
+ i0.ɵɵtemplate(1, MJFormField_Conditional_0_div_1_Conditional_1_Template, 2, 1, "label")(2, MJFormField_Conditional_0_div_1_Conditional_2_Template, 1, 3, "mj-link-field", 9)(3, MJFormField_Conditional_0_div_1_Conditional_3_Template, 8, 1);
186
196
  i0.ɵɵelementEnd();
187
197
  } if (rf & 2) {
188
198
  const ctx_r0 = i0.ɵɵnextContext(2);
@@ -303,6 +313,10 @@ export class MJFormField extends BaseRecordComponent {
303
313
  * valid when the FieldName field is a foreign key field to another entity.
304
314
  */
305
315
  this.LinkType = 'None';
316
+ /**
317
+ * Optional, when the field type is a linked field, you can specify if a search box is shown or a dropdown component is shown. The default is 'search'.
318
+ */
319
+ this.LinkComponentType = 'Dropdown';
306
320
  /**
307
321
  * If set to false, the label for the field will not be shown. The default is true.
308
322
  */
@@ -343,14 +357,14 @@ MJFormField.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJFormField, se
343
357
  } if (rf & 2) {
344
358
  let _t;
345
359
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.markdown = _t.first);
346
- } }, inputs: { record: "record", EditMode: "EditMode", FieldName: "FieldName", Type: "Type", LinkType: "LinkType", ShowLabel: "ShowLabel", DisplayName: "DisplayName", PossibleValues: "PossibleValues", Value: "Value" }, outputs: { ValueChange: "ValueChange" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["markdown", ""], ["class", "record-form-row", 4, "ngIf"], [1, "record-form-row"], [4, "ngIf"], ["mjEmailLink", "", 3, "field"], ["mjWebLink", "", 3, "field"], ["mjFieldLink", "", 3, "record", "fieldName"], [3, "value", "readonly", "languages", "language"], [3, "data"], [3, "record", "FieldName"], [3, "ngModel"], ["mjFillContainer", "", 3, "ngModel", "fillWidth", "fillHeight"], [3, "value"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModel"], [3, "data", "ngModel"], [3, "data", "allowCustom", "ngModel"], [3, "ngModelChange", "ngModel"], ["mjFillContainer", "", 3, "ngModelChange", "ngModel", "fillWidth", "fillHeight"], [3, "valueChange", "value"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModelChange", "ngModel"], [3, "ngModelChange", "data", "ngModel"], [3, "ngModelChange", "data", "allowCustom", "ngModel"]], template: function MJFormField_Template(rf, ctx) { if (rf & 1) {
360
+ } }, inputs: { record: "record", EditMode: "EditMode", FieldName: "FieldName", Type: "Type", LinkType: "LinkType", LinkComponentType: "LinkComponentType", ShowLabel: "ShowLabel", DisplayName: "DisplayName", PossibleValues: "PossibleValues", Value: "Value" }, outputs: { ValueChange: "ValueChange" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 1, vars: 1, consts: [["markdown", ""], ["class", "record-form-row", 4, "ngIf"], [1, "record-form-row"], [4, "ngIf"], ["mjEmailLink", "", 3, "field"], ["mjWebLink", "", 3, "field"], ["mjFieldLink", "", 3, "record", "fieldName"], [3, "value", "readonly", "languages", "language"], [3, "data"], [3, "record", "FieldName", "LinkComponentType"], [3, "ngModel", "languages", "language"], [3, "ngModel"], ["mjFillContainer", "", 3, "ngModel", "fillWidth", "fillHeight"], [3, "value"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModel"], [3, "data", "ngModel"], [3, "data", "allowCustom", "ngModel"], [3, "ngModelChange", "ngModel", "languages", "language"], [3, "ngModelChange", "ngModel"], ["mjFillContainer", "", 3, "ngModelChange", "ngModel", "fillWidth", "fillHeight"], [3, "valueChange", "value"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModelChange", "ngModel"], [3, "ngModelChange", "data", "ngModel"], [3, "ngModelChange", "data", "allowCustom", "ngModel"]], template: function MJFormField_Template(rf, ctx) { if (rf & 1) {
347
361
  i0.ɵɵtemplate(0, MJFormField_Conditional_0_Template, 2, 2);
348
362
  } if (rf & 2) {
349
363
  i0.ɵɵconditional(ctx.record.IsSaved || !ctx.IsFieldReadOnly ? 0 : -1);
350
364
  } }, dependencies: [i1.NgIf, i2.CheckboxControlValueAccessor, i2.NgControlStatus, i2.NgModel, i3.TextAreaComponent, i3.TextBoxComponent, i3.NumericTextBoxComponent, i3.CheckBoxDirective, i4.DatePickerComponent, i5.ComboBoxComponent, i5.DropDownListComponent, i6.EmailLink, i6.FieldLink, i6.WebLink, i7.FillContainer, i8.CodeEditorComponent, i9.MarkdownComponent, i10.MJLinkField], styles: [".record-form-row[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n align-items: start; \n\n} \n \n \n.record-form-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: bold;\n padding-right: 10px;\n width: 240px;\n margin-bottom: 0;\n align-self: start; \n\n}\n\n\n\n\n\n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > p[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h1[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h2[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h3[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h4[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h5[_ngcontent-%COMP%], \n.record-form-row[_ngcontent-%COMP%] markdown[_ngcontent-%COMP%] > h6[_ngcontent-%COMP%] {\n margin:0 !important;\n}\n\nmarkdown[_ngcontent-%COMP%] {\n font-size: 1rem; \n\n}\n\n\n@media (min-width: 768px) {\n .record-form-row[_ngcontent-%COMP%] {\n display: grid; \n\n grid-template-columns: auto 1fr;\n align-items: start; \n\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n }\n\n .record-form-row[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n width: 240px;\n margin-bottom: 0;\n align-self: start; \n\n }\n}"] });
351
365
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJFormField, [{
352
366
  type: Component,
353
- args: [{ selector: 'mj-form-field', template: "<!--\n Using a blend of *ngIf and the new @switch control flow because of a bug in early Angular 17 where\n the @if wrapping the @switch didn't fully remove elements when swtiching back and forth. In the future if Angular fixes the bug\n we can get rid of the *ngIf outer div blocks and instead use @if and contain the @switch within the same div block.\n-->\n@if (record.IsSaved || !IsFieldReadOnly) {\n <!-- We only render a field if the record is either saved, or the field is editable. Meaning, for NEW records, we only show editable fields -->\n <div class=\"record-form-row\" *ngIf=\"!EditMode || IsFieldReadOnly\">\n <label *ngIf=\"ShowLabel\">{{DisplayName}}</label>\n @switch (LinkType) {\n @case ('None') {\n @if (ExtendedType === 'Code') {\n <mj-code-editor [value]=\"record.Get(FieldName)\" [readonly]=\"true\" [languages]=\"languages\" [language]=\"'JavaScript'\"></mj-code-editor>\n }\n @else if (FieldInfo.Length === -1) {\n <!-- this is a varchar(max) type of field -->\n <markdown #markdown [data]=\"record.Get(FieldName)\"></markdown>\n <!-- <span [innerHTML]=\"record.Get(FieldName) | formatText\"></span> -->\n }\n @else {\n <span>{{FormatValue(FieldName, 0)}}</span>\n }\n }\n @case ('Email') {\n <span mjEmailLink [field]=\"record.GetFieldByName(FieldName)\" >{{FormatValue(FieldName, 0)}}</span>\n }\n @case ('URL') {\n <span mjWebLink [field]=\"record.GetFieldByName(FieldName)\" >{{FormatValue(FieldName, 0)}}</span>\n }\n @case ('Record') {\n <span mjFieldLink [record]=\"record\" [fieldName]=\"FieldName\" >{{FormatValue(FieldName, 0)}}</span>\n }\n }\n </div>\n <div class=\"record-form-row\" *ngIf=\"EditMode && !IsFieldReadOnly\">\n @if (ShowLabel) {\n <label>{{DisplayName}}</label>\n }\n @if (FieldInfo && FieldInfo.RelatedEntity && FieldInfo.RelatedEntity.length > 0) {\n <!-- Foreign Key Link here -->\n <mj-link-field [record]=\"record\" [FieldName]=\"FieldName\"></mj-link-field>\n }\n @else {\n <!-- Not a foreign key -->\n @switch (Type) {\n @case ('textbox') {\n <kendo-textbox [(ngModel)]=\"Value\" />\n }\n @case ('textarea') {\n <kendo-textarea [(ngModel)]=\"Value\" mjFillContainer [fillWidth]=\"ShowLabel ? false : true\" [fillHeight]=\"ShowLabel ? false : true\" ></kendo-textarea>\n }\n @case ('numerictextbox') {\n <kendo-numerictextbox [(value)]=\"Value\" />\n }\n @case ('datepicker') {\n <kendo-datepicker [(value)]=\"Value\"></kendo-datepicker>\n }\n @case ('checkbox') {\n <input type=\"checkbox\" [(ngModel)]=\"Value\" kendoCheckBox />\n }\n @case ('dropdownlist') {\n <kendo-dropdownlist [data]=\"PossibleValues\" [(ngModel)]=\"Value\"></kendo-dropdownlist>\n }\n @case ('combobox') {\n <kendo-combobox [data]=\"PossibleValues\" [allowCustom]=\"true\" [(ngModel)]=\"Value\"></kendo-combobox>\n }\n }\n }\n </div>\n}\n", styles: [".record-form-row {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n align-items: start; /* Ensure items are aligned at the top */\n} \n \n \n.record-form-row label {\n font-weight: bold;\n padding-right: 10px;\n width: 240px;\n margin-bottom: 0;\n align-self: start; /* Align the label to the start (top) */\n}\n\n/*\n Eliminate the default margin and padding for the markdown elements\n */\n.record-form-row markdown > p,\n.record-form-row markdown > h1,\n.record-form-row markdown > h2,\n.record-form-row markdown > h3,\n.record-form-row markdown > h4,\n.record-form-row markdown > h5,\n.record-form-row markdown > h6 {\n margin:0 !important;\n}\n\nmarkdown {\n font-size: 1rem; /* Adjust this value to match your app's regular text size */\n}\n\n\n@media (min-width: 768px) {\n .record-form-row {\n display: grid; /* Ensure grid display is used for larger screens as well */\n grid-template-columns: auto 1fr;\n align-items: start; /* Keep the alignment at the top */\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n }\n\n .record-form-row label {\n width: 240px;\n margin-bottom: 0;\n align-self: start; /* Ensure the label is aligned to the top */\n }\n}\n "] }]
367
+ args: [{ selector: 'mj-form-field', template: "<!--\n Using a blend of *ngIf and the new @switch control flow because of a bug in early Angular 17 where\n the @if wrapping the @switch didn't fully remove elements when swtiching back and forth. In the future if Angular fixes the bug\n we can get rid of the *ngIf outer div blocks and instead use @if and contain the @switch within the same div block.\n-->\n@if (record.IsSaved || !IsFieldReadOnly) {\n <!-- We only render a field if the record is either saved, or the field is editable. Meaning, for NEW records, we only show editable fields -->\n <div class=\"record-form-row\" *ngIf=\"!EditMode || IsFieldReadOnly\">\n <label *ngIf=\"ShowLabel\">{{DisplayName}}</label>\n @switch (LinkType) {\n @case ('None') {\n @if (ExtendedType === 'Code') {\n <mj-code-editor [value]=\"record.Get(FieldName)\" [readonly]=\"true\" [languages]=\"languages\" [language]=\"'JavaScript'\"></mj-code-editor>\n }\n @else if (FieldInfo.Length === -1) {\n <!-- this is a varchar(max) type of field -->\n <markdown #markdown [data]=\"record.Get(FieldName)\"></markdown>\n <!-- <span [innerHTML]=\"record.Get(FieldName) | formatText\"></span> -->\n }\n @else {\n <span>{{FormatValue(FieldName, 0)}}</span>\n }\n }\n @case ('Email') {\n <span mjEmailLink [field]=\"record.GetFieldByName(FieldName)\" >{{FormatValue(FieldName, 0)}}</span>\n }\n @case ('URL') {\n <span mjWebLink [field]=\"record.GetFieldByName(FieldName)\" >{{FormatValue(FieldName, 0)}}</span>\n }\n @case ('Record') {\n <span mjFieldLink [record]=\"record\" [fieldName]=\"FieldName\" >{{FormatValue(FieldName, 0)}}</span>\n }\n }\n </div>\n <div class=\"record-form-row\" *ngIf=\"EditMode && !IsFieldReadOnly\">\n @if (ShowLabel) {\n <label>{{DisplayName}}</label>\n }\n @if (FieldInfo && FieldInfo.RelatedEntity && FieldInfo.RelatedEntity.length > 0) {\n <!-- Foreign Key Link here -->\n <mj-link-field [record]=\"record\" [FieldName]=\"FieldName\" [LinkComponentType]=\"LinkComponentType\"></mj-link-field>\n }\n @else {\n <!-- Not a foreign key -->\n @switch (Type) {\n @case ('code') {\n <mj-code-editor [(ngModel)]=\"Value\" [languages]=\"languages\" [language]=\"'JavaScript'\"></mj-code-editor>\n }\n @case ('textbox') {\n <kendo-textbox [(ngModel)]=\"Value\" />\n }\n @case ('textarea') {\n <kendo-textarea [(ngModel)]=\"Value\" mjFillContainer [fillWidth]=\"ShowLabel ? false : true\" [fillHeight]=\"ShowLabel ? false : true\" ></kendo-textarea>\n }\n @case ('numerictextbox') {\n <kendo-numerictextbox [(value)]=\"Value\" />\n }\n @case ('datepicker') {\n <kendo-datepicker [(value)]=\"Value\"></kendo-datepicker>\n }\n @case ('checkbox') {\n <input type=\"checkbox\" [(ngModel)]=\"Value\" kendoCheckBox />\n }\n @case ('dropdownlist') {\n <kendo-dropdownlist [data]=\"PossibleValues\" [(ngModel)]=\"Value\"></kendo-dropdownlist>\n }\n @case ('combobox') {\n <kendo-combobox [data]=\"PossibleValues\" [allowCustom]=\"true\" [(ngModel)]=\"Value\"></kendo-combobox>\n }\n }\n }\n </div>\n}\n", styles: [".record-form-row {\n display: grid;\n grid-template-columns: auto 1fr;\n align-items: start;\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n align-items: start; /* Ensure items are aligned at the top */\n} \n \n \n.record-form-row label {\n font-weight: bold;\n padding-right: 10px;\n width: 240px;\n margin-bottom: 0;\n align-self: start; /* Align the label to the start (top) */\n}\n\n/*\n Eliminate the default margin and padding for the markdown elements\n */\n.record-form-row markdown > p,\n.record-form-row markdown > h1,\n.record-form-row markdown > h2,\n.record-form-row markdown > h3,\n.record-form-row markdown > h4,\n.record-form-row markdown > h5,\n.record-form-row markdown > h6 {\n margin:0 !important;\n}\n\nmarkdown {\n font-size: 1rem; /* Adjust this value to match your app's regular text size */\n}\n\n\n@media (min-width: 768px) {\n .record-form-row {\n display: grid; /* Ensure grid display is used for larger screens as well */\n grid-template-columns: auto 1fr;\n align-items: start; /* Keep the alignment at the top */\n gap: 10px;\n margin-bottom: 12px;\n padding-top: 5px;\n padding-bottom: 5px;\n }\n\n .record-form-row label {\n width: 240px;\n margin-bottom: 0;\n align-self: start; /* Ensure the label is aligned to the top */\n }\n}\n "] }]
354
368
  }], () => [{ type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }], { record: [{
355
369
  type: Input
356
370
  }], EditMode: [{
@@ -361,6 +375,8 @@ MJFormField.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJFormField, se
361
375
  type: Input
362
376
  }], LinkType: [{
363
377
  type: Input
378
+ }], LinkComponentType: [{
379
+ type: Input
364
380
  }], ShowLabel: [{
365
381
  type: Input
366
382
  }], DisplayName: [{
@@ -1,9 +1,10 @@
1
1
  import { AfterViewInit, OnInit, OnDestroy, QueryList, ElementRef, ChangeDetectorRef } from '@angular/core';
2
- import { EntityInfo, ValidationResult, BaseEntity, EntityPermissionType, EntityRelationshipInfo, RunViewParams, RecordDependency } from '@memberjunction/core';
2
+ import { EntityInfo, ValidationResult, EntityPermissionType, EntityRelationshipInfo, RunViewParams, RecordDependency } from '@memberjunction/core';
3
3
  import { BaseRecordComponent } from './base-record-component';
4
- import { BaseFormComponentEventCodes, SharedService } from '@memberjunction/ng-shared';
4
+ import { SharedService } from '@memberjunction/ng-shared';
5
5
  import { ActivatedRoute, Router } from '@angular/router';
6
6
  import { MJTabStripComponent } from '@memberjunction/ng-tabstrip';
7
+ import { FormEditingCompleteEvent, PendingRecordItem, BaseFormComponentEventCodes } from '@memberjunction/ng-base-types';
7
8
  import * as i0 from "@angular/core";
8
9
  export declare abstract class BaseFormComponent extends BaseRecordComponent implements AfterViewInit, OnInit, OnDestroy {
9
10
  protected elementRef: ElementRef;
@@ -42,7 +43,7 @@ export declare abstract class BaseFormComponent extends BaseRecordComponent impl
42
43
  CalcTopAreaHeight(): void;
43
44
  private resizeSub;
44
45
  ngOnDestroy(): void;
45
- protected get PendingRecords(): BaseEntity[];
46
+ protected get PendingRecords(): PendingRecordItem[];
46
47
  onTabSelect(e: any): void;
47
48
  StartEditMode(): void;
48
49
  handleHistoryDialog(): void;
@@ -52,6 +53,7 @@ export declare abstract class BaseFormComponent extends BaseRecordComponent impl
52
53
  SetFavoriteStatus(isFavorite: boolean): Promise<void>;
53
54
  private _isFavorite;
54
55
  get IsFavorite(): boolean;
56
+ private _userPermissions;
55
57
  CheckUserPermission(type: EntityPermissionType): boolean;
56
58
  get UserCanEdit(): boolean;
57
59
  get UserCanRead(): boolean;
@@ -87,12 +89,12 @@ export declare abstract class BaseFormComponent extends BaseRecordComponent impl
87
89
  GetRelatedEntityTabDisplayName(relatedEntityName: string): string;
88
90
  protected ValidatePendingRecords(): ValidationResult[];
89
91
  Validate(): ValidationResult;
90
- protected RaiseEvent(eventCode: BaseFormComponentEventCodes): any;
92
+ protected RaiseEvent(eventCode: BaseFormComponentEventCodes): FormEditingCompleteEvent;
91
93
  SaveRecord(StopEditModeAfterSave: boolean): Promise<boolean>;
92
94
  Wait(duration: number): Promise<void>;
93
95
  CancelEdit(): void;
94
96
  protected PendingRecordsDirty(): boolean;
95
- protected PopulatePendingRecords(): Promise<void>;
97
+ protected PopulatePendingRecords(): void;
96
98
  protected InternalSaveRecord(): Promise<boolean>;
97
99
  protected GetTabTopPosition(): number;
98
100
  private _tabMargin;
@@ -1 +1 @@
1
- {"version":3,"file":"base-form-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base-form-component.d.ts","sourceRoot":"","sources":["../../src/lib/base-form-component.ts"],"names":[],"mappings":"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"}
@@ -11,9 +11,9 @@ import { Directive, ViewChildren, ViewChild } from '@angular/core';
11
11
  import { Subject, debounceTime, fromEvent } from 'rxjs';
12
12
  import { EntityInfo, EntityPermissionType, Metadata, LogError } from '@memberjunction/core';
13
13
  import { BaseRecordComponent } from './base-record-component';
14
- import { BaseFormComponentEventCodes } from '@memberjunction/ng-shared';
15
14
  import { MJTabStripComponent } from '@memberjunction/ng-tabstrip';
16
15
  import { MJEventType, MJGlobal } from '@memberjunction/global';
16
+ import { FormEditingCompleteEvent, BaseFormComponentEventCodes } from '@memberjunction/ng-base-types';
17
17
  import * as i0 from "@angular/core";
18
18
  import * as i1 from "@memberjunction/ng-shared";
19
19
  import * as i2 from "@angular/router";
@@ -46,6 +46,7 @@ export class BaseFormComponent extends BaseRecordComponent {
46
46
  this.__debug = false;
47
47
  this.resizeSub = null;
48
48
  this._isFavorite = false;
49
+ this._userPermissions = [];
49
50
  this._tabMargin = 10;
50
51
  this.setupSplitterLayoutDebounce();
51
52
  }
@@ -176,8 +177,16 @@ export class BaseFormComponent extends BaseRecordComponent {
176
177
  }
177
178
  CheckUserPermission(type) {
178
179
  try {
179
- if (this.record)
180
- return this.record.CheckPermissions(type, false);
180
+ if (this.record) {
181
+ const perm = this._userPermissions.find(x => x.permission === type);
182
+ if (perm)
183
+ return perm.canDo;
184
+ else {
185
+ const result = this.record.CheckPermissions(type, false);
186
+ this._userPermissions.push({ permission: type, canDo: result });
187
+ return result;
188
+ }
189
+ }
181
190
  else
182
191
  return false;
183
192
  }
@@ -264,7 +273,7 @@ export class BaseFormComponent extends BaseRecordComponent {
264
273
  const results = [];
265
274
  for (let i = 0; i < this._pendingRecords.length; i++) {
266
275
  const pendingRecord = this._pendingRecords[i];
267
- results.push(pendingRecord.Validate());
276
+ results.push(pendingRecord.entityObject.Validate());
268
277
  }
269
278
  return results;
270
279
  }
@@ -281,21 +290,16 @@ export class BaseFormComponent extends BaseRecordComponent {
281
290
  return valResults;
282
291
  }
283
292
  RaiseEvent(eventCode) {
284
- const p = [];
285
- const event = {
286
- subEventCode: eventCode,
287
- elementRef: this.elementRef,
288
- returnValue: {
289
- pendingRecords: p
290
- }
291
- };
293
+ const event = new FormEditingCompleteEvent();
294
+ event.elementRef = this.elementRef;
295
+ event.subEventCode = eventCode;
292
296
  MJGlobal.Instance.RaiseEvent({
293
297
  event: MJEventType.ComponentEvent,
294
298
  component: this,
295
299
  eventCode: BaseFormComponentEventCodes.BASE_CODE,
296
300
  args: event
297
301
  });
298
- return event.returnValue; // if the recipients of the event provided any values, we have them now
302
+ return event; // if the recipients of the event provided any values, we have them now
299
303
  }
300
304
  SaveRecord(StopEditModeAfterSave) {
301
305
  return __awaiter(this, void 0, void 0, function* () {
@@ -304,13 +308,13 @@ export class BaseFormComponent extends BaseRecordComponent {
304
308
  // atempt to blur the active element to force any pending changes to be committed
305
309
  document.activeElement.blur();
306
310
  // notify child components of this component that they must stop editing with an EDITING_COMPLETE message via MJ_global
307
- this.RaiseEvent('EDITING_COMPLETE');
311
+ this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE);
308
312
  }
309
313
  catch (e2) {
310
314
  // ignore
311
315
  }
312
316
  if (this.record) {
313
- yield this.PopulatePendingRecords(); // do this before we validate as we must validate pending records too
317
+ this.PopulatePendingRecords(); // do this before we validate as we must validate pending records too
314
318
  const valResults = this.Validate();
315
319
  if (valResults.Success) {
316
320
  const result = yield this.InternalSaveRecord();
@@ -322,13 +326,15 @@ export class BaseFormComponent extends BaseRecordComponent {
322
326
  this.sharedService.CreateSimpleNotification('Record saved succesfully', 'success', 2500);
323
327
  return true;
324
328
  }
325
- else
329
+ else {
326
330
  this.sharedService.CreateSimpleNotification('Error saving record', 'error', 5000);
331
+ }
327
332
  }
328
333
  else {
329
334
  this.sharedService.CreateSimpleNotification('Validation Errors\n' + valResults.Errors.map(x => x.Message).join('\n'), 'warning', 10000);
330
335
  }
331
336
  }
337
+ LogError("Could not save reocrd: Record not found");
332
338
  return false; // if we get here, we have failed/validation error/etc
333
339
  }
334
340
  catch (e) {
@@ -355,10 +361,11 @@ export class BaseFormComponent extends BaseRecordComponent {
355
361
  if (pendingRecords && pendingRecords.length > 0) {
356
362
  // we have pending records, so we need to revert them as well
357
363
  pendingRecords.forEach(p => {
358
- p.Revert();
364
+ if (p.action === 'save')
365
+ p.entityObject.Revert(); // only do this if we are saving the record, ignore deletes
359
366
  });
360
367
  }
361
- this.RaiseEvent('REVERT_PENDING_CHANGES');
368
+ this.RaiseEvent(BaseFormComponentEventCodes.REVERT_PENDING_CHANGES);
362
369
  }
363
370
  // if we get here we are good to go
364
371
  this.EditMode = false;
@@ -368,32 +375,31 @@ export class BaseFormComponent extends BaseRecordComponent {
368
375
  this.PopulatePendingRecords();
369
376
  const pendingRecords = this.PendingRecords;
370
377
  if (pendingRecords && pendingRecords.length > 0) {
371
- for (let i = 0; i < pendingRecords.length; i++) {
372
- if (pendingRecords[i].Dirty)
378
+ for (const p of pendingRecords) {
379
+ if (p.action === 'delete')
380
+ return true;
381
+ else if (p.entityObject.Dirty)
373
382
  return true;
374
383
  }
375
384
  }
376
385
  return false;
377
386
  }
378
387
  PopulatePendingRecords() {
379
- return __awaiter(this, void 0, void 0, function* () {
380
- // this method is called by the parent class at the right time to populate all of the pending records for a transaction
381
- // all we do is talk to all of our child compoennts and get their pending records and xfer them over to the PendingRecords array
382
- // the parent class will then take care of the rest...
383
- this._pendingRecords = []; // wipe out our array first
384
- this.RaiseEvent('EDITING_COMPLETE'); // first tell the child components to finish up their editing
385
- const result = this.RaiseEvent('POPULATE_PENDING_RECORDS');
386
- if (result && result.pendingRecords) {
387
- for (const p of result.pendingRecords)
388
- this.PendingRecords.push(p);
389
- }
390
- });
388
+ // this method is called by the parent class at the right time to populate all of the pending records for a transaction
389
+ // all we do is talk to all of our child compoennts and get their pending records and xfer them over to the PendingRecords array
390
+ // the parent class will then take care of the rest...
391
+ this._pendingRecords = []; // wipe out our array first
392
+ this.RaiseEvent(BaseFormComponentEventCodes.EDITING_COMPLETE); // first tell the child components to finish up their editing
393
+ const result = this.RaiseEvent(BaseFormComponentEventCodes.POPULATE_PENDING_RECORDS);
394
+ if (result && result.pendingChanges) {
395
+ for (const p of result.pendingChanges)
396
+ this.PendingRecords.push(p);
397
+ }
391
398
  }
392
399
  InternalSaveRecord() {
393
400
  return __awaiter(this, void 0, void 0, function* () {
394
401
  if (this.record) {
395
- // save the record, but first create a transaction group if we have any other stuf to submit
396
- yield this.PopulatePendingRecords();
402
+ // DONT POPULATE PENDING RECORDS AGAIN HERE AS IT WAS DONE before Validate() was called
397
403
  if (this._pendingRecords.length > 0) {
398
404
  // we need to create a transaction group
399
405
  const md = new Metadata();
@@ -401,10 +407,12 @@ export class BaseFormComponent extends BaseRecordComponent {
401
407
  this.record.TransactionGroup = tg;
402
408
  this.record.Save(); // DO NOT USE await - trans group.submit() is where we await
403
409
  // now add to the rest of the pending records
404
- for (let i = 0; i < this._pendingRecords.length; i++) {
405
- const x = this._pendingRecords[i];
406
- x.TransactionGroup = tg;
407
- x.Save(); // DO NOT USE await - trans group.submit() is where we await
410
+ for (const x of this._pendingRecords) {
411
+ x.entityObject.TransactionGroup = tg;
412
+ if (x.action === 'save')
413
+ x.entityObject.Save(); // DO NOT AWAIT, part of a TG
414
+ else
415
+ x.entityObject.Delete(); // DO NOT AWAIT, part of a TG
408
416
  }
409
417
  // finally submit the TG
410
418
  return yield tg.Submit();
@@ -1,4 +1,4 @@
1
- import { AfterViewInit, ElementRef } from "@angular/core";
1
+ import { AfterViewInit, ElementRef, ChangeDetectorRef } from "@angular/core";
2
2
  import { BaseRecordComponent } from "./base-record-component";
3
3
  import { BaseEntity, EntityFieldInfo, EntityInfo } from "@memberjunction/core";
4
4
  import * as i0 from "@angular/core";
@@ -9,6 +9,8 @@ import * as i0 from "@angular/core";
9
9
  * components for field rendering/editing when needed.
10
10
  */
11
11
  export declare class MJLinkField extends BaseRecordComponent implements AfterViewInit {
12
+ private cdr;
13
+ constructor(cdr: ChangeDetectorRef);
12
14
  /**
13
15
  * The record object that contains the field to be rendered. This object should be an instance of BaseEntity or a derived class.
14
16
  */
@@ -21,11 +23,21 @@ export declare class MJLinkField extends BaseRecordComponent implements AfterVie
21
23
  * For users of this component, if you already know the name of the record we are linking to, provide it here to reduce DB overhead
22
24
  */
23
25
  RecordName?: string;
26
+ /**
27
+ * The type of component to show, search is a user input field that searches for records, dropdown is a dropdown list of records. The default is 'search'. If the related entity has
28
+ * a small list of possible records, it is often desirable to show a dropdown list instead of a search box.
29
+ */
30
+ LinkComponentType?: 'Search' | 'Dropdown';
24
31
  RelatedEntityInfo: EntityInfo | undefined;
32
+ private _SelectedRecord;
33
+ get SelectedRecord(): BaseEntity | undefined;
34
+ set SelectedRecord(val: BaseEntity | undefined);
25
35
  RecordLinked: boolean;
26
- matchingRecords: BaseEntity[];
36
+ RelatedEntityRecords: BaseEntity[];
27
37
  showMatchingRecords: boolean;
38
+ dropDownColumns: EntityFieldInfo[];
28
39
  inputBox: ElementRef;
40
+ private initComponent;
29
41
  ngAfterViewInit(): Promise<void>;
30
42
  protected AttemptToLinkValue(): Promise<void>;
31
43
  get Value(): any;
@@ -35,8 +47,10 @@ export declare class MJLinkField extends BaseRecordComponent implements AfterVie
35
47
  onClearClicked(): void;
36
48
  RelatedEntityNameField: string;
37
49
  protected fetchMatchingRecords(query: string): Promise<void>;
50
+ protected populateDropdownList(): Promise<void>;
51
+ protected SetDropdownValue(): Promise<void>;
38
52
  onRecordSelected(linkedRecord: BaseEntity): void;
39
53
  static ɵfac: i0.ɵɵFactoryDeclaration<MJLinkField, never>;
40
- static ɵcmp: i0.ɵɵComponentDeclaration<MJLinkField, "mj-link-field", never, { "record": { "alias": "record"; "required": false; }; "FieldName": { "alias": "FieldName"; "required": false; }; "RecordName": { "alias": "RecordName"; "required": false; }; }, {}, never, never, false, never>;
54
+ static ɵcmp: i0.ɵɵComponentDeclaration<MJLinkField, "mj-link-field", never, { "record": { "alias": "record"; "required": false; }; "FieldName": { "alias": "FieldName"; "required": false; }; "RecordName": { "alias": "RecordName"; "required": false; }; "LinkComponentType": { "alias": "LinkComponentType"; "required": false; }; }, {}, never, never, false, never>;
41
55
  }
42
56
  //# sourceMappingURL=link-field.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-field.component.d.ts","sourceRoot":"","sources":["../../src/lib/link-field.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,UAAU,EAAoB,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAgB,eAAe,EAAE,UAAU,EAAqB,MAAM,sBAAsB,CAAC;;AAGhH;;;;;GAKG;AACH,qBAKa,WAAY,SAAQ,mBAAoB,YAAW,aAAa;IACzE;;OAEG;IACM,MAAM,EAAG,UAAU,CAAC;IAE7B;;OAEG;IACM,SAAS,EAAE,MAAM,CAAM;IAEhC;;OAEG;IACM,UAAU,CAAC,EAAE,MAAM,CAAM;IAE3B,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAa;IACtD,YAAY,EAAE,OAAO,CAAS;IAC9B,eAAe,EAAE,UAAU,EAAE,CAAM;IACnC,mBAAmB,EAAE,OAAO,CAAS;IAEH,QAAQ,EAAG,UAAU,CAAC;IAGzD,eAAe;cA4BL,kBAAkB;IAoBlC,IAAW,KAAK,IAAI,GAAG,CAEtB;IAED,IAAW,KAAK,CAAC,GAAG,EAAE,GAAG,EAGxB;IAED,IAAW,WAAW,IAAI,eAAe,GAAG,SAAS,CAEpD;IACD,IAAW,WAAW,IAAI,MAAM,CAM/B;IAGM,cAAc;IAOd,sBAAsB,EAAE,MAAM,CAAM;cAC3B,oBAAoB,CAAC,KAAK,EAAE,MAAM;IA0B3C,gBAAgB,CAAC,YAAY,EAAE,UAAU;yCA/HvC,WAAW;2CAAX,WAAW;CAqIvB"}
1
+ {"version":3,"file":"link-field.component.d.ts","sourceRoot":"","sources":["../../src/lib/link-field.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAa,UAAU,EAAoB,iBAAiB,EAA4B,MAAM,eAAe,CAAC;AACpI,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAgB,eAAe,EAAE,UAAU,EAAqB,MAAM,sBAAsB,CAAC;;AAGhH;;;;;GAKG;AACH,qBAKa,WAAY,SAAQ,mBAAoB,YAAW,aAAa;IAC7D,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,iBAAiB;IAG1C;;OAEG;IACM,MAAM,EAAG,UAAU,CAAC;IAE7B;;OAEG;IACM,SAAS,EAAE,MAAM,CAAM;IAEhC;;OAEG;IACM,UAAU,CAAC,EAAE,MAAM,CAAM;IAElC;;;OAGG;IACM,iBAAiB,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAY;IAEvD,iBAAiB,EAAE,UAAU,GAAG,SAAS,CAAa;IAE7D,OAAO,CAAC,eAAe,CAAqC;IAC5D,IAAW,cAAc,IAAI,UAAU,GAAG,SAAS,CAElD;IACD,IAAW,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,EAOpD;IACM,YAAY,EAAE,OAAO,CAAS;IAC9B,oBAAoB,EAAE,UAAU,EAAE,CAAM;IACxC,mBAAmB,EAAE,OAAO,CAAS;IACrC,eAAe,EAAE,eAAe,EAAE,CAAM;IAEL,QAAQ,EAAG,UAAU,CAAC;YAElD,aAAa;IA0CrB,eAAe;cAIL,kBAAkB;IAoBlC,IAAW,KAAK,IAAI,GAAG,CAEtB;IAED,IAAW,KAAK,CAAC,GAAG,EAAE,GAAG,EAQxB;IAED,IAAW,WAAW,IAAI,eAAe,GAAG,SAAS,CAEpD;IACD,IAAW,WAAW,IAAI,MAAM,CAM/B;IAGM,cAAc;IAOd,sBAAsB,EAAE,MAAM,CAAM;cAC3B,oBAAoB,CAAC,KAAK,EAAE,MAAM;cAiDlC,oBAAoB;cA4BpB,gBAAgB;IAIzB,gBAAgB,CAAC,YAAY,EAAE,UAAU;yCAnOvC,WAAW;2CAAX,WAAW;CAoPvB"}
@@ -16,27 +16,70 @@ import * as i1 from "@angular/common";
16
16
  import * as i2 from "@angular/forms";
17
17
  import * as i3 from "@progress/kendo-angular-buttons";
18
18
  import * as i4 from "@progress/kendo-angular-inputs";
19
+ import * as i5 from "@progress/kendo-angular-dropdowns";
19
20
  const _c0 = ["inputBox"];
20
- function MJLinkField_ul_5_li_1_Template(rf, ctx) { if (rf & 1) {
21
- const _r2 = i0.ɵɵgetCurrentView();
21
+ function MJLinkField_Conditional_1_ul_4_li_1_Template(rf, ctx) { if (rf & 1) {
22
+ const _r3 = i0.ɵɵgetCurrentView();
22
23
  i0.ɵɵelementStart(0, "li", 6);
23
- i0.ɵɵlistener("click", function MJLinkField_ul_5_li_1_Template_li_click_0_listener() { const record_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.onRecordSelected(record_r3)); });
24
+ i0.ɵɵlistener("click", function MJLinkField_Conditional_1_ul_4_li_1_Template_li_click_0_listener() { const record_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.onRecordSelected(record_r4)); });
24
25
  i0.ɵɵtext(1);
25
26
  i0.ɵɵelementEnd();
26
27
  } if (rf & 2) {
27
- const record_r3 = ctx.$implicit;
28
- const ctx_r3 = i0.ɵɵnextContext(2);
28
+ const record_r4 = ctx.$implicit;
29
+ const ctx_r1 = i0.ɵɵnextContext(3);
29
30
  i0.ɵɵadvance();
30
- i0.ɵɵtextInterpolate1(" ", ctx_r3.RelatedEntityNameField ? record_r3.Get(ctx_r3.RelatedEntityNameField) : "No Value", " ");
31
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.RelatedEntityNameField ? record_r4.Get(ctx_r1.RelatedEntityNameField) : record_r4.PrimaryKey.ToString(), " ");
31
32
  } }
32
- function MJLinkField_ul_5_Template(rf, ctx) { if (rf & 1) {
33
+ function MJLinkField_Conditional_1_ul_4_Template(rf, ctx) { if (rf & 1) {
33
34
  i0.ɵɵelementStart(0, "ul", 4);
34
- i0.ɵɵtemplate(1, MJLinkField_ul_5_li_1_Template, 2, 1, "li", 5);
35
+ i0.ɵɵtemplate(1, MJLinkField_Conditional_1_ul_4_li_1_Template, 2, 1, "li", 5);
35
36
  i0.ɵɵelementEnd();
36
37
  } if (rf & 2) {
37
- const ctx_r3 = i0.ɵɵnextContext();
38
+ const ctx_r1 = i0.ɵɵnextContext(2);
38
39
  i0.ɵɵadvance();
39
- i0.ɵɵproperty("ngForOf", ctx_r3.matchingRecords);
40
+ i0.ɵɵproperty("ngForOf", ctx_r1.RelatedEntityRecords);
41
+ } }
42
+ function MJLinkField_Conditional_1_Template(rf, ctx) { if (rf & 1) {
43
+ const _r1 = i0.ɵɵgetCurrentView();
44
+ i0.ɵɵelementStart(0, "input", 1, 0);
45
+ i0.ɵɵtwoWayListener("ngModelChange", function MJLinkField_Conditional_1_Template_input_ngModelChange_0_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.RecordName, $event) || (ctx_r1.RecordName = $event); return i0.ɵɵresetView($event); });
46
+ i0.ɵɵelementEnd();
47
+ i0.ɵɵelementStart(2, "button", 2);
48
+ i0.ɵɵlistener("click", function MJLinkField_Conditional_1_Template_button_click_2_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onClearClicked()); });
49
+ i0.ɵɵtext(3, "Clear");
50
+ i0.ɵɵelementEnd();
51
+ i0.ɵɵtemplate(4, MJLinkField_Conditional_1_ul_4_Template, 2, 1, "ul", 3);
52
+ } if (rf & 2) {
53
+ const ctx_r1 = i0.ɵɵnextContext();
54
+ i0.ɵɵproperty("ngClass", ctx_r1.RecordLinked ? "record-linked" : "");
55
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.RecordName);
56
+ i0.ɵɵadvance(4);
57
+ i0.ɵɵproperty("ngIf", ctx_r1.showMatchingRecords);
58
+ } }
59
+ function MJLinkField_Conditional_2_Conditional_0_For_2_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵelement(0, "kendo-combobox-column", 9);
61
+ } if (rf & 2) {
62
+ const d_r6 = ctx.$implicit;
63
+ i0.ɵɵproperty("field", d_r6.Name)("title", d_r6.DisplayNameOrName);
64
+ } }
65
+ function MJLinkField_Conditional_2_Conditional_0_Template(rf, ctx) { if (rf & 1) {
66
+ const _r5 = i0.ɵɵgetCurrentView();
67
+ i0.ɵɵelementStart(0, "kendo-multicolumncombobox", 8);
68
+ i0.ɵɵtwoWayListener("valueChange", function MJLinkField_Conditional_2_Conditional_0_Template_kendo_multicolumncombobox_valueChange_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.SelectedRecord, $event) || (ctx_r1.SelectedRecord = $event); return i0.ɵɵresetView($event); });
69
+ i0.ɵɵrepeaterCreate(1, MJLinkField_Conditional_2_Conditional_0_For_2_Template, 1, 2, "kendo-combobox-column", 9, i0.ɵɵrepeaterTrackByIdentity);
70
+ i0.ɵɵelementEnd();
71
+ } if (rf & 2) {
72
+ const ctx_r1 = i0.ɵɵnextContext(2);
73
+ i0.ɵɵproperty("data", ctx_r1.RelatedEntityRecords)("textField", ctx_r1.RelatedEntityInfo.NameField ? ctx_r1.RelatedEntityInfo.NameField.Name : ctx_r1.RelatedEntityInfo.FirstPrimaryKey.Name)("valueField", ctx_r1.RelatedEntityInfo.FirstPrimaryKey.Name);
74
+ i0.ɵɵtwoWayProperty("value", ctx_r1.SelectedRecord);
75
+ i0.ɵɵadvance();
76
+ i0.ɵɵrepeater(ctx_r1.dropDownColumns);
77
+ } }
78
+ function MJLinkField_Conditional_2_Template(rf, ctx) { if (rf & 1) {
79
+ i0.ɵɵtemplate(0, MJLinkField_Conditional_2_Conditional_0_Template, 3, 4, "kendo-multicolumncombobox", 7);
80
+ } if (rf & 2) {
81
+ const ctx_r1 = i0.ɵɵnextContext();
82
+ i0.ɵɵconditional(ctx_r1.RelatedEntityInfo ? 0 : -1);
40
83
  } }
41
84
  /**
42
85
  * This component is used to automatically generate a UI for any field in a given BaseEntity object. The CodeGen tool will generate forms and form sections that
@@ -45,8 +88,9 @@ function MJLinkField_ul_5_Template(rf, ctx) { if (rf & 1) {
45
88
  * components for field rendering/editing when needed.
46
89
  */
47
90
  export class MJLinkField extends BaseRecordComponent {
48
- constructor() {
49
- super(...arguments);
91
+ constructor(cdr) {
92
+ super();
93
+ this.cdr = cdr;
50
94
  /**
51
95
  * The name of the field in the entity to be rendered.
52
96
  */
@@ -55,37 +99,74 @@ export class MJLinkField extends BaseRecordComponent {
55
99
  * For users of this component, if you already know the name of the record we are linking to, provide it here to reduce DB overhead
56
100
  */
57
101
  this.RecordName = '';
102
+ /**
103
+ * The type of component to show, search is a user input field that searches for records, dropdown is a dropdown list of records. The default is 'search'. If the related entity has
104
+ * a small list of possible records, it is often desirable to show a dropdown list instead of a search box.
105
+ */
106
+ this.LinkComponentType = 'Search';
58
107
  this.RelatedEntityInfo = undefined;
108
+ this._SelectedRecord = undefined;
59
109
  this.RecordLinked = false;
60
- this.matchingRecords = [];
110
+ this.RelatedEntityRecords = [];
61
111
  this.showMatchingRecords = false;
112
+ this.dropDownColumns = [];
62
113
  this.RelatedEntityNameField = '';
63
114
  }
64
- ngAfterViewInit() {
115
+ get SelectedRecord() {
116
+ return this._SelectedRecord;
117
+ }
118
+ set SelectedRecord(val) {
119
+ this._SelectedRecord = val;
120
+ if (val) {
121
+ this.Value = val.FirstPrimaryKey.Value;
122
+ }
123
+ else
124
+ this.Value = null;
125
+ }
126
+ initComponent() {
65
127
  return __awaiter(this, void 0, void 0, function* () {
128
+ var _a;
66
129
  if (!this.record)
67
130
  throw new Error('record property is required');
68
131
  if (!this.FieldName)
69
132
  throw new Error('FieldName property is required');
70
- yield this.AttemptToLinkValue();
71
- fromEvent(this.inputBox.nativeElement, 'input')
72
- .pipe(debounceTime(300))
73
- .subscribe(() => {
74
- if (!this.RecordLinked) {
75
- this.showMatchingRecords = true;
76
- this.fetchMatchingRecords(this.inputBox.nativeElement.value);
77
- }
78
- });
79
- fromEvent(this.inputBox.nativeElement, 'keydown').subscribe((event) => {
80
- if (this.RecordLinked && !['Backspace', 'Delete'].includes(event.key)) {
81
- event.preventDefault();
82
- }
83
- else if (['Backspace', 'Delete'].includes(event.key)) {
84
- this.RecordName = '';
85
- this.Value = null;
86
- this.RecordLinked = false;
133
+ const relatedEntityID = (_a = this.EntityField) === null || _a === void 0 ? void 0 : _a.RelatedEntityID;
134
+ const md = new Metadata();
135
+ if (relatedEntityID) {
136
+ this.RelatedEntityInfo = md.EntityByID(relatedEntityID);
137
+ this.cdr.detectChanges();
138
+ }
139
+ if (this.LinkComponentType === 'Search') {
140
+ yield this.AttemptToLinkValue();
141
+ if (this.inputBox) {
142
+ fromEvent(this.inputBox.nativeElement, 'input')
143
+ .pipe(debounceTime(300))
144
+ .subscribe(() => {
145
+ if (!this.RecordLinked) {
146
+ this.showMatchingRecords = true;
147
+ this.fetchMatchingRecords(this.inputBox.nativeElement.value);
148
+ }
149
+ });
150
+ fromEvent(this.inputBox.nativeElement, 'keydown').subscribe((event) => {
151
+ if (this.RecordLinked && !['Backspace', 'Delete'].includes(event.key)) {
152
+ event.preventDefault();
153
+ }
154
+ else if (['Backspace', 'Delete'].includes(event.key)) {
155
+ this.RecordName = '';
156
+ this.Value = null;
157
+ this.RecordLinked = false;
158
+ }
159
+ });
87
160
  }
88
- });
161
+ }
162
+ else {
163
+ yield this.populateDropdownList();
164
+ }
165
+ });
166
+ }
167
+ ngAfterViewInit() {
168
+ return __awaiter(this, void 0, void 0, function* () {
169
+ yield this.initComponent();
89
170
  });
90
171
  }
91
172
  AttemptToLinkValue() {
@@ -114,7 +195,12 @@ export class MJLinkField extends BaseRecordComponent {
114
195
  }
115
196
  set Value(val) {
116
197
  this.record.Set(this.FieldName, val);
117
- this.AttemptToLinkValue();
198
+ if (this.LinkComponentType === 'Search') {
199
+ this.AttemptToLinkValue();
200
+ }
201
+ else {
202
+ this.SetDropdownValue();
203
+ }
118
204
  }
119
205
  get EntityField() {
120
206
  var _a;
@@ -135,17 +221,35 @@ export class MJLinkField extends BaseRecordComponent {
135
221
  }
136
222
  fetchMatchingRecords(query) {
137
223
  return __awaiter(this, void 0, void 0, function* () {
138
- var _a, _b;
139
- const relatedEntityID = (_a = this.EntityField) === null || _a === void 0 ? void 0 : _a.RelatedEntityID;
140
- const md = new Metadata();
224
+ var _a;
141
225
  this.RecordLinked = false;
142
- this.matchingRecords = [];
143
- if (relatedEntityID) {
144
- this.RelatedEntityInfo = md.EntityByID(relatedEntityID);
145
- // do a lookup using runView for records that have the Name field that start with the query
226
+ this.RelatedEntityRecords = [];
227
+ if (this.RelatedEntityInfo) {
146
228
  this.RelatedEntityNameField = this.RelatedEntityInfo.NameField ? this.RelatedEntityInfo.NameField.Name : '';
229
+ const escapedQuery = query.replace(/'/g, "''");
230
+ let filter = '';
231
+ if (!this.RelatedEntityInfo.FirstPrimaryKey.NeedsQuotes) {
232
+ // the pkey is a number, so let's see if the query is a number
233
+ if (isNaN(Number(query)) && this.RelatedEntityNameField === '') {
234
+ // if the query is not a number (for number pkeys) and we don't have a name field to search on, then we can't search
235
+ return;
236
+ }
237
+ else {
238
+ // if we get here it means we either have a RelatedEntityNameField to search on or the query is a number
239
+ if (!isNaN(Number(query))) {
240
+ // if the query is a number, then we can search on the pkey
241
+ filter = `[${this.RelatedEntityInfo.FirstPrimaryKey.Name}] = ${query}`;
242
+ }
243
+ }
244
+ }
245
+ else {
246
+ // the pkey is a string, so we can search on it no matter what the query is, a number, not a number, whatever
247
+ filter = `[${this.RelatedEntityInfo.FirstPrimaryKey.Name}] = '${escapedQuery}'`;
248
+ }
147
249
  if (this.RelatedEntityNameField) {
148
- const filter = `[${this.RelatedEntityNameField}] LIKE '${query}%'`;
250
+ filter = `[${this.RelatedEntityNameField}] LIKE '${escapedQuery}%'${filter.length > 0 ? ' OR ' + filter : ''}`;
251
+ }
252
+ if (filter && filter.length > 0) {
149
253
  const rv = new RunView();
150
254
  const result = yield rv.RunView({
151
255
  EntityName: this.RelatedEntityInfo.Name,
@@ -154,55 +258,90 @@ export class MJLinkField extends BaseRecordComponent {
154
258
  ResultType: 'entity_object',
155
259
  MaxRows: 5
156
260
  });
157
- if (result && ((_b = result.Results) === null || _b === void 0 ? void 0 : _b.length) > 0) {
158
- this.matchingRecords = result.Results.filter(record => record[this.RelatedEntityNameField].toLowerCase().includes(query.toLowerCase()));
261
+ if (result && ((_a = result.Results) === null || _a === void 0 ? void 0 : _a.length) > 0) {
262
+ this.RelatedEntityRecords = result.Results;
159
263
  }
160
264
  }
265
+ else {
266
+ this.RelatedEntityRecords = [{ Name: "Can't search on " + this.RelatedEntityInfo.Name + ' records' }]; // this will have the effect of a single record in the list that says "Can't search on..."
267
+ }
161
268
  }
162
269
  });
163
270
  }
271
+ populateDropdownList() {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ if (this.RelatedEntityInfo) {
274
+ this.dropDownColumns = this.RelatedEntityInfo.Fields.filter(f => f.DefaultInView || f.IsPrimaryKey || f.IsNameField);
275
+ this.cdr.detectChanges();
276
+ // run a view to get the records
277
+ const rv = new RunView();
278
+ const result = yield rv.RunView({
279
+ EntityName: this.RelatedEntityInfo.Name,
280
+ ExtraFilter: '',
281
+ OrderBy: this.RelatedEntityNameField,
282
+ ResultType: 'entity_object',
283
+ });
284
+ if (result && result.Success) {
285
+ this.RelatedEntityRecords = result.Results;
286
+ // look for a match between the records we have, finding a match between our this.Value and the pkey of the record
287
+ const match = this.RelatedEntityRecords.find(r => r.FirstPrimaryKey.Value === this.Value);
288
+ if (match) {
289
+ this.SelectedRecord = match;
290
+ this.SetDropdownValue();
291
+ }
292
+ this.cdr.detectChanges();
293
+ }
294
+ }
295
+ });
296
+ }
297
+ SetDropdownValue() {
298
+ return __awaiter(this, void 0, void 0, function* () {
299
+ });
300
+ }
164
301
  onRecordSelected(linkedRecord) {
165
- this.RecordName = linkedRecord.Get(this.RelatedEntityNameField);
166
- this.RecordLinked = true;
167
- this.showMatchingRecords = false;
168
- this.record.Set(this.FieldName, linkedRecord.FirstPrimaryKey.Value);
302
+ if (linkedRecord.EntityInfo) {
303
+ this.SelectedRecord = linkedRecord;
304
+ this.RecordName = this.RelatedEntityNameField ? linkedRecord.Get(this.RelatedEntityNameField) : linkedRecord.PrimaryKey.ToString();
305
+ this.RecordLinked = true;
306
+ this.showMatchingRecords = false;
307
+ this.record.Set(this.FieldName, linkedRecord.FirstPrimaryKey.Value);
308
+ }
309
+ else {
310
+ // this means that we really don't have a selected record and we were just showing the "Can't search on..." record
311
+ this.showMatchingRecords = false;
312
+ this.RecordLinked = false;
313
+ this.RecordName = '';
314
+ }
315
+ this.cdr.detectChanges();
169
316
  }
170
317
  }
171
- MJLinkField.ɵfac = /*@__PURE__*/ (() => { let ɵMJLinkField_BaseFactory; return function MJLinkField_Factory(t) { return (ɵMJLinkField_BaseFactory || (ɵMJLinkField_BaseFactory = i0.ɵɵgetInheritedFactory(MJLinkField)))(t || MJLinkField); }; })();
318
+ MJLinkField.ɵfac = function MJLinkField_Factory(t) { return new (t || MJLinkField)(i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
172
319
  MJLinkField.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: MJLinkField, selectors: [["mj-link-field"]], viewQuery: function MJLinkField_Query(rf, ctx) { if (rf & 1) {
173
- i0.ɵɵviewQuery(_c0, 7);
320
+ i0.ɵɵviewQuery(_c0, 5);
174
321
  } if (rf & 2) {
175
322
  let _t;
176
323
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputBox = _t.first);
177
- } }, inputs: { record: "record", FieldName: "FieldName", RecordName: "RecordName" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 6, vars: 3, consts: [["inputBox", ""], ["type", "text", "kendoTextBox", "", 1, "input-box", 3, "ngModelChange", "ngClass", "ngModel"], ["kendoButton", "", 3, "click"], ["class", "matching-records", 4, "ngIf"], [1, "matching-records"], [3, "click", 4, "ngFor", "ngForOf"], [3, "click"]], template: function MJLinkField_Template(rf, ctx) { if (rf & 1) {
178
- const _r1 = i0.ɵɵgetCurrentView();
179
- i0.ɵɵelementStart(0, "div")(1, "input", 1, 0);
180
- i0.ɵɵtwoWayListener("ngModelChange", function MJLinkField_Template_input_ngModelChange_1_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.RecordName, $event) || (ctx.RecordName = $event); return i0.ɵɵresetView($event); });
181
- i0.ɵɵelementEnd();
182
- i0.ɵɵelementStart(3, "button", 2);
183
- i0.ɵɵlistener("click", function MJLinkField_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.onClearClicked()); });
184
- i0.ɵɵtext(4, "Clear");
185
- i0.ɵɵelementEnd();
186
- i0.ɵɵtemplate(5, MJLinkField_ul_5_Template, 2, 1, "ul", 3);
324
+ } }, inputs: { record: "record", FieldName: "FieldName", RecordName: "RecordName", LinkComponentType: "LinkComponentType" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 1, consts: [["inputBox", ""], ["type", "text", "kendoTextBox", "", 1, "input-box", 3, "ngModelChange", "ngClass", "ngModel"], ["kendoButton", "", 3, "click"], ["class", "matching-records", 4, "ngIf"], [1, "matching-records"], [3, "click", 4, "ngFor", "ngForOf"], [3, "click"], [3, "data", "textField", "valueField", "value"], [3, "valueChange", "data", "textField", "valueField", "value"], [3, "field", "title"]], template: function MJLinkField_Template(rf, ctx) { if (rf & 1) {
325
+ i0.ɵɵelementStart(0, "div");
326
+ i0.ɵɵtemplate(1, MJLinkField_Conditional_1_Template, 5, 3)(2, MJLinkField_Conditional_2_Template, 1, 1);
187
327
  i0.ɵɵelementEnd();
188
328
  } if (rf & 2) {
189
329
  i0.ɵɵadvance();
190
- i0.ɵɵproperty("ngClass", ctx.RecordLinked ? "record-linked" : "");
191
- i0.ɵɵtwoWayProperty("ngModel", ctx.RecordName);
192
- i0.ɵɵadvance(4);
193
- i0.ɵɵproperty("ngIf", ctx.showMatchingRecords);
194
- } }, dependencies: [i1.NgClass, i1.NgForOf, i1.NgIf, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.ButtonComponent, i4.TextBoxDirective], styles: [".record-linked[_ngcontent-%COMP%] {\n color: darkblue;\n text-decoration: underline;\n}\n\n.input-box[_ngcontent-%COMP%] {\n width: 400px;\n}\n\nbutton[_ngcontent-%COMP%] {\n width: 50px;\n}\n\n\n.matching-records[_ngcontent-%COMP%] {\n width: 400px;\n list-style-type: none;\n margin: 0;\n padding: 0;\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ccc;\n}\n\n.matching-records[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n padding: 8px;\n cursor: pointer;\n}\n\n.matching-records[_ngcontent-%COMP%] li[_ngcontent-%COMP%]:hover {\n background-color: #f0f0f0;\n}"] });
330
+ i0.ɵɵconditional(ctx.LinkComponentType === "Search" ? 1 : 2);
331
+ } }, dependencies: [i1.NgClass, i1.NgForOf, i1.NgIf, i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel, i3.ButtonComponent, i4.TextBoxDirective, i5.MultiColumnComboBoxComponent, i5.ComboBoxColumnComponent], styles: [".record-linked[_ngcontent-%COMP%] {\n color: darkblue;\n text-decoration: underline;\n}\n\n.input-box[_ngcontent-%COMP%] {\n width: 400px;\n}\n\nbutton[_ngcontent-%COMP%] {\n width: 50px;\n}\n\n\n.matching-records[_ngcontent-%COMP%] {\n width: 400px;\n list-style-type: none;\n margin: 0;\n padding: 0;\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ccc;\n}\n\n.matching-records[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n padding: 8px;\n cursor: pointer;\n}\n\n.matching-records[_ngcontent-%COMP%] li[_ngcontent-%COMP%]:hover {\n background-color: #f0f0f0;\n}"] });
195
332
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MJLinkField, [{
196
333
  type: Component,
197
- args: [{ selector: 'mj-link-field', template: "<!-- <input type=\"text\" class=\"input-box\" [ngClass]=\"RecordLinked ? 'record-linked' : ''\" [(ngModel)]=\"RecordName\" kendoTextBox /><button kendoButton (click)=\"onClearClicked()\">Clear</button>\n -->\n\n<div>\n <input \n #inputBox\n type=\"text\" \n class=\"input-box\" \n [ngClass]=\"RecordLinked ? 'record-linked' : ''\" \n [(ngModel)]=\"RecordName\" \n kendoTextBox \n />\n <button kendoButton (click)=\"onClearClicked()\">Clear</button>\n\n <ul *ngIf=\"showMatchingRecords\" class=\"matching-records\">\n <li *ngFor=\"let record of matchingRecords\" (click)=\"onRecordSelected(record)\">\n {{ RelatedEntityNameField ? record.Get(RelatedEntityNameField) : 'No Value' }}\n </li>\n </ul>\n</div>\n", styles: [".record-linked {\n color: darkblue;\n text-decoration: underline;\n}\n\n.input-box {\n width: 400px;\n}\n\nbutton {\n width: 50px;\n}\n\n\n.matching-records {\n width: 400px;\n list-style-type: none;\n margin: 0;\n padding: 0;\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ccc;\n}\n\n.matching-records li {\n padding: 8px;\n cursor: pointer;\n}\n\n.matching-records li:hover {\n background-color: #f0f0f0;\n}\n"] }]
198
- }], null, { record: [{
334
+ args: [{ selector: 'mj-link-field', template: "<div>\n @if (LinkComponentType === 'Search') {\n <input \n #inputBox\n type=\"text\" \n class=\"input-box\" \n [ngClass]=\"RecordLinked ? 'record-linked' : ''\" \n [(ngModel)]=\"RecordName\" \n kendoTextBox \n />\n <button kendoButton (click)=\"onClearClicked()\">Clear</button>\n\n <ul *ngIf=\"showMatchingRecords\" class=\"matching-records\">\n <li *ngFor=\"let record of RelatedEntityRecords\" (click)=\"onRecordSelected(record)\">\n {{ RelatedEntityNameField ? record.Get(RelatedEntityNameField) : record.PrimaryKey.ToString() }}\n </li>\n </ul>\n }\n @else {\n @if (RelatedEntityInfo) {\n <kendo-multicolumncombobox \n [data]=\"RelatedEntityRecords\"\n [textField]=\"RelatedEntityInfo.NameField ? RelatedEntityInfo.NameField.Name : RelatedEntityInfo.FirstPrimaryKey.Name\"\n [valueField]=\"RelatedEntityInfo.FirstPrimaryKey.Name\"\n [(value)]=\"SelectedRecord\"\n >\n @for (d of dropDownColumns; track d) {\n <kendo-combobox-column\n [field]=\"d.Name\"\n [title]=\"d.DisplayNameOrName\"\n >\n </kendo-combobox-column>\n }\n </kendo-multicolumncombobox> \n }\n }\n</div>", styles: [".record-linked {\n color: darkblue;\n text-decoration: underline;\n}\n\n.input-box {\n width: 400px;\n}\n\nbutton {\n width: 50px;\n}\n\n\n.matching-records {\n width: 400px;\n list-style-type: none;\n margin: 0;\n padding: 0;\n max-height: 200px;\n overflow-y: auto;\n border: 1px solid #ccc;\n}\n\n.matching-records li {\n padding: 8px;\n cursor: pointer;\n}\n\n.matching-records li:hover {\n background-color: #f0f0f0;\n}\n"] }]
335
+ }], () => [{ type: i0.ChangeDetectorRef }], { record: [{
199
336
  type: Input
200
337
  }], FieldName: [{
201
338
  type: Input
202
339
  }], RecordName: [{
203
340
  type: Input
341
+ }], LinkComponentType: [{
342
+ type: Input
204
343
  }], inputBox: [{
205
344
  type: ViewChild,
206
- args: ['inputBox', { static: true }]
345
+ args: ['inputBox', { static: false }]
207
346
  }] }); })();
208
347
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(MJLinkField, { className: "MJLinkField", filePath: "src/lib/link-field.component.ts", lineNumber: 17 }); })();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-base-forms",
3
- "version": "1.7.1",
3
+ "version": "1.8.1",
4
4
  "description": "MemberJunction: Angular Base Form Components",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -25,14 +25,15 @@
25
25
  "@angular/router": "18.0.2"
26
26
  },
27
27
  "dependencies": {
28
- "@memberjunction/global": "1.7.1",
29
- "@memberjunction/core": "1.7.1",
30
- "@memberjunction/ng-code-editor": "1.7.1",
31
- "@memberjunction/ng-shared": "1.7.1",
32
- "@memberjunction/ng-tabstrip": "1.7.1",
33
- "@memberjunction/ng-link-directives": "1.7.1",
34
- "@memberjunction/ng-container-directives": "1.7.1",
35
- "@memberjunction/ng-record-changes": "1.7.1",
28
+ "@memberjunction/global": "1.8.1",
29
+ "@memberjunction/core": "1.8.1",
30
+ "@memberjunction/ng-code-editor": "1.8.1",
31
+ "@memberjunction/ng-shared": "1.8.1",
32
+ "@memberjunction/ng-tabstrip": "1.8.1",
33
+ "@memberjunction/ng-link-directives": "1.8.1",
34
+ "@memberjunction/ng-container-directives": "1.8.1",
35
+ "@memberjunction/ng-record-changes": "1.8.1",
36
+ "@memberjunction/ng-base-types": "1.8.1",
36
37
  "@progress/kendo-angular-buttons": "16.2.0",
37
38
  "@progress/kendo-angular-dropdowns": "16.2.0",
38
39
  "@progress/kendo-angular-inputs": "16.2.0",