@itrocks/list 0.16.3 → 0.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/cjs/columns.js +45 -2
- package/cjs/columns.js.map +1 -1
- package/cjs/list.js +34 -2
- package/cjs/list.js.map +1 -1
- package/cjs/projection.d.ts +7 -0
- package/cjs/projection.js +36 -1
- package/cjs/projection.js.map +1 -1
- package/list.css +6 -3
- package/package.json +1 -1
- package/property-select.d.ts +4 -0
- package/property-select.js +95 -11
package/README.md
CHANGED
|
@@ -272,3 +272,24 @@ Set `PS_PLAYWRIGHT_MODULE` to an installed Playwright module when using a differ
|
|
|
272
272
|
(`PS_DATABASE_PORT` overrides it). It starts and stops its own application instance and checks desktop keyboard, touch,
|
|
273
273
|
reduced motion, horizontal reveal, removal and temporary-row transitions. `PS_TOGGLE_URL` reuses an existing instance
|
|
274
274
|
of that recipe instead. The synthetic database must already be running; this test never resets it.
|
|
275
|
+
|
|
276
|
+
## Component column batches
|
|
277
|
+
|
|
278
|
+
Selecting a component group sends one request with `loadColumns` listing missing paths, `columns` containing the
|
|
279
|
+
complete final configuration and `rowIds` identifying visible roots. The response contains `columns`, each with
|
|
280
|
+
`path`, `label`, `sortable` and rendered `rows`. Empty `loadColumns` saves group removals without querying records.
|
|
281
|
+
Failed batch projections preserve the saved configuration. Checkboxes update optimistically before metadata or HTTP
|
|
282
|
+
requests, for both individual selections and groups. The host commits placeholders and starts the shared green flash
|
|
283
|
+
before the values request; early values remain masked until the flash finishes, while late values appear immediately.
|
|
284
|
+
Removal starts one red flash after publishing the unchecked state, then sends the configuration request. Front-end
|
|
285
|
+
columns disappear at the animation deadline even if that request is still pending. Group actions use one HTTP request.
|
|
286
|
+
|
|
287
|
+
Sub-properties reached through one collection marked `@Component` are projected together when its element type
|
|
288
|
+
has one matching `@Composite` back-reference. The list reads visible root identities once, then all requested fields
|
|
289
|
+
in one query per component collection, restricted to those identities. Singular ancestors and related object labels
|
|
290
|
+
share these queries. Values retain component order and duplicates; these columns are not sortable.
|
|
291
|
+
The same projection is used when reloading the list or adding an individual component sub-property.
|
|
292
|
+
|
|
293
|
+
`test/browser-component-batch.mjs` verifies real browser interactions, HTTP request counts, MySQL query counts,
|
|
294
|
+
rendered values, mandatory row scope, partial selection, removal and session restoration. It creates and cleans up
|
|
295
|
+
its own temporary database and server using the existing selector integration recipe.
|
package/cjs/columns.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.projectColumns = projectColumns;
|
|
|
5
5
|
const list_properties_1 = require("@itrocks/list-properties");
|
|
6
6
|
const storage_1 = require("@itrocks/storage");
|
|
7
7
|
const storage_2 = require("@itrocks/storage");
|
|
8
|
+
const storage_3 = require("@itrocks/storage");
|
|
8
9
|
const parameter_1 = require("./parameter");
|
|
9
10
|
const projection_1 = require("./projection");
|
|
10
11
|
class Columns extends parameter_1.Parameter {
|
|
@@ -74,12 +75,51 @@ class Columns extends parameter_1.Parameter {
|
|
|
74
75
|
exports.Columns = Columns;
|
|
75
76
|
async function projectColumns(type, columns, search, options) {
|
|
76
77
|
const singular = columns.filter(column => !column.multiple);
|
|
77
|
-
const
|
|
78
|
+
const selections = singular.map(column => column.selection());
|
|
79
|
+
const parents = [...new Set(columns.flatMap(column => column.component?.parent ? [column.component.parent] : []))]
|
|
80
|
+
.filter(path => !singular.some(column => column.name === path));
|
|
81
|
+
selections.push(...parents.map(path => ({ path, objectFields: [] })));
|
|
82
|
+
const result = await (0, storage_1.dataSource)().select(type, selections, search, options);
|
|
78
83
|
if (!columns.some(column => column.multiple) || !result.rows.length)
|
|
79
84
|
return result;
|
|
80
85
|
const ids = result.rows.map(row => row.rootId);
|
|
81
|
-
const
|
|
86
|
+
const direct = columns.filter(column => column.multiple && !column.component);
|
|
87
|
+
const objects = direct.length ? await (0, storage_1.dataSource)().search(type, search, [new storage_2.Identifiers(ids)]) : [];
|
|
82
88
|
const byId = new Map(objects.map(object => [String(object.id), object]));
|
|
89
|
+
const components = new Map();
|
|
90
|
+
for (const path of new Set(columns.flatMap(column => column.component ? [column.component.path] : []))) {
|
|
91
|
+
const grouped = columns.filter(column => column.component?.path === path);
|
|
92
|
+
const component = grouped[0].component;
|
|
93
|
+
const parentIds = result.rows.map(row => {
|
|
94
|
+
if (!component.parent)
|
|
95
|
+
return row.rootId;
|
|
96
|
+
const index = singular.findIndex(column => column.name === component.parent);
|
|
97
|
+
const cell = row.cells[index < 0 ? singular.length + parents.indexOf(component.parent) : index];
|
|
98
|
+
return cell.kind === 'value' ? cell.value?.id : undefined;
|
|
99
|
+
});
|
|
100
|
+
const selectedIds = [...new Set(parentIds.filter((id) => id !== undefined))];
|
|
101
|
+
const selections = new Map([
|
|
102
|
+
[component.inverse, { path: component.inverse, objectFields: [] }]
|
|
103
|
+
]);
|
|
104
|
+
for (const column of grouped)
|
|
105
|
+
selections.set(column.component.column.name, column.component.column.selection());
|
|
106
|
+
const names = [...selections.keys()];
|
|
107
|
+
const values = selectedIds.length ? await (0, storage_1.dataSource)().select(component.type, [...selections.values()], { [component.inverse]: selectedIds }, [new storage_3.Sort([])]) : undefined;
|
|
108
|
+
for (const column of grouped) {
|
|
109
|
+
const byParent = new Map();
|
|
110
|
+
for (const row of values?.rows ?? []) {
|
|
111
|
+
const owner = row.cells[0];
|
|
112
|
+
if (owner.kind !== 'value' || !owner.value)
|
|
113
|
+
continue;
|
|
114
|
+
const id = String(owner.value.id);
|
|
115
|
+
let cells = byParent.get(id);
|
|
116
|
+
if (!cells)
|
|
117
|
+
byParent.set(id, cells = []);
|
|
118
|
+
cells.push(row.cells[names.indexOf(column.component.column.name)]);
|
|
119
|
+
}
|
|
120
|
+
components.set(column.name, new Map(result.rows.map((row, index) => [String(row.rootId), byParent.get(String(parentIds[index])) ?? []])));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
83
123
|
return {
|
|
84
124
|
rootType: type,
|
|
85
125
|
columns: columns.map(column => ({ path: column.name, kind: column.multiple ? 'scalar' :
|
|
@@ -89,6 +129,9 @@ async function projectColumns(type, columns, search, options) {
|
|
|
89
129
|
const cells = await Promise.all(columns.map(async (column) => {
|
|
90
130
|
if (!column.multiple)
|
|
91
131
|
return row.cells[singular.indexOf(column)];
|
|
132
|
+
if (column.component)
|
|
133
|
+
return { kind: 'value',
|
|
134
|
+
value: components.get(column.name).get(String(row.rootId)) ?? [] };
|
|
92
135
|
const value = object ? await object[column.name] : [];
|
|
93
136
|
return { kind: 'value', value: value ?? [] };
|
|
94
137
|
}));
|
package/cjs/columns.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../src/columns.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"columns.js","sourceRoot":"","sources":["../src/columns.ts"],"names":[],"mappings":"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"}
|
package/cjs/list.js
CHANGED
|
@@ -89,7 +89,8 @@ let List = (() => {
|
|
|
89
89
|
for (const field of column.fields ?? [])
|
|
90
90
|
await access.authorise(`${column.name}.${field}`);
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
const batch = typeof request.request.data.loadColumns === 'string';
|
|
93
|
+
if (request.request.data.columns !== undefined && typeof request.request.data.column !== 'string' && !batch) {
|
|
93
94
|
(0, persist_2.save)(this, request.request, type);
|
|
94
95
|
return this.htmlResponse('', 204);
|
|
95
96
|
}
|
|
@@ -98,13 +99,44 @@ let List = (() => {
|
|
|
98
99
|
for (const column of columns)
|
|
99
100
|
column.search = filter.search[column.name] ?? '';
|
|
100
101
|
sort.getParams(request.request, type);
|
|
101
|
-
|
|
102
|
+
if (!batch)
|
|
103
|
+
(0, persist_2.save)(this, request.request, type);
|
|
102
104
|
const options = feed.readOptions(filter.readOptions(sort.readOptions()));
|
|
103
105
|
const search = Object.assign(filter.searchObject(type), scope);
|
|
104
106
|
for (const path of Object.keys(search))
|
|
105
107
|
await access.authorise(path);
|
|
106
108
|
for (const path of Object.keys(sort.sorted ?? {}))
|
|
107
109
|
await access.authorise(path);
|
|
110
|
+
if (batch) {
|
|
111
|
+
try {
|
|
112
|
+
const names = request.request.data.loadColumns.split(',').filter(Boolean);
|
|
113
|
+
if (new Set(names).size !== names.length)
|
|
114
|
+
throw new Error('Duplicate column paths');
|
|
115
|
+
const requested = names.map(path => new projection_1.ListColumn(type, path));
|
|
116
|
+
for (const column of requested) {
|
|
117
|
+
if (!columns.serialize().includes(column.name))
|
|
118
|
+
throw new Error('Column absent from configuration');
|
|
119
|
+
await access.authorise(column.name);
|
|
120
|
+
for (const field of column.fields ?? [])
|
|
121
|
+
await access.authorise(`${column.name}.${field}`);
|
|
122
|
+
}
|
|
123
|
+
const ids = request.request.data.rowIds;
|
|
124
|
+
if (typeof ids !== 'string')
|
|
125
|
+
throw new Error('Visible row identities are required');
|
|
126
|
+
const result = requested.length ? await (0, columns_2.projectColumns)(type, requested, search, [new storage_1.Identifiers(ids ? ids.split(',') : [])]) : undefined;
|
|
127
|
+
const response = await Promise.all(requested.map(async (column, index) => ({
|
|
128
|
+
label: column.label, path: column.name, sortable: column.sortable,
|
|
129
|
+
rows: await Promise.all(result.rows.map(async (row) => ({
|
|
130
|
+
id: row.rootId, html: await column.output(row.cells[index])
|
|
131
|
+
})))
|
|
132
|
+
})));
|
|
133
|
+
(0, persist_2.save)(this, request.request, type);
|
|
134
|
+
return this.jsonResponse({ columns: response });
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
return this.jsonResponse({ error: error instanceof Error ? error.message : 'Columns unavailable' }, 400);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
108
140
|
if (typeof request.request.data.column === 'string') {
|
|
109
141
|
try {
|
|
110
142
|
const path = request.request.data.column;
|
package/cjs/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAAwD;AAExD,4CAAwD;AACxD,4CAAwD;AAExD,0CAAuD;AACvD,0CAAuD;AACvD,8CAAyD;AAEzD,8CAAyD;AACzD,8CAAyD;AACzD,qCAAiD;AACjD,uCAAkD;AAClD,uCAAkD;AAClD,iCAA+C;AAC/C,qCAAiD;AACjD,uCAAkD;AAClD,uCAAkD;AAClD,6CAAqD;AACrD,qDAAyD;AACzD,qDAAyD;AACzD,iCAA+C;AAE/C,mCAAwC;AAA/B,uGAAA,aAAa,OAAA;IAKT,IAAI;4BAFhB,IAAA,aAAI,EAAC,OAAO,EAAE,KAAK,CAAC,EACpB,IAAA,aAAK,EAAC,OAAO,CAAC;;;;sBACsC,eAAM;oBAAd,SAAQ,WAAS;;;;YAA9D,
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../src/list.ts"],"names":[],"mappings":"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"}
|
package/cjs/projection.d.ts
CHANGED
|
@@ -11,6 +11,13 @@ export declare function representationFields(type: Type, ancestors?: readonly Ty
|
|
|
11
11
|
export declare class ListColumn {
|
|
12
12
|
readonly root: Type;
|
|
13
13
|
readonly name: string;
|
|
14
|
+
readonly component?: {
|
|
15
|
+
column: ListColumn;
|
|
16
|
+
inverse: string;
|
|
17
|
+
parent: string;
|
|
18
|
+
path: string;
|
|
19
|
+
type: Type;
|
|
20
|
+
};
|
|
14
21
|
readonly field: string;
|
|
15
22
|
readonly fields?: readonly string[];
|
|
16
23
|
readonly label: string;
|
package/cjs/projection.js
CHANGED
|
@@ -3,13 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ListColumn = void 0;
|
|
4
4
|
exports.listRepresentationDependsOn = listRepresentationDependsOn;
|
|
5
5
|
exports.representationFields = representationFields;
|
|
6
|
+
const class_type_1 = require("@itrocks/class-type");
|
|
6
7
|
const class_view_1 = require("@itrocks/class-view");
|
|
7
8
|
const class_view_2 = require("@itrocks/class-view");
|
|
8
9
|
const class_view_3 = require("@itrocks/class-view");
|
|
9
10
|
const composition_1 = require("@itrocks/composition");
|
|
11
|
+
const composition_2 = require("@itrocks/composition");
|
|
10
12
|
const core_transformers_1 = require("@itrocks/core-transformers");
|
|
11
13
|
const core_transformers_2 = require("@itrocks/core-transformers");
|
|
12
14
|
const property_view_1 = require("@itrocks/property-view");
|
|
15
|
+
const reflect_1 = require("@itrocks/reflect");
|
|
16
|
+
const reflect_2 = require("@itrocks/reflect");
|
|
13
17
|
const reflect_path_1 = require("@itrocks/reflect-path");
|
|
14
18
|
const reflect_path_2 = require("@itrocks/reflect-path");
|
|
15
19
|
const storage_1 = require("@itrocks/storage");
|
|
@@ -41,6 +45,7 @@ function representationFields(type, ancestors = [], property) {
|
|
|
41
45
|
class ListColumn {
|
|
42
46
|
root;
|
|
43
47
|
name;
|
|
48
|
+
component;
|
|
44
49
|
field;
|
|
45
50
|
fields;
|
|
46
51
|
label;
|
|
@@ -58,12 +63,36 @@ class ListColumn {
|
|
|
58
63
|
const resolved = (0, reflect_path_2.resolvePropertyPath)(root, name);
|
|
59
64
|
this.multiple = resolved.targetMultiplicity === 'many';
|
|
60
65
|
this.sortable = !this.multiple;
|
|
61
|
-
if (
|
|
66
|
+
if (this.multiple && resolved.segments.length > 1) {
|
|
67
|
+
const index = resolved.segments.findIndex(property => property.relation?.targetMultiplicity === 'many');
|
|
68
|
+
const property = resolved.segments[index];
|
|
69
|
+
const target = property?.relation?.target;
|
|
70
|
+
if (target && (0, composition_1.componentOf)(property.class.type, property.name) && index < resolved.segments.length - 1) {
|
|
71
|
+
const inverses = Object.keys(new reflect_1.ReflectClass(target).propertyTypes).filter(name => {
|
|
72
|
+
if (!(0, composition_2.compositeOf)(target, name))
|
|
73
|
+
return false;
|
|
74
|
+
const relation = new reflect_2.ReflectProperty(target, name).relation;
|
|
75
|
+
return relation?.target && (0, class_type_1.inherits)(property.class.type, relation.target);
|
|
76
|
+
});
|
|
77
|
+
if (inverses.length === 1) {
|
|
78
|
+
const column = new ListColumn(target, name.split('.').slice(index + 1).join('.'));
|
|
79
|
+
if (!column.multiple)
|
|
80
|
+
this.component = {
|
|
81
|
+
column, inverse: inverses[0], parent: name.split('.').slice(0, index).join('.'),
|
|
82
|
+
path: name.split('.').slice(0, index + 1).join('.'), type: target
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (resolved.targetMultiplicity !== 'one' && !(this.multiple && resolved.segments.length === 1)
|
|
88
|
+
&& !this.component) {
|
|
62
89
|
throw new storage_1.SelectionError(resolved.targetMultiplicity === 'many' ? 'multiple-values' : 'unsupported-selection', name);
|
|
63
90
|
}
|
|
64
91
|
this.property = new reflect_path_1.ReflectPropertyPath(root, name);
|
|
65
92
|
this.target = resolved.target;
|
|
66
93
|
this.label = resolved.segments.map(property => (0, translate_1.tr)((0, property_view_1.displayOf)(property.class.type, property.name))).join('.');
|
|
94
|
+
if (this.component)
|
|
95
|
+
this.fields = this.component.column.fields;
|
|
67
96
|
if (resolved.target && !this.multiple)
|
|
68
97
|
this.fields = representationFields(resolved.target, [], resolved.property);
|
|
69
98
|
}
|
|
@@ -72,6 +101,12 @@ class ListColumn {
|
|
|
72
101
|
return '';
|
|
73
102
|
if (cell.kind === 'unloaded')
|
|
74
103
|
return '<span class="unavailable">Unavailable</span>';
|
|
104
|
+
if (this.component) {
|
|
105
|
+
const cells = cell.value;
|
|
106
|
+
const values = await Promise.all(cells.map(cell => this.component.column.output(cell)));
|
|
107
|
+
return (0, multiple_output_1.multipleOutputOf)(this.property.class.type, this.property.name) === 'lines'
|
|
108
|
+
? '<ul>' + values.map(value => `<li>${value}</li>`).join('') + '</ul>' : values.join(', ');
|
|
109
|
+
}
|
|
75
110
|
if (this.fields && this.fields.some(field => !cell.loadedFields?.includes(field)))
|
|
76
111
|
throw new storage_1.SelectionError('unsupported-selection', this.name);
|
|
77
112
|
if (this.multiple && (0, composition_1.componentOf)(this.property.class.type, this.property.name)) {
|
package/cjs/projection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"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"}
|
package/list.css
CHANGED
|
@@ -33,7 +33,7 @@ table.objects {
|
|
|
33
33
|
overflow-y: auto;
|
|
34
34
|
}
|
|
35
35
|
table.objects th {
|
|
36
|
-
background: #
|
|
36
|
+
background: #eee;
|
|
37
37
|
}
|
|
38
38
|
table.objects tr td, table.objects tr th {
|
|
39
39
|
border-bottom: 1px solid #d8d8d8;
|
|
@@ -164,12 +164,15 @@ table.objects > thead > tr.search > th > input:focus {
|
|
|
164
164
|
outline: none;
|
|
165
165
|
box-shadow: inset 0 0 0 2px Highlight, var(--column-reorder-tint, 0 0 transparent);
|
|
166
166
|
}
|
|
167
|
-
table.objects > thead + tbody > tr:nth-child(even)
|
|
167
|
+
table.objects > thead + tbody > tr:nth-child(even) {
|
|
168
168
|
background: #f8f8f8;
|
|
169
169
|
}
|
|
170
|
-
table.objects > thead + tbody > tr:nth-child(odd)
|
|
170
|
+
table.objects > thead + tbody > tr:nth-child(odd) {
|
|
171
171
|
background: white;
|
|
172
172
|
}
|
|
173
|
+
table.objects > thead + tbody > tr:hover {
|
|
174
|
+
background: #f4f4f4;
|
|
175
|
+
}
|
|
173
176
|
|
|
174
177
|
:not(article, article > form) > table.objects td, :not(article, article > form) > table.objects th {
|
|
175
178
|
border-top: 1px solid #d8d8d8;
|
package/package.json
CHANGED
package/property-select.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare class ListPropertySelect implements ConsumerPort {
|
|
|
33
33
|
private readonly article;
|
|
34
34
|
private readonly options;
|
|
35
35
|
private readonly abort;
|
|
36
|
+
private batch;
|
|
36
37
|
private readonly button;
|
|
37
38
|
private readonly content;
|
|
38
39
|
private disposed;
|
|
@@ -46,6 +47,8 @@ export declare class ListPropertySelect implements ConsumerPort {
|
|
|
46
47
|
readonly view: PropertySelectView;
|
|
47
48
|
constructor(article: HTMLElement, options: ListSelectorOptions);
|
|
48
49
|
private loadColumn;
|
|
50
|
+
private loadColumns;
|
|
51
|
+
private columnContent;
|
|
49
52
|
private add;
|
|
50
53
|
begin(intent: SelectionIntent, sample: PointerSample): void;
|
|
51
54
|
private columnSource;
|
|
@@ -58,4 +61,5 @@ export declare class ListPropertySelect implements ConsumerPort {
|
|
|
58
61
|
paths(): string[];
|
|
59
62
|
private remove;
|
|
60
63
|
select(intent: SelectionIntent, signal: AbortSignal): Promise<Outcome>;
|
|
64
|
+
selectMany(intents: readonly SelectionIntent[], signal: AbortSignal): Promise<readonly Outcome[]>;
|
|
61
65
|
}
|
package/property-select.js
CHANGED
|
@@ -5,6 +5,7 @@ export class ListPropertySelect {
|
|
|
5
5
|
article;
|
|
6
6
|
options;
|
|
7
7
|
abort = new AbortController();
|
|
8
|
+
batch = false;
|
|
8
9
|
button;
|
|
9
10
|
content = document.createElement('div');
|
|
10
11
|
disposed = false;
|
|
@@ -46,24 +47,36 @@ export class ListPropertySelect {
|
|
|
46
47
|
this.button.addEventListener('click', () => this.pane.open(), { signal: this.abort.signal });
|
|
47
48
|
}
|
|
48
49
|
async loadColumn(path, signal) {
|
|
50
|
+
return (await this.loadColumns([path], this.paths(), signal, true)).get(path);
|
|
51
|
+
}
|
|
52
|
+
async loadColumns(paths, columns, signal, single = false) {
|
|
49
53
|
const form = this.article.querySelector('form');
|
|
50
54
|
const table = this.article.querySelector('table.objects');
|
|
51
55
|
const rows = [...table.tBodies[0].rows];
|
|
52
56
|
const ids = rows.map(row => row.querySelector('input[name=id]').value);
|
|
53
|
-
const query = new URLSearchParams({
|
|
57
|
+
const query = new URLSearchParams({ columns: columns.join(','), rowIds: ids.join(',') });
|
|
58
|
+
query.set(single ? 'column' : 'loadColumns', paths.join(','));
|
|
54
59
|
const combined = AbortSignal.any([signal, this.abort.signal]);
|
|
55
60
|
const response = this.options.request
|
|
56
61
|
? await this.options.request(query, combined)
|
|
57
62
|
: await fetch(`${form.action}?${query}`, { signal: combined });
|
|
58
|
-
|
|
59
|
-
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
const result = await response.json();
|
|
60
65
|
throw new Error(result.error ?? 'Column unavailable');
|
|
66
|
+
}
|
|
67
|
+
const result = single ? [await response.json()]
|
|
68
|
+
: (await response.json()).columns;
|
|
61
69
|
signal.throwIfAborted();
|
|
62
70
|
if (this.disposed || !this.article.isConnected || rows.some((row, index) => table.tBodies[0].rows[index] !== row)
|
|
63
71
|
|| rows.length !== table.tBodies[0].rows.length)
|
|
64
72
|
throw new Error('The row view changed; try again');
|
|
65
|
-
if (result.
|
|
73
|
+
if (!Array.isArray(result) || result.length !== paths.length
|
|
74
|
+
|| paths.some(path => result.filter(column => column.path === path).length !== 1))
|
|
66
75
|
throw new Error('Mismatched column response');
|
|
76
|
+
return new Map(result.map(column => [column.path, this.columnContent(column, ids, table)]));
|
|
77
|
+
}
|
|
78
|
+
columnContent(result, ids, table) {
|
|
79
|
+
const path = result.path;
|
|
67
80
|
const values = new Map(result.rows.map(row => [String(row.id), row.html]));
|
|
68
81
|
if (ids.some(id => !values.has(id)))
|
|
69
82
|
throw new Error('The row scope changed; reload the list');
|
|
@@ -92,8 +105,10 @@ export class ListPropertySelect {
|
|
|
92
105
|
});
|
|
93
106
|
return { cells, header };
|
|
94
107
|
}
|
|
95
|
-
add(path, signal, options = {}) {
|
|
108
|
+
add(path, signal, options = {}, load) {
|
|
96
109
|
const source = this.columnSource(path);
|
|
110
|
+
if (load)
|
|
111
|
+
source.load = load;
|
|
97
112
|
const operation = this.options.addition.begin(source, options);
|
|
98
113
|
try {
|
|
99
114
|
signal.throwIfAborted();
|
|
@@ -114,7 +129,8 @@ export class ListPropertySelect {
|
|
|
114
129
|
}
|
|
115
130
|
const outcome = operation.commit();
|
|
116
131
|
this.removedColumns.delete(path);
|
|
117
|
-
|
|
132
|
+
if (!this.batch)
|
|
133
|
+
this.view.selector.setConfiguration({ usedPaths: this.paths() });
|
|
118
134
|
return outcome;
|
|
119
135
|
}
|
|
120
136
|
catch (error) {
|
|
@@ -123,7 +139,7 @@ export class ListPropertySelect {
|
|
|
123
139
|
}
|
|
124
140
|
}
|
|
125
141
|
begin(intent, sample) {
|
|
126
|
-
if (this.disposed || this.drag || this.pending.size)
|
|
142
|
+
if (this.disposed || this.batch || this.drag || this.pending.size)
|
|
127
143
|
throw new Error('A column operation is pending');
|
|
128
144
|
const path = normalisePath(intent.path);
|
|
129
145
|
const added = !this.paths().includes(path);
|
|
@@ -266,9 +282,14 @@ export class ListPropertySelect {
|
|
|
266
282
|
// Publish the unchecked state before starting the table's removal flash.
|
|
267
283
|
this.view.selector.setConfiguration({ usedPaths: this.paths() });
|
|
268
284
|
try {
|
|
269
|
-
const saving = this.options.saveColumns(this.paths());
|
|
270
285
|
const animation = this.options.addition.remove(path, AbortSignal.any([signal, removal.signal]));
|
|
271
|
-
const
|
|
286
|
+
const saving = this.options.saveColumns(this.paths());
|
|
287
|
+
const [animationResult, saved] = await Promise.allSettled([animation, saving]);
|
|
288
|
+
if (animationResult.status === 'rejected')
|
|
289
|
+
throw animationResult.reason;
|
|
290
|
+
if (saved.status === 'rejected')
|
|
291
|
+
throw saved.reason;
|
|
292
|
+
const removed = animationResult.value;
|
|
272
293
|
if (!removed) {
|
|
273
294
|
if (removal.signal.aborted && !signal.aborted && !this.disposed) {
|
|
274
295
|
await this.options.saveColumns(this.paths());
|
|
@@ -294,8 +315,8 @@ export class ListPropertySelect {
|
|
|
294
315
|
async select(intent, signal) {
|
|
295
316
|
const path = normalisePath(intent.path);
|
|
296
317
|
try {
|
|
297
|
-
if (this.drag)
|
|
298
|
-
throw new Error('A column
|
|
318
|
+
if (this.drag || this.batch)
|
|
319
|
+
throw new Error('A column operation is pending');
|
|
299
320
|
let status;
|
|
300
321
|
const pending = this.pending.get(path);
|
|
301
322
|
if (pending) {
|
|
@@ -343,4 +364,67 @@ export class ListPropertySelect {
|
|
|
343
364
|
return { ...intent, message: error instanceof Error ? error.message : 'Column unavailable', status: 'rejected' };
|
|
344
365
|
}
|
|
345
366
|
}
|
|
367
|
+
async selectMany(intents, signal) {
|
|
368
|
+
if (!intents.length)
|
|
369
|
+
return [];
|
|
370
|
+
if (this.batch || this.drag || this.pending.size || this.disposed)
|
|
371
|
+
return intents.map(intent => ({ ...intent, status: 'rejected', message: 'A column operation is pending' }));
|
|
372
|
+
this.batch = true;
|
|
373
|
+
const previous = this.paths();
|
|
374
|
+
const added = intents.filter(intent => !previous.includes(intent.path)).map(intent => intent.path);
|
|
375
|
+
const removed = intents.filter(intent => previous.includes(intent.path) && intent.action !== 'add')
|
|
376
|
+
.map(intent => intent.path);
|
|
377
|
+
const paths = [...previous.filter(path => !removed.includes(path)), ...added];
|
|
378
|
+
const abort = new AbortController();
|
|
379
|
+
const combined = AbortSignal.any([signal, this.abort.signal, abort.signal]);
|
|
380
|
+
let receive;
|
|
381
|
+
let fail;
|
|
382
|
+
const content = new Promise((resolve, reject) => { receive = resolve; fail = reject; });
|
|
383
|
+
void content.catch(() => { });
|
|
384
|
+
try {
|
|
385
|
+
for (const path of removed)
|
|
386
|
+
this.removals.set(path, abort);
|
|
387
|
+
for (const path of added) {
|
|
388
|
+
let first = true;
|
|
389
|
+
this.add(path, combined, { effects: 'deferred' }, signal => {
|
|
390
|
+
if (!first)
|
|
391
|
+
return this.loadColumn(path, signal);
|
|
392
|
+
first = false;
|
|
393
|
+
return content.then(content => content.get(path));
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
this.view.selector.setConfiguration({ usedPaths: this.paths() });
|
|
397
|
+
if (added.length)
|
|
398
|
+
this.options.addition.reveal(added.at(-1));
|
|
399
|
+
this.options.addition.highlightMany(added, true);
|
|
400
|
+
const animation = removed.length ? this.options.addition.removeMany(removed, combined) : Promise.resolve(true);
|
|
401
|
+
const request = this.loadColumns(added, paths, combined).then(receive, error => { fail(error); throw error; });
|
|
402
|
+
const [animated, loaded] = await Promise.allSettled([animation, request]);
|
|
403
|
+
if (animated.status === 'rejected')
|
|
404
|
+
throw animated.reason;
|
|
405
|
+
if (loaded.status === 'rejected')
|
|
406
|
+
throw loaded.reason;
|
|
407
|
+
if (!animated.value)
|
|
408
|
+
throw new Error('Column removal cancelled');
|
|
409
|
+
for (const path of removed) {
|
|
410
|
+
const index = previous.indexOf(path);
|
|
411
|
+
this.removedColumns.set(path, { left: previous[index - 1], right: previous[index + 1] });
|
|
412
|
+
}
|
|
413
|
+
return intents.map(intent => ({ ...intent, status: added.includes(intent.path) ? 'added'
|
|
414
|
+
: removed.includes(intent.path) ? 'removed' : 'existing' }));
|
|
415
|
+
}
|
|
416
|
+
catch (error) {
|
|
417
|
+
fail(error);
|
|
418
|
+
return intents.map(intent => ({ ...intent, status: 'rejected',
|
|
419
|
+
message: error instanceof Error ? error.message : 'Columns unavailable' }));
|
|
420
|
+
}
|
|
421
|
+
finally {
|
|
422
|
+
for (const path of removed)
|
|
423
|
+
if (this.removals.get(path) === abort)
|
|
424
|
+
this.removals.delete(path);
|
|
425
|
+
this.batch = false;
|
|
426
|
+
if (!this.disposed)
|
|
427
|
+
this.view.selector.setConfiguration({ usedPaths: this.paths() });
|
|
428
|
+
}
|
|
429
|
+
}
|
|
346
430
|
}
|