ngx-t-forms-types 0.0.25 → 0.0.27

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.
@@ -38,7 +38,9 @@ export declare enum ElementEditorTypes {
38
38
  MapMatOptionsKeys = "mapMatOptionsKeys",
39
39
  FormPayloadProjection = "formPayloadProjection",
40
40
  /** Opt-in JSON body template ({@link PayloadTemplate}) for a POST value/options fetch. */
41
- PayloadTemplate = "payloadTemplate"
41
+ PayloadTemplate = "payloadTemplate",
42
+ /** JSON request-header template ({@link HeaderTemplate}) for a value/options fetch (GET and POST alike). */
43
+ HeaderTemplate = "headerTemplate"
42
44
  }
43
45
  export interface ElementEditorConfigInterface {
44
46
  editorSections: Array<ElementEditorConfigSectionInterface>;
@@ -33,6 +33,8 @@ export var ElementEditorTypes;
33
33
  ElementEditorTypes["FormPayloadProjection"] = "formPayloadProjection";
34
34
  /** Opt-in JSON body template ({@link PayloadTemplate}) for a POST value/options fetch. */
35
35
  ElementEditorTypes["PayloadTemplate"] = "payloadTemplate";
36
+ /** JSON request-header template ({@link HeaderTemplate}) for a value/options fetch (GET and POST alike). */
37
+ ElementEditorTypes["HeaderTemplate"] = "headerTemplate";
36
38
  })(ElementEditorTypes || (ElementEditorTypes = {}));
37
39
  // interface TStringExpressionValidationTest{
38
40
  // expression: string;
@@ -10,6 +10,159 @@ import { RichTextEditorType } from "../../formInput/RichTextEditorInput.js";
10
10
  import { LabelPosition } from "../../formInput/ToggleInputInterface.js";
11
11
  import { AllFormInputPrimaryKeys, SpecialElementKeys } from "../FormInputKeys.js";
12
12
  import { BlurHandleTypes, ElementEditorTypes } from "../elementEditor.js";
