@mj-biz-apps/common-ng 5.55.0 → 5.56.0

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.
Files changed (25) hide show
  1. package/dist/lib/components/party-field/__tests__/party-field.component.test.d.ts +2 -0
  2. package/dist/lib/components/party-field/__tests__/party-field.component.test.d.ts.map +1 -0
  3. package/dist/lib/components/party-field/__tests__/party-field.component.test.js +266 -0
  4. package/dist/lib/components/party-field/__tests__/party-field.component.test.js.map +1 -0
  5. package/dist/lib/components/party-field/__tests__/party-lookup-term.test.d.ts +2 -0
  6. package/dist/lib/components/party-field/__tests__/party-lookup-term.test.d.ts.map +1 -0
  7. package/dist/lib/components/party-field/__tests__/party-lookup-term.test.js +41 -0
  8. package/dist/lib/components/party-field/__tests__/party-lookup-term.test.js.map +1 -0
  9. package/dist/lib/components/party-field/party-field.component.d.ts +92 -0
  10. package/dist/lib/components/party-field/party-field.component.d.ts.map +1 -0
  11. package/dist/lib/components/party-field/party-field.component.js +351 -0
  12. package/dist/lib/components/party-field/party-field.component.js.map +1 -0
  13. package/dist/lib/components/party-field/party-lookup-term.d.ts +21 -0
  14. package/dist/lib/components/party-field/party-lookup-term.d.ts.map +1 -0
  15. package/dist/lib/components/party-field/party-lookup-term.js +42 -0
  16. package/dist/lib/components/party-field/party-lookup-term.js.map +1 -0
  17. package/dist/lib/generated/Entities/mjBizAppsCommonOrganization/mjbizappscommonorganization.form.component.js +37 -35
  18. package/dist/lib/generated/Entities/mjBizAppsCommonOrganization/mjbizappscommonorganization.form.component.js.map +1 -1
  19. package/dist/lib/generated/Entities/mjBizAppsCommonPerson/mjbizappscommonperson.form.component.js +43 -41
  20. package/dist/lib/generated/Entities/mjBizAppsCommonPerson/mjbizappscommonperson.form.component.js.map +1 -1
  21. package/dist/public-api.d.ts +2 -0
  22. package/dist/public-api.d.ts.map +1 -1
  23. package/dist/public-api.js +2 -0
  24. package/dist/public-api.js.map +1 -1
  25. package/package.json +6 -4
