@proteinjs/db-ui 1.11.2 → 1.12.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/CHANGELOG.md +19 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/src/form/RecordForm.d.ts.map +1 -1
- package/dist/src/form/RecordForm.js +74 -2
- package/dist/src/form/RecordForm.js.map +1 -1
- package/dist/src/form/RecordFormCustomization.d.ts +32 -1
- package/dist/src/form/RecordFormCustomization.d.ts.map +1 -1
- package/dist/src/form/RecordFormCustomization.js +12 -0
- package/dist/src/form/RecordFormCustomization.js.map +1 -1
- package/dist/test/recordFormFieldRenderers.test.d.ts +5 -0
- package/dist/test/recordFormFieldRenderers.test.d.ts.map +1 -0
- package/dist/test/recordFormFieldRenderers.test.js +323 -0
- package/dist/test/recordFormFieldRenderers.test.js.map +1 -0
- package/generated/index.ts +1 -1
- package/package.json +3 -3
- package/src/form/RecordForm.tsx +81 -4
- package/src/form/RecordFormCustomization.tsx +37 -1
- package/test/recordFormFieldRenderers.test.tsx +202 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __extends = (this && this.__extends) || (function () {
|
|
3
|
+
var extendStatics = function (d, b) {
|
|
4
|
+
extendStatics = Object.setPrototypeOf ||
|
|
5
|
+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
+
return extendStatics(d, b);
|
|
8
|
+
};
|
|
9
|
+
return function (d, b) {
|
|
10
|
+
if (typeof b !== "function" && b !== null)
|
|
11
|
+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
+
extendStatics(d, b);
|
|
13
|
+
function __() { this.constructor = d; }
|
|
14
|
+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
+
};
|
|
16
|
+
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
28
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
29
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
30
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
31
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
32
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
33
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
34
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
38
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
39
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
40
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
41
|
+
function step(op) {
|
|
42
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
43
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
44
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
45
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
46
|
+
switch (op[0]) {
|
|
47
|
+
case 0: case 1: t = op; break;
|
|
48
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
49
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
50
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
51
|
+
default:
|
|
52
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
53
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
54
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
55
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
56
|
+
if (t[2]) _.ops.pop();
|
|
57
|
+
_.trys.pop(); continue;
|
|
58
|
+
}
|
|
59
|
+
op = body.call(thisArg, _);
|
|
60
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
61
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
65
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
66
|
+
if (ar || !(i in from)) {
|
|
67
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
68
|
+
ar[i] = from[i];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
72
|
+
};
|
|
73
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
74
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
75
|
+
};
|
|
76
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
77
|
+
/**
|
|
78
|
+
* @jest-environment jsdom
|
|
79
|
+
*
|
|
80
|
+
* Custom field components on the record form (`RecordFormCustomization.getFieldRenderer`).
|
|
81
|
+
*
|
|
82
|
+
* A customization can take over a field's slot with its own component. The component OWNS the
|
|
83
|
+
* field: it presents the stored value and routes edits through a service of its own, then calls
|
|
84
|
+
* `reload` so the slot shows the stored truth. Consequences pinned here:
|
|
85
|
+
* - the component renders in the field's slot instead of the default control, and declaring a
|
|
86
|
+
* renderer surfaces a column the default form hides (ArrayColumn is ui.hidden by default —
|
|
87
|
+
* the reason user.roles never appeared on the user form);
|
|
88
|
+
* - the form's save payload never carries a custom-rendered field (its writes are the
|
|
89
|
+
* component's, through its service — a form save that echoed the value back would either be
|
|
90
|
+
* refused as a protected-column write or clobber the service's state);
|
|
91
|
+
* - `reload` re-reads the record through the db service and re-renders the slot;
|
|
92
|
+
* - renderers are not consulted on the new-record form: a record that doesn't exist yet has no
|
|
93
|
+
* stored state to present or service to write through.
|
|
94
|
+
*/
|
|
95
|
+
var react_1 = __importDefault(require("react"));
|
|
96
|
+
var client_1 = require("react-dom/client");
|
|
97
|
+
var test_utils_1 = require("react-dom/test-utils");
|
|
98
|
+
var react_router_dom_1 = require("react-router-dom");
|
|
99
|
+
var db_1 = require("@proteinjs/db");
|
|
100
|
+
require("../generated");
|
|
101
|
+
var RecordForm_1 = require("../src/form/RecordForm");
|
|
102
|
+
var RecordFormCustomization_1 = require("../src/form/RecordFormCustomization");
|
|
103
|
+
var DocTable = /** @class */ (function (_super) {
|
|
104
|
+
__extends(DocTable, _super);
|
|
105
|
+
function DocTable() {
|
|
106
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
107
|
+
_this.name = 'field_renderer_test_doc';
|
|
108
|
+
_this.columns = (0, db_1.withRecordColumns)({
|
|
109
|
+
title: new db_1.StringColumn('title'),
|
|
110
|
+
// ArrayColumn is ui.hidden by default; only the renderer surfaces it
|
|
111
|
+
labels: new db_1.ArrayColumn('labels'),
|
|
112
|
+
});
|
|
113
|
+
return _this;
|
|
114
|
+
}
|
|
115
|
+
return DocTable;
|
|
116
|
+
}(db_1.Table));
|
|
117
|
+
/** The stored row the (fake) labels service writes and the db service reads back. */
|
|
118
|
+
var stored;
|
|
119
|
+
var mockLabelsService = {
|
|
120
|
+
addLabel: jest.fn(function (docId, label) { return __awaiter(void 0, void 0, void 0, function () {
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
stored = __assign(__assign({}, stored), { labels: __spreadArray(__spreadArray([], stored.labels, true), [label], false) });
|
|
123
|
+
return [2 /*return*/];
|
|
124
|
+
});
|
|
125
|
+
}); }),
|
|
126
|
+
};
|
|
127
|
+
var mockDbService = {
|
|
128
|
+
get: jest.fn(function (table, query) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
129
|
+
return [2 /*return*/, stored];
|
|
130
|
+
}); }); }),
|
|
131
|
+
insert: jest.fn(function (table, record) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
132
|
+
return [2 /*return*/, record];
|
|
133
|
+
}); }); }),
|
|
134
|
+
update: jest.fn(function (table, record) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
135
|
+
return [2 /*return*/, record];
|
|
136
|
+
}); }); }),
|
|
137
|
+
delete: jest.fn(function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
138
|
+
return [2 /*return*/, 1];
|
|
139
|
+
}); }); }),
|
|
140
|
+
};
|
|
141
|
+
jest.mock('@proteinjs/db', function () { return (__assign(__assign({}, jest.requireActual('@proteinjs/db')), { getDbService: function () { return mockDbService; } })); });
|
|
142
|
+
function LabelsField(_a) {
|
|
143
|
+
var _this = this;
|
|
144
|
+
var record = _a.record, value = _a.value, reload = _a.reload, label = _a.label;
|
|
145
|
+
return (react_1.default.createElement("div", { "data-field-renderer": 'labels' },
|
|
146
|
+
react_1.default.createElement("span", null, label),
|
|
147
|
+
value.map(function (item) { return (react_1.default.createElement("span", { key: item, "data-label-chip": true }, item)); }),
|
|
148
|
+
react_1.default.createElement("button", { type: 'button', onClick: function () { return __awaiter(_this, void 0, void 0, function () {
|
|
149
|
+
return __generator(this, function (_a) {
|
|
150
|
+
switch (_a.label) {
|
|
151
|
+
case 0: return [4 /*yield*/, mockLabelsService.addLabel(record.id, 'c')];
|
|
152
|
+
case 1:
|
|
153
|
+
_a.sent();
|
|
154
|
+
return [4 /*yield*/, reload()];
|
|
155
|
+
case 2:
|
|
156
|
+
_a.sent();
|
|
157
|
+
return [2 /*return*/];
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}); } }, "Add label")));
|
|
161
|
+
}
|
|
162
|
+
var DocRecordFormCustomization = /** @class */ (function (_super) {
|
|
163
|
+
__extends(DocRecordFormCustomization, _super);
|
|
164
|
+
function DocRecordFormCustomization() {
|
|
165
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
166
|
+
_this.table = new DocTable();
|
|
167
|
+
return _this;
|
|
168
|
+
}
|
|
169
|
+
DocRecordFormCustomization.prototype.getFieldRenderer = function (fieldName, record) {
|
|
170
|
+
return fieldName === 'labels' ? LabelsField : undefined;
|
|
171
|
+
};
|
|
172
|
+
return DocRecordFormCustomization;
|
|
173
|
+
}(RecordFormCustomization_1.RecordFormCustomization));
|
|
174
|
+
// Stands in for the SourceRepository registration a real customization gets from reflection-build.
|
|
175
|
+
jest.mock('../src/form/RecordFormCustomization', function () { return (__assign(__assign({}, jest.requireActual('../src/form/RecordFormCustomization')), { getRecordFormCustomization: function (tableName) {
|
|
176
|
+
return tableName === 'field_renderer_test_doc' ? new DocRecordFormCustomization() : undefined;
|
|
177
|
+
} })); });
|
|
178
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
|
|
179
|
+
describe('RecordForm custom field renderers', function () {
|
|
180
|
+
var container;
|
|
181
|
+
var root;
|
|
182
|
+
beforeEach(function () {
|
|
183
|
+
jest.clearAllMocks();
|
|
184
|
+
stored = { id: 'doc-1', title: 'Doc', labels: ['a', 'b'] };
|
|
185
|
+
container = document.createElement('div');
|
|
186
|
+
document.body.appendChild(container);
|
|
187
|
+
root = (0, client_1.createRoot)(container);
|
|
188
|
+
});
|
|
189
|
+
afterEach(function () {
|
|
190
|
+
(0, test_utils_1.act)(function () {
|
|
191
|
+
root.unmount();
|
|
192
|
+
});
|
|
193
|
+
container.remove();
|
|
194
|
+
});
|
|
195
|
+
var mount = function (record) { return __awaiter(void 0, void 0, void 0, function () {
|
|
196
|
+
return __generator(this, function (_a) {
|
|
197
|
+
switch (_a.label) {
|
|
198
|
+
case 0: return [4 /*yield*/, (0, test_utils_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
199
|
+
return __generator(this, function (_a) {
|
|
200
|
+
root.render(react_1.default.createElement(react_router_dom_1.MemoryRouter, null,
|
|
201
|
+
react_1.default.createElement(RecordForm_1.RecordForm, { table: new DocTable(), record: record })));
|
|
202
|
+
return [2 /*return*/];
|
|
203
|
+
});
|
|
204
|
+
}); })];
|
|
205
|
+
case 1:
|
|
206
|
+
_a.sent();
|
|
207
|
+
return [4 /*yield*/, (0, test_utils_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
208
|
+
return __generator(this, function (_a) {
|
|
209
|
+
switch (_a.label) {
|
|
210
|
+
case 0: return [4 /*yield*/, Promise.resolve()];
|
|
211
|
+
case 1:
|
|
212
|
+
_a.sent();
|
|
213
|
+
return [2 /*return*/];
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}); })];
|
|
217
|
+
case 2:
|
|
218
|
+
_a.sent();
|
|
219
|
+
return [2 /*return*/];
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}); };
|
|
223
|
+
var findButton = function (name) {
|
|
224
|
+
var button = Array.from(document.querySelectorAll('button')).find(function (b) { return b.textContent === name; });
|
|
225
|
+
if (!button) {
|
|
226
|
+
throw new Error("Button not rendered: ".concat(name));
|
|
227
|
+
}
|
|
228
|
+
return button;
|
|
229
|
+
};
|
|
230
|
+
var click = function (element) { return __awaiter(void 0, void 0, void 0, function () {
|
|
231
|
+
return __generator(this, function (_a) {
|
|
232
|
+
switch (_a.label) {
|
|
233
|
+
case 0: return [4 /*yield*/, (0, test_utils_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
234
|
+
return __generator(this, function (_a) {
|
|
235
|
+
element.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
236
|
+
return [2 /*return*/];
|
|
237
|
+
});
|
|
238
|
+
}); })];
|
|
239
|
+
case 1:
|
|
240
|
+
_a.sent();
|
|
241
|
+
return [4 /*yield*/, (0, test_utils_1.act)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
242
|
+
return __generator(this, function (_a) {
|
|
243
|
+
switch (_a.label) {
|
|
244
|
+
case 0: return [4 /*yield*/, Promise.resolve()];
|
|
245
|
+
case 1:
|
|
246
|
+
_a.sent();
|
|
247
|
+
return [2 /*return*/];
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}); })];
|
|
251
|
+
case 2:
|
|
252
|
+
_a.sent();
|
|
253
|
+
return [2 /*return*/];
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}); };
|
|
257
|
+
var chips = function () { return Array.from(document.querySelectorAll('[data-label-chip]')).map(function (chip) { return chip.textContent; }); };
|
|
258
|
+
var labelsInput = function () { return Array.from(document.querySelectorAll('label')).find(function (l) { return l.textContent === 'Labels'; }); };
|
|
259
|
+
it('renders the customization component in the field slot, surfacing a column the default form hides', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
260
|
+
return __generator(this, function (_a) {
|
|
261
|
+
switch (_a.label) {
|
|
262
|
+
case 0: return [4 /*yield*/, mount(__assign({}, stored))];
|
|
263
|
+
case 1:
|
|
264
|
+
_a.sent();
|
|
265
|
+
expect(document.querySelector('[data-field-renderer="labels"]')).not.toBeNull();
|
|
266
|
+
expect(chips()).toEqual(['a', 'b']);
|
|
267
|
+
// The default control is replaced, not doubled: no text input for the field
|
|
268
|
+
expect(labelsInput()).toBeUndefined();
|
|
269
|
+
// Default controls still render for the other columns
|
|
270
|
+
expect(Array.from(document.querySelectorAll('label')).some(function (l) { var _a; return (_a = l.textContent) === null || _a === void 0 ? void 0 : _a.startsWith('Title'); })).toBe(true);
|
|
271
|
+
return [2 /*return*/];
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}); });
|
|
275
|
+
it('never carries a custom-rendered field in the save payload', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
276
|
+
var payload;
|
|
277
|
+
return __generator(this, function (_a) {
|
|
278
|
+
switch (_a.label) {
|
|
279
|
+
case 0: return [4 /*yield*/, mount(__assign({}, stored))];
|
|
280
|
+
case 1:
|
|
281
|
+
_a.sent();
|
|
282
|
+
return [4 /*yield*/, click(findButton('Save'))];
|
|
283
|
+
case 2:
|
|
284
|
+
_a.sent();
|
|
285
|
+
expect(mockDbService.update).toHaveBeenCalledTimes(1);
|
|
286
|
+
payload = mockDbService.update.mock.calls[0][1];
|
|
287
|
+
expect(payload.title).toBe('Doc');
|
|
288
|
+
expect('labels' in payload).toBe(false);
|
|
289
|
+
return [2 /*return*/];
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}); });
|
|
293
|
+
it('reload re-reads the record so the slot shows the stored truth after a service write', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
294
|
+
return __generator(this, function (_a) {
|
|
295
|
+
switch (_a.label) {
|
|
296
|
+
case 0: return [4 /*yield*/, mount(__assign({}, stored))];
|
|
297
|
+
case 1:
|
|
298
|
+
_a.sent();
|
|
299
|
+
return [4 /*yield*/, click(findButton('Add label'))];
|
|
300
|
+
case 2:
|
|
301
|
+
_a.sent();
|
|
302
|
+
expect(mockLabelsService.addLabel).toHaveBeenCalledWith('doc-1', 'c');
|
|
303
|
+
expect(mockDbService.get).toHaveBeenCalledTimes(1);
|
|
304
|
+
expect(mockDbService.get.mock.calls[0][1]).toEqual({ id: 'doc-1' });
|
|
305
|
+
expect(chips()).toEqual(['a', 'b', 'c']);
|
|
306
|
+
return [2 /*return*/];
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
}); });
|
|
310
|
+
it('does not consult renderers on the new-record form; hidden columns stay hidden there', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
311
|
+
return __generator(this, function (_a) {
|
|
312
|
+
switch (_a.label) {
|
|
313
|
+
case 0: return [4 /*yield*/, mount(undefined)];
|
|
314
|
+
case 1:
|
|
315
|
+
_a.sent();
|
|
316
|
+
expect(document.querySelector('[data-field-renderer="labels"]')).toBeNull();
|
|
317
|
+
expect(labelsInput()).toBeUndefined();
|
|
318
|
+
return [2 /*return*/];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}); });
|
|
322
|
+
});
|
|
323
|
+
//# sourceMappingURL=recordFormFieldRenderers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recordFormFieldRenderers.test.js","sourceRoot":"","sources":["../../test/recordFormFieldRenderers.test.tsx"],"names":[],"mappings":"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"}
|
package/generated/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import '@proteinjs/ui';
|
|
|
6
6
|
/** Generate Source Graph */
|
|
7
7
|
|
|
8
8
|
const sourceGraph =
|
|
9
|
-
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-ui/QueryCursorLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryCursorLoader","filePath":"src/table/QueryCursorLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryCursorLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"reactQueryKeys","type":{"packageName":"@proteinjs/ui","name":"ReactQueryKeys","filePath":null,"qualifiedName":"@proteinjs/ui/ReactQueryKeys","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"pager","type":{"packageName":"","name":"CursorWindowPager<T>","filePath":null,"qualifiedName":"/CursorWindowPager<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"loadWindow","returnType":{"packageName":"","name":"Promise<CursorWindow<T>>","filePath":null,"qualifiedName":"/Promise<CursorWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"cursor","type":{"packageName":"","name":"CursorValue | null","filePath":null,"qualifiedName":"/CursorValue | null","typeParameters":null,"directParents":null}},{"name":"windowSize","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"CursorLoader","filePath":null,"qualifiedName":"@proteinjs/ui/CursorLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/CursorLoader"},{"v":"@proteinjs/db-ui/QueryTableLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryTableLoader","filePath":"src/table/QueryTableLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryTableLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"rowCountQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"paginationQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"reactQueryKeys","type":{"packageName":"","name":"TableLoader<T>[\'reactQueryKeys\']","filePath":null,"qualifiedName":"/TableLoader<T>[\'reactQueryKeys\']","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"table","type":{"packageName":"","name":"Table<T>","filePath":null,"qualifiedName":"/Table<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"query","type":{"packageName":"","name":"Query<T>","filePath":null,"qualifiedName":"/Query<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"sort","type":{"packageName":"","name":"SortCriteria<T>[]","filePath":null,"qualifiedName":"/SortCriteria<T>[]","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"queryOptions","type":{"packageName":"","name":"QueryOptions<T>","filePath":null,"qualifiedName":"/QueryOptions<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"load","returnType":{"packageName":"","name":"Promise<RowWindow<T>>","filePath":null,"qualifiedName":"/Promise<RowWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"startIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"endIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"skipRowCount","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"TableLoader","filePath":null,"qualifiedName":"@proteinjs/ui/TableLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/TableLoader"},{"v":"@proteinjs/db-ui/RecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":"src/form/RecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":true,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]},{"name":"getFieldLayout","returnType":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFieldLayout","type":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/reflection","name":"Loadable","filePath":null,"qualifiedName":"@proteinjs/reflection/Loadable","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/reflection/Loadable"},{"v":"@proteinjs/db-ui/hashGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"hashGeneratorPage","filePath":"src/pages/HashGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/hashGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/ui/Page"},{"v":"@proteinjs/db-ui/recordFormPage","value":{"packageName":"@proteinjs/db-ui","name":"recordFormPage","filePath":"src/pages/RecordFormPage.tsx","qualifiedName":"@proteinjs/db-ui/recordFormPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/recordTablePage","value":{"packageName":"@proteinjs/db-ui","name":"recordTablePage","filePath":"src/pages/RecordTablePage.tsx","qualifiedName":"@proteinjs/db-ui/recordTablePage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/tablesPage","value":{"packageName":"@proteinjs/db-ui","name":"tablesPage","filePath":"src/pages/TablesPage.tsx","qualifiedName":"@proteinjs/db-ui/tablesPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/uuidGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"uuidGeneratorPage","filePath":"src/pages/UuidGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/uuidGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/SpecificTableProps"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"MigrationRecordFormCustomization","filePath":"src/form/customizations/MigrationRecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/MigrationRecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"migration","type":{"packageName":"@proteinjs/db","name":"Migration","filePath":null,"qualifiedName":"@proteinjs/db/Migration","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]},{"name":"setRetired","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"migration","type":{"packageName":"@proteinjs/db","name":"Migration","filePath":null,"qualifiedName":"@proteinjs/db/Migration","typeParameters":null,"directParents":null}},{"name":"retired","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}},{"name":"fields","type":{"packageName":"@proteinjs/ui","name":"Fields","filePath":null,"qualifiedName":"@proteinjs/ui/Fields","typeParameters":null,"directParents":null}},{"name":"formButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":null,"qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}}],"edges":[{"v":"@proteinjs/db-ui/QueryCursorLoader","w":"@proteinjs/ui/CursorLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/QueryTableLoader","w":"@proteinjs/ui/TableLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/RecordFormCustomization","w":"@proteinjs/reflection/Loadable","value":"implements interface"},{"v":"@proteinjs/db-ui/hashGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordFormPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordTablePage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/tablesPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/uuidGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","w":"@proteinjs/db-ui/RecordFormCustomization","value":"extends class"}]}';
|
|
9
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/db-ui/QueryCursorLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryCursorLoader","filePath":"src/table/QueryCursorLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryCursorLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"reactQueryKeys","type":{"packageName":"@proteinjs/ui","name":"ReactQueryKeys","filePath":null,"qualifiedName":"@proteinjs/ui/ReactQueryKeys","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"pager","type":{"packageName":"","name":"CursorWindowPager<T>","filePath":null,"qualifiedName":"/CursorWindowPager<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"loadWindow","returnType":{"packageName":"","name":"Promise<CursorWindow<T>>","filePath":null,"qualifiedName":"/Promise<CursorWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"cursor","type":{"packageName":"","name":"CursorValue | null","filePath":null,"qualifiedName":"/CursorValue | null","typeParameters":null,"directParents":null}},{"name":"windowSize","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"CursorLoader","filePath":null,"qualifiedName":"@proteinjs/ui/CursorLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/CursorLoader"},{"v":"@proteinjs/db-ui/QueryTableLoader","value":{"packageName":"@proteinjs/db-ui","name":"QueryTableLoader","filePath":"src/table/QueryTableLoader.ts","qualifiedName":"@proteinjs/db-ui/QueryTableLoader","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"rowCountQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"paginationQb","type":{"packageName":"","name":"QueryBuilder<T>","filePath":null,"qualifiedName":"/QueryBuilder<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"reactQueryKeys","type":{"packageName":"","name":"TableLoader<T>[\'reactQueryKeys\']","filePath":null,"qualifiedName":"/TableLoader<T>[\'reactQueryKeys\']","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"},{"name":"table","type":{"packageName":"","name":"Table<T>","filePath":null,"qualifiedName":"/Table<T>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"query","type":{"packageName":"","name":"Query<T>","filePath":null,"qualifiedName":"/Query<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"sort","type":{"packageName":"","name":"SortCriteria<T>[]","filePath":null,"qualifiedName":"/SortCriteria<T>[]","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"},{"name":"queryOptions","type":{"packageName":"","name":"QueryOptions<T>","filePath":null,"qualifiedName":"/QueryOptions<T>","typeParameters":null,"directParents":null},"isOptional":true,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"load","returnType":{"packageName":"","name":"Promise<RowWindow<T>>","filePath":null,"qualifiedName":"/Promise<RowWindow<T>>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"startIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"endIndex","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"skipRowCount","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}}]}],"typeParameters":["/T extends Record"],"directParentInterfaces":[{"packageName":"@proteinjs/ui","name":"TableLoader","filePath":null,"qualifiedName":"@proteinjs/ui/TableLoader","properties":[],"methods":[],"typeParameters":["/T"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/ui/TableLoader"},{"v":"/React.ComponentType"},{"v":"@proteinjs/db-ui/RecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":"src/form/RecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":true,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":{"packageName":"","name":"Table<any>","filePath":null,"qualifiedName":"/Table<any>","typeParameters":null,"directParents":null},"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]},{"name":"getFieldLayout","returnType":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}},{"name":"defaultFieldLayout","type":{"packageName":"","name":"string[] | string[][]","filePath":null,"qualifiedName":"/string[] | string[][]","typeParameters":null,"directParents":null}}]},{"name":"getFieldRenderer","returnType":{"packageName":"","name":"RecordFormFieldRenderer | undefined","filePath":null,"qualifiedName":"/RecordFormFieldRenderer | undefined","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"fieldName","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}},{"name":"record","type":{"packageName":"","name":"any","filePath":null,"qualifiedName":"/any","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/reflection","name":"Loadable","filePath":null,"qualifiedName":"@proteinjs/reflection/Loadable","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/reflection/Loadable"},{"v":"@proteinjs/db-ui/hashGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"hashGeneratorPage","filePath":"src/pages/HashGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/hashGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/ui/Page"},{"v":"@proteinjs/db-ui/recordFormPage","value":{"packageName":"@proteinjs/db-ui","name":"recordFormPage","filePath":"src/pages/RecordFormPage.tsx","qualifiedName":"@proteinjs/db-ui/recordFormPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/recordTablePage","value":{"packageName":"@proteinjs/db-ui","name":"recordTablePage","filePath":"src/pages/RecordTablePage.tsx","qualifiedName":"@proteinjs/db-ui/recordTablePage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/tablesPage","value":{"packageName":"@proteinjs/db-ui","name":"tablesPage","filePath":"src/pages/TablesPage.tsx","qualifiedName":"@proteinjs/db-ui/tablesPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/uuidGeneratorPage","value":{"packageName":"@proteinjs/db-ui","name":"uuidGeneratorPage","filePath":"src/pages/UuidGeneratorPage.tsx","qualifiedName":"@proteinjs/db-ui/uuidGeneratorPage","type":{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":[{"packageName":"@proteinjs/ui","name":"Page","filePath":null,"qualifiedName":"@proteinjs/ui/Page","typeParameters":[],"directParents":null}]},"isExported":true,"isConst":true,"sourceType":0}},{"v":"@proteinjs/db-ui/SpecificTableProps"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","value":{"packageName":"@proteinjs/db-ui","name":"MigrationRecordFormCustomization","filePath":"src/form/customizations/MigrationRecordFormCustomization.tsx","qualifiedName":"@proteinjs/db-ui/MigrationRecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"table","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public"}],"methods":[{"name":"getFormButtons","returnType":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"migration","type":{"packageName":"@proteinjs/db","name":"Migration","filePath":null,"qualifiedName":"@proteinjs/db/Migration","typeParameters":null,"directParents":null}},{"name":"defaultFormButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]},{"name":"setRetired","returnType":null,"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"migration","type":{"packageName":"@proteinjs/db","name":"Migration","filePath":null,"qualifiedName":"@proteinjs/db/Migration","typeParameters":null,"directParents":null}},{"name":"retired","type":{"packageName":"","name":"boolean","filePath":null,"qualifiedName":"/boolean","typeParameters":null,"directParents":null}},{"name":"fields","type":{"packageName":"@proteinjs/ui","name":"Fields","filePath":null,"qualifiedName":"@proteinjs/ui/Fields","typeParameters":null,"directParents":null}},{"name":"formButtons","type":{"packageName":"","name":"FormButtons<any>","filePath":null,"qualifiedName":"/FormButtons<any>","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[{"packageName":"@proteinjs/db-ui","name":"RecordFormCustomization","filePath":null,"qualifiedName":"@proteinjs/db-ui/RecordFormCustomization","isAbstract":false,"isStatic":false,"visibility":"public","properties":[],"methods":[],"typeParameters":[],"directParentInterfaces":[],"directParentClasses":[]}],"sourceType":2}}],"edges":[{"v":"@proteinjs/db-ui/QueryCursorLoader","w":"@proteinjs/ui/CursorLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/QueryTableLoader","w":"@proteinjs/ui/TableLoader","value":"implements interface"},{"v":"@proteinjs/db-ui/RecordFormCustomization","w":"@proteinjs/reflection/Loadable","value":"implements interface"},{"v":"@proteinjs/db-ui/hashGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordFormPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/recordTablePage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/tablesPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/uuidGeneratorPage","w":"@proteinjs/ui/Page","value":"has type"},{"v":"@proteinjs/db-ui/MigrationRecordFormCustomization","w":"@proteinjs/db-ui/RecordFormCustomization","value":"extends class"}]}';
|
|
10
10
|
|
|
11
11
|
/** Generate Source Links */
|
|
12
12
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/db-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Db ui components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@emotion/styled": "11.11.0",
|
|
27
27
|
"@mui/icons-material": "5.14.11",
|
|
28
28
|
"@mui/material": "5.14.11",
|
|
29
|
-
"@proteinjs/db": "^1.
|
|
29
|
+
"@proteinjs/db": "^1.35.0",
|
|
30
30
|
"@proteinjs/reflection": "^1.2.0",
|
|
31
31
|
"@proteinjs/ui": "^4.10.0",
|
|
32
32
|
"@proteinjs/util": "^1.6.1",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
},
|
|
56
56
|
"main": "./dist/generated/index.js",
|
|
57
57
|
"types": "./dist/generated/index.d.ts",
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "06ddfa575d927114076efa181555521087cf3625"
|
|
59
59
|
}
|
package/src/form/RecordForm.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import S from 'string';
|
|
3
3
|
import moment from 'moment';
|
|
4
4
|
import { StringUtil, isInstanceOf } from '@proteinjs/util';
|
|
5
|
-
import { Form, Fields, textField, checkboxField, dateField, FormButtons } from '@proteinjs/ui';
|
|
5
|
+
import { Form, Fields, FieldComponentProps, textField, checkboxField, dateField, FormButtons } from '@proteinjs/ui';
|
|
6
6
|
import {
|
|
7
7
|
Table,
|
|
8
8
|
Record,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from '@proteinjs/db';
|
|
19
19
|
import { recordTableLink } from '../pages/RecordTablePage';
|
|
20
20
|
import { recordFormLink } from '../pages/RecordFormPage';
|
|
21
|
-
import { getRecordFormCustomization } from './RecordFormCustomization';
|
|
21
|
+
import { getRecordFormCustomization, RecordFormFieldRenderer } from './RecordFormCustomization';
|
|
22
22
|
|
|
23
23
|
export type RecordFormProps<T extends Record> = {
|
|
24
24
|
table: Table<T>;
|
|
@@ -149,7 +149,8 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
149
149
|
continue;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
// A customization's field component surfaces a column the default form hides
|
|
153
|
+
if (column.options?.ui?.hidden && !getFieldRenderer(columnPropertyName)) {
|
|
153
154
|
continue;
|
|
154
155
|
}
|
|
155
156
|
|
|
@@ -192,11 +193,29 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
192
193
|
);
|
|
193
194
|
}
|
|
194
195
|
|
|
196
|
+
/**
|
|
197
|
+
* A customization's component for the field, if it declared one. Only existing records have
|
|
198
|
+
* stored state to present, so the new-record form never consults renderers (see
|
|
199
|
+
* `RecordFormCustomization.getFieldRenderer`).
|
|
200
|
+
*/
|
|
201
|
+
function getFieldRenderer(columnPropertyName: string): RecordFormFieldRenderer<T> | undefined {
|
|
202
|
+
if (isNewRecord || !recordFormCustomization) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return recordFormCustomization.getFieldRenderer(columnPropertyName, record);
|
|
207
|
+
}
|
|
208
|
+
|
|
195
209
|
/** Pick the field control that tells the truth about the column's type. */
|
|
196
210
|
function createField(columnPropertyName: string, column: Column<T, any>) {
|
|
197
211
|
const name = columnPropertyName;
|
|
198
212
|
const label = StringUtil.humanizeCamel(columnPropertyName);
|
|
199
213
|
|
|
214
|
+
const fieldRenderer = getFieldRenderer(columnPropertyName);
|
|
215
|
+
if (fieldRenderer) {
|
|
216
|
+
return customField(name, label, column, fieldRenderer);
|
|
217
|
+
}
|
|
218
|
+
|
|
200
219
|
// Readonly values render as text (a native date input isn't text-selectable): copyable
|
|
201
220
|
// ids/timestamps beat a type-specific control the user can't interact with anyway.
|
|
202
221
|
if (isReadonlyField(columnPropertyName, column)) {
|
|
@@ -242,6 +261,38 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
242
261
|
return textField({ name, label });
|
|
243
262
|
}
|
|
244
263
|
|
|
264
|
+
/**
|
|
265
|
+
* The slot a customization's component renders in. The component reads its value from the
|
|
266
|
+
* loaded record (not the form's field value), so one `reload` refreshes every custom field:
|
|
267
|
+
* reload re-reads the record in place and reports the change through the form's own onChange,
|
|
268
|
+
* which is what re-renders the form.
|
|
269
|
+
*/
|
|
270
|
+
function customField(name: string, label: string, column: Column<T, any>, FieldRenderer: RecordFormFieldRenderer<T>) {
|
|
271
|
+
const loadedRecord = record as T;
|
|
272
|
+
return {
|
|
273
|
+
field: { name, label },
|
|
274
|
+
component: ({ field, onChange }: FieldComponentProps<any, Fields>) => (
|
|
275
|
+
<FieldRenderer
|
|
276
|
+
table={table}
|
|
277
|
+
column={column}
|
|
278
|
+
fieldName={name}
|
|
279
|
+
label={label}
|
|
280
|
+
record={loadedRecord}
|
|
281
|
+
value={(loadedRecord as any)[name]}
|
|
282
|
+
reload={async () => {
|
|
283
|
+
const fresh = await getDbService().get(table, { id: loadedRecord.id } as any);
|
|
284
|
+
if (!fresh) {
|
|
285
|
+
throw new Error(`${S(table.name).humanize().s} no longer exists`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
Object.assign(loadedRecord, fresh);
|
|
289
|
+
await onChange(field, (fresh as any)[name], () => {});
|
|
290
|
+
}}
|
|
291
|
+
/>
|
|
292
|
+
),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
245
296
|
function fieldLayout(): any {
|
|
246
297
|
const columns = getColumns();
|
|
247
298
|
const layoutColumns = Object.entries(columns).length > 6 ? 2 : 1;
|
|
@@ -298,6 +349,23 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
298
349
|
return fieldValue;
|
|
299
350
|
}
|
|
300
351
|
|
|
352
|
+
/**
|
|
353
|
+
* The update payload is the loaded record minus what this form doesn't own: service-protected
|
|
354
|
+
* columns, and custom-rendered fields — those are their component's, written through the
|
|
355
|
+
* component's own service. Echoing a loaded value back would clobber whatever that service
|
|
356
|
+
* wrote since the load.
|
|
357
|
+
*/
|
|
358
|
+
function savePayload(): Partial<T> {
|
|
359
|
+
const payload: any = stripServiceProtectedColumns(table, record as T);
|
|
360
|
+
for (const columnPropertyName in getColumns()) {
|
|
361
|
+
if (getFieldRenderer(columnPropertyName)) {
|
|
362
|
+
delete payload[columnPropertyName];
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
return payload;
|
|
367
|
+
}
|
|
368
|
+
|
|
301
369
|
function buttons(): FormButtons<any> {
|
|
302
370
|
let newRecord: T;
|
|
303
371
|
return {
|
|
@@ -352,11 +420,15 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
352
420
|
continue;
|
|
353
421
|
}
|
|
354
422
|
|
|
423
|
+
if (getFieldRenderer(columnPropertyName)) {
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
|
|
355
427
|
const field = fields[columnPropertyName];
|
|
356
428
|
(record as any)[columnPropertyName] = getFieldValue(columnPropertyName, field.field.value);
|
|
357
429
|
}
|
|
358
430
|
|
|
359
|
-
await getDbService().update(table,
|
|
431
|
+
await getDbService().update(table, savePayload());
|
|
360
432
|
return `Saved ${S(table.name).humanize().s}`;
|
|
361
433
|
},
|
|
362
434
|
progressMessage: (fields: Fields) => {
|
|
@@ -398,6 +470,11 @@ export function RecordForm<T extends Record>({ table, record }: RecordFormProps<
|
|
|
398
470
|
}
|
|
399
471
|
|
|
400
472
|
for (const columnPropertyName in fields) {
|
|
473
|
+
// Custom-rendered fields read straight from the loaded record
|
|
474
|
+
if (getFieldRenderer(columnPropertyName)) {
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
|
|
401
478
|
const column = getColumn(columnPropertyName);
|
|
402
479
|
const field = fields[columnPropertyName].field;
|
|
403
480
|
let fieldValue = (record as any)[columnPropertyName];
|