13
+ import { DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES } from "../../formInput/WorkflowDocumentPicker.js";
14
+ /** Human-facing names for the document-picker filter operators. */
15
+ const DOCUMENT_PICKER_FILTER_OPERATOR_LABELS = {
16
+ eq: 'Is',
17
+ ne: 'Is not',
18
+ in: 'Is any of',
19
+ nin: 'Is none of',
20
+ gt: 'Greater than',
21
+ gte: 'Greater than or equal to',
22
+ lt: 'Less than',
23
+ lte: 'Less than or equal to',
24
+ regex: 'Contains',
25
+ exists: 'Has a value',
26
+ };
27
+ /** Human-facing names for the two mutually exclusive filter value sources. */
28
+ const DOCUMENT_PICKER_FILTER_VALUE_SOURCE_LABELS = {
29
+ fixed: 'Fixed value',
30
+ input: 'From another input',
31
+ };
32
+ /**
33
+ * Shows a row only while the filter is NOT input-bound.
34
+ *
35
+ * Deliberately written as `!== input` rather than `=== fixed`: `valueSource` is
36
+ * absent on every filter saved before the switch existed and on a brand-new
37
+ * record, and `testAgainstItem` resolves an absent deep-bound key to `undefined`.
38
+ * `undefined !== 'input'` is true, so the fixed-value rows stay visible for those
39
+ * records instead of silently becoming uneditable.
40
+ */
41
+ const DOCUMENT_PICKER_FILTER_IS_FIXED_TEST = `valueSource !== input`;
42
+ /** Shows a row only once the administrator has explicitly chosen the input source. */
43
+ const DOCUMENT_PICKER_FILTER_IS_INPUT_TEST = `valueSource === input`;
44
+ /**
45
+ * Per-record editor for one preset filter (`IDocumentPickerFilter`) inside the
46
+ * document picker's "Preset filters" list.
47
+ */
48
+ const DOCUMENT_PICKER_FILTER_EDITOR = () => [
49
+ {
50
+ label: 'Filter',
51
+ id: "0f0a5c1e-1d3b-4a76-9e2c-6b8f4a91d0c7",
52
+ elements: [
53
+ {
54
+ name: SpecialElementKeys.Default,
55
+ deepBind: ['path'],
56
+ editType: ElementEditorTypes.Input,
57
+ label: 'Field',
58
+ required: true,
59
+ placeholder: 'form.status',
60
+ hint: `The document field to filter on. Form fields are written as form.<field name>; reference, status and archive live on the document itself.`,
61
+ id: "5c9d2f70-8e41-4b0a-9d63-2a7c5e18b4f2"
62
+ },
63
+ {
64
+ name: SpecialElementKeys.Default,
65
+ deepBind: ['op'],
66
+ editType: ElementEditorTypes.ChipSelect,
67
+ label: 'Operator',
68
+ defaultValue: 'eq',
69
+ options: DOCUMENT_PICKER_FILTER_OPERATORS.map((op) => ({
70
+ label: DOCUMENT_PICKER_FILTER_OPERATOR_LABELS[op],
71
+ value: op,
72
+ })),
73
+ id: "b1e74a63-0c95-4d8e-8f27-3d6a9c02e5b8"
74
+ },
75
+ {
76
+ name: SpecialElementKeys.Default,
77
+ deepBind: ['valueSource'],
78
+ editType: ElementEditorTypes.ChipSelect,
79
+ label: 'Where the value comes from',
80
+ hint: `A filter compares against one value only. Pick a fixed value you type here, or follow an input the user fills in earlier on this form.`,
81
+ options: DOCUMENT_PICKER_FILTER_VALUE_SOURCES.map((source) => ({
82
+ label: DOCUMENT_PICKER_FILTER_VALUE_SOURCE_LABELS[source],
83
+ value: source,
84
+ })),
85
+ // NO defaultValue. The nested editor emits `defaultValue` on init when the
86
+ // bound key is absent, which would stamp `fixed` onto every filter saved
87
+ // before this switch existed — silently converting an input-bound filter
88
+ // the moment an administrator merely opened it. The two `additionalTest`
89
+ // expressions below tolerate an absent `valueSource` on their own instead.
90
+ //
91
+ // `clearOnChange` drops the input-bound side, so switching to a fixed value
92
+ // can never leave a live binding behind. It is deliberately one-sided: the
93
+ // fixed `value` is NOT listed, because a leftover `value` under the input
94
+ // source is hidden here and ignored by `buildDocumentFilter`, whereas
95
+ // clearing it would throw away typed work every time the source is toggled.
96
+ // RecordListManager applies these paths only when `valueSource` moves away
97
+ // from a value the record already held, so opening a filter saved before
98
+ // this switch existed never clears anything.
99
+ clearOnChange: [
100
+ ['fromInputId'],
101
+ ['omitWhenEmpty'],
102
+ ],
103
+ id: "2f6b8d04-91c7-4a5e-b3f0-7d2e6a148c15",
104
+ },
105
+ {
106
+ name: SpecialElementKeys.Default,
107
+ deepBind: ['fromInputId'],
108
+ editType: ElementEditorTypes.FormInputSelector,
109
+ label: 'Take the value from another input',
110
+ hint: `The filter follows that input's current value — use it to show only transactions matching something the user picked earlier in this form.`,
111
+ additionalTest: [
112
+ {
113
+ expression: DOCUMENT_PICKER_FILTER_IS_INPUT_TEST,
114
+ deepBind: ['valueSource'],
115
+ },
116
+ ],
117
+ id: "7a3f8d21-4b60-4e19-a5c8-91d4e7f36b0a"
118
+ },
119
+ {
120
+ name: SpecialElementKeys.Default,
121
+ deepBind: ['omitWhenEmpty'],
122
+ editType: ElementEditorTypes.Toggle,
123
+ label: 'Ignore this filter when the value is empty',
124
+ hint: `On: the filter is skipped until that input has a value. Off: an empty value is filtered on literally.`,
125
+ additionalTest: [
126
+ {
127
+ expression: DOCUMENT_PICKER_FILTER_IS_INPUT_TEST,
128
+ deepBind: ['valueSource'],
129
+ },
130
+ ],
131
+ id: "9b52c7e3-6d81-40af-a7c9-4e13b805d6f2"
132
+ },
133
+ {
134
+ name: SpecialElementKeys.Default,
135
+ deepBind: ['value'],
136
+ editType: ElementEditorTypes.Input,
137
+ label: 'Fixed value',
138
+ hint: `For "Is any of" / "Is none of", separate values with commas.`,
139
+ additionalTest: [
140
+ {
141
+ expression: DOCUMENT_PICKER_FILTER_IS_FIXED_TEST,
142
+ deepBind: ['valueSource'],
143
+ },
144
+ ],
145
+ id: "e6c05b94-2f78-4a3d-b1e5-8c07f9a24d63"
146
+ },
147
+ {
148
+ name: SpecialElementKeys.Default,
149
+ deepBind: ['valueType'],
150
+ editType: ElementEditorTypes.ChipSelect,
151
+ label: 'Value type',
152
+ defaultValue: 'string',
153
+ hint: `How the fixed value is read. Pick Number or Boolean when the stored field is not text, otherwise the comparison never matches.`,
154
+ options: DOCUMENT_PICKER_FILTER_VALUE_TYPES.map((type) => ({ label: type, value: type })),
155
+ additionalTest: [
156
+ {
157
+ expression: DOCUMENT_PICKER_FILTER_IS_FIXED_TEST,
158
+ deepBind: ['valueSource'],
159
+ },
160
+ ],
161
+ id: "3d8b1e07-9a24-4c65-8f0b-52e7a6c91f4d"
162
+ },
163
+ ],
164
+ },
165
+ ];
13
166
  export var ElementConfig = {
14
167
  editorSections: [
15
168
  {
@@ -424,8 +577,13 @@ export var ElementConfig = {
424
577
  name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
425
578
  deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'primaryIdentifierKey'],
426
579
  label: "Select primary identifier key",
427
- hint: "Choose a key other than _id to serve as the primary identifier for workflow documents. Note: existing mappings will be cleared when reconfigured. After updating, reselect the workflow above.",
580
+ hint: "Choose a key other than _id to identify the selected transaction. Leave it unset to use _id.",
428
581
  editType: ElementEditorTypes.MapMatOptionsKeys,
582
+ // The key tree is built from `sampleDocument`. This row must NOT clear it:
583
+ // `clearOnChange` runs on every emission from this editor, so clearing the
584
+ // sample here wiped the tree the moment a key was picked — the options
585
+ // appeared, then vanished on first click. The sample is owned by the
586
+ // workflow selection above and is refreshed whenever the workflow changes.
429
587
  fetchOptions: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'sampleDocument'],
430
588
  additionalTest: [
431
589
  {
@@ -433,98 +591,43 @@ export var ElementConfig = {
433
591
  testType: 'exists',
434
592
  }
435
593
  ],
436
- clearOnChange: [
437
- [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'sampleDocument'],
438
- ],
439
594
  id: "c9396a58-1d72-4ef9-8eff-5a28e8f738a1"
440
595
  },
441
596
  {
442
597
  name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
443
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentSourceType'],
444
- hint: `Choose the source type for document options: 'Postman API' fetches from an external API, 'Data Pipeline' pulls from MongoDB.`,
598
+ deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'stepFilter', 'stepIds'],
445
599
  editType: ElementEditorTypes.ChipSelect,
446
- label: 'Document options source type',
447
- defaultValue: 'default',
448
- clearOnChange: [
449
- [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource'],
450
- ],
451
- options: [
452
- {
453
- label: 'Default',
454
- value: 'default'
455
- },
456
- { label: 'Postman API', value: DataSources.Api },
457
- // { label: 'Data Pipeline', value: DataSources.MongoDb },
458
- ],
459
- id: "f04cc297-9b22-403a-afe4-4fb2e84fa503"
460
- },
461
- {
462
- name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
463
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource'],
464
- editType: ElementEditorTypes.ApiCall,
600
+ multipleSelection: true,
601
+ label: 'Limit to workflow steps',
602
+ hint: `Optional. Restricts the picker to transactions currently sitting on the selected steps. Leave empty to let the user choose a step while browsing.`,
603
+ fetchOptions: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'availableSteps'],
465
604
  additionalTest: [
466
605
  {
467
- expression: `documentSourceType === ${DataSources.Api}`,
468
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentSourceType'],
606
+ testType: 'exists',
607
+ deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'workflowId'],
469
608
  },
470
609
  ],
471
- clearOnChange: [
472
- [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource'],
473
- ],
474
- hint: `Select an API endpoint from your Postman collection to fetch document options. Configure headers, payload format, and response mapping as needed.`,
475
- label: 'Select doc option API endpoint',
476
- id: "ecb1ea0e-3d2d-447f-a68e-48f1378fc0a7"
610
+ id: "f04cc297-9b22-403a-afe4-4fb2e84fa503"
477
611
  },
478
612
  {
479
613
  name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
480
- deepBind: [
481
- AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource',
482
- 'backEndConfig',
483
- 'minimumInputRequired',
614
+ deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'presetFilters'],
615
+ editType: ElementEditorTypes.RecordListManager,
616
+ label: 'Preset filters',
617
+ hint: `Optional. Narrows the transactions a user can pick from, before they search. Each filter targets a document field: form fields are written as form.<field name>, and the document itself exposes reference, status and archive.`,
618
+ secondaryElementEditorConfig: DOCUMENT_PICKER_FILTER_EDITOR(),
619
+ options: [
620
+ { label: 'Field', value: 'path' },
621
+ { label: 'Operator', value: 'op' },
622
+ { label: 'Value', value: 'value' },
484
623
  ],
485
624
  additionalTest: [
486
625
  {
487
626
  testType: 'exists',
488
- deepBind: [
489
- AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource',
490
- 'backEndConfig',
491
- 'minimumInputRequired',
492
- ],
493
- }
494
- ],
495
- hint: `These are payload fields that are required to be filled in order to fetch data from the selected source`,
496
- editType: ElementEditorTypes.RequiredInputs,
497
- label: 'Set up required inputs',
498
- id: "c1e79e55-18b7-4c4c-8b16-5f792f34e0be"
499
- },
500
- {
501
- name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
502
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource', 'valueAccessRules'],
503
- hint: `Map the fetched data to the input value. This is useful when the fetched data is an object and you want to map a specific field to the input value.It also allow data transformation before setting the value`,
504
- fetchOptions: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource', '_id'],
505
- additionalTest: [
506
- {
507
- expression: `documentSourceType === ${DataSources.Api}`,
508
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentSourceType'],
509
- },
510
- ],
511
- editType: ElementEditorTypes.ApiValueAccessRules,
512
- label: 'Map value to fetched data',
513
- id: "9ccb074d-00be-4c90-8989-2309e9faed10"
514
- },
515
- {
516
- name: AllFormInputPrimaryKeys.WorkflowPickerConfig,
517
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentsSource'],
518
- additionalTest: [
519
- {
520
- expression: "documentSourceType === mongoPipeline",
521
- deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'documentSourceType'],
627
+ deepBind: [AllFormInputPrimaryKeys.WorkflowPickerConfig, 'workflowId'],
522
628
  },
523
629
  ],
524
- editType: ElementEditorTypes.MongoPipelineBuilder,
525
- label: 'Configure MongoDB pipeline',
526
- hint: `Create a MongoDB aggregation pipeline to fetch document options from your database.`,
527
- id: "1b826f36-08ad-46b5-86ea-c1c48fd90f51"
630
+ id: "ecb1ea0e-3d2d-447f-a68e-48f1378fc0a7"
528
631
  },