@@ -0,0 +1,2 @@
1
+ import '@angular/compiler';
2
+ //# sourceMappingURL=party-field.component.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"party-field.component.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/party-field/__tests__/party-field.component.test.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC"}
@@ -0,0 +1,266 @@
1
+ import '@angular/compiler';
2
+ import { ChangeDetectorRef, Injector, runInInjectionContext } from '@angular/core';
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
4
+ const H = vi.hoisted(() => ({ logError: vi.fn(), runQuery: vi.fn(), runView: vi.fn() }));
5
+ vi.mock('@memberjunction/core', async (importOriginal) => ({
6
+ ...(await importOriginal()),
7
+ LogError: H.logError,
8
+ RunQuery: class {
9
+ RunQuery = H.runQuery;
10
+ },
11
+ Metadata: class {
12
+ static Provider = {
13
+ EntityByName: (name) => (name === 'Organizations' ? { NameField: { Name: 'Name' } } : undefined),
14
+ };
15
+ },
16
+ RunView: { FromMetadataProvider: () => ({ RunView: H.runView }) },
17
+ }));
18
+ vi.mock('@memberjunction/ng-base-forms', () => ({ BaseFormsModule: class {
19
+ } }));
20
+ vi.mock('@memberjunction/ng-ui-components', () => ({ MJComboboxComponent: class {
21
+ } }));
22
+ import { PartyFieldComponent } from '../party-field.component';
23
+ function record(accountID, accountName = null, dirty = false) {
24
+ const values = { AccountID: accountID, Account: accountName };
25
+ const rec = {
26
+ values,
27
+ dirty,
28
+ EntityInfo: {
29
+ Fields: [
30
+ {
31
+ Name: 'AccountID',
32
+ DisplayNameOrName: 'Account',
33
+ RelatedEntityNameFieldMap: 'Account',
34
+ RelatedEntity: 'Organizations',
35
+ RelatedEntityFieldName: 'ID',
36
+ },
37
+ ],
38
+ },
39
+ Get: (field) => values[field],
40
+ Set: (field, value) => {
41
+ values[field] = value;
42
+ },
43
+ GetFieldByName: () => ({ Dirty: rec.dirty }),
44
+ };
45
+ return rec;
46
+ }
47
+ /** Stubs the RunQuery seam: each call returns a promise the test resolves by hand, in any order. */
48
+ class TestPartyField extends PartyFieldComponent {
49
+ Calls = [];
50
+ runSearch(params) {
51
+ return new Promise((resolve, reject) => this.Calls.push({ params, resolve, reject }));
52
+ }
53
+ /** Labels the combobox was told to show: the visible text, not just the option list. */
54
+ Shown = [];
55
+ RefreshComboboxText() {
56
+ this.Shown.push(this.Options.find((o) => o.ID === this.CurrentID)?.Name ?? null);
57
+ }
58
+ }
59
+ function build(rec) {
60
+ const injector = Injector.create({
61
+ providers: [{ provide: ChangeDetectorRef, useValue: { markForCheck: () => undefined } }],
62
+ });
63
+ const component = runInInjectionContext(injector, () => new TestPartyField());
64
+ component.Record = rec;
65
+ component.FieldName = 'AccountID';
66
+ component.Kind = 'Organization';
67
+ component.EditMode = true;
68
+ component.ngOnInit();
69
+ return component;
70
+ }
71
+ const DAVE = { ID: 'o-dave', Name: 'Dave Co', Detail: 'dave.com' };
72
+ const DA = { ID: 'o-da', Name: 'Da Inc', Detail: null };
73
+ describe('PartyFieldComponent', () => {
74
+ beforeEach(() => {
75
+ vi.useFakeTimers();
76
+ H.logError.mockReset();
77
+ H.runView.mockReset();
78
+ });
79
+ afterEach(() => vi.useRealTimers());
80
+ it('names a value set in code (no name on the record) with one lookup on the related entity', async () => {
81
+ H.runView.mockResolvedValue({ Success: true, Results: [{ ID: 'o-new', Name: 'New Co' }] });
82
+ const c = build(record('o-new', null));
83
+ await vi.advanceTimersByTimeAsync(0);
84
+ expect(H.runView).toHaveBeenCalledWith(expect.objectContaining({ EntityName: 'Organizations', ExtraFilter: "ID='o-new'", Fields: ['ID', 'Name'], MaxRows: 1 }));
85
+ expect(c.Options).toEqual([{ ID: 'o-new', Name: 'New Co', Detail: null }]);
86
+ });
87
+ it('re-reads the name when the field was changed in code, since the view name is stale', async () => {
88
+ H.runView.mockResolvedValue({ Success: true, Results: [{ ID: 'o-new', Name: 'New Co' }] });
89
+ const c = build(record('o-new', 'Old Co', true));
90
+ await vi.advanceTimersByTimeAsync(0);
91
+ expect(c.Options).toEqual([{ ID: 'o-new', Name: 'New Co', Detail: null }]);
92
+ });
93
+ it('logs a failed name lookup and keeps the ID as the label', async () => {
94
+ H.runView.mockResolvedValue({ Success: false, ErrorMessage: 'denied', Results: [] });
95
+ const c = build(record('o-new', null));
96
+ await vi.advanceTimersByTimeAsync(0);
97
+ expect(H.logError).toHaveBeenCalled();
98
+ expect(c.Options).toEqual([{ ID: 'o-new', Name: 'o-new', Detail: null }]);
99
+ });
100
+ it('sends nothing and lists nothing for one character', async () => {
101
+ const c = build(record(null));
102
+ c.OnFilterChange('d');
103
+ await vi.advanceTimersByTimeAsync(300);
104
+ expect(c.Calls).toHaveLength(0);
105
+ expect(c.Options).toEqual([]);
106
+ });
107
+ it('debounces typing into one search with the last term', async () => {
108
+ const c = build(record(null));
109
+ c.OnFilterChange('da');
110
+ await vi.advanceTimersByTimeAsync(100);
111
+ c.OnFilterChange('dave');
112
+ await vi.advanceTimersByTimeAsync(250);
113
+ expect(c.Calls.map((call) => call.params.Term)).toEqual(['dave']);
114
+ });
115
+ it('drops a slow response for an earlier term', async () => {
116
+ const c = build(record(null));
117
+ c.OnFilterChange('da');
118
+ await vi.advanceTimersByTimeAsync(250);
119
+ c.OnFilterChange('dave');
120
+ await vi.advanceTimersByTimeAsync(250);
121
+ c.Calls[1].resolve([DAVE]);
122
+ await vi.advanceTimersByTimeAsync(0);
123
+ c.Calls[0].resolve([DA]);
124
+ await vi.advanceTimersByTimeAsync(0);
125
+ expect(c.Options).toEqual([DAVE]);
126
+ });
127
+ it('writes the picked ID and emits old and new values', async () => {
128
+ const c = build(record('o-old', 'Old Co'));
129
+ const emitted = [];
130
+ c.ValueChange.subscribe((e) => emitted.push(e));
131
+ c.OnFilterChange('dave');
132
+ await vi.advanceTimersByTimeAsync(250);
133
+ c.Calls[0].resolve([DAVE]);
134
+ await vi.advanceTimersByTimeAsync(0);
135
+ c.OnSelect('o-dave');
136
+ expect(c.Record.Get('AccountID')).toBe('o-dave');
137
+ expect(emitted).toEqual([{ FieldName: 'AccountID', OldValue: 'o-old', NewValue: 'o-dave' }]);
138
+ });
139
+ it('shows a saved value by name without searching', () => {
140
+ const c = build(record('o-old', 'Old Co'));
141
+ expect(c.Options).toEqual([{ ID: 'o-old', Name: 'Old Co', Detail: null }]);
142
+ expect(c.CurrentID).toBe('o-old');
143
+ expect(c.Label).toBe('Account');
144
+ expect(c.Calls).toHaveLength(0);
145
+ expect(H.runView).not.toHaveBeenCalled();
146
+ });
147
+ it('keeps the picked name when focus leaves after a pick', async () => {
148
+ const rec = record('o-old', 'Old Co');
149
+ const c = build(rec);
150
+ c.OnFilterChange('dave');
151
+ await vi.advanceTimersByTimeAsync(250);
152
+ c.Calls[0].resolve([DAVE]);
153
+ await vi.advanceTimersByTimeAsync(0);
154
+ c.OnSelect('o-dave');
155
+ rec.dirty = true;
156
+ c.OnFocusOut();
157
+ await vi.advanceTimersByTimeAsync(300);
158
+ expect(c.Options).toEqual([DAVE]);
159
+ });
160
+ it('writes null when cleared', () => {
161
+ const c = build(record('o-old', 'Old Co'));
162
+ c.OnSelect(null);
163
+ expect(c.Record.Get('AccountID')).toBeNull();
164
+ });
165
+ it('goes back to the current value when focus leaves mid-search', async () => {
166
+ const c = build(record('o-old', 'Old Co'));
167
+ c.OnFilterChange('dave');
168
+ await vi.advanceTimersByTimeAsync(250);
169
+ c.Calls[0].resolve([DAVE]);
170
+ await vi.advanceTimersByTimeAsync(0);
171
+ c.OnFocusOut();
172
+ expect(c.Options).toEqual([{ ID: 'o-old', Name: 'Old Co', Detail: null }]);
173
+ });
174
+ it('shows the resolved name in the combobox, not only in the option list', async () => {
175
+ H.runView.mockResolvedValue({ Success: true, Results: [{ ID: 'o-new', Name: 'New Co' }] });
176
+ const c = build(record('o-new', null));
177
+ await vi.advanceTimersByTimeAsync(0);
178
+ expect(c.Shown.at(-1)).toBe('New Co');
179
+ });
180
+ it('re-reads the current value when it changes outside the picker', async () => {
181
+ H.runView.mockResolvedValue({ Success: true, Results: [{ ID: 'o-new', Name: 'New Co' }] });
182
+ const rec = record('o-old', 'Old Co');
183
+ const c = build(rec);
184
+ rec.values['AccountID'] = 'o-new';
185
+ rec.dirty = true;
186
+ c.ngDoCheck();
187
+ await vi.advanceTimersByTimeAsync(0);
188
+ expect(c.Options).toEqual([{ ID: 'o-new', Name: 'New Co', Detail: null }]);
189
+ expect(c.Shown.at(-1)).toBe('New Co');
190
+ });
191
+ it('does nothing on a check when the value has not changed', () => {
192
+ const c = build(record('o-old', 'Old Co'));
193
+ c.ngDoCheck();
194
+ expect(H.runView).not.toHaveBeenCalled();
195
+ expect(c.Shown).toEqual([]);
196
+ });
197
+ it('does not show a stale failure beside newer results', async () => {
198
+ const c = build(record(null));
199
+ c.OnFilterChange('da');
200
+ await vi.advanceTimersByTimeAsync(250);
201
+ c.OnFilterChange('dave');
202
+ await vi.advanceTimersByTimeAsync(250);
203
+ c.Calls[1].resolve([DAVE]);
204
+ await vi.advanceTimersByTimeAsync(0);
205
+ c.Calls[0].reject(new Error('late'));
206
+ await vi.advanceTimersByTimeAsync(0);
207
+ expect(c.Options).toEqual([DAVE]);
208
+ expect(c.SearchFailed).toBe(false);
209
+ });
210
+ it('logs a failed search and shows an empty list with a hint', async () => {
211
+ const c = build(record(null));
212
+ c.OnFilterChange('dave');
213
+ await vi.advanceTimersByTimeAsync(250);
214
+ c.Calls[0].reject(new Error('boom'));
215
+ await vi.advanceTimersByTimeAsync(0);
216
+ expect(H.logError).toHaveBeenCalled();
217
+ expect(c.Options).toEqual([]);
218
+ expect(c.SearchFailed).toBe(true);
219
+ });
220
+ });
221
+ describe('PartyFieldComponent.runSearch', () => {
222
+ beforeEach(() => H.runQuery.mockReset());
223
+ class Exposed extends PartyFieldComponent {
224
+ Search(params) {
225
+ return this.runSearch(params);
226
+ }
227
+ }
228
+ function bare() {
229
+ const injector = Injector.create({
230
+ providers: [{ provide: ChangeDetectorRef, useValue: { markForCheck: () => undefined } }],
231
+ });
232
+ return runInInjectionContext(injector, () => new Exposed());
233
+ }
234
+ it('runs the default query for the kind and omits a null domain', async () => {
235
+ H.runQuery.mockResolvedValue({ Success: true, Results: [{ ID: 'p1', Name: 'Zed', Detail: 'z@x.com' }] });
236
+ const c = bare();
237
+ c.Kind = 'Person';
238
+ const rows = await c.Search({ Term: 'ze', Domain: null });
239
+ expect(H.runQuery).toHaveBeenCalledWith({
240
+ QueryName: 'Common: Party Lookup People',
241
+ CategoryPath: 'Common',
242
+ Parameters: { Term: 'ze' },
243
+ });
244
+ expect(rows).toEqual([{ ID: 'p1', Name: 'Zed', Detail: 'z@x.com' }]);
245
+ });
246
+ it('runs the QueryName override with its category and passes the domain', async () => {
247
+ H.runQuery.mockResolvedValue({ Success: true, Results: [] });
248
+ const c = bare();
249
+ c.Kind = 'Organization';
250
+ c.QueryName = 'Sales: Party Lookup Accounts';
251
+ c.CategoryPath = 'Sales';
252
+ await c.Search({ Term: 'acme.com', Domain: 'acme.com' });
253
+ expect(H.runQuery).toHaveBeenCalledWith({
254
+ QueryName: 'Sales: Party Lookup Accounts',
255
+ CategoryPath: 'Sales',
256
+ Parameters: { Term: 'acme.com', Domain: 'acme.com' },
257
+ });
258
+ });
259
+ it('throws when the query fails, so the caller can log it', async () => {
260
+ H.runQuery.mockResolvedValue({ Success: false, ErrorMessage: 'denied', Results: [] });
261
+ const c = bare();
262
+ c.Kind = 'Person';
263
+ await expect(c.Search({ Term: 'ze', Domain: null })).rejects.toThrow('denied');
264
+ });
265
+ });
266
+ //# sourceMappingURL=party-field.component.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"party-field.component.test.js","sourceRoot":"","sources":["../../../../../src/lib/components/party-field/__tests__/party-field.component.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=party-lookup-term.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"party-lookup-term.test.d.ts","sourceRoot":"","sources":["../../../../../src/lib/components/party-field/__tests__/party-lookup-term.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { PARTY_LOOKUP_QUERIES, PartyLookupParamsFor } from '../party-lookup-term';
3
+ describe('PartyLookupParamsFor', () => {
4
+ it('sends nothing under two non-blank characters', () => {
5
+ expect(PartyLookupParamsFor('Person', ' d ')).toBeNull();
6
+ expect(PartyLookupParamsFor('Organization', '')).toBeNull();
7
+ });
8
+ it('does not count % toward the two characters, so "%%" cannot match every row', () => {
9
+ expect(PartyLookupParamsFor('Person', '%%')).toBeNull();
10
+ expect(PartyLookupParamsFor('Organization', '%a%')).toBeNull();
11
+ expect(PartyLookupParamsFor('Organization', 'ab%')).toEqual({ Term: 'ab%', Domain: null });
12
+ });
13
+ it('sends a trimmed name term with no domain', () => {
14
+ expect(PartyLookupParamsFor('Person', ' da ')).toEqual({ Term: 'da', Domain: null });
15
+ expect(PartyLookupParamsFor('Organization', 'acme')).toEqual({ Term: 'acme', Domain: null });
16
+ });
17
+ it('treats a person term with @ or . as an email domain, without the leading @', () => {
18
+ expect(PartyLookupParamsFor('Person', '@AQHA.com')).toEqual({ Term: '@AQHA.com', Domain: 'aqha.com' });
19
+ expect(PartyLookupParamsFor('Person', 'dave.smith')).toEqual({ Term: 'dave.smith', Domain: 'dave.smith' });
20
+ });
21
+ it('normalizes an organization URL the way the WebsiteDomain column does', () => {
22
+ expect(PartyLookupParamsFor('Organization', 'https://www.Acme.com/about')).toEqual({
23
+ Term: 'https://www.Acme.com/about',
24
+ Domain: 'acme.com',
25
+ });
26
+ expect(PartyLookupParamsFor('Organization', 'HTTP://acme.com')?.Domain).toBe('acme.com');
27
+ expect(PartyLookupParamsFor('Organization', 'www.acme.com:8080')?.Domain).toBe('acme.com:8080');
28
+ });
29
+ it('only strips scheme, www and path from an organization term', () => {
30
+ expect(PartyLookupParamsFor('Organization', 'acme@x.com')?.Domain).toBe('acme@x.com');
31
+ });
32
+ it('sends no domain when normalization leaves fewer than two characters', () => {
33
+ expect(PartyLookupParamsFor('Organization', 'https://')).toEqual({ Term: 'https://', Domain: null });
34
+ expect(PartyLookupParamsFor('Person', '@.')).toEqual({ Term: '@.', Domain: null });
35
+ });
36
+ it('names the common query for each kind', () => {
37
+ expect(PARTY_LOOKUP_QUERIES.Person).toEqual({ QueryName: 'Common: Party Lookup People', CategoryPath: 'Common' });
38
+ expect(PARTY_LOOKUP_QUERIES.Organization).toEqual({ QueryName: 'Common: Party Lookup Organizations', CategoryPath: 'Common' });
39
+ });
40
+ });
41
+ //# sourceMappingURL=party-lookup-term.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"party-lookup-term.test.js","sourceRoot":"","sources":["../../../../../src/lib/components/party-field/__tests__/party-lookup-term.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAElF,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACzD,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QAClF,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/D,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrF,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;QAClF,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACvG,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAC/G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC5E,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,4BAA4B,CAAC,CAAC,CAAC,OAAO,CAAC;YAC/E,IAAI,EAAE,4BAA4B;YAClC,MAAM,EAAE,UAAU;SACrB,CAAC,CAAC;QACH,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACzF,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,mBAAmB,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QAClE,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC3E,MAAM,CAAC,oBAAoB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,6BAA6B,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;QAClH,MAAM,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,oCAAoC,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnI,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { DoCheck, EventEmitter, OnDestroy, OnInit } from '@angular/core';
2
+ import { BaseEntity } from '@memberjunction/core';
3
+ import { type FormContext, type FormNavigationEvent } from '@memberjunction/ng-base-forms';
4
+ import { type PartyKind, type PartyLookupParams } from './party-lookup-term';
5
+ import * as i0 from "@angular/core";
6
+ /** One row of a party lookup query: the contract every app's lookup query honours. */
7
+ export interface PartyOption {
8
+ ID: string;
9
+ Name: string;
10
+ Detail: string | null;
11
+ }
12
+ /**
13
+ * `bizapps-party-field` — a Person or Organization foreign key that searches as you type.
14
+ *
15
+ * The stock form field lists rows on focus, matches `LIKE '%q%'` on one view column and counts
16
+ * every full page, which takes seconds on a party file of a million people. This one lists nothing
17
+ * until two characters are typed, then runs one parameterized query (prefix match on indexed base
18
+ * columns, TOP 20, no count). People match last name, display name, email or email domain;
19
+ * organizations match name, legal name or website domain.
20
+ *
21
+ * Read mode is the stock `mj-form-field`, so labels, links and navigation stay the platform's.
22
+ * An app whose foreign key points at a subtype (Sales Contacts, Sales Accounts) passes its own
23
+ * `QueryName` with the same result contract (ID, Name, Detail; parameters Term, Domain).
24
+ */
25
+ export declare class PartyFieldComponent implements OnInit, DoCheck, OnDestroy {
26
+ private readonly cdr;
27
+ Record: BaseEntity;
28
+ FieldName: string;
29
+ Kind: PartyKind;
30
+ /** Overrides the Kind's default query; pair with CategoryPath. */
31
+ QueryName?: string;
32
+ CategoryPath?: string;
33
+ EditMode: boolean;
34
+ ShowLabel: boolean;
35
+ FormContext?: FormContext;
36
+ /** The shape mj-form-field emits, so handlers written for it keep working. */
37
+ ValueChange: EventEmitter<{
38
+ FieldName: string;
39
+ OldValue: unknown;
40
+ NewValue: unknown;
41
+ }>;
42
+ Navigate: EventEmitter<FormNavigationEvent>;
43
+ /** What the dropdown lists: search results, or just the current value when not searching. */
44
+ Options: PartyOption[];
45
+ SearchFailed: boolean;
46
+ /** The current value as a one-item list (empty when unset): what the list goes back to. */
47
+ private current;
48
+ private readonly terms;
49
+ private subscription?;
50
+ private combobox?;
51
+ ngOnInit(): void;
52
+ /**
53
+ * Code can change the value after load (Deal's FillContactsFromAccount, a cancelled edit
54
+ * reverting the record). Re-seed when the record no longer holds the value this field shows.
55
+ */
56
+ ngDoCheck(): void;
57
+ ngOnDestroy(): void;
58
+ get Label(): string;
59
+ get CurrentID(): string | null;
60
+ OnFilterChange(text: string): void;
61
+ /** Picked (an ID) or cleared (null). */
62
+ OnSelect(value: unknown): void;
63
+ /**
64
+ * Leaving the field mid-search puts the current value back in the list, so the combobox can
65
+ * show its name rather than a raw ID, and cancels any search still pending.
66
+ */
67
+ OnFocusOut(): void;
68
+ /** The RunQuery call. Throws on failure; a test seam. */
69
+ protected runSearch(params: PartyLookupParams): Promise<PartyOption[]>;
70
+ /**
71
+ * mj-combobox re-reads its text from Data only while the text is empty, so a name that arrives
72
+ * after the ID was shown has to be pushed: Data first, then the value. A test seam.
73
+ */
74
+ protected RefreshComboboxText(): void;
75
+ private seedCurrent;
76
+ /** The options to list, or null when the search failed (logged). */
77
+ private optionsFor;
78
+ /**
79
+ * The current value as an option, named from the record's related-name view column. That
80
+ * column is empty, or stale, when code set the foreign key after load (Deal's
81
+ * FillContactsFromAccount); the ID stands in until resolveCurrentName replaces it.
82
+ */
83
+ private currentOption;
84
+ private recordName;
85
+ private needsNameLookup;
86
+ /** One read of the related record's name field. A failure is logged and the ID stays as the label. */
87
+ private resolveCurrentName;
88
+ private fieldInfo;
89
+ static ɵfac: i0.ɵɵFactoryDeclaration<PartyFieldComponent, never>;
90
+ static ɵcmp: i0.ɵɵComponentDeclaration<PartyFieldComponent, "bizapps-party-field", never, { "Record": { "alias": "Record"; "required": true; }; "FieldName": { "alias": "FieldName"; "required": true; }; "Kind": { "alias": "Kind"; "required": true; }; "QueryName": { "alias": "QueryName"; "required": false; }; "CategoryPath": { "alias": "CategoryPath"; "required": false; }; "EditMode": { "alias": "EditMode"; "required": false; }; "ShowLabel": { "alias": "ShowLabel"; "required": false; }; "FormContext": { "alias": "FormContext"; "required": false; }; }, { "ValueChange": "ValueChange"; "Navigate": "Navigate"; }, never, never, true, never>;
91
+ }
92
+ //# sourceMappingURL=party-field.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"party-field.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/party-field/party-field.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,OAAO,EACP,YAAY,EAEZ,SAAS,EACT,MAAM,EAIT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,UAAU,EAAyC,MAAM,sBAAsB,CAAC;AAEzF,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAI5G,OAAO,EAA8C,KAAK,SAAS,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;;AAEzH,sFAAsF;AACtF,MAAM,WAAW,WAAW;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAID;;;;;;;;;;;;GAYG;AACH,qBA4Ea,mBAAoB,YAAW,MAAM,EAAE,OAAO,EAAE,SAAS;IAClE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAA6B;IAEtB,MAAM,EAAG,UAAU,CAAC;IACpB,SAAS,EAAG,MAAM,CAAC;IACnB,IAAI,EAAG,SAAS,CAAC;IAC5C,kEAAkE;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,UAAS;IACjB,SAAS,UAAQ;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IACnC,8EAA8E;IACpE,WAAW;mBAAiC,MAAM;kBAAY,OAAO;kBAAY,OAAO;OAAM;IAC9F,QAAQ,oCAA2C;IAE7D,6FAA6F;IACtF,OAAO,EAAE,WAAW,EAAE,CAAM;IAC5B,YAAY,UAAS;IAE5B,2FAA2F;IAC3F,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,YAAY,CAAC,CAAe;IAEJ,OAAO,CAAC,QAAQ,CAAC,CAAsB;IAEhE,QAAQ,IAAI,IAAI;IAcvB;;;OAGG;IACI,SAAS,IAAI,IAAI;IAQjB,WAAW,IAAI,IAAI;IAI1B,IAAW,KAAK,IAAI,MAAM,CAEzB;IAED,IAAW,SAAS,IAAI,MAAM,GAAG,IAAI,CAGpC;IAEM,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzC,wCAAwC;IACjC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAWrC;;;OAGG;IACI,UAAU,IAAI,IAAI;IAMzB,yDAAyD;cACzC,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAe5E;;;OAGG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAQrC,OAAO,CAAC,WAAW;IAQnB,oEAAoE;YACtD,UAAU;IAaxB;;;;OAIG;IACH,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,eAAe;IAOvB,sGAAsG;YACxF,kBAAkB;IAyBhC,OAAO,CAAC,SAAS;yCAnMR,mBAAmB;2CAAnB,mBAAmB;CAsM/B"}