@revisium/schema-toolkit-ui 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -1
- package/dist/index.cjs +488 -137
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +138 -52
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +138 -52
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +491 -141
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -6593,7 +6593,12 @@ const FileActions = (0, mobx_react_lite.observer)(({ node }) => {
|
|
|
6593
6593
|
const file = event.target.files?.[0];
|
|
6594
6594
|
if (!file) return;
|
|
6595
6595
|
event.target.value = "";
|
|
6596
|
-
const
|
|
6596
|
+
const rowId = node.editorContext?.rowId ?? "";
|
|
6597
|
+
const result = await node.callbacks?.onUploadFile?.({
|
|
6598
|
+
rowId,
|
|
6599
|
+
fileId,
|
|
6600
|
+
file
|
|
6601
|
+
});
|
|
6597
6602
|
if (result) node.node.setValue(result, { internal: true });
|
|
6598
6603
|
}, [node, fileId]);
|
|
6599
6604
|
const handleOpenFile = (0, react.useCallback)(() => {
|
|
@@ -6930,9 +6935,10 @@ function extractColumns(rootNode) {
|
|
|
6930
6935
|
function collectColumns(node, parentPath, columns) {
|
|
6931
6936
|
for (const child of node.properties()) {
|
|
6932
6937
|
const fieldPath = buildFieldPath(parentPath, child.name());
|
|
6933
|
-
const
|
|
6934
|
-
if (
|
|
6935
|
-
else if (
|
|
6938
|
+
const result = resolveColumn(child, fieldPath);
|
|
6939
|
+
if (result === "recurse") collectColumns(child, fieldPath, columns);
|
|
6940
|
+
else if (result) if (Array.isArray(result)) for (const col of result) columns.push(col);
|
|
6941
|
+
else columns.push(result);
|
|
6936
6942
|
}
|
|
6937
6943
|
}
|
|
6938
6944
|
function buildFieldPath(parentPath, fieldName) {
|
|
@@ -6940,8 +6946,8 @@ function buildFieldPath(parentPath, fieldName) {
|
|
|
6940
6946
|
}
|
|
6941
6947
|
function resolveColumn(child, fieldPath) {
|
|
6942
6948
|
if (child.isArray()) return null;
|
|
6943
|
-
const
|
|
6944
|
-
if (
|
|
6949
|
+
const refResult = resolveRefColumn(child, fieldPath);
|
|
6950
|
+
if (refResult) return refResult;
|
|
6945
6951
|
if (child.isObject() && !child.isRef()) return "recurse";
|
|
6946
6952
|
if (child.foreignKey() !== void 0) {
|
|
6947
6953
|
const col = createColumn(fieldPath, child, FilterFieldType.ForeignKey);
|
|
@@ -6965,13 +6971,22 @@ function resolveRefColumn(child, fieldPath) {
|
|
|
6965
6971
|
isDeprecated: child.metadata().deprecated ?? false,
|
|
6966
6972
|
hasFormula: child.hasFormula()
|
|
6967
6973
|
};
|
|
6968
|
-
if (refValue === _revisium_schema_toolkit.SystemSchemaIds.File) return
|
|
6974
|
+
if (refValue === _revisium_schema_toolkit.SystemSchemaIds.File) return resolveFileRefColumns(child, fieldPath);
|
|
6969
6975
|
return null;
|
|
6970
6976
|
}
|
|
6977
|
+
function resolveFileRefColumns(child, fieldPath) {
|
|
6978
|
+
const result = [createColumn(fieldPath, child, FilterFieldType.File)];
|
|
6979
|
+
if (child.isObject()) for (const subField of child.properties()) {
|
|
6980
|
+
const subFieldPath = buildFieldPath(fieldPath, subField.name());
|
|
6981
|
+
const fieldType = NODE_TYPE_TO_FIELD_TYPE[subField.nodeType()];
|
|
6982
|
+
if (fieldType) result.push(createColumn(subFieldPath, subField, fieldType));
|
|
6983
|
+
}
|
|
6984
|
+
return result;
|
|
6985
|
+
}
|
|
6971
6986
|
function createColumn(fieldPath, child, fieldType) {
|
|
6972
6987
|
return {
|
|
6973
6988
|
field: fieldPath,
|
|
6974
|
-
label:
|
|
6989
|
+
label: fieldPath,
|
|
6975
6990
|
fieldType,
|
|
6976
6991
|
isSystem: false,
|
|
6977
6992
|
isDeprecated: child.metadata().deprecated ?? false,
|
|
@@ -6981,9 +6996,9 @@ function createColumn(fieldPath, child, fieldType) {
|
|
|
6981
6996
|
|
|
6982
6997
|
//#endregion
|
|
6983
6998
|
//#region src/table-editor/Columns/model/selectDefaultColumns.ts
|
|
6984
|
-
const SEMANTIC_NAME_PATTERNS = /^(title|name|label)$/i;
|
|
6999
|
+
const SEMANTIC_NAME_PATTERNS = /^(title|name|label|subject|summary|description|heading|caption|email|username|displayName|firstName|lastName)$/i;
|
|
6985
7000
|
const PRIORITY_BY_TYPE = {
|
|
6986
|
-
[FilterFieldType.File]:
|
|
7001
|
+
[FilterFieldType.File]: 2,
|
|
6987
7002
|
[FilterFieldType.String]: 2,
|
|
6988
7003
|
[FilterFieldType.Number]: 3,
|
|
6989
7004
|
[FilterFieldType.Boolean]: 3,
|
|
@@ -6994,8 +7009,23 @@ function columnPriority(col) {
|
|
|
6994
7009
|
if (col.fieldType === FilterFieldType.String && SEMANTIC_NAME_PATTERNS.test(col.label)) return 1;
|
|
6995
7010
|
return PRIORITY_BY_TYPE[col.fieldType];
|
|
6996
7011
|
}
|
|
6997
|
-
function selectDefaultColumns(columns, maxVisible =
|
|
6998
|
-
|
|
7012
|
+
function selectDefaultColumns(columns, maxVisible = 4) {
|
|
7013
|
+
const idColumn = columns.find((col) => col.isSystem && col.field === "id");
|
|
7014
|
+
const fileFieldPrefixes = columns.filter((col) => col.fieldType === FilterFieldType.File).map((col) => `${col.field}.`);
|
|
7015
|
+
const sorted = [...columns.filter((col) => !col.isSystem && !col.isDeprecated && !fileFieldPrefixes.some((prefix) => col.field.startsWith(prefix)))].sort((a, b) => columnPriority(a) - columnPriority(b));
|
|
7016
|
+
const dataSlots = idColumn ? maxVisible - 1 : maxVisible;
|
|
7017
|
+
let fileIncluded = false;
|
|
7018
|
+
const dataColumns = [];
|
|
7019
|
+
for (const col of sorted) {
|
|
7020
|
+
if (dataColumns.length >= dataSlots) break;
|
|
7021
|
+
if (col.fieldType === FilterFieldType.File) {
|
|
7022
|
+
if (fileIncluded) continue;
|
|
7023
|
+
fileIncluded = true;
|
|
7024
|
+
}
|
|
7025
|
+
dataColumns.push(col);
|
|
7026
|
+
}
|
|
7027
|
+
if (idColumn) return [idColumn, ...dataColumns];
|
|
7028
|
+
return dataColumns;
|
|
6999
7029
|
}
|
|
7000
7030
|
|
|
7001
7031
|
//#endregion
|
|
@@ -7038,10 +7068,13 @@ var ColumnsModel = class {
|
|
|
7038
7068
|
return this._visibleFields.length > 1;
|
|
7039
7069
|
}
|
|
7040
7070
|
get sortableFields() {
|
|
7041
|
-
return this.
|
|
7071
|
+
return this._operableFields;
|
|
7042
7072
|
}
|
|
7043
7073
|
get filterableFields() {
|
|
7044
|
-
return this.
|
|
7074
|
+
return this._operableFields;
|
|
7075
|
+
}
|
|
7076
|
+
get _operableFields() {
|
|
7077
|
+
return this._allColumns.filter((col) => !col.isDeprecated && col.fieldType !== FilterFieldType.File);
|
|
7045
7078
|
}
|
|
7046
7079
|
get pinnedLeftCount() {
|
|
7047
7080
|
let count = 0;
|
|
@@ -7164,6 +7197,8 @@ var ColumnsModel = class {
|
|
|
7164
7197
|
}
|
|
7165
7198
|
setColumnWidth(field, width) {
|
|
7166
7199
|
this._columnWidths.set(field, width);
|
|
7200
|
+
}
|
|
7201
|
+
commitColumnWidth() {
|
|
7167
7202
|
this._notifyChange();
|
|
7168
7203
|
}
|
|
7169
7204
|
getColumnWidth(field) {
|
|
@@ -7290,7 +7325,8 @@ var ColumnsModel = class {
|
|
|
7290
7325
|
if (vc.pinned !== void 0) this._pinnedColumns.set(field, vc.pinned);
|
|
7291
7326
|
}
|
|
7292
7327
|
}
|
|
7293
|
-
this._visibleFields =
|
|
7328
|
+
if (fields.length === 0) this._visibleFields = selectDefaultColumns(this._allColumns).map((col) => col.field);
|
|
7329
|
+
else this._visibleFields = fields;
|
|
7294
7330
|
}
|
|
7295
7331
|
setOnChange(cb) {
|
|
7296
7332
|
this._onChange = cb;
|
|
@@ -8146,9 +8182,25 @@ var FilterCore = class FilterCore {
|
|
|
8146
8182
|
this._notifyChange();
|
|
8147
8183
|
}
|
|
8148
8184
|
applySnapshot(serialized) {
|
|
8149
|
-
|
|
8185
|
+
let parsed;
|
|
8186
|
+
try {
|
|
8187
|
+
parsed = JSON.parse(serialized);
|
|
8188
|
+
} catch {
|
|
8189
|
+
return;
|
|
8190
|
+
}
|
|
8191
|
+
if (!parsed || typeof parsed !== "object" || !Array.isArray(parsed.conditions) || !Array.isArray(parsed.groups)) return;
|
|
8192
|
+
const validFields = new Set(this._availableFields.map((f) => f.field));
|
|
8193
|
+
const cleaned = FilterCore._stripInvalidConditions(parsed, validFields);
|
|
8194
|
+
this._committedHasFilters = this._serializer.applySnapshot(JSON.stringify(cleaned));
|
|
8150
8195
|
this._notifyChange();
|
|
8151
8196
|
}
|
|
8197
|
+
static _stripInvalidConditions(group, validFields) {
|
|
8198
|
+
return {
|
|
8199
|
+
...group,
|
|
8200
|
+
conditions: group.conditions.filter((c) => validFields.has(c.field)),
|
|
8201
|
+
groups: group.groups.map((g) => FilterCore._stripInvalidConditions(g, validFields)).filter((g) => g.conditions.length > 0 || g.groups.length > 0)
|
|
8202
|
+
};
|
|
8203
|
+
}
|
|
8152
8204
|
clearAll() {
|
|
8153
8205
|
this._row.reset(FilterCore._emptyFilterData());
|
|
8154
8206
|
this._committedHasFilters = false;
|
|
@@ -9642,11 +9694,11 @@ var ObservableFSM = class {
|
|
|
9642
9694
|
_onUnhandledEvent;
|
|
9643
9695
|
constructor(config) {
|
|
9644
9696
|
this._state = config.initial;
|
|
9645
|
-
this._context = { ...config.context };
|
|
9697
|
+
this._context = mobx.observable.object({ ...config.context }, void 0, { deep: false });
|
|
9646
9698
|
this._transitions = config.transitions;
|
|
9647
9699
|
this._onTransition = config.onTransition;
|
|
9648
9700
|
this._onUnhandledEvent = config.onUnhandledEvent;
|
|
9649
|
-
(0, mobx.makeAutoObservable)(this, {}, { autoBind: true });
|
|
9701
|
+
(0, mobx.makeAutoObservable)(this, { _context: false }, { autoBind: true });
|
|
9650
9702
|
}
|
|
9651
9703
|
get state() {
|
|
9652
9704
|
return this._state;
|
|
@@ -9932,6 +9984,7 @@ var CellFSM = class {
|
|
|
9932
9984
|
_fsm;
|
|
9933
9985
|
constructor() {
|
|
9934
9986
|
this._fsm = new ObservableFSM(createConfig());
|
|
9987
|
+
(0, mobx.makeAutoObservable)(this, {}, { autoBind: true });
|
|
9935
9988
|
}
|
|
9936
9989
|
get state() {
|
|
9937
9990
|
return this._fsm.state;
|
|
@@ -10116,13 +10169,15 @@ var CellVM = class {
|
|
|
10116
10169
|
_rowId;
|
|
10117
10170
|
_cellFSM;
|
|
10118
10171
|
_onCommit;
|
|
10119
|
-
|
|
10172
|
+
_systemValues;
|
|
10173
|
+
constructor(rowModel, column, rowId, cellFSM, onCommit, systemValues) {
|
|
10120
10174
|
this._rowModel = rowModel;
|
|
10121
10175
|
this._column = column;
|
|
10122
10176
|
this._rowId = rowId;
|
|
10123
10177
|
this._cellFSM = cellFSM;
|
|
10124
10178
|
this._onCommit = onCommit ?? null;
|
|
10125
|
-
|
|
10179
|
+
this._systemValues = systemValues ?? null;
|
|
10180
|
+
(0, mobx.makeAutoObservable)(this, { selectionEdges: (0, mobx.computed)({ equals: mobx.comparer.structural }) }, { autoBind: true });
|
|
10126
10181
|
}
|
|
10127
10182
|
get field() {
|
|
10128
10183
|
return this._column.field;
|
|
@@ -10137,6 +10192,7 @@ var CellVM = class {
|
|
|
10137
10192
|
return this._rowId;
|
|
10138
10193
|
}
|
|
10139
10194
|
get value() {
|
|
10195
|
+
if (this._systemValues) return this._systemValues[this._column.field];
|
|
10140
10196
|
const node = this._getNode();
|
|
10141
10197
|
if (!node) return;
|
|
10142
10198
|
return node.getPlainValue();
|
|
@@ -10148,10 +10204,21 @@ var CellVM = class {
|
|
|
10148
10204
|
if (typeof val === "number") return String(val);
|
|
10149
10205
|
if (typeof val === "string") return val;
|
|
10150
10206
|
if (Array.isArray(val)) return `[${val.length}]`;
|
|
10151
|
-
if (typeof val === "object")
|
|
10207
|
+
if (typeof val === "object") {
|
|
10208
|
+
const obj = val;
|
|
10209
|
+
if (typeof obj.fileName === "string" && obj.fileName) return obj.fileName;
|
|
10210
|
+
if (this._column.fieldType === FilterFieldType.File) return "";
|
|
10211
|
+
return "{...}";
|
|
10212
|
+
}
|
|
10152
10213
|
return "";
|
|
10153
10214
|
}
|
|
10154
10215
|
get isReadOnly() {
|
|
10216
|
+
if (this._systemValues) return true;
|
|
10217
|
+
if (this._column.fieldType === FilterFieldType.File) {
|
|
10218
|
+
const fileNameNode = this._getFileNameNode();
|
|
10219
|
+
if (!fileNameNode?.isPrimitive()) return true;
|
|
10220
|
+
return fileNameNode.isReadOnly;
|
|
10221
|
+
}
|
|
10155
10222
|
const node = this._getNode();
|
|
10156
10223
|
if (!node) return true;
|
|
10157
10224
|
if (node.isPrimitive()) return node.isReadOnly;
|
|
@@ -10160,8 +10227,25 @@ var CellVM = class {
|
|
|
10160
10227
|
get foreignKeyTableId() {
|
|
10161
10228
|
return this._column.foreignKeyTableId;
|
|
10162
10229
|
}
|
|
10230
|
+
get fileData() {
|
|
10231
|
+
if (this._column.fieldType !== FilterFieldType.File) return null;
|
|
10232
|
+
const val = this.value;
|
|
10233
|
+
if (!val || typeof val !== "object" || Array.isArray(val)) return null;
|
|
10234
|
+
const obj = val;
|
|
10235
|
+
return {
|
|
10236
|
+
status: obj.status ?? "",
|
|
10237
|
+
fileId: obj.fileId ?? "",
|
|
10238
|
+
url: obj.url ?? "",
|
|
10239
|
+
fileName: obj.fileName ?? "",
|
|
10240
|
+
mimeType: obj.mimeType ?? "",
|
|
10241
|
+
width: typeof obj.width === "number" ? obj.width : 0,
|
|
10242
|
+
height: typeof obj.height === "number" ? obj.height : 0
|
|
10243
|
+
};
|
|
10244
|
+
}
|
|
10163
10245
|
get isEditable() {
|
|
10246
|
+
if (this._systemValues) return false;
|
|
10164
10247
|
if (this.isReadOnly) return false;
|
|
10248
|
+
if (this._column.fieldType === FilterFieldType.File) return this._getFileNameNode() !== void 0;
|
|
10165
10249
|
const node = this._getNode();
|
|
10166
10250
|
if (!node) return false;
|
|
10167
10251
|
return node.isPrimitive();
|
|
@@ -10213,6 +10297,11 @@ var CellVM = class {
|
|
|
10213
10297
|
this._cellFSM.doubleClick(clickOffset);
|
|
10214
10298
|
}
|
|
10215
10299
|
commitEdit(newValue) {
|
|
10300
|
+
if (this._column.fieldType === FilterFieldType.File) {
|
|
10301
|
+
this._commitFileNameEdit(newValue);
|
|
10302
|
+
this._cellFSM.commit();
|
|
10303
|
+
return;
|
|
10304
|
+
}
|
|
10216
10305
|
const node = this._getNode();
|
|
10217
10306
|
const previousValue = node?.getPlainValue();
|
|
10218
10307
|
if (node?.isPrimitive()) node.setValue(newValue);
|
|
@@ -10220,6 +10309,11 @@ var CellVM = class {
|
|
|
10220
10309
|
this._onCommit?.(this._rowId, this._column.field, newValue, previousValue);
|
|
10221
10310
|
}
|
|
10222
10311
|
commitEditAndMoveDown(newValue) {
|
|
10312
|
+
if (this._column.fieldType === FilterFieldType.File && newValue !== void 0) {
|
|
10313
|
+
this._commitFileNameEdit(newValue);
|
|
10314
|
+
this._cellFSM.commitAndMoveDown();
|
|
10315
|
+
return;
|
|
10316
|
+
}
|
|
10223
10317
|
let previousValue;
|
|
10224
10318
|
if (newValue !== void 0) {
|
|
10225
10319
|
const node = this._getNode();
|
|
@@ -10232,6 +10326,13 @@ var CellVM = class {
|
|
|
10232
10326
|
cancelEdit() {
|
|
10233
10327
|
this._cellFSM.cancel();
|
|
10234
10328
|
}
|
|
10329
|
+
commitFileUpload(result) {
|
|
10330
|
+
const node = this._getNode();
|
|
10331
|
+
if (!node?.isObject()) return;
|
|
10332
|
+
const previousValue = node.getPlainValue();
|
|
10333
|
+
node.setValue(result, { internal: true });
|
|
10334
|
+
this._onCommit?.(this._rowId, this._column.field, result, previousValue);
|
|
10335
|
+
}
|
|
10235
10336
|
clearToDefault() {
|
|
10236
10337
|
const node = this._getNode();
|
|
10237
10338
|
if (!node || !node.isPrimitive() || node.isReadOnly) return;
|
|
@@ -10314,6 +10415,19 @@ var CellVM = class {
|
|
|
10314
10415
|
_getNode() {
|
|
10315
10416
|
return this._rowModel.get(this._column.field);
|
|
10316
10417
|
}
|
|
10418
|
+
_getFileNameNode() {
|
|
10419
|
+
return this._rowModel.get(`${this._column.field}.fileName`);
|
|
10420
|
+
}
|
|
10421
|
+
_commitFileNameEdit(newFileName) {
|
|
10422
|
+
const fileNameNode = this._getFileNameNode();
|
|
10423
|
+
if (!fileNameNode?.isPrimitive()) return;
|
|
10424
|
+
const objectNode = this._getNode();
|
|
10425
|
+
if (!objectNode) return;
|
|
10426
|
+
const previousValue = objectNode.getPlainValue();
|
|
10427
|
+
fileNameNode.setValue(newFileName);
|
|
10428
|
+
const newValue = objectNode.getPlainValue();
|
|
10429
|
+
this._onCommit?.(this._rowId, this._column.field, newValue, previousValue);
|
|
10430
|
+
}
|
|
10317
10431
|
_applyPastedString(node, text) {
|
|
10318
10432
|
let trimmed = text;
|
|
10319
10433
|
while (trimmed.endsWith("\n")) trimmed = trimmed.slice(0, -1);
|
|
@@ -10340,13 +10454,15 @@ var RowVM = class {
|
|
|
10340
10454
|
_cellFSM;
|
|
10341
10455
|
_selection;
|
|
10342
10456
|
_onCellCommit;
|
|
10457
|
+
_systemValues;
|
|
10343
10458
|
_cellCache = /* @__PURE__ */ new Map();
|
|
10344
|
-
constructor(rowModel, rowId, cellFSM, selection, onCellCommit) {
|
|
10459
|
+
constructor(rowModel, rowId, cellFSM, selection, onCellCommit, systemValues) {
|
|
10345
10460
|
this._rowModel = rowModel;
|
|
10346
10461
|
this._rowId = rowId;
|
|
10347
10462
|
this._cellFSM = cellFSM;
|
|
10348
10463
|
this._selection = selection;
|
|
10349
10464
|
this._onCellCommit = onCellCommit ?? null;
|
|
10465
|
+
this._systemValues = systemValues ?? {};
|
|
10350
10466
|
(0, mobx.makeAutoObservable)(this, {}, { autoBind: true });
|
|
10351
10467
|
}
|
|
10352
10468
|
get rowId() {
|
|
@@ -10364,7 +10480,7 @@ var RowVM = class {
|
|
|
10364
10480
|
getCellVM(column) {
|
|
10365
10481
|
const cached = this._cellCache.get(column.field);
|
|
10366
10482
|
if (cached) return cached;
|
|
10367
|
-
const cell = new CellVM(this._rowModel, column, this._rowId, this._cellFSM, this._onCellCommit ?? void 0);
|
|
10483
|
+
const cell = new CellVM(this._rowModel, column, this._rowId, this._cellFSM, this._onCellCommit ?? void 0, column.isSystem ? this._systemValues : void 0);
|
|
10368
10484
|
this._cellCache.set(column.field, cell);
|
|
10369
10485
|
return cell;
|
|
10370
10486
|
}
|
|
@@ -10758,14 +10874,13 @@ const stateStyles = {
|
|
|
10758
10874
|
}
|
|
10759
10875
|
};
|
|
10760
10876
|
function getCellState(cell) {
|
|
10761
|
-
const hasRange = cell.hasRangeSelection;
|
|
10762
10877
|
if (cell.isReadOnly) {
|
|
10763
|
-
if (cell.isFocused && !
|
|
10878
|
+
if (cell.isFocused && !cell.isInSelection) return "readonlyFocused";
|
|
10764
10879
|
if (cell.isInSelection) return "selected";
|
|
10765
10880
|
return "readonly";
|
|
10766
10881
|
}
|
|
10767
10882
|
if (cell.isEditing) return "editing";
|
|
10768
|
-
if (cell.isFocused && !
|
|
10883
|
+
if (cell.isFocused && !cell.isInSelection) return "focused";
|
|
10769
10884
|
if (cell.isInSelection) return "selected";
|
|
10770
10885
|
return "display";
|
|
10771
10886
|
}
|
|
@@ -10803,7 +10918,7 @@ const CellWrapper = (0, mobx_react_lite.observer)(({ cell, children, onDoubleCli
|
|
|
10803
10918
|
const deferredEdit = useDeferredMenuEdit(onStartEdit ?? onDoubleClick);
|
|
10804
10919
|
const state = getCellState(cell);
|
|
10805
10920
|
const selectionEdges = cell.selectionEdges;
|
|
10806
|
-
const isAnchorInRange = cell.isAnchor && cell.
|
|
10921
|
+
const isAnchorInRange = cell.isAnchor && cell.isInSelection;
|
|
10807
10922
|
const navVersion = cell.navigationVersion;
|
|
10808
10923
|
(0, react.useEffect)(() => {
|
|
10809
10924
|
if (!cellRef.current) return;
|
|
@@ -10966,61 +11081,68 @@ function useTextareaCell(cell) {
|
|
|
10966
11081
|
};
|
|
10967
11082
|
}, []);
|
|
10968
11083
|
const trigger = cell.editTrigger;
|
|
11084
|
+
const clickOffsetValue = trigger?.type === "doubleClick" ? trigger.clickOffset : void 0;
|
|
11085
|
+
const appendCharValue = trigger?.type === "char" ? trigger.char : void 0;
|
|
11086
|
+
const startEditing = (0, react.useCallback)((clientX) => {
|
|
11087
|
+
if (!cell.isEditable) return;
|
|
11088
|
+
const offset = clientX === void 0 ? void 0 : getClickOffset(textRef.current, cell.displayValue, clientX);
|
|
11089
|
+
cell.startEditWithDoubleClick(offset);
|
|
11090
|
+
}, [cell]);
|
|
11091
|
+
const handleTypeChar = (0, react.useCallback)((char) => {
|
|
11092
|
+
if (!cell.isEditable) return;
|
|
11093
|
+
cell.startEditWithChar(char);
|
|
11094
|
+
}, [cell]);
|
|
11095
|
+
const handleCommitted = (0, react.useCallback)(() => {}, []);
|
|
11096
|
+
const handleCancel = (0, react.useCallback)(() => {
|
|
11097
|
+
cell.cancelEdit();
|
|
11098
|
+
}, [cell]);
|
|
11099
|
+
const handleStartEditFromKeyboard = (0, react.useCallback)(() => {
|
|
11100
|
+
if (!cell.isEditable) return;
|
|
11101
|
+
cell.startEdit();
|
|
11102
|
+
}, [cell]);
|
|
11103
|
+
const trimValue = (0, react.useCallback)((localValue) => {
|
|
11104
|
+
let trimmed = localValue;
|
|
11105
|
+
while (trimmed.endsWith("\n")) trimmed = trimmed.slice(0, -1);
|
|
11106
|
+
return trimmed;
|
|
11107
|
+
}, []);
|
|
10969
11108
|
return {
|
|
10970
11109
|
cellRef,
|
|
10971
11110
|
textRef,
|
|
10972
11111
|
getEditPosition,
|
|
10973
|
-
clickOffsetValue
|
|
10974
|
-
appendCharValue
|
|
10975
|
-
startEditing
|
|
10976
|
-
|
|
10977
|
-
|
|
10978
|
-
|
|
10979
|
-
|
|
10980
|
-
|
|
10981
|
-
|
|
10982
|
-
|
|
10983
|
-
|
|
10984
|
-
|
|
10985
|
-
|
|
10986
|
-
|
|
10987
|
-
|
|
10988
|
-
|
|
10989
|
-
if (
|
|
10990
|
-
cell.
|
|
10991
|
-
|
|
11112
|
+
clickOffsetValue,
|
|
11113
|
+
appendCharValue,
|
|
11114
|
+
startEditing,
|
|
11115
|
+
handleTypeChar,
|
|
11116
|
+
handleCommit: (0, react.useCallback)((localValue) => {
|
|
11117
|
+
const trimmed = trimValue(localValue);
|
|
11118
|
+
if (trimmed === cell.displayValue) cell.cancelEdit();
|
|
11119
|
+
else cell.commitEdit(trimmed);
|
|
11120
|
+
handleCommitted();
|
|
11121
|
+
}, [
|
|
11122
|
+
cell,
|
|
11123
|
+
handleCommitted,
|
|
11124
|
+
trimValue
|
|
11125
|
+
]),
|
|
11126
|
+
handleCommitEnter: (0, react.useCallback)((localValue) => {
|
|
11127
|
+
const trimmed = trimValue(localValue);
|
|
11128
|
+
if (trimmed === cell.displayValue) cell.commitEditAndMoveDown();
|
|
11129
|
+
else cell.commitEditAndMoveDown(trimmed);
|
|
11130
|
+
handleCommitted();
|
|
11131
|
+
}, [
|
|
11132
|
+
cell,
|
|
11133
|
+
handleCommitted,
|
|
11134
|
+
trimValue
|
|
11135
|
+
]),
|
|
11136
|
+
handleCommitted,
|
|
11137
|
+
handleCancel,
|
|
11138
|
+
handleStartEditFromKeyboard
|
|
10992
11139
|
};
|
|
10993
11140
|
}
|
|
10994
11141
|
|
|
10995
11142
|
//#endregion
|
|
10996
11143
|
//#region src/table-editor/Table/ui/Cell/StringCell.tsx
|
|
10997
11144
|
const StringCell = (0, mobx_react_lite.observer)(({ cell }) => {
|
|
10998
|
-
const { cellRef, textRef, getEditPosition, clickOffsetValue, appendCharValue, startEditing, handleTypeChar,
|
|
10999
|
-
const trimValue = (0, react.useCallback)((localValue) => {
|
|
11000
|
-
let trimmed = localValue;
|
|
11001
|
-
while (trimmed.endsWith("\n")) trimmed = trimmed.slice(0, -1);
|
|
11002
|
-
return trimmed;
|
|
11003
|
-
}, []);
|
|
11004
|
-
const handleCommit = (0, react.useCallback)((localValue) => {
|
|
11005
|
-
const trimmed = trimValue(localValue);
|
|
11006
|
-
if (trimmed !== cell.displayValue) cell.commitEdit(trimmed);
|
|
11007
|
-
else cell.cancelEdit();
|
|
11008
|
-
handleCommitted();
|
|
11009
|
-
}, [
|
|
11010
|
-
cell,
|
|
11011
|
-
handleCommitted,
|
|
11012
|
-
trimValue
|
|
11013
|
-
]);
|
|
11014
|
-
const handleCommitEnter = (0, react.useCallback)((localValue) => {
|
|
11015
|
-
const trimmed = trimValue(localValue);
|
|
11016
|
-
if (trimmed === cell.displayValue) cell.commitEditAndMoveDown();
|
|
11017
|
-
else cell.commitEditAndMoveDown(trimmed);
|
|
11018
|
-
handleCommitted();
|
|
11019
|
-
}, [
|
|
11020
|
-
cell,
|
|
11021
|
-
handleCommitted,
|
|
11022
|
-
trimValue
|
|
11023
|
-
]);
|
|
11145
|
+
const { cellRef, textRef, getEditPosition, clickOffsetValue, appendCharValue, startEditing, handleTypeChar, handleCommit, handleCommitEnter, handleCancel, handleStartEditFromKeyboard } = useTextareaCell(cell);
|
|
11024
11146
|
const editPosition = cell.isEditing ? getEditPosition() : null;
|
|
11025
11147
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, {
|
|
11026
11148
|
ref: cellRef,
|
|
@@ -11261,19 +11383,144 @@ const ForeignKeyCell = (0, mobx_react_lite.observer)(({ cell, onSearchForeignKey
|
|
|
11261
11383
|
|
|
11262
11384
|
//#endregion
|
|
11263
11385
|
//#region src/table-editor/Table/ui/Cell/FileCell.tsx
|
|
11264
|
-
const FileCell = (0, mobx_react_lite.observer)(({ cell }) => {
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11386
|
+
const FileCell = (0, mobx_react_lite.observer)(({ cell, onUploadFile, onOpenFile }) => {
|
|
11387
|
+
const fileInputRef = (0, react.useRef)(null);
|
|
11388
|
+
const fileData = cell.fileData;
|
|
11389
|
+
const status = fileData?.status ?? "";
|
|
11390
|
+
const fileId = fileData?.fileId ?? "";
|
|
11391
|
+
const url = fileData?.url ?? "";
|
|
11392
|
+
const mimeType = fileData?.mimeType ?? "";
|
|
11393
|
+
const width = fileData?.width ?? 0;
|
|
11394
|
+
const height = fileData?.height ?? 0;
|
|
11395
|
+
const isReadonly = cell.isReadOnly;
|
|
11396
|
+
const isEditing = cell.isEditing;
|
|
11397
|
+
const availablePreview = mimeType.startsWith("image/");
|
|
11398
|
+
const showViewFile = Boolean(url);
|
|
11399
|
+
const showUploadFile = !isReadonly && Boolean(onUploadFile) && (status === "ready" || status === "uploaded");
|
|
11400
|
+
const showInfo = !showViewFile && !showUploadFile && isReadonly;
|
|
11401
|
+
const { cellRef, textRef, getEditPosition, clickOffsetValue, appendCharValue, startEditing, handleTypeChar, handleCommit, handleCommitEnter, handleCancel, handleStartEditFromKeyboard } = useTextareaCell(cell);
|
|
11402
|
+
const handleFileChange = (0, react.useCallback)(async (event) => {
|
|
11403
|
+
const file = event.target.files?.[0];
|
|
11404
|
+
if (!file) return;
|
|
11405
|
+
event.target.value = "";
|
|
11406
|
+
try {
|
|
11407
|
+
const result = await onUploadFile?.({
|
|
11408
|
+
rowId: cell.rowId,
|
|
11409
|
+
fileId,
|
|
11410
|
+
file
|
|
11411
|
+
});
|
|
11412
|
+
if (result) cell.commitFileUpload(result);
|
|
11413
|
+
} catch {}
|
|
11414
|
+
}, [
|
|
11415
|
+
onUploadFile,
|
|
11416
|
+
fileId,
|
|
11417
|
+
cell
|
|
11418
|
+
]);
|
|
11419
|
+
const handleOpenFile = (0, react.useCallback)(() => {
|
|
11420
|
+
if (onOpenFile) onOpenFile(url);
|
|
11421
|
+
else window.open(url, "_blank", "noopener,noreferrer");
|
|
11422
|
+
}, [onOpenFile, url]);
|
|
11423
|
+
const handleUploadClick = (0, react.useCallback)((e) => {
|
|
11424
|
+
e.stopPropagation();
|
|
11425
|
+
fileInputRef.current?.click();
|
|
11426
|
+
}, []);
|
|
11427
|
+
const editPosition = isEditing ? getEditPosition() : null;
|
|
11428
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, {
|
|
11429
|
+
ref: cellRef,
|
|
11430
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellWrapper, {
|
|
11431
|
+
cell,
|
|
11432
|
+
onDoubleClick: cell.isEditable ? startEditing : void 0,
|
|
11433
|
+
onStartEdit: cell.isEditable ? handleStartEditFromKeyboard : void 0,
|
|
11434
|
+
onTypeChar: cell.isEditable ? handleTypeChar : void 0,
|
|
11435
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.HStack, {
|
|
11436
|
+
gap: 1,
|
|
11437
|
+
width: "100%",
|
|
11438
|
+
justifyContent: "space-between",
|
|
11439
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Text, {
|
|
11440
|
+
ref: textRef,
|
|
11441
|
+
whiteSpace: "nowrap",
|
|
11442
|
+
textOverflow: "ellipsis",
|
|
11443
|
+
overflow: "hidden",
|
|
11444
|
+
fontWeight: "300",
|
|
11445
|
+
flex: 1,
|
|
11446
|
+
minWidth: 0,
|
|
11447
|
+
children: cell.displayValue
|
|
11448
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Flex, {
|
|
11449
|
+
className: "file-action-buttons",
|
|
11450
|
+
alignItems: "center",
|
|
11451
|
+
flexShrink: 0,
|
|
11452
|
+
opacity: 0,
|
|
11453
|
+
transition: "opacity 0.15s ease",
|
|
11454
|
+
css: { "td:hover &, &[data-visible]": { opacity: 1 } },
|
|
11455
|
+
...showInfo ? { "data-visible": true } : {},
|
|
11456
|
+
children: [
|
|
11457
|
+
showInfo && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
|
|
11458
|
+
openDelay: 50,
|
|
11459
|
+
closeDelay: 50,
|
|
11460
|
+
content: "The file was not uploaded in this revision",
|
|
11461
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Flex, {
|
|
11462
|
+
width: "24px",
|
|
11463
|
+
height: "24px",
|
|
11464
|
+
alignItems: "center",
|
|
11465
|
+
justifyContent: "center",
|
|
11466
|
+
color: "gray.400",
|
|
11467
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiInfo, {})
|
|
11468
|
+
})
|
|
11469
|
+
}),
|
|
11470
|
+
showViewFile && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileHoverCard, {
|
|
11471
|
+
url,
|
|
11472
|
+
availablePreview,
|
|
11473
|
+
width,
|
|
11474
|
+
height,
|
|
11475
|
+
onClick: handleOpenFile,
|
|
11476
|
+
dataTestId: `cell-file-open-${cell.rowId}-${cell.field}`
|
|
11477
|
+
}),
|
|
11478
|
+
showUploadFile && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
11479
|
+
ref: fileInputRef,
|
|
11480
|
+
type: "file",
|
|
11481
|
+
onChange: handleFileChange,
|
|
11482
|
+
style: { display: "none" },
|
|
11483
|
+
"data-testid": `cell-file-input-${cell.rowId}-${cell.field}`
|
|
11484
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.IconButton, {
|
|
11485
|
+
"aria-label": "Upload file",
|
|
11486
|
+
variant: "ghost",
|
|
11487
|
+
size: "2xs",
|
|
11488
|
+
color: showViewFile ? "gray.300" : "gray.500",
|
|
11489
|
+
_hover: {
|
|
11490
|
+
bg: "gray.100",
|
|
11491
|
+
color: "black"
|
|
11492
|
+
},
|
|
11493
|
+
onClick: handleUploadClick,
|
|
11494
|
+
"data-testid": `cell-file-upload-${cell.rowId}-${cell.field}`,
|
|
11495
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiUploadThin, {})
|
|
11496
|
+
})] }),
|
|
11497
|
+
!showInfo && !showViewFile && !showUploadFile && !isReadonly && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Tooltip, {
|
|
11498
|
+
openDelay: 50,
|
|
11499
|
+
closeDelay: 50,
|
|
11500
|
+
content: "Save the row first, then upload the file",
|
|
11501
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Flex, {
|
|
11502
|
+
width: "24px",
|
|
11503
|
+
height: "24px",
|
|
11504
|
+
alignItems: "center",
|
|
11505
|
+
justifyContent: "center",
|
|
11506
|
+
color: "gray.400",
|
|
11507
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_icons_pi.PiInfo, {})
|
|
11508
|
+
})
|
|
11509
|
+
})
|
|
11510
|
+
]
|
|
11511
|
+
})]
|
|
11512
|
+
})
|
|
11513
|
+
}), editPosition && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellTextareaEditor, {
|
|
11514
|
+
value: cell.displayValue,
|
|
11515
|
+
position: editPosition,
|
|
11516
|
+
clickOffset: clickOffsetValue,
|
|
11517
|
+
appendChar: appendCharValue,
|
|
11518
|
+
autoHeight: true,
|
|
11519
|
+
onCommit: handleCommit,
|
|
11520
|
+
onCommitEnter: handleCommitEnter,
|
|
11521
|
+
onCancel: handleCancel,
|
|
11522
|
+
testId: "file-cell-input"
|
|
11523
|
+
})]
|
|
11277
11524
|
});
|
|
11278
11525
|
});
|
|
11279
11526
|
|
|
@@ -11311,7 +11558,7 @@ const ReadonlyCell = (0, mobx_react_lite.observer)(({ cell }) => {
|
|
|
11311
11558
|
|
|
11312
11559
|
//#endregion
|
|
11313
11560
|
//#region src/table-editor/Table/ui/Cell/CellRenderer.tsx
|
|
11314
|
-
const CellRenderer = (0, mobx_react_lite.observer)(({ cell, onSearchForeignKey }) => {
|
|
11561
|
+
const CellRenderer = (0, mobx_react_lite.observer)(({ cell, onSearchForeignKey, onUploadFile, onOpenFile }) => {
|
|
11315
11562
|
switch (cell.column.fieldType) {
|
|
11316
11563
|
case FilterFieldType.String: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StringCell, { cell });
|
|
11317
11564
|
case FilterFieldType.Number: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(NumberCell, { cell });
|
|
@@ -11320,7 +11567,11 @@ const CellRenderer = (0, mobx_react_lite.observer)(({ cell, onSearchForeignKey }
|
|
|
11320
11567
|
cell,
|
|
11321
11568
|
onSearchForeignKey
|
|
11322
11569
|
});
|
|
11323
|
-
case FilterFieldType.File: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileCell, {
|
|
11570
|
+
case FilterFieldType.File: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileCell, {
|
|
11571
|
+
cell,
|
|
11572
|
+
onUploadFile,
|
|
11573
|
+
onOpenFile
|
|
11574
|
+
});
|
|
11324
11575
|
case FilterFieldType.DateTime: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DateTimeCell, { cell });
|
|
11325
11576
|
default: return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReadonlyCell, { cell });
|
|
11326
11577
|
}
|
|
@@ -11489,6 +11740,7 @@ const ResizeHandle = (0, mobx_react_lite.observer)(({ field, columnsModel }) =>
|
|
|
11489
11740
|
};
|
|
11490
11741
|
const cleanup = () => {
|
|
11491
11742
|
cancelAnimationFrame(rafRef.current);
|
|
11743
|
+
columnsModel.commitColumnWidth();
|
|
11492
11744
|
setIsResizing(false);
|
|
11493
11745
|
document.body.style.cursor = "";
|
|
11494
11746
|
document.body.style.userSelect = "";
|
|
@@ -12018,7 +12270,7 @@ const AddColumnButton = (0, mobx_react_lite.observer)(({ columnsModel }) => {
|
|
|
12018
12270
|
const SELECTION_COLUMN_WIDTH$1 = 40;
|
|
12019
12271
|
const ADD_COLUMN_BUTTON_WIDTH$1 = 40;
|
|
12020
12272
|
const BOTTOM_BORDER_SHADOW$1 = "inset 0 -1px 0 0 var(--chakra-colors-gray-100)";
|
|
12021
|
-
const HeaderRow = (0, mobx_react_lite.observer)(({ columnsModel, sortModel, filterModel, onCopyPath, showSelection,
|
|
12273
|
+
const HeaderRow = (0, mobx_react_lite.observer)(({ columnsModel, sortModel, filterModel, onCopyPath, showSelection, scrollShadow }) => {
|
|
12022
12274
|
const selectionWidth = showSelection ? SELECTION_COLUMN_WIDTH$1 : 0;
|
|
12023
12275
|
const addColumnStickyRight = columnsModel.hasHiddenColumns;
|
|
12024
12276
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, {
|
|
@@ -12045,8 +12297,8 @@ const HeaderRow = (0, mobx_react_lite.observer)(({ columnsModel, sortModel, filt
|
|
|
12045
12297
|
filterModel,
|
|
12046
12298
|
onCopyPath,
|
|
12047
12299
|
stickyPosition: getStickyPosition(col.field, columnsModel, selectionWidth, addColumnStickyRight),
|
|
12048
|
-
showLeftShadow,
|
|
12049
|
-
showRightShadow
|
|
12300
|
+
showLeftShadow: scrollShadow?.showLeftShadow,
|
|
12301
|
+
showRightShadow: scrollShadow?.showRightShadow
|
|
12050
12302
|
}, col.field);
|
|
12051
12303
|
}),
|
|
12052
12304
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Box, {
|
|
@@ -12291,7 +12543,7 @@ function getCellBoxShadow(isSticky, side) {
|
|
|
12291
12543
|
if (!isSticky) return BOTTOM_BORDER_SHADOW;
|
|
12292
12544
|
return `${BOTTOM_BORDER_SHADOW}, ${side === "left" ? "inset -1px 0 0 0 var(--chakra-colors-gray-100)" : "inset 1px 0 0 0 var(--chakra-colors-gray-100)"}`;
|
|
12293
12545
|
}
|
|
12294
|
-
const DataRow = (0, mobx_react_lite.observer)(({ row, columnsModel, showSelection,
|
|
12546
|
+
const DataRow = (0, mobx_react_lite.observer)(({ row, columnsModel, showSelection, scrollShadow, onSearchForeignKey, onUploadFile, onOpenFile, onOpenRow, onSelectRow, onDuplicateRow, onDeleteRow }) => {
|
|
12295
12547
|
const hasRowActions = Boolean(onOpenRow || onSelectRow || onDuplicateRow || onDeleteRow);
|
|
12296
12548
|
const selectionWidth = showSelection ? SELECTION_COLUMN_WIDTH : 0;
|
|
12297
12549
|
const addColumnStickyRight = columnsModel.hasHiddenColumns;
|
|
@@ -12306,7 +12558,7 @@ const DataRow = (0, mobx_react_lite.observer)(({ row, columnsModel, showSelectio
|
|
|
12306
12558
|
const cellVM = row.getCellVM(col);
|
|
12307
12559
|
const isFirstColumn = index === 0;
|
|
12308
12560
|
const showOverlay = isFirstColumn && hasRowActions && !cellVM.isEditing;
|
|
12309
|
-
const sticky = computeStickyProps(col, columnsModel, selectionWidth, addColOffset, showLeftShadow, showRightShadow);
|
|
12561
|
+
const sticky = computeStickyProps(col, columnsModel, selectionWidth, addColOffset, scrollShadow?.showLeftShadow, scrollShadow?.showRightShadow);
|
|
12310
12562
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, {
|
|
12311
12563
|
as: "td",
|
|
12312
12564
|
width: sticky.colWidth,
|
|
@@ -12327,11 +12579,15 @@ const DataRow = (0, mobx_react_lite.observer)(({ row, columnsModel, showSelectio
|
|
|
12327
12579
|
overflow: "hidden",
|
|
12328
12580
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellRenderer, {
|
|
12329
12581
|
cell: cellVM,
|
|
12330
|
-
onSearchForeignKey
|
|
12582
|
+
onSearchForeignKey,
|
|
12583
|
+
onUploadFile,
|
|
12584
|
+
onOpenFile
|
|
12331
12585
|
})
|
|
12332
12586
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CellRenderer, {
|
|
12333
12587
|
cell: cellVM,
|
|
12334
|
-
onSearchForeignKey
|
|
12588
|
+
onSearchForeignKey,
|
|
12589
|
+
onUploadFile,
|
|
12590
|
+
onOpenFile
|
|
12335
12591
|
}), showOverlay && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RowActionOverlay, {
|
|
12336
12592
|
rowId: row.rowId,
|
|
12337
12593
|
onOpen: onOpenRow,
|
|
@@ -12483,16 +12739,29 @@ const TableRowComponent = ({ "data-index": index, context, style, children, ...p
|
|
|
12483
12739
|
|
|
12484
12740
|
//#endregion
|
|
12485
12741
|
//#region src/table-editor/Table/ui/hooks/useScrollShadow.ts
|
|
12486
|
-
|
|
12487
|
-
showLeftShadow
|
|
12488
|
-
showRightShadow
|
|
12742
|
+
var ScrollShadowModel = class {
|
|
12743
|
+
showLeftShadow = false;
|
|
12744
|
+
showRightShadow = false;
|
|
12745
|
+
constructor() {
|
|
12746
|
+
(0, mobx.makeAutoObservable)(this);
|
|
12747
|
+
}
|
|
12748
|
+
update(left, right) {
|
|
12749
|
+
this.showLeftShadow = left;
|
|
12750
|
+
this.showRightShadow = right;
|
|
12751
|
+
}
|
|
12752
|
+
reset() {
|
|
12753
|
+
this.showLeftShadow = false;
|
|
12754
|
+
this.showRightShadow = false;
|
|
12755
|
+
}
|
|
12489
12756
|
};
|
|
12490
12757
|
function getScrollElement(target) {
|
|
12491
12758
|
if (target instanceof HTMLElement) return target;
|
|
12492
12759
|
return document.scrollingElement;
|
|
12493
12760
|
}
|
|
12494
12761
|
function useScrollShadow() {
|
|
12495
|
-
const
|
|
12762
|
+
const modelRef = (0, react.useRef)(null);
|
|
12763
|
+
if (!modelRef.current) modelRef.current = new ScrollShadowModel();
|
|
12764
|
+
const model = modelRef.current;
|
|
12496
12765
|
const targetRef = (0, react.useRef)(null);
|
|
12497
12766
|
const rafRef = (0, react.useRef)(0);
|
|
12498
12767
|
const update = (0, react.useCallback)(() => {
|
|
@@ -12502,11 +12771,10 @@ function useScrollShadow() {
|
|
|
12502
12771
|
if (!el) return;
|
|
12503
12772
|
const scrollLeft = el.scrollLeft;
|
|
12504
12773
|
const maxScroll = el.scrollWidth - el.clientWidth;
|
|
12505
|
-
|
|
12506
|
-
|
|
12507
|
-
showRightShadow: maxScroll > 1 && scrollLeft < maxScroll - 1
|
|
12774
|
+
(0, mobx.runInAction)(() => {
|
|
12775
|
+
model.update(scrollLeft > 0, maxScroll > 1 && scrollLeft < maxScroll - 1);
|
|
12508
12776
|
});
|
|
12509
|
-
}, []);
|
|
12777
|
+
}, [model]);
|
|
12510
12778
|
const handleScroll = (0, react.useCallback)(() => {
|
|
12511
12779
|
if (rafRef.current) cancelAnimationFrame(rafRef.current);
|
|
12512
12780
|
rafRef.current = requestAnimationFrame(update);
|
|
@@ -12520,9 +12788,15 @@ function useScrollShadow() {
|
|
|
12520
12788
|
rafRef.current = requestAnimationFrame(update);
|
|
12521
12789
|
} else {
|
|
12522
12790
|
targetRef.current = null;
|
|
12523
|
-
|
|
12791
|
+
(0, mobx.runInAction)(() => {
|
|
12792
|
+
model.reset();
|
|
12793
|
+
});
|
|
12524
12794
|
}
|
|
12525
|
-
}, [
|
|
12795
|
+
}, [
|
|
12796
|
+
handleScroll,
|
|
12797
|
+
update,
|
|
12798
|
+
model
|
|
12799
|
+
]);
|
|
12526
12800
|
(0, react.useEffect)(() => {
|
|
12527
12801
|
return () => {
|
|
12528
12802
|
const prev = targetRef.current;
|
|
@@ -12531,7 +12805,7 @@ function useScrollShadow() {
|
|
|
12531
12805
|
};
|
|
12532
12806
|
}, [handleScroll]);
|
|
12533
12807
|
return {
|
|
12534
|
-
|
|
12808
|
+
model,
|
|
12535
12809
|
setScrollerRef
|
|
12536
12810
|
};
|
|
12537
12811
|
}
|
|
@@ -12542,11 +12816,11 @@ const baseComponents = {
|
|
|
12542
12816
|
Table: TableComponent,
|
|
12543
12817
|
TableRow: TableRowComponent
|
|
12544
12818
|
};
|
|
12545
|
-
const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM, selection, sortModel, filterModel, onSearchForeignKey, onOpenRow, onDeleteSelected, onDuplicateSelected, onDeleteRow, onDuplicateRow, onCopyPath, onEndReached, isLoadingMore, useWindowScroll: useWindowScrollProp }) => {
|
|
12819
|
+
const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM, selection, sortModel, filterModel, onSearchForeignKey, onUploadFile, onOpenFile, onOpenRow, onDeleteSelected, onDuplicateSelected, onDeleteRow, onDuplicateRow, onCopyPath, onEndReached, isLoadingMore, useWindowScroll: useWindowScrollProp }) => {
|
|
12546
12820
|
const showSelection = selection.isSelectionMode;
|
|
12547
12821
|
const allRowIds = rows.map((r) => r.rowId);
|
|
12548
12822
|
const [deleteConfirm, setDeleteConfirm] = (0, react.useState)(null);
|
|
12549
|
-
const {
|
|
12823
|
+
const { model: scrollShadow, setScrollerRef } = useScrollShadow();
|
|
12550
12824
|
const handleSelectRow = (0, react.useCallback)((rowId) => {
|
|
12551
12825
|
selection.enterSelectionMode(rowId);
|
|
12552
12826
|
}, [selection]);
|
|
@@ -12644,9 +12918,10 @@ const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM
|
|
|
12644
12918
|
row,
|
|
12645
12919
|
columnsModel,
|
|
12646
12920
|
showSelection,
|
|
12647
|
-
|
|
12648
|
-
showRightShadow: scrollShadow.showRightShadow,
|
|
12921
|
+
scrollShadow,
|
|
12649
12922
|
onSearchForeignKey,
|
|
12923
|
+
onUploadFile,
|
|
12924
|
+
onOpenFile,
|
|
12650
12925
|
onOpenRow,
|
|
12651
12926
|
onSelectRow: canSelect ? handleSelectRow : void 0,
|
|
12652
12927
|
onDuplicateRow: canDuplicateRow ? onDuplicateRow : void 0,
|
|
@@ -12654,9 +12929,10 @@ const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM
|
|
|
12654
12929
|
}), [
|
|
12655
12930
|
columnsModel,
|
|
12656
12931
|
showSelection,
|
|
12657
|
-
scrollShadow
|
|
12658
|
-
scrollShadow.showRightShadow,
|
|
12932
|
+
scrollShadow,
|
|
12659
12933
|
onSearchForeignKey,
|
|
12934
|
+
onUploadFile,
|
|
12935
|
+
onOpenFile,
|
|
12660
12936
|
onOpenRow,
|
|
12661
12937
|
canSelect,
|
|
12662
12938
|
canDeleteRow,
|
|
@@ -12671,16 +12947,14 @@ const TableWidget = (0, mobx_react_lite.observer)(({ rows, columnsModel, cellFSM
|
|
|
12671
12947
|
filterModel,
|
|
12672
12948
|
onCopyPath,
|
|
12673
12949
|
showSelection,
|
|
12674
|
-
|
|
12675
|
-
showRightShadow: scrollShadow.showRightShadow
|
|
12950
|
+
scrollShadow
|
|
12676
12951
|
}), [
|
|
12677
12952
|
columnsModel,
|
|
12678
12953
|
sortModel,
|
|
12679
12954
|
filterModel,
|
|
12680
12955
|
onCopyPath,
|
|
12681
12956
|
showSelection,
|
|
12682
|
-
scrollShadow
|
|
12683
|
-
scrollShadow.showRightShadow
|
|
12957
|
+
scrollShadow
|
|
12684
12958
|
]);
|
|
12685
12959
|
const virtuosoContext = (0, react.useMemo)(() => ({ rows }), [rows]);
|
|
12686
12960
|
const totalColumns = columnsModel.visibleColumns.length + (showSelection ? 4 : 3);
|
|
@@ -12934,6 +13208,67 @@ var ViewSettingsBadgeModel = class {
|
|
|
12934
13208
|
}
|
|
12935
13209
|
};
|
|
12936
13210
|
|
|
13211
|
+
//#endregion
|
|
13212
|
+
//#region src/table-editor/TableEditor/model/SchemaContext.ts
|
|
13213
|
+
const SYSTEM_REF_SCHEMAS = {
|
|
13214
|
+
[_revisium_schema_toolkit.SystemSchemaIds.File]: _revisium_schema_toolkit.fileSchema,
|
|
13215
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowId]: _revisium_schema_toolkit.rowIdSchema,
|
|
13216
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowCreatedAt]: _revisium_schema_toolkit.rowCreatedAtSchema,
|
|
13217
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowCreatedId]: _revisium_schema_toolkit.rowCreatedIdSchema,
|
|
13218
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowVersionId]: _revisium_schema_toolkit.rowVersionIdSchema,
|
|
13219
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowPublishedAt]: _revisium_schema_toolkit.rowPublishedAtSchema,
|
|
13220
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowUpdatedAt]: _revisium_schema_toolkit.rowUpdatedAtSchema,
|
|
13221
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowHash]: _revisium_schema_toolkit.rowHashSchema,
|
|
13222
|
+
[_revisium_schema_toolkit.SystemSchemaIds.RowSchemaHash]: _revisium_schema_toolkit.rowSchemaHashSchema
|
|
13223
|
+
};
|
|
13224
|
+
function buildRowSchema(dataSchema) {
|
|
13225
|
+
const systemProperties = {};
|
|
13226
|
+
for (const sf of SYSTEM_FIELDS) systemProperties[sf.id] = { $ref: sf.ref };
|
|
13227
|
+
return {
|
|
13228
|
+
type: "object",
|
|
13229
|
+
properties: {
|
|
13230
|
+
...systemProperties,
|
|
13231
|
+
...dataSchema.properties
|
|
13232
|
+
},
|
|
13233
|
+
additionalProperties: false,
|
|
13234
|
+
required: [...Object.keys(systemProperties), ...dataSchema.required ?? []]
|
|
13235
|
+
};
|
|
13236
|
+
}
|
|
13237
|
+
var SchemaContext = class {
|
|
13238
|
+
_allColumns = [];
|
|
13239
|
+
_dataSchema = null;
|
|
13240
|
+
_fullRefSchemas = {};
|
|
13241
|
+
_rootNode = null;
|
|
13242
|
+
get allColumns() {
|
|
13243
|
+
return this._allColumns;
|
|
13244
|
+
}
|
|
13245
|
+
get sortableFields() {
|
|
13246
|
+
return this._allColumns.filter((col) => !col.isDeprecated && col.fieldType !== FilterFieldType.File);
|
|
13247
|
+
}
|
|
13248
|
+
get filterableFields() {
|
|
13249
|
+
return this.sortableFields;
|
|
13250
|
+
}
|
|
13251
|
+
get dataSchema() {
|
|
13252
|
+
return this._dataSchema;
|
|
13253
|
+
}
|
|
13254
|
+
get fullRefSchemas() {
|
|
13255
|
+
return this._fullRefSchemas;
|
|
13256
|
+
}
|
|
13257
|
+
get rootNode() {
|
|
13258
|
+
return this._rootNode;
|
|
13259
|
+
}
|
|
13260
|
+
init(dataSchema, refSchemas) {
|
|
13261
|
+
this._dataSchema = dataSchema;
|
|
13262
|
+
this._fullRefSchemas = {
|
|
13263
|
+
...SYSTEM_REF_SCHEMAS,
|
|
13264
|
+
...refSchemas
|
|
13265
|
+
};
|
|
13266
|
+
const rowSchema = buildRowSchema(dataSchema);
|
|
13267
|
+
this._rootNode = new _revisium_schema_toolkit.SchemaParser().parse(rowSchema, this._fullRefSchemas);
|
|
13268
|
+
this._allColumns = extractColumns(this._rootNode);
|
|
13269
|
+
}
|
|
13270
|
+
};
|
|
13271
|
+
|
|
12937
13272
|
//#endregion
|
|
12938
13273
|
//#region src/table-editor/TableEditor/model/TableEditorCore.ts
|
|
12939
13274
|
const DEFAULT_PAGE_SIZE = 50;
|
|
@@ -12951,7 +13286,7 @@ var TableEditorCore = class {
|
|
|
12951
13286
|
_breadcrumbs;
|
|
12952
13287
|
_callbacks;
|
|
12953
13288
|
_tableId;
|
|
12954
|
-
|
|
13289
|
+
_schemaContext = new SchemaContext();
|
|
12955
13290
|
_readonly = false;
|
|
12956
13291
|
_rows = [];
|
|
12957
13292
|
_isBootstrapping = true;
|
|
@@ -13060,13 +13395,13 @@ var TableEditorCore = class {
|
|
|
13060
13395
|
try {
|
|
13061
13396
|
const meta = await this._dataSource.fetchMetadata();
|
|
13062
13397
|
(0, mobx.runInAction)(() => {
|
|
13063
|
-
this.
|
|
13398
|
+
this._schemaContext.init(meta.dataSchema, meta.refSchemas);
|
|
13064
13399
|
this._readonly = meta.readonly;
|
|
13065
13400
|
this.viewBadge.setCanSave(!meta.readonly);
|
|
13066
13401
|
});
|
|
13067
|
-
this.columns.init(
|
|
13068
|
-
this.sorts.init(this.
|
|
13069
|
-
this.filters.init(this.
|
|
13402
|
+
this.columns.init(this._schemaContext.allColumns);
|
|
13403
|
+
this.sorts.init(this._schemaContext.sortableFields);
|
|
13404
|
+
this.filters.init(this._schemaContext.filterableFields);
|
|
13070
13405
|
if (meta.viewState) this.applyViewState(meta.viewState);
|
|
13071
13406
|
this._saveViewSnapshot();
|
|
13072
13407
|
await this._loadRows();
|
|
@@ -13117,15 +13452,26 @@ var TableEditorCore = class {
|
|
|
13117
13452
|
this._updateNavigationContext();
|
|
13118
13453
|
}
|
|
13119
13454
|
_createRowVMs(rawRows) {
|
|
13120
|
-
|
|
13121
|
-
|
|
13455
|
+
const dataSchema = this._schemaContext.dataSchema;
|
|
13456
|
+
if (!dataSchema) return [];
|
|
13457
|
+
const tableModel = (0, _revisium_schema_toolkit.createTableModel)({
|
|
13122
13458
|
tableId: this._tableId,
|
|
13123
|
-
schema:
|
|
13459
|
+
schema: dataSchema,
|
|
13124
13460
|
rows: rawRows.map((r) => ({
|
|
13125
13461
|
rowId: r.rowId,
|
|
13126
13462
|
data: r.data
|
|
13127
|
-
}))
|
|
13128
|
-
|
|
13463
|
+
})),
|
|
13464
|
+
refSchemas: this._schemaContext.fullRefSchemas
|
|
13465
|
+
});
|
|
13466
|
+
const systemValuesMap = /* @__PURE__ */ new Map();
|
|
13467
|
+
for (const raw of rawRows) systemValuesMap.set(raw.rowId, this._buildSystemValues(raw));
|
|
13468
|
+
return tableModel.rows.map((rowModel) => new RowVM(rowModel, rowModel.rowId, this.cellFSM, this.selection, (rowId, field, value, previousValue) => this._commitCell(rowId, field, value, previousValue), systemValuesMap.get(rowModel.rowId)));
|
|
13469
|
+
}
|
|
13470
|
+
_buildSystemValues(rawRow) {
|
|
13471
|
+
return {
|
|
13472
|
+
...rawRow.systemFields,
|
|
13473
|
+
id: rawRow.rowId
|
|
13474
|
+
};
|
|
13129
13475
|
}
|
|
13130
13476
|
async _commitCell(rowId, field, value, previousValue) {
|
|
13131
13477
|
const result = (await this._dataSource.patchCells([{
|
|
@@ -13138,6 +13484,7 @@ var TableEditorCore = class {
|
|
|
13138
13484
|
if (row && previousValue !== void 0) {
|
|
13139
13485
|
const node = row.rowModel.get(field);
|
|
13140
13486
|
if (node?.isPrimitive()) node.setValue(previousValue);
|
|
13487
|
+
else if (node?.isObject()) node.setValue(previousValue, { internal: true });
|
|
13141
13488
|
}
|
|
13142
13489
|
});
|
|
13143
13490
|
}
|
|
@@ -13192,37 +13539,39 @@ var TableEditorCore = class {
|
|
|
13192
13539
|
//#region src/table-editor/TableEditor/model/MockDataSource.ts
|
|
13193
13540
|
var MockDataSource = class {
|
|
13194
13541
|
_allRows;
|
|
13195
|
-
|
|
13196
|
-
_columns;
|
|
13542
|
+
_dataSchema;
|
|
13197
13543
|
_viewState;
|
|
13198
13544
|
_readonly;
|
|
13199
13545
|
_failPatches;
|
|
13546
|
+
_refSchemas;
|
|
13200
13547
|
fetchMetadataLog = [];
|
|
13201
13548
|
fetchLog = [];
|
|
13202
13549
|
patchLog = [];
|
|
13203
13550
|
deleteLog = [];
|
|
13204
13551
|
saveViewLog = [];
|
|
13205
13552
|
constructor(params) {
|
|
13206
|
-
this.
|
|
13207
|
-
this._columns = params.columns;
|
|
13553
|
+
this._dataSchema = params.dataSchema;
|
|
13208
13554
|
this._allRows = [...params.rows];
|
|
13209
13555
|
this._viewState = params.viewState ?? null;
|
|
13210
13556
|
this._readonly = params.readonly ?? false;
|
|
13211
13557
|
this._failPatches = params.failPatches ?? /* @__PURE__ */ new Set();
|
|
13558
|
+
this._refSchemas = params.refSchemas;
|
|
13212
13559
|
}
|
|
13213
|
-
static createRow(rowId, data) {
|
|
13214
|
-
|
|
13560
|
+
static createRow(rowId, data, systemFields) {
|
|
13561
|
+
const row = {
|
|
13215
13562
|
rowId,
|
|
13216
13563
|
data: { ...data }
|
|
13217
13564
|
};
|
|
13565
|
+
if (systemFields) row.systemFields = systemFields;
|
|
13566
|
+
return row;
|
|
13218
13567
|
}
|
|
13219
13568
|
fetchMetadata() {
|
|
13220
13569
|
this.fetchMetadataLog.push(true);
|
|
13221
13570
|
return Promise.resolve({
|
|
13222
|
-
|
|
13223
|
-
columns: this._columns,
|
|
13571
|
+
dataSchema: this._dataSchema,
|
|
13224
13572
|
viewState: this._viewState,
|
|
13225
|
-
readonly: this._readonly
|
|
13573
|
+
readonly: this._readonly,
|
|
13574
|
+
refSchemas: this._refSchemas
|
|
13226
13575
|
});
|
|
13227
13576
|
}
|
|
13228
13577
|
fetchRows(query) {
|
|
@@ -13404,7 +13753,6 @@ const TableEditor = (0, mobx_react_lite.observer)(({ viewModel, useWindowScroll
|
|
|
13404
13753
|
height: "100%",
|
|
13405
13754
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_chakra_ui_react.Spinner, {})
|
|
13406
13755
|
});
|
|
13407
|
-
const columns = viewModel.columns.visibleColumns;
|
|
13408
13756
|
const isReadonly = viewModel.readonly;
|
|
13409
13757
|
const { breadcrumbs, callbacks } = viewModel;
|
|
13410
13758
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_chakra_ui_react.Box, {
|
|
@@ -13434,11 +13782,11 @@ const TableEditor = (0, mobx_react_lite.observer)(({ viewModel, useWindowScroll
|
|
|
13434
13782
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SearchWidget, { model: viewModel.search }),
|
|
13435
13783
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FilterWidget, {
|
|
13436
13784
|
model: viewModel.filters,
|
|
13437
|
-
availableFields: columns
|
|
13785
|
+
availableFields: viewModel.columns.filterableFields
|
|
13438
13786
|
}),
|
|
13439
13787
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SortingsWidget, {
|
|
13440
13788
|
model: viewModel.sorts,
|
|
13441
|
-
availableFields: columns,
|
|
13789
|
+
availableFields: viewModel.columns.sortableFields,
|
|
13442
13790
|
onChange: noop
|
|
13443
13791
|
})
|
|
13444
13792
|
]
|
|
@@ -13461,6 +13809,8 @@ const TableEditor = (0, mobx_react_lite.observer)(({ viewModel, useWindowScroll
|
|
|
13461
13809
|
onDuplicateRow: isReadonly ? void 0 : callbacks.onDuplicateRow,
|
|
13462
13810
|
onDeleteSelected: isReadonly ? void 0 : (ids) => viewModel.deleteRows(ids),
|
|
13463
13811
|
onSearchForeignKey: callbacks.onSearchForeignKey,
|
|
13812
|
+
onUploadFile: isReadonly ? void 0 : callbacks.onUploadFile,
|
|
13813
|
+
onOpenFile: callbacks.onOpenFile,
|
|
13464
13814
|
onCopyPath: callbacks.onCopyPath,
|
|
13465
13815
|
useWindowScroll
|
|
13466
13816
|
})
|
|
@@ -13528,6 +13878,7 @@ exports.SORT_SCHEMA = SORT_SCHEMA;
|
|
|
13528
13878
|
exports.SYSTEM_FIELDS = SYSTEM_FIELDS;
|
|
13529
13879
|
exports.SYSTEM_FIELD_BY_REF = SYSTEM_FIELD_BY_REF;
|
|
13530
13880
|
exports.SYSTEM_FIELD_IDS = SYSTEM_FIELD_IDS;
|
|
13881
|
+
exports.SchemaContext = SchemaContext;
|
|
13531
13882
|
exports.SchemaEditorCore = SchemaEditorCore;
|
|
13532
13883
|
exports.SchemaTypeIds = SchemaTypeIds;
|
|
13533
13884
|
exports.SearchForeignKey = SearchForeignKey;
|