529
632
  //********************** */
530
633
  {
@@ -745,6 +848,26 @@ export var ElementConfig = {
745
848
  label: 'Configure MongoDB pipeline',
746
849
  id: "7b2989ae-2f54-4849-93d0-aff56ac12ef2"
747
850
  },
851
+ {
852
+ name: SpecialElementKeys.Default,
853
+ deepBind: ['matOptions', 'fetch', 'value', 'headerTemplate'],
854
+ additionalTest: [
855
+ {
856
+ // Headers are a transport concern — offered for GET and POST
857
+ // alike, but only once an API endpoint has been selected.
858
+ expression: `source === ${DataSources.Api}`,
859
+ deepBind: ['matOptions', 'fetch', 'value', 'source'],
860
+ },
861
+ {
862
+ testType: 'exists',
863
+ deepBind: ['matOptions', 'fetch', 'value', 'httpEndPoint'],
864
+ },
865
+ ],
866
+ hint: `Author the request headers as JSON. Type $ to bind a header to a live field value; every other literal is a fixed default. The fetch waits until every bound field has a value.`,
867
+ editType: ElementEditorTypes.HeaderTemplate,
868
+ label: 'Request headers',
869
+ id: "f4b1c8d2-6e35-4a71-9f08-3c7d2b6a5e14"
870
+ },
748
871
  {
749
872
  name: SpecialElementKeys.Default,
750
873
  deepBind: ['matOptions', 'fetch', 'value', 'backEndConfig', 'requestBodyMode'],
@@ -932,6 +1055,26 @@ export var ElementConfig = {
932
1055
  label: 'Select API to fetch data from',
933
1056
  id: "df9e2a34-7bf5-411e-a265-14ca4f85166d"
934
1057
  },
1058
+ {
1059
+ name: SpecialElementKeys.Default,
1060
+ deepBind: ['matOptions', 'fetch', 'options', 'headerTemplate'],
1061
+ additionalTest: [
1062
+ {
1063
+ // Headers are a transport concern — offered for GET and POST
1064
+ // alike, but only once an API endpoint has been selected.
1065
+ expression: `source === ${DataSources.Api}`,
1066
+ deepBind: ['matOptions', 'fetch', 'options', 'source'],
1067
+ },
1068
+ {
1069
+ testType: 'exists',
1070
+ deepBind: ['matOptions', 'fetch', 'options', 'httpEndPoint'],
1071
+ },
1072
+ ],
1073
+ hint: `Author the request headers as JSON. Type $ to bind a header to a live field value; every other literal is a fixed default. The fetch waits until every bound field has a value.`,
1074
+ editType: ElementEditorTypes.HeaderTemplate,
1075
+ label: 'Request headers',
1076
+ id: "9a5e7c30-2d84-4b16-8e5f-6b0c4d1a7f92"
1077
+ },
935
1078
  {
936
1079
  name: SpecialElementKeys.Default,
937
1080
  deepBind: ['matOptions', 'fetch', 'options', 'backEndConfig', 'requestBodyMode'],
@@ -8,8 +8,35 @@ export interface IWorkflowOption {
8
8
  isDocument: boolean;
9
9
  id: string;
10
10
  }
11
+ /**
12
+ * A column of the workflow's transaction list, as configured on the workflow itself.
13
+ *
14
+ * `formControlName` names the form field; `path` is where that field actually lives
15
+ * in the stored document and is what sorting and searching must address — a form
16
+ * field sorted by its bare control name silently sorts on a non-existent root field.
17
+ */
11
18
  export interface IWorkflowDocListCols {
12
19
  label: string;
13
20
  formControlName: string;
14
21
  type?: DocumentLitsLabelConfigInterfaceValueType | InputDataTypes | undefined | InputPipeTypes;
22
+ /**
23
+ * Where the column's value actually lives in the stored document — `form.amount`
24
+ * for a form field, or a root field such as `reference`. Sorting and searching
25
+ * address this path: a form field addressed by its bare control name resolves to
26
+ * a non-existent root field and silently returns unordered, unsearched results.
27
+ */
28
+ path: string;
29
+ /** `true` when the workflow marks the column hidden from its transaction list. */
30
+ hidden: boolean;
31
+ }
32
+ /** A step of a workflow, as offered to a user filtering transactions by step. */
33
+ export interface IWorkflowStepOption {
34
+ /** Matches the transaction's `currentStepID`. */
35
+ stepId: string;
36
+ /** Human-facing step name. */
37
+ label: string;
38
+ /** Zero-based position in the workflow's process tree. */
39
+ index: number;
40
+ /** Step kind, e.g. `initiate`, `review`, `edit`. */
41
+ stepType?: string;
15
42
  }
@@ -4,7 +4,8 @@ import { IWorkflowOption } from "../FormBuilder/index.js";
4
4
  import { AccountingBasis, AdjResponseReviewColumnMapping, IGetTreeResponse, ScoaSegmentValue, WorkflowAdjudicationScoreSheetValue } from "../formInput/index.js";
5
5
  import { FormListSection } from "../Form/IFormsInitStateInterface.js";
6
6
  import { IUserSignature, PointGroup } from "../formInput/userSignature.js";
7
- import { IWorkflowDocListCols } from "../FormBuilder/workflowSelectionConfig.js";
7
+ import { IWorkflowDocListCols, IWorkflowStepOption } from "../FormBuilder/workflowSelectionConfig.js";
8
+ import { IDocumentPage, IDocumentQueryRequest } from "../formInput/WorkflowDocumentPicker.js";
8
9
  import { IFinancialCycles } from "./environment.js";
9
10
  export interface DialogConfig {
10
11
  title: string;
@@ -68,14 +69,28 @@ export interface IStoreFunctions {
68
69
  results: any;
69
70
  message: string;
70
71
  }>;
71
- getWorkflowDocuments: (workflowId: string, page: number, itemsPerPage: number, sort: Record<string, -1 | 1>, searchKey: string | undefined, filter?: Record<string, any>) => Observable<{
72
- footerConfig: {
73
- totalPages: number;
74
- totalItems: number;
75
- itemsPerPage: number;
76
- };
77
- formValues: Record<string, unknown>[];
78
- }>;
72
+ /**
73
+ * The single query used by every document picker. One request carries paging,
74
+ * sorting, filtering and search, and one page comes back.
75
+ *
76
+ * Paging is keyset-based: omit `cursor` for the first page, then pass the
77
+ * previous page's `nextCursor`. `sort` must stay identical for the life of a
78
+ * cursor sequence — a changed sort invalidates outstanding cursors, so reset
79
+ * paging whenever the sort, filter or search term changes.
80
+ *
81
+ * @example
82
+ * queryDocuments({
83
+ * workflowId,
84
+ * itemsPerPage: 10,
85
+ * sort: { updatedAt: -1 },
86
+ * filter: { archive: false, currentStep: stepId },
87
+ * searchKey: 'chairs',
88
+ * schema: { reference: 'string', 'form.description': 'string' },
89
+ * })
90
+ */
91
+ queryDocuments: (request: IDocumentQueryRequest) => Observable<IDocumentPage>;
92
+ /** Steps of a workflow, in process-tree order, for the picker's step filter. */
93
+ getWorkflowSteps: (workflowId: string) => Observable<IWorkflowStepOption[]>;
79
94
  fileUpload: FileUploadFn;
80
95
  formSubmittedSuccessfully: (formId: string) => void;
81
96
  getUserSignature: () => Observable<IUserSignature>;
@@ -1,5 +1,6 @@
1
1
  import { IStoreFunctions } from "./IStoreFunctions.js";
2
2
  import { Moment } from 'moment';
3
+ import type { FormSubmissionHandleInterface } from "../Form/formSubmissionHandleInterface.js";
3
4
  export interface IFinancialCycles {
4
5
  CURRENT_FINANCIAL_CYCLE: string;
5
6
  CURRENT_FINANCIAL_CYCLE_START_DATE: Moment;
@@ -16,5 +17,37 @@ export interface IFinancialCycles {
16
17
  export interface NgxTFormsConfig {
17
18
  base_url?: string;
18
19
  formBuilder: IStoreFunctions;
20
+ /**
21
+ * Submission configuration pre-inserted into every NEW form the builder creates.
22
+ *
23
+ * Applies ONLY at new-form creation. Forms loaded from storage keep whatever they
24
+ * already carry — including nothing — so an author can delete the pre-inserted
25
+ * endpoints and have that stick. Changing this value never rewrites existing forms.
26
+ *
27
+ * The value is deep-copied per form, so the builder editing one form's submission
28
+ * config can never mutate this object or leak into the next new form. API entry
29
+ * `_id`s are copied verbatim, so the same default yields the same ids across forms.
30
+ *
31
+ * Omit it and new forms start with `{ submissionAPI: [] }`, exactly as before.
32
+ *
33
+ * @example
34
+ * provideNgxTForms({
35
+ * formBuilder: myStoreFunctions,
36
+ * defaultSubmissionHandle: {
37
+ * innerComponentShowSubmitButton: false,
38
+ * submissionAPI: [{
39
+ * _id: '80eca6b1-923a-4c0e-a863-2f56a7e52a67',
40
+ * name: 'Generate/Update WF Document',
41
+ * httpEndPoint: '{{$iserve-back-end-url}}/api/form/generateWFFormValues',
42
+ * httpMethod: 'POST',
43
+ * postFormData: true,
44
+ * backEndConfig: { minimumInputRequired: [] },
45
+ * source: DataSources.Api,
46
+ * projectFormData: 'data:{$formValue}',
47
+ * }],
48
+ * },
49
+ * })
50
+ */
51
+ defaultSubmissionHandle?: FormSubmissionHandleInterface;
19
52
  [key: string]: string | Object | undefined;
20
53
  }
@@ -65,6 +65,44 @@ export type PayloadTemplate = {
65
65
  * configuration.
66
66
  */
67
67
  export type RequestBodyMode = 'mappedInputs' | 'template';
68
+ /**
69
+ * A single header value in a {@link HeaderTemplate}.
70
+ *
71
+ * Scalars only — an HTTP header value is text on the wire, so a number/boolean
72
+ * literal is stringified at request time. Nesting is deliberately not expressible:
73
+ * a header has no structure to nest into.
74
+ */
75
+ export type HeaderTemplateValue = string | number | boolean;
76
+ /**
77
+ * Declarative request headers for a value/options fetch, authored in the same
78
+ * JSON editor as {@link PayloadTemplate} and resolved with the same
79
+ * `{{inputId}}` token syntax.
80
+ *
81
+ * A value that is EXACTLY `"{{inputId}}"` is replaced by that input's live value
82
+ * (stringified); a value that merely CONTAINS token(s) is interpolated
83
+ * (`"Bearer {{accessToken}}"`); every other literal is a fixed default. Header
84
+ * names are always literal.
85
+ *
86
+ * Applies to GET as well as POST — headers are a transport concern, not a body
87
+ * concern. The resolved map is merged into
88
+ * {@link APIDataFetchingConfigurationInterface.httpHeaderOptions}`.headers`
89
+ * (the template wins on a name collision) before the request is issued.
90
+ *
91
+ * Like a payload template, a token that resolves empty keeps the fetch **idle**:
92
+ * a request that would go out without its `Authorization`/tenant header is a
93
+ * request that fails, so the engine waits for the bound field instead of issuing
94
+ * a doomed call.
95
+ *
96
+ * @example
97
+ * headerTemplate: {
98
+ * Authorization: 'Bearer {{accessToken}}',
99
+ * 'x-tenant-id': '{{municipality}}',
100
+ * 'Content-Type': 'application/json',
101
+ * }
102
+ */
103
+ export type HeaderTemplate = {
104
+ [headerName: string]: HeaderTemplateValue;
105
+ };
68
106
  export interface APIDataFetchingConfigurationInterface extends DataFetchingBaseConfig {
69
107
  _id: string;
70
108
  name: string;
@@ -89,6 +127,19 @@ export interface APIDataFetchingConfigurationInterface extends DataFetchingBaseC
89
127
  includeHeaders?: string[];
90
128
  } | boolean;
91
129
  };
130
+ /**
131
+ * Author-configured request headers, optionally bound to live form values (see
132
+ * {@link HeaderTemplate}). Merged over {@link httpHeaderOptions}`.headers` at
133
+ * request time; absent means "send exactly what `httpHeaderOptions` says",
134
+ * which is the historical behaviour.
135
+ */
136
+ headerTemplate?: HeaderTemplate;
137
+ /**
138
+ * The headers captured from the selected endpoint (e.g. the Postman request's
139
+ * enabled headers). Persisted only to seed {@link headerTemplate}'s editor so
140
+ * it never opens blank; never sent on its own.
141
+ */
142
+ capturedHeaders?: HeaderTemplate;
92
143
  backEndConfig: {
93
144
  /**
94
145
  * The default/mapTo mapping that shapes the POST body in `'mappedInputs'` mode.
@@ -1,17 +1,198 @@
1
1
  import { AllFormInputPrimaryKeys } from "../FormBuilder/FormInputKeys.js";
2
2
  import { TreeNode } from "../FormSlide/accessTree.js";
3
- import { APIDataFetchingConfigurationInterface, DataSources, MongoDbPipeLineConfigInterface } from "./APIDataFetchingConfigurationInterface.js";
3
+ import { FormInputBasicOptionInterface } from "./FormInputBasicOptionInterface.js";
4
4
  import { IBasicFormInput } from "./BasicFormInputInterface.js";
5
5
  export interface IWorkflowDocumentPicker extends IBasicFormInput {
6
6
  workflowPickerConfig: IWorkflowDocumentPickerConfig;
7
7
  [AllFormInputPrimaryKeys.AllowMultipleSelection]: boolean;
8
8
  }
9
+ /**
10
+ * Document-picker configuration.
11
+ *
12
+ * The only field an administrator must supply is `workflowId` — the table columns,
13
+ * the search schema, the sortable fields and the runtime step chooser are all
14
+ * derived from the selected workflow. Everything after it is optional and exists
15
+ * only to pin a picker to a narrower slice of transactions.
16
+ */
9
17
  export interface IWorkflowDocumentPickerConfig {
10
18
  workflowId: string;
11
19
  primaryIdentifierKey?: TreeNode[];
12
20
  sampleDocument?: Record<string, unknown>;
13
- documentSourceType: DataSources | 'default';
14
- documentsSource?: APIDataFetchingConfigurationInterface | MongoDbPipeLineConfigInterface;
21
+ /**
22
+ * Restricts the picker to transactions currently sitting on specific workflow
23
+ * steps. Omitted — or an empty `stepIds` — means every step is eligible and the
24
+ * end user gets a step chooser in the browse dialog.
25
+ */
26
+ stepFilter?: IWorkflowDocumentStepFilter;
27
+ /**
28
+ * Filters applied on top of the workflow scope before the user sees anything.
29
+ * Static values are baked in by the administrator; `fromFormControl` reads the
30
+ * value off a sibling control of the same form at query time.
31
+ */
32
+ presetFilters?: IDocumentPickerFilter[];
33
+ /**
34
+ * Step options captured when `workflowId` was chosen, so the builder can render
35
+ * a step multi-select without a live workflow round-trip. Refreshed whenever the
36
+ * workflow changes; the runtime step chooser always uses live steps, never this.
37
+ */
38
+ availableSteps?: FormInputBasicOptionInterface[];
39
+ }
40
+ /** Step restriction for a document picker. */
41
+ export interface IWorkflowDocumentStepFilter {
42
+ /**
43
+ * Workflow step ids (`currentStepID` values) the picker is limited to.
44
+ *
45
+ * Optional, because the whole step restriction is: the builder writes a
46
+ * `stepFilter` record as soon as the administrator opens that control, and an
47
+ * empty or absent list means "every step is eligible" — the same thing as
48
+ * omitting `stepFilter` altogether. The runtime already reads it as
49
+ * `stepFilter?.stepIds ?? []`.
50
+ */
51
+ stepIds?: string[];
52
+ }
53
+ /** Comparison operators a {@link IDocumentPickerFilter} may apply. */
54
+ export declare const DOCUMENT_PICKER_FILTER_OPERATORS: readonly ["eq", "ne", "in", "nin", "gt", "gte", "lt", "lte", "regex", "exists"];
55
+ /** Comparison operator applied by a {@link IDocumentPickerFilter}. */
56
+ export type DocumentPickerFilterOperator = typeof DOCUMENT_PICKER_FILTER_OPERATORS[number];
57
+ /** How a filter's configured value is coerced before it is sent. */
58
+ export declare const DOCUMENT_PICKER_FILTER_VALUE_TYPES: readonly ["string", "number", "boolean"];
59
+ /** Declared type of a {@link IDocumentPickerFilter} value. */
60
+ export type DocumentPickerFilterValueType = typeof DOCUMENT_PICKER_FILTER_VALUE_TYPES[number];
61
+ /** Where a {@link IDocumentPickerFilter} reads its comparison value from. */
62
+ export declare const DOCUMENT_PICKER_FILTER_VALUE_SOURCES: readonly ["fixed", "input"];
63
+ /** Declared value source of a {@link IDocumentPickerFilter}. */
64
+ export type DocumentPickerFilterValueSource = typeof DOCUMENT_PICKER_FILTER_VALUE_SOURCES[number];
65
+ /**
66
+ * One administrator-configured filter clause.
67
+ *
68
+ * Exactly one value source is used, chosen by `valueSource`: the static `value`
69
+ * (`'fixed'`) or the current value of a sibling input (`'input'`, via `fromInputId`).
70
+ * For the `in` / `nin` operators a static value is split on commas before coercion.
71
+ *
72
+ * @example
73
+ * // Only requisitions already approved
74
+ * { path: 'form.status', op: 'eq', valueSource: 'fixed', value: 'approved' }
75
+ *
76
+ * @example
77
+ * // Only transactions for the department chosen earlier in this form
78
+ * { path: 'form.departmentId', op: 'eq', valueSource: 'input', fromInputId: '9f2c…', omitWhenEmpty: true }
79
+ */
80
+ export interface IDocumentPickerFilter {
81
+ /**
82
+ * Stable identity of this clause, stamped by the builder's record-list editor the
83
+ * first time the filter is saved. It is the key that editor tracks a row by — for
84
+ * edit and for delete — so it is written to every persisted filter and has to
85
+ * round-trip through validation.
86
+ */
87
+ id?: string;
88
+ /**
89
+ * Document path to filter on. Form fields are addressed as `form.<name>`; the
90
+ * document root exposes `reference`, `status`, `currentStep` and `archive`.
91
+ */
92
+ path: string;
93
+ /** Comparison operator. Defaults to `eq` when omitted. */
94
+ op?: DocumentPickerFilterOperator;
95
+ /**
96
+ * Which of the two mutually exclusive value sources this clause uses.
97
+ *
98
+ * - `'fixed'` — use the static {@link IDocumentPickerFilter.value}, coerced by
99
+ * {@link IDocumentPickerFilter.valueType}. Any `fromInputId` is ignored.
100
+ * - `'input'` — use the current value of {@link IDocumentPickerFilter.fromInputId}.
101
+ * Any static `value` is ignored.
102
+ * - omitted — the source is inferred from what is set, so filters saved before
103
+ * this field existed keep working: a present `fromInputId` means `'input'`,
104
+ * otherwise `'fixed'`.
105
+ */
106
+ valueSource?: DocumentPickerFilterValueSource;
107
+ /**
108
+ * Static value supplied by the administrator. Used when `valueSource` is
109
+ * `'fixed'`, or — for filters saved before `valueSource` existed — when no
110
+ * `fromInputId` is set.
111
+ */
112
+ value?: unknown;
113
+ /** Coercion applied to the resolved value. Defaults to `string`. */
114
+ valueType?: DocumentPickerFilterValueType;
115
+ /**
116
+ * Id of a sibling input on the same form whose current value supplies the
117
+ * comparison value. The runtime form group is keyed by input id, not by
118
+ * form-control name. Used when `valueSource` is `'input'`, or — for filters
119
+ * saved before `valueSource` existed — whenever it is set.
120
+ */
121
+ fromInputId?: string;
122
+ /**
123
+ * Drops the clause entirely when the resolved value is empty, instead of matching
124
+ * on an empty value. Only meaningful for the input-bound source.
125
+ */
126
+ omitWhenEmpty?: boolean;
127
+ }
128
+ /**
129
+ * A single page of documents.
130
+ *
131
+ * Cursor-native: `nextCursor` drives forward navigation, and `totalItems` /
132
+ * `totalPages` are populated only on the first page — the request that carried no
133
+ * cursor — because the count scan is skipped on continuation pages. Cache the totals
134
+ * client-side rather than expecting them on every page.
135
+ */
136
+ export interface IDocumentPage {
137
+ items: Record<string, unknown>[];
138
+ /** Effective page size applied, which may be clamped below the requested size. */
139
+ itemsPerPage: number;
140
+ /** `true` when another page exists after this one. */
141
+ hasMore: boolean;
142
+ /** Token to send back as `cursor` for the next page, or `null` at the end. */
143
+ nextCursor: string | null;
144
+ /** Total records matching the query. First page only. */
145
+ totalItems?: number;
146
+ /** Total page count for the query. First page only. */
147
+ totalPages?: number;
148
+ }
149
+ /**
150
+ * The one request shape every document-picker query uses.
151
+ *
152
+ * Sort and filter keys are document paths, not form-control names: root fields
153
+ * (`updatedAt`, `reference`, `currentStep`, `archive`) stay as they are, while form
154
+ * fields are addressed as `form.<name>`.
155
+ */
156
+ export interface IDocumentQueryRequest {
157
+ workflowId: string;
158
+ itemsPerPage: number;
159
+ /** Omit for the first page; otherwise the previous page's `nextCursor`. */
160
+ cursor?: string;
161
+ /**
162
+ * Sort descriptor. Only the first entry is honoured, and `_id` is appended as a
163
+ * tiebreaker. Must stay identical across a cursor sequence — changing it
164
+ * invalidates every outstanding cursor, so reset paging when the sort changes.
165
+ */
166
+ sort: Record<string, 1 | -1>;
167
+ /**
168
+ * Merged step, preset and user filters. `_id: { $in: [...] }` is how a selection
169
+ * spanning several pages is hydrated in one request.
170
+ */
171
+ filter: Record<string, unknown>;
172
+ /**
173
+ * Free-text term. Requires {@link IDocumentQueryRequest.schema}: without it the
174
+ * term is silently ignored and an unfiltered page comes back.
175
+ */
176
+ searchKey?: string;
177
+ /** Path → type map scoping which fields `searchKey` searches. */
178
+ schema?: Record<string, string>;
179
+ }
180
+ /**
181
+ * The value a document picker writes to its form control — one entry per linked
182
+ * transaction, or a single entry when the input is not multi-select.
183
+ *
184
+ * Carries enough context to render the link without re-reading the builder config or
185
+ * re-fetching the document.
186
+ */
187
+ export interface IDocumentReference {
188
+ /** Value of the picker's primary identifier key — `_id` unless configured otherwise. */
189
+ id: string;
190
+ /** Workflow the transaction belongs to. */
191
+ workflowId: string;
192
+ /** Human-facing transaction reference, e.g. `REQ-00412`. */
193
+ reference?: string;
194
+ /** Short descriptive label drawn from the workflow's first configured column. */
195
+ label?: string;
15
196
  }
16
197
  export declare enum workflowStepStatus {
17
198
  PENDING = "pending",
@@ -1,4 +1,21 @@
1
1
  import { AllFormInputPrimaryKeys } from "../FormBuilder/FormInputKeys.js";
2
+ /** Comparison operators a {@link IDocumentPickerFilter} may apply. */
3
+ export const DOCUMENT_PICKER_FILTER_OPERATORS = [
4
+ 'eq',
5
+ 'ne',
6
+ 'in',
7
+ 'nin',
8
+ 'gt',
9
+ 'gte',
10
+ 'lt',
11
+ 'lte',
12
+ 'regex',
13
+ 'exists',
14
+ ];
15
+ /** How a filter's configured value is coerced before it is sent. */
16
+ export const DOCUMENT_PICKER_FILTER_VALUE_TYPES = ['string', 'number', 'boolean'];
17
+ /** Where a {@link IDocumentPickerFilter} reads its comparison value from. */
18
+ export const DOCUMENT_PICKER_FILTER_VALUE_SOURCES = ['fixed', 'input'];
2
19
  export var workflowStepStatus;
3
20
  (function (workflowStepStatus) {
4
21
  workflowStepStatus["PENDING"] = "pending";
@@ -1,7 +1,7 @@
1
1
  import { IFolderItem, IPostmanCollection } from "../FormBuilder/postmanCollection.js";
2
- import { IWorkflowDocListCols } from "../FormBuilder/workflowSelectionConfig.js";
2
+ import { IWorkflowDocListCols, IWorkflowStepOption } from "../FormBuilder/workflowSelectionConfig.js";
3
3
  import { TreeNode } from "../FormSlide/accessTree.js";
4
- import { APIDataFetchingConfigurationInterface, InputAPIDataId, MongoDbPipeLineConfigInterface, PayloadTemplate, PayloadTemplateValue, RequestBodyMode } from "./APIDataFetchingConfigurationInterface.js";
4
+ import { APIDataFetchingConfigurationInterface, HeaderTemplate, HeaderTemplateValue, InputAPIDataId, MongoDbPipeLineConfigInterface, PayloadTemplate, PayloadTemplateValue, RequestBodyMode } from "./APIDataFetchingConfigurationInterface.js";
5
5
  import { AutocapitalizeOptions, AutocompleteOptions, ElementTypes, IBasicFormInput, IFormElementTemplate, InputDataTypes, InputPipeTypes, InputTypes, OptionSelectTypes } from "./BasicFormInputInterface.js";
6
6
  import { IDateRangePickerInput } from "./DateRangePickerInput.js";
7
7
  import { AllDocumentFileExtensions, AllImageFileExtensions, FileUploadInputValueInterface, IFileUploadInput, InputFileType, UploadTypes } from "./FileUploadInputInterface.js";
@@ -19,10 +19,10 @@ import { TableColumnConfigInterface, TableConfigurationsInterface } from "./Tabl
19
19
  import { ITextareaProperties } from "./TextAreaInput.js";
20
20
  import { IToggleInput } from "./ToggleInputInterface.js";
21
21
  import { AdjResponseReviewColumnMapping, AdjudicationSteps, IWorkflowAdjudicationInput, WorkflowAdjudicationMicroFlowReviewValue, WorkflowAdjudicationResponseElectedSupplierSelectionValue, WorkflowAdjudicationScoreSheetValue } from "./WorkflowAdjudication.js";
22
- import { IWorkflowDocumentPicker, IWorkflowDocumentPickerConfig, workflowStepStatus } from "./WorkflowDocumentPicker.js";
22
+ import { DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES, DocumentPickerFilterOperator, DocumentPickerFilterValueSource, DocumentPickerFilterValueType, IDocumentPage, IDocumentPickerFilter, IDocumentQueryRequest, IDocumentReference, IWorkflowDocumentPicker, IWorkflowDocumentPickerConfig, IWorkflowDocumentStepFilter, workflowStepStatus } from "./WorkflowDocumentPicker.js";
23
23
  import { CalculatedFieldRules } from "./calculatedFieldRules.js";
24
24
  import { CalculationFunctions, calculationVariableInterface } from "./calculationVariableInterface.js";
25
25
  import { IRichTextEditor, RichTextEditorType } from "./RichTextEditorInput.js";
26
26
  import { ValidationError, ValidationOptions } from "./schema.js";
27
27
  import { IUserSignature } from "./userSignature.js";
28
- export { ElementTypes, InputTypes, InputPipeTypes, AutocapitalizeOptions, AutocompleteOptions, InputDataTypes, MinInputTypes, IFormElementTemplate, IBasicFormInput, IFileUploadInput, IDateRangePickerInput, ITextareaProperties, IToggleInput, IMatrixInput, IMultiple, IMultipleInputCal, IScoaInput, TableConfigurationsInterface, TableColumnConfigInterface, FormControlCustomValidatorsInterface, InputObservedForChange, DraftFormControlCustomValidator, IFormValidationOverride, MinimumInputRequiredInterface, MinInputMapInput, CalculatedFieldRules, calculationVariableInterface, APIDataFetchingConfigurationInterface, PayloadTemplate, PayloadTemplateValue, RequestBodyMode, IGetTreeResponse, CalculationFunctions, TreeNode, IPostmanCollection, IFolderItem, FileUploadInputValueInterface, AllDocumentFileExtensions, AllImageFileExtensions, UploadTypes, InputFileType, IScoaAccount, IScoaInputConfig, ITableScoaSelectionRow, ScoaSegmentValue, ScoaSegmentValueBag, IIncludedSegmentConfig, AccountingBasis, ScoaAccountTree, IUserSignature, ValidationOptions, ValidationError, MatDataOptionsInterface, MongoDbPipeLineConfigInterface, InputAPIDataId, FormInputBasicOptionInterface, ScoaInterface, ScoaInnerInput, IAccountSegmentTreeKeys, IWorkflowDocumentPicker, IWorkflowDocumentPickerConfig, workflowStepStatus, IWorkflowDocListCols, JsDataTypes, AdjudicationSteps, IWorkflowAdjudicationInput, WorkflowAdjudicationScoreSheetValue, WorkflowAdjudicationMicroFlowReviewValue, WorkflowAdjudicationResponseElectedSupplierSelectionValue, ScoreSheetItem, AdjResponseReviewColumnMapping, OptionSelectTypes, ISelectInputInterface, MultipleInputAvailableOperations, RichTextEditorType, IRichTextEditor, };
28
+ export { ElementTypes, InputTypes, InputPipeTypes, AutocapitalizeOptions, AutocompleteOptions, InputDataTypes, MinInputTypes, IFormElementTemplate, IBasicFormInput, IFileUploadInput, IDateRangePickerInput, ITextareaProperties, IToggleInput, IMatrixInput, IMultiple, IMultipleInputCal, IScoaInput, TableConfigurationsInterface, TableColumnConfigInterface, FormControlCustomValidatorsInterface, InputObservedForChange, DraftFormControlCustomValidator, IFormValidationOverride, MinimumInputRequiredInterface, MinInputMapInput, CalculatedFieldRules, calculationVariableInterface, APIDataFetchingConfigurationInterface, PayloadTemplate, PayloadTemplateValue, RequestBodyMode, HeaderTemplate, HeaderTemplateValue, IGetTreeResponse, CalculationFunctions, TreeNode, IPostmanCollection, IFolderItem, FileUploadInputValueInterface, AllDocumentFileExtensions, AllImageFileExtensions, UploadTypes, InputFileType, IScoaAccount, IScoaInputConfig, ITableScoaSelectionRow, ScoaSegmentValue, ScoaSegmentValueBag, IIncludedSegmentConfig, AccountingBasis, ScoaAccountTree, IUserSignature, ValidationOptions, ValidationError, MatDataOptionsInterface, MongoDbPipeLineConfigInterface, InputAPIDataId, FormInputBasicOptionInterface, ScoaInterface, ScoaInnerInput, IAccountSegmentTreeKeys, IWorkflowDocumentPicker, IWorkflowDocumentPickerConfig, IWorkflowDocumentStepFilter, IDocumentPickerFilter, IDocumentPage, IDocumentQueryRequest, IDocumentReference, DocumentPickerFilterOperator, DocumentPickerFilterValueSource, DocumentPickerFilterValueType, DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES, workflowStepStatus, IWorkflowDocListCols, IWorkflowStepOption, JsDataTypes, AdjudicationSteps, IWorkflowAdjudicationInput, WorkflowAdjudicationScoreSheetValue, WorkflowAdjudicationMicroFlowReviewValue, WorkflowAdjudicationResponseElectedSupplierSelectionValue, ScoreSheetItem, AdjResponseReviewColumnMapping, OptionSelectTypes, ISelectInputInterface, MultipleInputAvailableOperations, RichTextEditorType, IRichTextEditor, };
@@ -4,7 +4,7 @@ import { AccountingBasis } from "./IMscoaAccount.js";
4
4
  import { JsDataTypes, MinInputTypes } from "./MinimumInputRequiredInterface.js";
5
5
  import { MultipleInputAvailableOperations } from "./MultipleInterface.js";
6
6
  import { AdjudicationSteps } from "./WorkflowAdjudication.js";
7
- import { workflowStepStatus } from "./WorkflowDocumentPicker.js";
7
+ import { DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES, workflowStepStatus, } from "./WorkflowDocumentPicker.js";
8
8
  import { CalculationFunctions } from "./calculationVariableInterface.js";
9
9
  import { RichTextEditorType } from "./RichTextEditorInput.js";
10
10
  // H-018b (Worker T-C): `OLD_FormInterface` and `FormInterfaceMigration` are
@@ -14,4 +14,4 @@ import { RichTextEditorType } from "./RichTextEditorInput.js";
14
14
  // would otherwise trigger TS2300 "Duplicate identifier".
15
15
  export {
16
16
  ///ENUMS
17
- ElementTypes, InputTypes, InputPipeTypes, AutocapitalizeOptions, AutocompleteOptions, InputDataTypes, MinInputTypes, CalculationFunctions, AllDocumentFileExtensions, AllImageFileExtensions, UploadTypes, InputFileType, AccountingBasis, workflowStepStatus, JsDataTypes, AdjudicationSteps, OptionSelectTypes, MultipleInputAvailableOperations, RichTextEditorType, };
17
+ ElementTypes, InputTypes, InputPipeTypes, AutocapitalizeOptions, AutocompleteOptions, InputDataTypes, MinInputTypes, CalculationFunctions, AllDocumentFileExtensions, AllImageFileExtensions, UploadTypes, InputFileType, AccountingBasis, DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES, workflowStepStatus, JsDataTypes, AdjudicationSteps, OptionSelectTypes, MultipleInputAvailableOperations, RichTextEditorType, };
@@ -1,3 +1,5 @@
1
1
  import Joi from 'joi';
2
+ declare const documentPickerFilterSchema: Joi.ObjectSchema<any>;
3
+ declare const workflowDocumentStepFilterSchema: Joi.ObjectSchema<any>;
2
4
  declare const workflowDocumentPickerConfigSchema: Joi.ObjectSchema<any>;
3
- export { workflowDocumentPickerConfigSchema };
5
+ export { workflowDocumentPickerConfigSchema, documentPickerFilterSchema, workflowDocumentStepFilterSchema };
@@ -1,12 +1,40 @@
1
1
  import Joi from 'joi';
2
- import { APIDataFetchingConfigurationSchema, MongoDbPipeLineConfigSchema } from './MatOptionsSchema.js';
3
- import { DataSources } from '../interfaces/FormBuilder/index.js';
2
+ import { DOCUMENT_PICKER_FILTER_OPERATORS, DOCUMENT_PICKER_FILTER_VALUE_SOURCES, DOCUMENT_PICKER_FILTER_VALUE_TYPES, } from '../interfaces/formInput/WorkflowDocumentPicker.js';
3
+ // Schema for IDocumentPickerFilter
4
+ const documentPickerFilterSchema = Joi.object({
5
+ // The record-list editor stamps an id on every filter it saves and tracks the row
6
+ // by it, so a persisted filter always carries one. Rejecting it made every saved
7
+ // preset filter fail validation on the next open.
8
+ id: Joi.string().optional(),
9
+ path: Joi.string().required(),
10
+ op: Joi.string().valid(...DOCUMENT_PICKER_FILTER_OPERATORS).optional(),
11
+ // Optional: absent means "infer from what is set", so filters saved before
12
+ // `valueSource` existed still validate.
13
+ valueSource: Joi.string().valid(...DOCUMENT_PICKER_FILTER_VALUE_SOURCES).optional(),
14
+ value: Joi.any().optional(),
15
+ valueType: Joi.string().valid(...DOCUMENT_PICKER_FILTER_VALUE_TYPES).optional(),
16
+ fromInputId: Joi.string().allow('').optional(),
17
+ omitWhenEmpty: Joi.boolean().optional(),
18
+ });
19
+ // Schema for IWorkflowDocumentStepFilter
20
+ const workflowDocumentStepFilterSchema = Joi.object({
21
+ // Optional, because the step restriction itself is. The builder writes a stepFilter
22
+ // record as soon as the administrator opens that control, so requiring stepIds made
23
+ // "I looked at the step chooser and picked nothing" a validation failure. An empty
24
+ // or absent list means every step is eligible — what the runtime already assumes
25
+ // via `stepFilter?.stepIds ?? []`.
26
+ stepIds: Joi.array().items(Joi.string()).optional(),
27
+ });
4
28
  // Schema for IWorkflowDocumentPickerConfig
5
29
  const workflowDocumentPickerConfigSchema = Joi.object({
6
30
  workflowId: Joi.string().required(),
7
31
  primaryIdentifierKey: Joi.array().items(Joi.object()).optional(),
8
32
  sampleDocument: Joi.object().optional(), // Optional field for sample document structure
9
- documentSourceType: Joi.string().valid(...Object.values(DataSources), 'default').required(),
10
- documentsSource: Joi.alternatives().try(APIDataFetchingConfigurationSchema, MongoDbPipeLineConfigSchema, Joi.object()).optional(),
33
+ stepFilter: workflowDocumentStepFilterSchema.optional(),
34
+ presetFilters: Joi.array().items(documentPickerFilterSchema).optional(),
35
+ availableSteps: Joi.array().items(Joi.object({
36
+ label: Joi.string().optional(),
37
+ value: Joi.string().required(),
38
+ })).optional(),
11
39
  });
12
- export { workflowDocumentPickerConfigSchema };
40
+ export { workflowDocumentPickerConfigSchema, documentPickerFilterSchema, workflowDocumentStepFilterSchema };
@@ -22,6 +22,8 @@ const minimumInputRequiredSchema = Joi.object({
22
22
  activeChangeId: Joi.string().optional(),
23
23
  primaryKey: Joi.boolean().optional()
24
24
  });
25
+ /** A flat `header name → scalar value` map (see `HeaderTemplate`). */
26
+ const headerTemplateSchema = Joi.object().pattern(Joi.string(), Joi.alternatives().try(Joi.string().allow(''), Joi.number(), Joi.boolean()));
25
27
  const APIDataFetchingConfigurationSchema = Joi.object({
26
28
  _id: Joi.string().required(),
27
29
  name: Joi.string().required(),
@@ -42,6 +44,12 @@ const APIDataFetchingConfigurationSchema = Joi.object({
42
44
  withCredentials: Joi.boolean().optional(),
43
45
  transferCache: Joi.alternatives().try(Joi.object({ includeHeaders: Joi.array().items(Joi.string()).optional() }), Joi.boolean()).optional()
44
46
  }).optional(),
47
+ // Author-configured headers, values optionally carrying {{inputId}} tokens bound to
48
+ // live form values. Flat by construction — a header value is text on the wire, so
49
+ // only scalars are accepted (numbers/booleans are stringified at request time).
50
+ headerTemplate: headerTemplateSchema.optional(),
51
+ // Headers captured from the selected endpoint; seeds the editor, never sent alone.
52
+ capturedHeaders: headerTemplateSchema.optional(),
45
53
  backEndConfig: Joi.object({
46
54
  // Optional: a 'template'-mode fetch shapes its body from payloadTemplate and
47
55
  // carries no mapping; GET fetches never had one. Readers default it to [].
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngx-t-forms-types",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "Typings and interfaces for the ngx-t-forms library for dynamic forms.",
5
5
  "keywords": [
6
6
  "typings",