pict-section-form 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +2 -2
- package/package.json +6 -2
- package/source/providers/Pict-Provider-Informary.js +22 -21
- package/test/Pict-Provider-Informary-RenderSelector_tests.js +145 -0
- package/test/Pict-Provider-Informary_tests.js +111 -0
- package/test/PictSectionForm-Basic_tests.js +3 -0
- package/tsconfig.build.json +16 -0
- package/tsconfig.json +1 -1
- package/types/source/providers/Pict-Provider-DynamicTabularData.d.ts +33 -0
- package/types/source/providers/Pict-Provider-DynamicTabularData.d.ts.map +1 -1
- package/types/source/providers/Pict-Provider-Informary.d.ts +12 -13
- package/types/source/providers/Pict-Provider-Informary.d.ts.map +1 -1
- package/types/source/providers/layouts/Pict-Layout-Custom.d.ts.map +1 -1
- package/types/source/providers/layouts/Pict-Layout-Record.d.ts.map +1 -1
- package/types/source/providers/layouts/Pict-Layout-Tabular.d.ts +202 -0
- package/types/source/providers/layouts/Pict-Layout-Tabular.d.ts.map +1 -1
- package/types/source/providers/layouts/Pict-Layout-VerticalRecord.d.ts.map +1 -1
- package/types/source/services/ManifestFactory.d.ts +2 -1
- package/types/source/services/ManifestFactory.d.ts.map +1 -1
package/eslint.config.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import pluginJs from "@eslint/js";
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
export default [
|
|
6
|
-
{ files: ["source/**"], languageOptions: { sourceType: "commonjs" } },
|
|
7
|
-
{ languageOptions: { globals: { ...globals.browser, ...globals.mocha, } } },
|
|
6
|
+
{ files: ["source/**", "test/**"], languageOptions: { sourceType: "commonjs" } },
|
|
7
|
+
{ languageOptions: { globals: { ...globals.browser, ...globals.mocha, ...globals.node, } } },
|
|
8
8
|
pluginJs.configs.recommended,
|
|
9
9
|
{ rules: { "no-prototype-builtins": "off", "no-unused-vars": "warn", "no-case-declarations": "warn" } },
|
|
10
10
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pict-section-form",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "Pict dynamic form sections",
|
|
5
5
|
"main": "source/Pict-Section-Form.js",
|
|
6
6
|
"directories": {
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"build": "npx quack build",
|
|
22
22
|
"test": "npx quack test",
|
|
23
23
|
"lint": "eslint source/**",
|
|
24
|
-
"types": "tsc -p .",
|
|
24
|
+
"types": "tsc -p ./tsconfig.build.json",
|
|
25
|
+
"check": "tsc -p ./tsconfig.json --noEmit",
|
|
25
26
|
"docker-dev-build": "docker build ./ -f Dockerfile_LUXURYCode -t pict-section-form-image:local",
|
|
26
27
|
"docker-dev-run": "docker run -it -d --name pict-section-form-dev -p 48888:8080 -p 49999:9999 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/pict-section-form\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" pict-section-form-image:local",
|
|
27
28
|
"docker-dev-shell": "docker exec -it pict-section-form-dev /bin/bash"
|
|
@@ -31,6 +32,9 @@
|
|
|
31
32
|
"license": "MIT",
|
|
32
33
|
"devDependencies": {
|
|
33
34
|
"@eslint/js": "^9.39.2",
|
|
35
|
+
"@types/chai": "^4.3.20",
|
|
36
|
+
"@types/mocha": "^10.0.10",
|
|
37
|
+
"@types/node": "^22.19.21",
|
|
34
38
|
"browser-env": "^3.3.0",
|
|
35
39
|
"eslint": "^9.39.2",
|
|
36
40
|
"jquery": "^4.0.0",
|
|
@@ -96,7 +96,7 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
96
96
|
*
|
|
97
97
|
* @param {object} pAppStateData - The application state data object to marshal the form data to.
|
|
98
98
|
* @param {string} pFormHash - The form hash representing the form elements.
|
|
99
|
-
* @param {
|
|
99
|
+
* @param {import('manyfest')} pManifest - The manifest object used to map form data to the application state data.
|
|
100
100
|
* @param {string} [pDatum] - The datum hash to pull in. If not provided, all data is marshalled.
|
|
101
101
|
* @param {number|string} [pRecordIndex] - The record index to pull in. If not provided, all data is marshalled.
|
|
102
102
|
*/
|
|
@@ -120,19 +120,19 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
120
120
|
* Marshals a specific form element's data to the application state data.
|
|
121
121
|
*
|
|
122
122
|
* @param {string} pFormHash - The hash of the form.
|
|
123
|
-
* @param {HTMLElement}
|
|
124
|
-
* @param {
|
|
123
|
+
* @param {HTMLElement} pFormElement - The form element to marshal.
|
|
124
|
+
* @param {import('manyfest')} pManifest - The manifest object to set values.
|
|
125
125
|
* @param {Object} pAppStateData - The application state data object.
|
|
126
126
|
* @param {any} [pDatumFilter] - Optional filter for datum address.
|
|
127
127
|
* @param {any} [pRecordIndexFilter] - Optional filter for record index.
|
|
128
128
|
* @returns {boolean} - Returns false if the element falls outside the filters or if the browser value is null.
|
|
129
129
|
*/
|
|
130
|
-
marshalSpecicificFormElementToData(pFormHash,
|
|
130
|
+
marshalSpecicificFormElementToData(pFormHash, pFormElement, pManifest, pAppStateData, pDatumFilter, pRecordIndexFilter)
|
|
131
131
|
{
|
|
132
|
-
const tmpDatumAddress =
|
|
132
|
+
const tmpDatumAddress = pFormElement.getAttribute('data-i-datum');
|
|
133
133
|
|
|
134
|
-
const tmpContainerAddress =
|
|
135
|
-
const tmpIndex =
|
|
134
|
+
const tmpContainerAddress = pFormElement.getAttribute('data-i-container');
|
|
135
|
+
const tmpIndex = pFormElement.getAttribute('data-i-index');
|
|
136
136
|
|
|
137
137
|
// Process the filters
|
|
138
138
|
// TODO: Now that this is a function, having these filters here is not good. We need to move this to the caller. But the above getAttribute is required... rethink filtering?
|
|
@@ -160,13 +160,14 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
160
160
|
|
|
161
161
|
if (!tmpContainerAddress)
|
|
162
162
|
{
|
|
163
|
-
|
|
163
|
+
pManifest.setValueAtAddress(pAppStateData, tmpDatumAddress, tmpBrowserValue);
|
|
164
164
|
}
|
|
165
165
|
else
|
|
166
166
|
{
|
|
167
167
|
// Compose the address .. right now only arrays
|
|
168
|
-
|
|
169
|
-
}
|
|
168
|
+
pManifest.setValueAtAddress(pAppStateData, this.getComposedContainerAddress(tmpContainerAddress, tmpIndex, tmpDatumAddress), tmpBrowserValue);
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
170
171
|
}
|
|
171
172
|
|
|
172
173
|
/**
|
|
@@ -174,7 +175,7 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
174
175
|
*
|
|
175
176
|
* @param {object} pAppStateData - The application state data to marshal into the form. Usually AppData but can be other objects.
|
|
176
177
|
* @param {string} pFormHash - The hash of the form to marshal data into. This is the data-i-form attribute.
|
|
177
|
-
* @param {
|
|
178
|
+
* @param {import('manyfest')} pManifest - The manifest object. If not provided, the generic manifest is used.
|
|
178
179
|
*/
|
|
179
180
|
marshalDataToForm(pAppStateData, pFormHash, pManifest)
|
|
180
181
|
{
|
|
@@ -185,20 +186,19 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
185
186
|
// Enumerate the form elements, and put data in them for each address
|
|
186
187
|
for (let i = 0; i < tmpFormElements.length; i++)
|
|
187
188
|
{
|
|
188
|
-
this.marshalSpecificElementDataToForm(
|
|
189
|
+
this.marshalSpecificElementDataToForm(tmpFormElements[i], tmpManifest, pAppStateData);
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
/**
|
|
193
194
|
* Marshals specific element data to a form.
|
|
194
195
|
*
|
|
195
|
-
* @param {string} pFormHash - The hash of the form.
|
|
196
196
|
* @param {HTMLElement} pFormElement - The form element to marshal data to.
|
|
197
|
-
* @param {
|
|
198
|
-
* @param {
|
|
197
|
+
* @param {import('manyfest')} pManifest - The manifest object containing data retrieval methods.
|
|
198
|
+
* @param {Record<string, any>} pAppStateData - The application state data.
|
|
199
199
|
* @returns {boolean} Returns false if the form element does not have a datum address.
|
|
200
200
|
*/
|
|
201
|
-
marshalSpecificElementDataToForm(
|
|
201
|
+
marshalSpecificElementDataToForm(pFormElement, pManifest, pAppStateData)
|
|
202
202
|
{
|
|
203
203
|
let tmpDatumAddress = pFormElement.getAttribute('data-i-datum');
|
|
204
204
|
|
|
@@ -213,7 +213,7 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
213
213
|
|
|
214
214
|
if (!tmpContainerAddress)
|
|
215
215
|
{
|
|
216
|
-
let tmpAppStateValue =
|
|
216
|
+
let tmpAppStateValue = pManifest.getValueAtAddress(pAppStateData, tmpDatumAddress);
|
|
217
217
|
|
|
218
218
|
if (this.pict.LogNoisiness > 3)
|
|
219
219
|
{
|
|
@@ -222,12 +222,12 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
222
222
|
|
|
223
223
|
if (tmpAppStateValue != null)
|
|
224
224
|
{
|
|
225
|
-
this.pict.ContentAssignment.assignContent(
|
|
225
|
+
this.pict.ContentAssignment.assignContent(pFormElement, tmpAppStateValue);
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
else
|
|
229
229
|
{
|
|
230
|
-
let tmpAppStateValue =
|
|
230
|
+
let tmpAppStateValue = pManifest.getValueAtAddress(pAppStateData, this.getComposedContainerAddress(tmpContainerAddress, tmpIndex, tmpDatumAddress));
|
|
231
231
|
|
|
232
232
|
if (this.pict.LogNoisiness > 3)
|
|
233
233
|
{
|
|
@@ -236,14 +236,15 @@ class PictDynamicFormsInformary extends libPictProvider
|
|
|
236
236
|
|
|
237
237
|
if (tmpAppStateValue != null)
|
|
238
238
|
{
|
|
239
|
-
this.pict.ContentAssignment.assignContent(
|
|
239
|
+
this.pict.ContentAssignment.assignContent(pFormElement, tmpAppStateValue);
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
|
+
return true;
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
/**
|
|
245
246
|
* Manually marshals data to a form by assigning content based on context in the descriptor.
|
|
246
|
-
* @param {
|
|
247
|
+
* @param {Record<string, any>} pInput - The input manifest descriptor to marshal data to form from.
|
|
247
248
|
* @returns boolean if assignment was successful
|
|
248
249
|
*/
|
|
249
250
|
manualMarshalDataToFormByInput(pInput)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Regression guard for the Informary "assign straight to the element" marshal optimization
|
|
3
|
+
(marshalSpecificElementDataToForm assigns to pFormElement directly instead of re-resolving a
|
|
4
|
+
selector built from that element's own data-i-* attributes — a per-cell full-document scan).
|
|
5
|
+
|
|
6
|
+
That optimization is only correct because the selector getContentBrowserAddress() builds is
|
|
7
|
+
UNIQUE — it resolves to exactly the one element being marshalled. This test renders a real form
|
|
8
|
+
(non-tabular fields + a multi-row tabular group) into a jsdom DOM and asserts, for EVERY
|
|
9
|
+
datum-bound cell, that the actual getContentBrowserAddress() output resolves to exactly that
|
|
10
|
+
element. If a future template change makes the (form, datum, container, index) tuple non-unique,
|
|
11
|
+
the marshal would write to the wrong/extra element — and this test fails.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const libBrowserEnv = require('browser-env');
|
|
15
|
+
libBrowserEnv();
|
|
16
|
+
|
|
17
|
+
const Chai = require('chai');
|
|
18
|
+
const Expect = Chai.expect;
|
|
19
|
+
|
|
20
|
+
const libPict = require('pict');
|
|
21
|
+
const libPictSectionForm = require('../source/Pict-Section-Form.js');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {(pict: libPict) => void} fOnReady
|
|
25
|
+
*/
|
|
26
|
+
function buildRenderedForm(fOnReady)
|
|
27
|
+
{
|
|
28
|
+
const tmpManifest =
|
|
29
|
+
{
|
|
30
|
+
Scope: 'InformarySelectorForm',
|
|
31
|
+
Descriptors:
|
|
32
|
+
{
|
|
33
|
+
Title: { Name: 'Title', Hash: 'Title', DataType: 'String', PictForm: { Section: 'Sheet', Group: 'Meta', InputType: 'Text' } },
|
|
34
|
+
Teacher: { Name: 'Teacher', Hash: 'Teacher', DataType: 'String', PictForm: { Section: 'Sheet', Group: 'Meta', InputType: 'Text' } }
|
|
35
|
+
},
|
|
36
|
+
Sections:
|
|
37
|
+
[
|
|
38
|
+
{
|
|
39
|
+
Hash: 'Sheet', Name: 'Sheet', Groups:
|
|
40
|
+
[
|
|
41
|
+
{ Hash: 'Meta', Name: 'Meta' },
|
|
42
|
+
{ Hash: 'Grades', Name: 'Grades', Layout: 'Tabular', RecordSetAddress: 'Grades', RecordManifest: 'GradeRow' }
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
ReferenceManifests:
|
|
47
|
+
{
|
|
48
|
+
GradeRow:
|
|
49
|
+
{
|
|
50
|
+
Scope: 'GradeRow',
|
|
51
|
+
Descriptors:
|
|
52
|
+
{
|
|
53
|
+
StudentName: { Name: 'Student', Hash: 'StudentName', DataType: 'String', PictForm: { Section: 'Sheet', Group: 'Grades', InputType: 'Text' } },
|
|
54
|
+
Score: { Name: 'Score', Hash: 'Score', DataType: 'Number', PictForm: { Section: 'Sheet', Group: 'Grades', InputType: 'Text' } }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const tmpAppData =
|
|
60
|
+
{
|
|
61
|
+
Title: 'Term 1', Teacher: 'Ms. Frizzle',
|
|
62
|
+
Grades:
|
|
63
|
+
[
|
|
64
|
+
{ StudentName: 'Alice', Score: 95 },
|
|
65
|
+
{ StudentName: 'Bob', Score: 80 },
|
|
66
|
+
{ StudentName: 'Carol', Score: 60 },
|
|
67
|
+
{ StudentName: 'Dan', Score: 72 }
|
|
68
|
+
]
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
class TestApp extends libPictSectionForm.PictFormApplication
|
|
72
|
+
{
|
|
73
|
+
onAfterInitialize() { this.solve(); return super.onAfterInitialize(); }
|
|
74
|
+
}
|
|
75
|
+
TestApp.default_configuration = JSON.parse(JSON.stringify(libPictSectionForm.PictFormApplication.default_configuration));
|
|
76
|
+
TestApp.default_configuration.pict_configuration =
|
|
77
|
+
{
|
|
78
|
+
Product: 'InformarySelectorTest',
|
|
79
|
+
DefaultAppData: tmpAppData,
|
|
80
|
+
DefaultFormManifest: tmpManifest
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
document.body.innerHTML = '<div id="Pict-Form-Container"></div>';
|
|
84
|
+
const _Pict = new libPict(TestApp.default_configuration.pict_configuration);
|
|
85
|
+
_Pict.LogNoisiness = 0;
|
|
86
|
+
_Pict.addApplication('InformarySelectorTest', TestApp.default_configuration, TestApp);
|
|
87
|
+
_Pict.PictApplication.initializeAsync(() =>
|
|
88
|
+
{
|
|
89
|
+
// browser-env doesn't drive the render cycle on init; render the form views explicitly so
|
|
90
|
+
// the data-i-* cells land in the DOM.
|
|
91
|
+
Object.keys(_Pict.views).forEach((pHash) =>
|
|
92
|
+
{
|
|
93
|
+
const tmpView = _Pict.views[pHash];
|
|
94
|
+
if (tmpView && tmpView.isPictSectionForm)
|
|
95
|
+
{
|
|
96
|
+
try { tmpView.render(); }
|
|
97
|
+
catch (pError) { /* a view that can't render in jsdom is fine; we assert on what did */ }
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
fOnReady(_Pict);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
suite('Pict Provider Informary — render-time selector uniqueness', () =>
|
|
105
|
+
{
|
|
106
|
+
test('getContentBrowserAddress resolves to EXACTLY its own element for every datum cell', (fDone) =>
|
|
107
|
+
{
|
|
108
|
+
buildRenderedForm((_Pict) =>
|
|
109
|
+
{
|
|
110
|
+
try
|
|
111
|
+
{
|
|
112
|
+
const tmpInformary = _Pict.providers.Informary;
|
|
113
|
+
const tmpElements = document.querySelectorAll('[data-i-form][data-i-datum]');
|
|
114
|
+
// Guard against a vacuous pass (render produced no cells).
|
|
115
|
+
Expect(tmpElements.length).to.be.greaterThan(6, 'the form rendered its datum cells to the DOM');
|
|
116
|
+
|
|
117
|
+
let tmpTabularChecked = 0;
|
|
118
|
+
let tmpNonTabularChecked = 0;
|
|
119
|
+
tmpElements.forEach((pElement) =>
|
|
120
|
+
{
|
|
121
|
+
const tmpForm = pElement.getAttribute('data-i-form');
|
|
122
|
+
const tmpDatum = pElement.getAttribute('data-i-datum');
|
|
123
|
+
const tmpContainer = pElement.getAttribute('data-i-container');
|
|
124
|
+
const tmpIndexRaw = pElement.getAttribute('data-i-index');
|
|
125
|
+
// Mirror the marshal: tmpIndex = Number(getAttribute('data-i-index')).
|
|
126
|
+
const tmpIndex = (tmpIndexRaw == null) ? tmpIndexRaw : Number(tmpIndexRaw);
|
|
127
|
+
if (tmpContainer) { tmpTabularChecked++; } else { tmpNonTabularChecked++; }
|
|
128
|
+
|
|
129
|
+
// The ACTUAL selector the old marshal re-resolved, from the element's own attributes.
|
|
130
|
+
const tmpSelector = tmpInformary.getContentBrowserAddress(tmpForm, tmpDatum, tmpContainer, tmpIndex);
|
|
131
|
+
const tmpMatches = document.querySelectorAll(tmpSelector);
|
|
132
|
+
Expect(tmpMatches.length).to.equal(1, `selector [${tmpSelector}] must match exactly one element`);
|
|
133
|
+
Expect(tmpMatches[0]).to.equal(pElement, `selector [${tmpSelector}] must resolve to its own element`);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Make sure we exercised BOTH selector shapes — the 4-part container/index (tabular)
|
|
137
|
+
// AND the 2-part (non-tabular) path through getContentBrowserAddress.
|
|
138
|
+
Expect(tmpTabularChecked).to.be.greaterThan(0, 'exercised tabular container/index cells');
|
|
139
|
+
Expect(tmpNonTabularChecked).to.be.greaterThan(0, 'exercised non-tabular cells');
|
|
140
|
+
fDone();
|
|
141
|
+
}
|
|
142
|
+
catch (pError) { fDone(pError); }
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Unit tests for the Informary provider's element marshal.
|
|
3
|
+
|
|
4
|
+
Focus: marshalSpecificElementDataToForm must assign content straight to the form
|
|
5
|
+
element it is handed, NOT re-resolve a selector built from that element's own
|
|
6
|
+
attributes (a full-document scan per cell -> O(n^2) across a large tabular marshal).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const libBrowserEnv = require('browser-env');
|
|
10
|
+
libBrowserEnv();
|
|
11
|
+
|
|
12
|
+
const Chai = require('chai');
|
|
13
|
+
const Expect = Chai.expect;
|
|
14
|
+
|
|
15
|
+
const libPict = require('pict');
|
|
16
|
+
const libInformary = require('../source/providers/Pict-Provider-Informary.js');
|
|
17
|
+
|
|
18
|
+
suite(
|
|
19
|
+
'Pict Provider Informary',
|
|
20
|
+
() =>
|
|
21
|
+
{
|
|
22
|
+
suite(
|
|
23
|
+
'marshalSpecificElementDataToForm assigns to the element in hand',
|
|
24
|
+
() =>
|
|
25
|
+
{
|
|
26
|
+
const buildHarness = () =>
|
|
27
|
+
{
|
|
28
|
+
const tmpPict = new libPict({ Product: 'MockInformary', ProductVersion: '1.0.0' });
|
|
29
|
+
tmpPict.addProviderSingleton('Informary', libInformary.default_configuration, libInformary);
|
|
30
|
+
const tmpAssignCalls = [];
|
|
31
|
+
// Capture what assignContent is handed.
|
|
32
|
+
tmpPict.ContentAssignment.assignContent = (pAddress, pContent) =>
|
|
33
|
+
{
|
|
34
|
+
tmpAssignCalls.push({ Address: pAddress, Content: pContent });
|
|
35
|
+
};
|
|
36
|
+
// The whole point of the fix: the marshal must NOT resolve a selector.
|
|
37
|
+
tmpPict.ContentAssignment.getElement = (pAddress) =>
|
|
38
|
+
{
|
|
39
|
+
throw new Error(`getElement must not be called during the element marshal; got [${pAddress}]`);
|
|
40
|
+
};
|
|
41
|
+
return { pict: tmpPict, informary: tmpPict.providers.Informary, assigns: tmpAssignCalls };
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const buildElement = (pAttributes) =>
|
|
45
|
+
{
|
|
46
|
+
return { getAttribute: (pName) => (pName in pAttributes ? pAttributes[pName] : null) };
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const tmpManifest = { getValueAtAddress: (pData, pAddress) => pData[pAddress] };
|
|
50
|
+
|
|
51
|
+
test(
|
|
52
|
+
'non-container datum: assigns the value straight to the passed element',
|
|
53
|
+
(fDone) =>
|
|
54
|
+
{
|
|
55
|
+
const tmpHarness = buildHarness();
|
|
56
|
+
const tmpElement = buildElement({ 'data-i-datum': 'Greeting', 'data-i-container': null, 'data-i-index': '0' });
|
|
57
|
+
tmpHarness.informary.marshalSpecificElementDataToForm(tmpElement, tmpManifest, { Greeting: 'hello' });
|
|
58
|
+
Expect(tmpHarness.assigns.length).to.equal(1);
|
|
59
|
+
// The ELEMENT itself, never a string selector.
|
|
60
|
+
Expect(tmpHarness.assigns[0].Address).to.equal(tmpElement);
|
|
61
|
+
Expect(typeof tmpHarness.assigns[0].Address).to.not.equal('string');
|
|
62
|
+
Expect(tmpHarness.assigns[0].Content).to.equal('hello');
|
|
63
|
+
fDone();
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
test(
|
|
68
|
+
'container datum: assigns the composed-address value straight to the passed element',
|
|
69
|
+
(fDone) =>
|
|
70
|
+
{
|
|
71
|
+
const tmpHarness = buildHarness();
|
|
72
|
+
const tmpElement = buildElement({ 'data-i-datum': 'Score', 'data-i-container': 'Grades', 'data-i-index': '2' });
|
|
73
|
+
const tmpKey = tmpHarness.informary.getComposedContainerAddress('Grades', 2, 'Score');
|
|
74
|
+
const tmpData = {};
|
|
75
|
+
tmpData[tmpKey] = 99;
|
|
76
|
+
tmpHarness.informary.marshalSpecificElementDataToForm(tmpElement, tmpManifest, tmpData);
|
|
77
|
+
Expect(tmpHarness.assigns.length).to.equal(1);
|
|
78
|
+
Expect(tmpHarness.assigns[0].Address).to.equal(tmpElement);
|
|
79
|
+
Expect(tmpHarness.assigns[0].Content).to.equal(99);
|
|
80
|
+
fDone();
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
test(
|
|
85
|
+
'element with no datum address is skipped (returns false, no assignment)',
|
|
86
|
+
(fDone) =>
|
|
87
|
+
{
|
|
88
|
+
const tmpHarness = buildHarness();
|
|
89
|
+
const tmpElement = buildElement({});
|
|
90
|
+
const tmpResult = tmpHarness.informary.marshalSpecificElementDataToForm(tmpElement, tmpManifest, {});
|
|
91
|
+
Expect(tmpResult).to.equal(false);
|
|
92
|
+
Expect(tmpHarness.assigns.length).to.equal(0);
|
|
93
|
+
fDone();
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
test(
|
|
98
|
+
'a null app-state value does not assign (no spurious blank write)',
|
|
99
|
+
(fDone) =>
|
|
100
|
+
{
|
|
101
|
+
const tmpHarness = buildHarness();
|
|
102
|
+
const tmpElement = buildElement({ 'data-i-datum': 'Missing', 'data-i-container': null, 'data-i-index': '0' });
|
|
103
|
+
tmpHarness.informary.marshalSpecificElementDataToForm(tmpElement, tmpManifest, {});
|
|
104
|
+
Expect(tmpHarness.assigns.length).to.equal(0);
|
|
105
|
+
fDone();
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
);
|
|
@@ -39,6 +39,7 @@ class DoNothingApplication extends libPictSectionForm.PictFormApplication
|
|
|
39
39
|
{
|
|
40
40
|
this.solve();
|
|
41
41
|
this._testDone();
|
|
42
|
+
return true;
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
@@ -65,10 +66,12 @@ class OrderedSolverApplication extends DoNothingApplication
|
|
|
65
66
|
super.onAfterSolve();
|
|
66
67
|
this.pict.log.info('OrderedSolverApplication onAfterSolve called.');
|
|
67
68
|
this._testDone?.();
|
|
69
|
+
return true;
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
onAfterInitialize()
|
|
71
73
|
{
|
|
74
|
+
return true;
|
|
72
75
|
}
|
|
73
76
|
}
|
|
74
77
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": ["source"],
|
|
3
|
+
"compilerOptions":
|
|
4
|
+
{
|
|
5
|
+
"target": "es2019",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"allowJs": true,
|
|
8
|
+
"checkJs": true,
|
|
9
|
+
"declaration": true,
|
|
10
|
+
"emitDeclarationOnly": true,
|
|
11
|
+
"outDir": "types",
|
|
12
|
+
"declarationMap": true,
|
|
13
|
+
"module": "commonjs",
|
|
14
|
+
"resolveJsonModule": true
|
|
15
|
+
}
|
|
16
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -121,6 +121,39 @@ declare class DynamicTabularData extends libPictProvider {
|
|
|
121
121
|
* @param {number} pOriginalLength - Source row count BEFORE the removal.
|
|
122
122
|
*/
|
|
123
123
|
_spliceDependentPositionalColumns(pSourceRecordSetAddress: string, pDeletedIndex: number, pOriginalLength: number): void;
|
|
124
|
+
/**
|
|
125
|
+
* For position-keyed DynamicColumns (KeyBy: "Position") sourced from
|
|
126
|
+
* pSourceRecordSetAddress, REORDER each dependent row's positional cells to
|
|
127
|
+
* mirror a source row that moved from pOldIndex to pNewIndex. The source array
|
|
128
|
+
* was already spliced (remove at pOldIndex, insert at pNewIndex); this applies
|
|
129
|
+
* the identical permutation to every dependent row's positional cell VALUES so
|
|
130
|
+
* the data stays attached to its column when the columns re-resolve to the new
|
|
131
|
+
* source order. Without it, a reorder leaves user-entered cells under the wrong
|
|
132
|
+
* (renamed) column. Solver-filled rows re-derive on the next solve regardless;
|
|
133
|
+
* applying the move to them too is harmless (the solve overwrites them). No-op
|
|
134
|
+
* for value-keyed generators (their data stays attached to the stable value).
|
|
135
|
+
*
|
|
136
|
+
* Must run AFTER the source splice and BEFORE the dependent views re-resolve +
|
|
137
|
+
* the marshal repaints them. Symmetric with _spliceDependentPositionalColumns.
|
|
138
|
+
*
|
|
139
|
+
* @param {string} pSourceRecordSetAddress - RecordSetAddress of the moved-within source.
|
|
140
|
+
* @param {number} pOldIndex - Source row's index before the move.
|
|
141
|
+
* @param {number} pNewIndex - Source row's index after the move.
|
|
142
|
+
* @param {number} pLength - Source row count (unchanged by a move).
|
|
143
|
+
*/
|
|
144
|
+
_moveDependentPositionalColumns(pSourceRecordSetAddress: string, pOldIndex: number, pNewIndex: number, pLength: number): void;
|
|
145
|
+
/**
|
|
146
|
+
* Shared tail for the row-reorder handlers (move up / move down / set index).
|
|
147
|
+
* Repaints the moved source table and every dependent view, in the RENDER phase
|
|
148
|
+
* BEFORE solving + marshaling, then solves and marshals. Mirrors what the add /
|
|
149
|
+
* delete handlers do so a reorder doesn't blank dependent DynamicColumns tables
|
|
150
|
+
* (or the rest of their section) until the next edit. Render happens before the
|
|
151
|
+
* solve so the solve's DOM side effects (e.g. SetGroupVisibility) land on the
|
|
152
|
+
* freshly rebuilt DOM and survive.
|
|
153
|
+
*
|
|
154
|
+
* @param {Object} pGroup - The reordered group (its RecordSetAddress drives dependents).
|
|
155
|
+
*/
|
|
156
|
+
_repaintAfterRowReorder(pGroup: any): void;
|
|
124
157
|
}
|
|
125
158
|
declare namespace DynamicTabularData {
|
|
126
159
|
export { _DefaultProviderConfiguration as default_configuration, ElementDescriptor };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Provider-DynamicTabularData.d.ts","sourceRoot":"","sources":["../../../source/providers/Pict-Provider-DynamicTabularData.js"],"names":[],"mappings":";AAaA;;;GAGG;AAEH;;GAEG;AACH;IAcE,kBAAkB;IAClB,SADW,GAAG,CACF;IACZ,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IAKV;;;;;;OAMG;IACH,6CAHW,MAAM,GACJ,cAAa,OAAO,CAehC;IAED;;;;;;;OAOG;IACH,+CAJW,MAAM,eACN,MAAM,GACJ,iBAAiB,GAAC,OAAO,CAiBrC;IAED;;;;;;;OAOG;IACH,oDAJW,MAAM,cACN,MAAM,GACJ,iBAAiB,GAAC,OAAO,CA+BrC;IAED;;;;;;;OAOG;IACH,8CAJW,MAAM,kBACN,MAAM,GACJ,OAAO,MAAO,CAkD1B;IAED;;;;;OAKG;IACH,+CAFW,MAAM,QAqEhB;IAGD;;;;;OAKG;IACH,4DAFW,MAAM,QAyBhB;IAED;;;;;;;;OAQG;IACH,iDALW,MAAM,aACN,MAAM,GAAC,MAAM,gBACb,MAAM,GACJ,OAAO,
|
|
1
|
+
{"version":3,"file":"Pict-Provider-DynamicTabularData.d.ts","sourceRoot":"","sources":["../../../source/providers/Pict-Provider-DynamicTabularData.js"],"names":[],"mappings":";AAaA;;;GAGG;AAEH;;GAEG;AACH;IAcE,kBAAkB;IAClB,SADW,GAAG,CACF;IACZ,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IAKV;;;;;;OAMG;IACH,6CAHW,MAAM,GACJ,cAAa,OAAO,CAehC;IAED;;;;;;;OAOG;IACH,+CAJW,MAAM,eACN,MAAM,GACJ,iBAAiB,GAAC,OAAO,CAiBrC;IAED;;;;;;;OAOG;IACH,oDAJW,MAAM,cACN,MAAM,GACJ,iBAAiB,GAAC,OAAO,CA+BrC;IAED;;;;;;;OAOG;IACH,8CAJW,MAAM,kBACN,MAAM,GACJ,OAAO,MAAO,CAkD1B;IAED;;;;;OAKG;IACH,+CAFW,MAAM,QAqEhB;IAGD;;;;;OAKG;IACH,4DAFW,MAAM,QAyBhB;IAED;;;;;;;;OAQG;IACH,iDALW,MAAM,aACN,MAAM,GAAC,MAAM,gBACb,MAAM,GACJ,OAAO,CAoCnB;IAED;;;;;;;OAOG;IACH,iDAJW,MAAM,aACN,MAAM,GAAC,MAAM,GACX,OAAO,CAqCnB;IAED;;;;;;;OAOG;IACH,+CAJW,MAAM,aACN,MAAM,GAAC,MAAM,GACX,OAAO,CA0CnB;IAGD;;;;;;;OAOG;IACH,+CAJW,MAAM,aACN,MAAM,GAAC,MAAM,GACX,OAAO,CA6EnB;IAED;;;;;;;;;OASG;IACH,6DAFW,MAAM,QAqDhB;IAED;;;;;;;;;;;OAWG;IACH,2DAJW,MAAM,iBACN,MAAM,mBACN,MAAM,QAoFhB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,yDALW,MAAM,aACN,MAAM,aACN,MAAM,WACN,MAAM,QAwFhB;IAED;;;;;;;;;;OAUG;IACH,2CAsCC;CACD;;;;;AAn0BD,kCAAkC;AAClC,6CADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAS3B;;;;;UAIW,MAAM"}
|
|
@@ -44,47 +44,46 @@ declare class PictDynamicFormsInformary extends libPictProvider {
|
|
|
44
44
|
*
|
|
45
45
|
* @param {object} pAppStateData - The application state data object to marshal the form data to.
|
|
46
46
|
* @param {string} pFormHash - The form hash representing the form elements.
|
|
47
|
-
* @param {
|
|
47
|
+
* @param {import('manyfest')} pManifest - The manifest object used to map form data to the application state data.
|
|
48
48
|
* @param {string} [pDatum] - The datum hash to pull in. If not provided, all data is marshalled.
|
|
49
49
|
* @param {number|string} [pRecordIndex] - The record index to pull in. If not provided, all data is marshalled.
|
|
50
50
|
*/
|
|
51
|
-
marshalFormToData(pAppStateData: object, pFormHash: string, pManifest:
|
|
51
|
+
marshalFormToData(pAppStateData: object, pFormHash: string, pManifest: import("manyfest"), pDatum?: string, pRecordIndex?: number | string): void;
|
|
52
52
|
/**
|
|
53
53
|
* Marshals a specific form element's data to the application state data.
|
|
54
54
|
*
|
|
55
55
|
* @param {string} pFormHash - The hash of the form.
|
|
56
|
-
* @param {HTMLElement}
|
|
57
|
-
* @param {
|
|
56
|
+
* @param {HTMLElement} pFormElement - The form element to marshal.
|
|
57
|
+
* @param {import('manyfest')} pManifest - The manifest object to set values.
|
|
58
58
|
* @param {Object} pAppStateData - The application state data object.
|
|
59
59
|
* @param {any} [pDatumFilter] - Optional filter for datum address.
|
|
60
60
|
* @param {any} [pRecordIndexFilter] - Optional filter for record index.
|
|
61
61
|
* @returns {boolean} - Returns false if the element falls outside the filters or if the browser value is null.
|
|
62
62
|
*/
|
|
63
|
-
marshalSpecicificFormElementToData(pFormHash: string,
|
|
63
|
+
marshalSpecicificFormElementToData(pFormHash: string, pFormElement: HTMLElement, pManifest: import("manyfest"), pAppStateData: any, pDatumFilter?: any, pRecordIndexFilter?: any): boolean;
|
|
64
64
|
/**
|
|
65
65
|
* Marshals data from some application state object to a specific subset of browser form elements.
|
|
66
66
|
*
|
|
67
67
|
* @param {object} pAppStateData - The application state data to marshal into the form. Usually AppData but can be other objects.
|
|
68
68
|
* @param {string} pFormHash - The hash of the form to marshal data into. This is the data-i-form attribute.
|
|
69
|
-
* @param {
|
|
69
|
+
* @param {import('manyfest')} pManifest - The manifest object. If not provided, the generic manifest is used.
|
|
70
70
|
*/
|
|
71
|
-
marshalDataToForm(pAppStateData: object, pFormHash: string, pManifest:
|
|
71
|
+
marshalDataToForm(pAppStateData: object, pFormHash: string, pManifest: import("manyfest")): void;
|
|
72
72
|
/**
|
|
73
73
|
* Marshals specific element data to a form.
|
|
74
74
|
*
|
|
75
|
-
* @param {string} pFormHash - The hash of the form.
|
|
76
75
|
* @param {HTMLElement} pFormElement - The form element to marshal data to.
|
|
77
|
-
* @param {
|
|
78
|
-
* @param {
|
|
76
|
+
* @param {import('manyfest')} pManifest - The manifest object containing data retrieval methods.
|
|
77
|
+
* @param {Record<string, any>} pAppStateData - The application state data.
|
|
79
78
|
* @returns {boolean} Returns false if the form element does not have a datum address.
|
|
80
79
|
*/
|
|
81
|
-
marshalSpecificElementDataToForm(
|
|
80
|
+
marshalSpecificElementDataToForm(pFormElement: HTMLElement, pManifest: import("manyfest"), pAppStateData: Record<string, any>): boolean;
|
|
82
81
|
/**
|
|
83
82
|
* Manually marshals data to a form by assigning content based on context in the descriptor.
|
|
84
|
-
* @param {
|
|
83
|
+
* @param {Record<string, any>} pInput - The input manifest descriptor to marshal data to form from.
|
|
85
84
|
* @returns boolean if assignment was successful
|
|
86
85
|
*/
|
|
87
|
-
manualMarshalDataToFormByInput(pInput:
|
|
86
|
+
manualMarshalDataToFormByInput(pInput: Record<string, any>): false | void;
|
|
88
87
|
/**
|
|
89
88
|
* Manually marshals tabular data to a form by assigning content based on context in the descriptor.
|
|
90
89
|
* @param {object} pInput - The input manifest descriptor to marshal data to form from.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Provider-Informary.d.ts","sourceRoot":"","sources":["../../../source/providers/Pict-Provider-Informary.js"],"names":[],"mappings":";AAcA;;;GAGG;AACH;IAeE,kBAAkB;IAClB,SADW,GAAG,CACF;IACZ,qFAAqF;IACrF,MADW,OAAO,MAAM,CAAC,GAAG;QAAE,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,UAAU,CAAC,CAAA;KAAE,CACxE;IAIT,oCAAwE;IAGzE;;;;;OAKG;IACH,2BAHW,MAAM,GACJ,WAAW,EAAE,CAOzB;IAED;;;;;;;;;;OAUG;IACH,oCANW,MAAM,cACN,MAAM,cACN,MAAM,GAAC,IAAI,UACX,MAAM,GAAC,MAAM,GACX,MAAM,CAalB;IAED;;;;;;;OAOG;IACH,wCALW,MAAM,UACN,MAAM,GAAC,MAAM,cACb,MAAM,GACJ,MAAM,CAKlB;IAED;;;;;;;;OAQG;IACH,iCANW,MAAM,aACN,MAAM,aACN,
|
|
1
|
+
{"version":3,"file":"Pict-Provider-Informary.d.ts","sourceRoot":"","sources":["../../../source/providers/Pict-Provider-Informary.js"],"names":[],"mappings":";AAcA;;;GAGG;AACH;IAeE,kBAAkB;IAClB,SADW,GAAG,CACF;IACZ,qFAAqF;IACrF,MADW,OAAO,MAAM,CAAC,GAAG;QAAE,WAAW,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,OAAO,UAAU,CAAC,CAAA;KAAE,CACxE;IAIT,oCAAwE;IAGzE;;;;;OAKG;IACH,2BAHW,MAAM,GACJ,WAAW,EAAE,CAOzB;IAED;;;;;;;;;;OAUG;IACH,oCANW,MAAM,cACN,MAAM,cACN,MAAM,GAAC,IAAI,UACX,MAAM,GAAC,MAAM,GACX,MAAM,CAalB;IAED;;;;;;;OAOG;IACH,wCALW,MAAM,UACN,MAAM,GAAC,MAAM,cACb,MAAM,GACJ,MAAM,CAKlB;IAED;;;;;;;;OAQG;IACH,iCANW,MAAM,aACN,MAAM,aACN,OAAO,UAAU,CAAC,WAClB,MAAM,iBACN,MAAM,GAAC,MAAM,QAgBvB;IAED;;;;;;;;;;OAUG;IACH,8CARW,MAAM,gBACN,WAAW,aACX,OAAO,UAAU,CAAC,qCAElB,GAAG,uBACH,GAAG,GACD,OAAO,CA2CnB;IAED;;;;;;OAMG;IACH,iCAJW,MAAM,aACN,MAAM,aACN,OAAO,UAAU,CAAC,QAa5B;IAED;;;;;;;OAOG;IACH,+CALW,WAAW,aACX,OAAO,UAAU,CAAC,iBAClB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjB,OAAO,CA4CnB;IAED;;;;OAIG;IACH,uCAHW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,gBA2B7B;IAED;;;;;OAKG;IACH,8CAJW,MAAM,aACN,MAAM,gBA4BhB;IAED;;;;;OAKG;IACH,sCAHW,MAAM,UACN,MAAM,QAKhB;IAED;;;;;;OAMG;IACH,6CAJW,MAAM,UACN,MAAM,aACN,MAAM,QAKhB;CACD;;;;;AAvUD,kCAAkC;AAClC,6CADW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAS3B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Layout-Custom.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Custom.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;
|
|
1
|
+
{"version":3,"file":"Pict-Layout-Custom.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Custom.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;CA0DX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Layout-Record.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Record.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;
|
|
1
|
+
{"version":3,"file":"Pict-Layout-Record.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Record.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;CA8GX"}
|
|
@@ -205,6 +205,208 @@ declare class TabularLayout extends libPictSectionGroupLayout {
|
|
|
205
205
|
* @param {Object} pGroup
|
|
206
206
|
*/
|
|
207
207
|
_reapplyTabularSelectionHighlights(pView: any, pGroup: any): void;
|
|
208
|
+
/**
|
|
209
|
+
* Normalize a Group.ColumnChooser config value.
|
|
210
|
+
*
|
|
211
|
+
* Accepts `true` (use all defaults) or an object
|
|
212
|
+
* `{ Enabled, DataAddress, ButtonLabel, DefaultHiddenColumns }`. Returns null
|
|
213
|
+
* when the chooser is not enabled (the feature is strictly opt-in).
|
|
214
|
+
*
|
|
215
|
+
* - `DataAddress` — address (relative to the form's marshal destination) where
|
|
216
|
+
* the array of hidden column hashes is stored, so it persists with the form data.
|
|
217
|
+
* - `ButtonLabel` — text for the trigger button above the table.
|
|
218
|
+
* - `DefaultHiddenColumns` — column hashes hidden until the user changes them
|
|
219
|
+
* (merged with any descriptor-level `PictForm.TabularDefaultHidden` flags).
|
|
220
|
+
*
|
|
221
|
+
* @param {boolean|Object} pConfigValue
|
|
222
|
+
* @param {string} pDefaultDataAddress
|
|
223
|
+
* @returns {{DataAddress: string, ButtonLabel: string, DefaultHiddenColumns: Array<string>}|null}
|
|
224
|
+
*/
|
|
225
|
+
_normalizeColumnChooserConfig(pConfigValue: boolean | any, pDefaultDataAddress: string): {
|
|
226
|
+
DataAddress: string;
|
|
227
|
+
ButtonLabel: string;
|
|
228
|
+
DefaultHiddenColumns: Array<string>;
|
|
229
|
+
} | null;
|
|
230
|
+
/**
|
|
231
|
+
* Lazily normalize (and cache on the group) the ColumnChooser config. The
|
|
232
|
+
* template bake re-normalizes each pass; this accessor covers code paths
|
|
233
|
+
* (marshal hooks, inline handlers) that may run against a group whose
|
|
234
|
+
* template hasn't been baked yet.
|
|
235
|
+
*
|
|
236
|
+
* @param {Object} pGroup
|
|
237
|
+
* @returns {{DataAddress: string, ButtonLabel: string, DefaultHiddenColumns: Array<string>}|null}
|
|
238
|
+
*/
|
|
239
|
+
_ensureTabularColumnChooserConfig(pGroup: any): {
|
|
240
|
+
DataAddress: string;
|
|
241
|
+
ButtonLabel: string;
|
|
242
|
+
DefaultHiddenColumns: Array<string>;
|
|
243
|
+
} | null;
|
|
244
|
+
/**
|
|
245
|
+
* The absolute address (within the form's marshal destination) of the
|
|
246
|
+
* chooser's hidden-column-hash array.
|
|
247
|
+
*
|
|
248
|
+
* @param {Object} pView
|
|
249
|
+
* @param {{DataAddress: string}} pChooserConfig
|
|
250
|
+
* @returns {string}
|
|
251
|
+
*/
|
|
252
|
+
_getTabularHiddenColumnsAddress(pView: any, pChooserConfig: {
|
|
253
|
+
DataAddress: string;
|
|
254
|
+
}): string;
|
|
255
|
+
/**
|
|
256
|
+
* The set of column hashes hidden BY DEFAULT for a group: the chooser
|
|
257
|
+
* config's DefaultHiddenColumns plus every descriptor flagged
|
|
258
|
+
* `PictForm.TabularDefaultHidden`. These apply only until the user changes
|
|
259
|
+
* column visibility (which writes an explicit array into the form data).
|
|
260
|
+
*
|
|
261
|
+
* @param {Object} pGroup
|
|
262
|
+
* @returns {Array<string>}
|
|
263
|
+
*/
|
|
264
|
+
_getTabularColumnChooserDefaultHidden(pGroup: any): Array<string>;
|
|
265
|
+
/**
|
|
266
|
+
* The EFFECTIVE set of chooser-hidden column hashes for a group: the array
|
|
267
|
+
* stored in the form data when the user has made choices, otherwise the
|
|
268
|
+
* configured defaults. Returns null when the chooser is not enabled, so
|
|
269
|
+
* callers can use a single falsy check to keep the legacy code path intact.
|
|
270
|
+
*
|
|
271
|
+
* @param {Object} pView
|
|
272
|
+
* @param {Object} pGroup
|
|
273
|
+
* @returns {Set<string>|null}
|
|
274
|
+
*/
|
|
275
|
+
_getTabularColumnChooserHiddenSet(pView: any, pGroup: any): Set<string> | null;
|
|
276
|
+
/**
|
|
277
|
+
* A canonical string for the group's effective hidden-column set, used to
|
|
278
|
+
* detect (on marshal) that loaded form data carries different column
|
|
279
|
+
* visibility than the table template was baked with.
|
|
280
|
+
*
|
|
281
|
+
* @param {Object} pView
|
|
282
|
+
* @param {Object} pGroup
|
|
283
|
+
* @returns {string}
|
|
284
|
+
*/
|
|
285
|
+
_getTabularColumnChooserStateKey(pView: any, pGroup: any): string;
|
|
286
|
+
/**
|
|
287
|
+
* The columns the chooser can manage, in manifest order. Statically hidden
|
|
288
|
+
* descriptors (`PictForm.TabularHidden`) are never choosable and never
|
|
289
|
+
* listed. Each entry carries the descriptor's manifest index so inline
|
|
290
|
+
* handlers can address it without string-escaping concerns.
|
|
291
|
+
*
|
|
292
|
+
* @param {Object} pView
|
|
293
|
+
* @param {Object} pGroup
|
|
294
|
+
* @returns {Array<{Key: string, Name: string, ColumnIndex: number, Visible: boolean}>}
|
|
295
|
+
*/
|
|
296
|
+
_getTabularChoosableColumns(pView: any, pGroup: any): Array<{
|
|
297
|
+
Key: string;
|
|
298
|
+
Name: string;
|
|
299
|
+
ColumnIndex: number;
|
|
300
|
+
Visible: boolean;
|
|
301
|
+
}>;
|
|
302
|
+
/**
|
|
303
|
+
* DOM element id for one of the chooser's baked elements (TRIGGER / POPOVER),
|
|
304
|
+
* namespaced by form and group so multiple tabular groups can each carry
|
|
305
|
+
* their own chooser.
|
|
306
|
+
*
|
|
307
|
+
* @param {Object} pView
|
|
308
|
+
* @param {Object} pGroup
|
|
309
|
+
* @param {string} pElement
|
|
310
|
+
* @returns {string}
|
|
311
|
+
*/
|
|
312
|
+
_getTabularColumnChooserElementId(pView: any, pGroup: any, pElement: string): string;
|
|
313
|
+
/**
|
|
314
|
+
* Builds the chooser bar baked above the table: a right-aligned trigger
|
|
315
|
+
* button (with a "n hidden" hint when columns are hidden) plus the empty
|
|
316
|
+
* popover container the open action renders into.
|
|
317
|
+
*
|
|
318
|
+
* @param {Object} pView
|
|
319
|
+
* @param {Object} pGroup
|
|
320
|
+
* @returns {string}
|
|
321
|
+
*/
|
|
322
|
+
_buildTabularColumnChooserBarHTML(pView: any, pGroup: any): string;
|
|
323
|
+
/**
|
|
324
|
+
* Renders the chooser popover's content (backdrop + panel of checkbox rows +
|
|
325
|
+
* reset footer) into its baked container. Runs on open and after each toggle
|
|
326
|
+
* (the table re-render replaces the popover element, so its content must be
|
|
327
|
+
* repainted to keep the menu open across toggles).
|
|
328
|
+
*
|
|
329
|
+
* @param {Object} pView
|
|
330
|
+
* @param {Object} pGroup
|
|
331
|
+
*/
|
|
332
|
+
_renderTabularColumnChooserPopover(pView: any, pGroup: any): void;
|
|
333
|
+
/**
|
|
334
|
+
* Reflect the chooser popover's open/closed state on its container element,
|
|
335
|
+
* positioning it against the trigger when opening.
|
|
336
|
+
*
|
|
337
|
+
* @param {Object} pView
|
|
338
|
+
* @param {Object} pGroup
|
|
339
|
+
* @param {boolean} pOpen
|
|
340
|
+
*/
|
|
341
|
+
_paintTabularColumnChooserOpenState(pView: any, pGroup: any, pOpen: boolean): void;
|
|
342
|
+
/**
|
|
343
|
+
* Position the (fixed) chooser popover against its trigger button, flipping
|
|
344
|
+
* above when the room below is genuinely cramped — same approach as the
|
|
345
|
+
* recordset's column chooser, so no ancestor overflow can clip it.
|
|
346
|
+
*
|
|
347
|
+
* @param {Object} pView
|
|
348
|
+
* @param {Object} pGroup
|
|
349
|
+
* @param {HTMLElement} pPopover
|
|
350
|
+
*/
|
|
351
|
+
_positionTabularColumnChooserPopover(pView: any, pGroup: any, pPopover: HTMLElement): void;
|
|
352
|
+
/**
|
|
353
|
+
* Rebuild + re-render a tabular view and re-marshal the form data into it.
|
|
354
|
+
* Same tail as sortTabularColumn: the rebuild re-bakes the table template
|
|
355
|
+
* (column set, headers, chooser bar), the render repaints, the marshal
|
|
356
|
+
* pushes current values back into the freshly built inputs.
|
|
357
|
+
*
|
|
358
|
+
* @param {Object} pView
|
|
359
|
+
*/
|
|
360
|
+
_rebuildTabularGroupView(pView: any): void;
|
|
361
|
+
/**
|
|
362
|
+
* Inline-handler entry point: opens/closes a group's column chooser popover
|
|
363
|
+
* (the trigger button's handler). Open/closed is derived from the popover's
|
|
364
|
+
* DOM class, not an instance flag — a re-render replaces the popover element
|
|
365
|
+
* (visually closed), so a flag would go stale and demand a double-click.
|
|
366
|
+
*
|
|
367
|
+
* @param {string} pViewHash
|
|
368
|
+
* @param {number|string} pGroupIndex
|
|
369
|
+
* @returns {boolean}
|
|
370
|
+
*/
|
|
371
|
+
toggleTabularColumnChooser(pViewHash: string, pGroupIndex: number | string): boolean;
|
|
372
|
+
/**
|
|
373
|
+
* Inline-handler entry point: closes a group's column chooser popover (the
|
|
374
|
+
* backdrop's handler).
|
|
375
|
+
*
|
|
376
|
+
* @param {string} pViewHash
|
|
377
|
+
* @param {number|string} pGroupIndex
|
|
378
|
+
* @returns {boolean}
|
|
379
|
+
*/
|
|
380
|
+
closeTabularColumnChooser(pViewHash: string, pGroupIndex: number | string): boolean;
|
|
381
|
+
/**
|
|
382
|
+
* Inline-handler entry point: shows/hides one column (a chooser checkbox's
|
|
383
|
+
* handler). Writes the updated hidden-hash array into the form data (so it
|
|
384
|
+
* persists with a save), rebuilds the table template without the column,
|
|
385
|
+
* re-renders, re-marshals, then re-opens the popover the re-render closed.
|
|
386
|
+
*
|
|
387
|
+
* Hiding never touches the underlying record data — the column's values
|
|
388
|
+
* stay in the record set and reappear when the column is shown again.
|
|
389
|
+
*
|
|
390
|
+
* Refuses to hide the last visible column (the checkbox snaps back).
|
|
391
|
+
*
|
|
392
|
+
* @param {string} pViewHash
|
|
393
|
+
* @param {number|string} pGroupIndex
|
|
394
|
+
* @param {number|string} pColumnIndex - The column's manifest index (stable within a bake).
|
|
395
|
+
* @param {boolean} pVisible - true to show the column, false to hide it.
|
|
396
|
+
* @returns {boolean}
|
|
397
|
+
*/
|
|
398
|
+
toggleTabularColumnVisibility(pViewHash: string, pGroupIndex: number | string, pColumnIndex: number | string, pVisible: boolean): boolean;
|
|
399
|
+
/**
|
|
400
|
+
* Inline-handler entry point: resets a group's column visibility to its
|
|
401
|
+
* configured defaults (the reset footer button's handler). Writes the
|
|
402
|
+
* default hidden set into the form data explicitly — the user interacted,
|
|
403
|
+
* so the state should serialize deterministically with a save.
|
|
404
|
+
*
|
|
405
|
+
* @param {string} pViewHash
|
|
406
|
+
* @param {number|string} pGroupIndex
|
|
407
|
+
* @returns {boolean}
|
|
408
|
+
*/
|
|
409
|
+
resetTabularColumnVisibility(pViewHash: string, pGroupIndex: number | string): boolean;
|
|
208
410
|
}
|
|
209
411
|
import libPictSectionGroupLayout = require("../Pict-Provider-DynamicLayout.js");
|
|
210
412
|
//# sourceMappingURL=Pict-Layout-Tabular.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Layout-Tabular.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Tabular.js"],"names":[],"mappings":";AAEA;IAEC,
|
|
1
|
+
{"version":3,"file":"Pict-Layout-Tabular.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-Tabular.js"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pict-Layout-VerticalRecord.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-VerticalRecord.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;
|
|
1
|
+
{"version":3,"file":"Pict-Layout-VerticalRecord.d.ts","sourceRoot":"","sources":["../../../../source/providers/layouts/Pict-Layout-VerticalRecord.js"],"names":[],"mappings":";AAEA;IAEC,2DAUC;IANA,6BAA6B;IAC7B,MADW,OAAO,MAAM,CAAC,CAChB;IACT,6BAA6B;IAC7B,OADW,OAAO,MAAM,CAAC,CACf;CAgEX"}
|
|
@@ -53,13 +53,14 @@ declare class ManifestFactory extends libFableServiceProviderBase {
|
|
|
53
53
|
*
|
|
54
54
|
* @param {Object} pView - The view containing the group.
|
|
55
55
|
* @param {Object} pGroup - The group object (must already have supportingManifest).
|
|
56
|
-
* @returns {{added: Array<string>, removed: Array<string>, unchanged: Array<string>, changed: boolean}}
|
|
56
|
+
* @returns {{added: Array<string>, removed: Array<string>, unchanged: Array<string>, changed: boolean, namesChanged: boolean}}
|
|
57
57
|
*/
|
|
58
58
|
_resolveDynamicColumns(pView: any, pGroup: any): {
|
|
59
59
|
added: Array<string>;
|
|
60
60
|
removed: Array<string>;
|
|
61
61
|
unchanged: Array<string>;
|
|
62
62
|
changed: boolean;
|
|
63
|
+
namesChanged: boolean;
|
|
63
64
|
};
|
|
64
65
|
/**
|
|
65
66
|
* Adds a manifest descriptor to the manifest.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ManifestFactory.d.ts","sourceRoot":"","sources":["../../../source/services/ManifestFactory.js"],"names":[],"mappings":";AAOA;IAEC,2DA4CC;IAtCA,6KAA6K;IAC7K,OADW,OAAO,MAAM,CAAC,GAAG;QAAE,6CAA6C,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;QAAC,WAAW,EAAE,MAAM,OAAO,UAAU,CAAC,CAAA;KAAE,CAC/J;IAMV,cAAmC;IAcnC,+BAAoC;IAEpC,sBAA2B;IAC3B,oBAAyB;IASzB,2BAA2B;IAE3B,gCAAgD;IAChD,sCAAwC;IACxC,kCAA0C;IAG3C;;;;;OAKG;IACH,2BAHW,MAAM,GACL,MAAM,CASjB;IAED;;;;;;;;;OASG;IACH,
|
|
1
|
+
{"version":3,"file":"ManifestFactory.d.ts","sourceRoot":"","sources":["../../../source/services/ManifestFactory.js"],"names":[],"mappings":";AAOA;IAEC,2DA4CC;IAtCA,6KAA6K;IAC7K,OADW,OAAO,MAAM,CAAC,GAAG;QAAE,6CAA6C,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,GAAG,CAAC;QAAC,WAAW,EAAE,MAAM,OAAO,UAAU,CAAC,CAAA;KAAE,CAC/J;IAMV,cAAmC;IAcnC,+BAAoC;IAEpC,sBAA2B;IAC3B,oBAAyB;IASzB,2BAA2B;IAE3B,gCAAgD;IAChD,sCAAwC;IACxC,kCAA0C;IAG3C;;;;;OAKG;IACH,2BAHW,MAAM,GACL,MAAM,CASjB;IAED;;;;;;;;;OASG;IACH,uCAuKC;IAED;;;;;;OAMG;IACH,uCAJW,MAAM,iBAEJ,MAAM,CAsBlB;IAED;;;;;;;;;;;;;;OAcG;IACH,iDAFa;QAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAC,CAsP7H;IAED;;;;OAIG;IACH,8CAOC;IAED;;;;;;OAMG;IACH,iCAJW,MAAM,OAiBhB;IAED;;;;;;;OAOG;IACH,mCALW,MAAM,MAAO,cACb,MAAM,OAkBhB;IAED;;;;OAIG;IACH,8BAFa,OAAO,CAenB;IAED,2FAyDC;IAED;;;;;;;OAOG;IACH,kEA8hBC;IAED;;;;;OAKG;IACH,kCAHW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,WACnB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAmC7B;IAED;;;;;;;;;OASG;IACH,2GAGC;IAED,0DAsGC;IAED;;;;;;OAMG;IACH,gBAJW,GAAG,GAEF,OAAO,CAclB;IAED;;;;;;OAMG;IACH,0CAJW,GAAG,GAEF,GAAG,CA8Dd;CACD;;+BAGU,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC"}
|