@aglyn/plugins-data 1.0.0-beta.143

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.
Files changed (39) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +7 -0
  3. package/package.json +47 -0
  4. package/src/index.d.ts +19 -0
  5. package/src/index.js +20 -0
  6. package/src/index.js.map +1 -0
  7. package/src/lib/components/data-console-page.d.ts +13 -0
  8. package/src/lib/components/data-console-page.js +63 -0
  9. package/src/lib/components/data-console-page.js.map +1 -0
  10. package/src/lib/components/dataset-record-dialog.component.d.ts +52 -0
  11. package/src/lib/components/dataset-record-dialog.component.js +249 -0
  12. package/src/lib/components/dataset-record-dialog.component.js.map +1 -0
  13. package/src/lib/components/dataset-schema-dialog.component.d.ts +51 -0
  14. package/src/lib/components/dataset-schema-dialog.component.js +979 -0
  15. package/src/lib/components/dataset-schema-dialog.component.js.map +1 -0
  16. package/src/lib/components/host-datasets-card.component.d.ts +39 -0
  17. package/src/lib/components/host-datasets-card.component.js +1831 -0
  18. package/src/lib/components/host-datasets-card.component.js.map +1 -0
  19. package/src/lib/constants/bundle-common.d.ts +8 -0
  20. package/src/lib/constants/bundle-common.js +9 -0
  21. package/src/lib/constants/bundle-common.js.map +1 -0
  22. package/src/lib/model/dataset-io.d.ts +43 -0
  23. package/src/lib/model/dataset-io.js +84 -0
  24. package/src/lib/model/dataset-io.js.map +1 -0
  25. package/src/lib/model/dataset-record-view.d.ts +157 -0
  26. package/src/lib/model/dataset-record-view.js +293 -0
  27. package/src/lib/model/dataset-record-view.js.map +1 -0
  28. package/src/lib/model/index.d.ts +22 -0
  29. package/src/lib/model/index.js +22 -0
  30. package/src/lib/model/index.js.map +1 -0
  31. package/src/lib/plugin.d.ts +35 -0
  32. package/src/lib/plugin.js +78 -0
  33. package/src/lib/plugin.js.map +1 -0
  34. package/src/lib/repeat/dataset-repeat-rows.d.ts +45 -0
  35. package/src/lib/repeat/dataset-repeat-rows.js +108 -0
  36. package/src/lib/repeat/dataset-repeat-rows.js.map +1 -0
  37. package/src/lib/repeat/dataset-repeat-source.d.ts +39 -0
  38. package/src/lib/repeat/dataset-repeat-source.js +95 -0
  39. package/src/lib/repeat/dataset-repeat-source.js.map +1 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Aglyn LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */ 'use client';
17
+ import { _ as _extends } from "@swc/helpers/_/_extends";
18
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
19
+ import { validateDocument } from "@aglyn/aglyn";
20
+ import { datasetRecordFields } from "../model/dataset-record-view.js";
21
+ import { Alert, Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Stack, Tooltip, Typography } from "@mui/material";
22
+ import { useMemo } from "react";
23
+ /** What each "no value" state is called on screen. */ const PLACEHOLDER = {
24
+ absent: 'Not set',
25
+ null: 'Null',
26
+ 'empty-text': 'Empty text',
27
+ 'empty-list': 'Empty list',
28
+ 'empty-map': 'Empty map'
29
+ };
30
+ /**
31
+ * One field's value.
32
+ *
33
+ * The four empty states get four different words, deliberately. A table cell
34
+ * prints `--` for all of them because it has one line to work with; here there
35
+ * is room to say which, and the difference decides what a reader does next —
36
+ * a field that was never written and a field holding a real empty string are
37
+ * not the same finding.
38
+ */ function RecordFieldValue(props) {
39
+ const { value } = props.field;
40
+ if (value.kind === 'opaque') {
41
+ return /*#__PURE__*/ _jsx(Typography, {
42
+ variant: "body2",
43
+ color: "text.secondary",
44
+ sx: {
45
+ fontStyle: 'italic'
46
+ },
47
+ children: value.text
48
+ });
49
+ }
50
+ if (value.kind !== 'value') {
51
+ var _PLACEHOLDER_value_kind;
52
+ return /*#__PURE__*/ _jsx(Typography, {
53
+ variant: "body2",
54
+ color: "text.disabled",
55
+ sx: {
56
+ fontStyle: 'italic'
57
+ },
58
+ children: (_PLACEHOLDER_value_kind = PLACEHOLDER[value.kind]) != null ? _PLACEHOLDER_value_kind : 'Not set'
59
+ });
60
+ }
61
+ if (value.references) {
62
+ return /*#__PURE__*/ _jsx(Stack, {
63
+ direction: "row",
64
+ spacing: 1,
65
+ sx: {
66
+ flexWrap: 'wrap',
67
+ rowGap: 0.5
68
+ },
69
+ children: value.references.map((reference)=>{
70
+ var _reference_label;
71
+ return /*#__PURE__*/ _jsx(Typography, {
72
+ variant: "body2",
73
+ // An unresolved target is a fact about the data, not a rendering
74
+ // failure to paper over: the ID is shown either way, and only the
75
+ // resolved one is allowed to look like a working link.
76
+ color: reference.label ? 'text.primary' : 'warning.main',
77
+ sx: {
78
+ overflowWrap: 'anywhere'
79
+ },
80
+ children: (_reference_label = reference.label) != null ? _reference_label : `${reference.id} · unresolved`
81
+ }, reference.id);
82
+ })
83
+ });
84
+ }
85
+ if (value.items) {
86
+ return(// One line per item. The comma-joined form a cell shows cannot say
87
+ // whether `a, b` is one item or two; a list of lines can.
88
+ /*#__PURE__*/ _jsx(Stack, {
89
+ component: "ul",
90
+ spacing: 0.25,
91
+ sx: {
92
+ m: 0,
93
+ pl: 2.5
94
+ },
95
+ children: value.items.map((item, index)=>/*#__PURE__*/ _jsx(Typography, {
96
+ component: "li",
97
+ variant: "body2",
98
+ sx: {
99
+ overflowWrap: 'anywhere'
100
+ },
101
+ children: item
102
+ }, `${index}:${item}`))
103
+ }));
104
+ }
105
+ return /*#__PURE__*/ _jsx(Typography, _extends({
106
+ variant: "body2"
107
+ }, value.block ? {
108
+ component: 'pre',
109
+ sx: {
110
+ m: 0,
111
+ fontFamily: 'monospace',
112
+ whiteSpace: 'pre-wrap',
113
+ overflowWrap: 'anywhere'
114
+ }
115
+ } : {
116
+ sx: {
117
+ overflowWrap: 'anywhere'
118
+ }
119
+ }, {
120
+ children: value.text
121
+ }));
122
+ }
123
+ RecordFieldValue.displayName = 'RecordFieldValue';
124
+ export function DatasetRecordDialog(props) {
125
+ var _ref;
126
+ const { record, model, resolveReference, onClose, onEdit } = props;
127
+ const values = record == null ? void 0 : record.values;
128
+ const fields = useMemo(()=>record ? datasetRecordFields(model, values, resolveReference) : [], [
129
+ record,
130
+ model,
131
+ values,
132
+ resolveReference
133
+ ]);
134
+ /**
135
+ * The same mismatch report the editor shows, for the same reason: a type
136
+ * change never rewrites stored documents, so a record may legitimately hold
137
+ * a value its model no longer describes. Reporting it beside the value is
138
+ * what stops the view claiming the record conforms.
139
+ */ const mismatches = useMemo(()=>record ? validateDocument(model, values != null ? values : {}) : {}, [
140
+ record,
141
+ model,
142
+ values
143
+ ]);
144
+ return /*#__PURE__*/ _jsxs(Dialog, {
145
+ open: Boolean(record),
146
+ onClose: onClose,
147
+ maxWidth: "sm",
148
+ fullWidth: true,
149
+ "aria-labelledby": "dataset-record-view-title",
150
+ children: [
151
+ /*#__PURE__*/ _jsx(DialogTitle, {
152
+ id: "dataset-record-view-title",
153
+ children: 'View record'
154
+ }),
155
+ /*#__PURE__*/ _jsx(DialogContent, {
156
+ dividers: true,
157
+ children: /*#__PURE__*/ _jsxs(Stack, {
158
+ spacing: 2,
159
+ children: [
160
+ /*#__PURE__*/ _jsxs(Box, {
161
+ children: [
162
+ /*#__PURE__*/ _jsx(Typography, {
163
+ variant: "overline",
164
+ color: "text.secondary",
165
+ component: "div",
166
+ children: 'Record ID'
167
+ }),
168
+ /*#__PURE__*/ _jsx(Typography, {
169
+ variant: "body2",
170
+ sx: {
171
+ overflowWrap: 'anywhere'
172
+ },
173
+ children: (_ref = record == null ? void 0 : record.$id) != null ? _ref : ''
174
+ })
175
+ ]
176
+ }),
177
+ fields.map((field)=>/*#__PURE__*/ _jsxs(Box, {
178
+ children: [
179
+ /*#__PURE__*/ _jsxs(Stack, {
180
+ direction: "row",
181
+ spacing: 1,
182
+ sx: {
183
+ alignItems: 'baseline',
184
+ flexWrap: 'wrap'
185
+ },
186
+ children: [
187
+ /*#__PURE__*/ _jsx(Typography, {
188
+ variant: "overline",
189
+ color: "text.secondary",
190
+ component: "div",
191
+ children: field.label
192
+ }),
193
+ field.source === 'extra' ? /*#__PURE__*/ _jsx(Tooltip, {
194
+ title: 'Stored on this record with no field in the ' + 'collection’s schema. The table cannot show it, and ' + 'the next save through the editor removes it.',
195
+ children: /*#__PURE__*/ _jsx(Typography, {
196
+ variant: "caption",
197
+ color: "warning.main",
198
+ sx: {
199
+ cursor: 'help'
200
+ },
201
+ children: 'not in schema'
202
+ })
203
+ }) : null
204
+ ]
205
+ }),
206
+ /*#__PURE__*/ _jsx(RecordFieldValue, {
207
+ field: field
208
+ }),
209
+ mismatches[field.fieldId] ? /*#__PURE__*/ _jsx(Typography, {
210
+ variant: "caption",
211
+ color: "warning.main",
212
+ children: mismatches[field.fieldId]
213
+ }) : null,
214
+ field.description ? /*#__PURE__*/ _jsx(Typography, {
215
+ variant: "caption",
216
+ color: "text.secondary",
217
+ component: "div",
218
+ children: field.description
219
+ }) : null
220
+ ]
221
+ }, field.fieldId)),
222
+ fields.length === 0 ? /*#__PURE__*/ _jsx(Alert, {
223
+ severity: "info",
224
+ children: 'This record holds no fields.'
225
+ }) : null
226
+ ]
227
+ })
228
+ }),
229
+ /*#__PURE__*/ _jsxs(DialogActions, {
230
+ children: [
231
+ onEdit ? /*#__PURE__*/ _jsx(Button, {
232
+ onClick: onEdit,
233
+ children: 'Edit record'
234
+ }) : null,
235
+ /*#__PURE__*/ _jsx(Button, {
236
+ variant: "contained",
237
+ color: "primary",
238
+ onClick: onClose,
239
+ children: 'Close'
240
+ })
241
+ ]
242
+ })
243
+ ]
244
+ });
245
+ }
246
+ DatasetRecordDialog.displayName = 'DatasetRecordDialog';
247
+ export default DatasetRecordDialog;
248
+
249
+ //# sourceMappingURL=dataset-record-dialog.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/data/src/lib/components/dataset-record-dialog.component.tsx"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n'use client'\n\nimport { type DatasetModel, validateDocument } from '@aglyn/aglyn'\nimport {\n type DatasetRecordField,\n type DatasetReferenceResolver,\n datasetRecordFields,\n} from '../model/dataset-record-view'\nimport {\n Alert,\n Box,\n Button,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Stack,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { useMemo } from 'react'\n\n/**\n * Looking at a record, as its own gesture.\n *\n * The records table has room for the model's columns and one line per value,\n * so the only way to see what a record actually holds was to open it in the\n * EDITOR — which made reading a record and changing one the same click, on a\n * dialog whose primary button writes. This is the other half: the whole\n * record, nothing writable.\n *\n * ## It reads nothing\n *\n * Every value on screen arrives as a prop, out of the page the table already\n * listens to. There is no query, no `getDoc`, and no effect — opening a record\n * costs zero documents, and rendering the table does not open one dialog per\n * row to find out. That is not an optimization detail: a viewer that fetched\n * the record it was handed would bill a read per glance, and one that mounted\n * per row would bill the whole page on arrival.\n *\n * ## Read-only means read-only\n *\n * Nothing here takes input and nothing here writes. `Edit record` is a\n * separate, explicitly labelled action that closes this and opens the editor —\n * the dialog that has always owned writing — so the two gestures stay\n * distinct rather than one being a slip away from the other.\n */\nexport interface DatasetRecordDialogProps {\n /**\n * The record row itself, straight from the table's page. `null` closes the\n * dialog — including when the row leaves the page under it, which is the\n * honest response to a record this reader can no longer see.\n */\n record: { $id: string; values?: Record<string, unknown> } | null\n model: DatasetModel\n /** Reference target ID → label, or `null` when it resolves to nothing. */\n resolveReference?: DatasetReferenceResolver\n onClose: () => void\n /**\n * Opens the record in the editor. Omitted for a reader who cannot write, so\n * the control is absent rather than present-and-refusing.\n */\n onEdit?: () => void\n}\n\n/** What each \"no value\" state is called on screen. */\nconst PLACEHOLDER: Record<string, string> = {\n absent: 'Not set',\n null: 'Null',\n 'empty-text': 'Empty text',\n 'empty-list': 'Empty list',\n 'empty-map': 'Empty map',\n}\n\n/**\n * One field's value.\n *\n * The four empty states get four different words, deliberately. A table cell\n * prints `--` for all of them because it has one line to work with; here there\n * is room to say which, and the difference decides what a reader does next —\n * a field that was never written and a field holding a real empty string are\n * not the same finding.\n */\nfunction RecordFieldValue(props: { field: DatasetRecordField }) {\n const { value } = props.field\n if (value.kind === 'opaque') {\n return (\n <Typography\n variant=\"body2\"\n color=\"text.secondary\"\n sx={{ fontStyle: 'italic' }}\n >\n {value.text}\n </Typography>\n )\n }\n if (value.kind !== 'value') {\n return (\n <Typography\n variant=\"body2\"\n color=\"text.disabled\"\n sx={{ fontStyle: 'italic' }}\n >\n {PLACEHOLDER[value.kind] ?? 'Not set'}\n </Typography>\n )\n }\n if (value.references) {\n return (\n <Stack direction=\"row\" spacing={1} sx={{ flexWrap: 'wrap', rowGap: 0.5 }}>\n {value.references.map((reference) => (\n <Typography\n key={reference.id}\n variant=\"body2\"\n // An unresolved target is a fact about the data, not a rendering\n // failure to paper over: the ID is shown either way, and only the\n // resolved one is allowed to look like a working link.\n color={reference.label ? 'text.primary' : 'warning.main'}\n sx={{ overflowWrap: 'anywhere' }}\n >\n {reference.label ?? `${reference.id} · unresolved`}\n </Typography>\n ))}\n </Stack>\n )\n }\n if (value.items) {\n return (\n // One line per item. The comma-joined form a cell shows cannot say\n // whether `a, b` is one item or two; a list of lines can.\n <Stack component=\"ul\" spacing={0.25} sx={{ m: 0, pl: 2.5 }}>\n {value.items.map((item, index) => (\n <Typography\n // Items are values, not identities — two equal strings are two\n // real entries and the position is what tells them apart.\n key={`${index}:${item}`}\n component=\"li\"\n variant=\"body2\"\n sx={{ overflowWrap: 'anywhere' }}\n >\n {item}\n </Typography>\n ))}\n </Stack>\n )\n }\n return (\n <Typography\n variant=\"body2\"\n // Pretty-printed JSON is only readable where its whitespace survives.\n {...(value.block\n ? {\n component: 'pre',\n sx: {\n m: 0,\n fontFamily: 'monospace',\n whiteSpace: 'pre-wrap',\n overflowWrap: 'anywhere',\n },\n }\n : { sx: { overflowWrap: 'anywhere' } })}\n >\n {value.text}\n </Typography>\n )\n}\nRecordFieldValue.displayName = 'RecordFieldValue'\n\nexport function DatasetRecordDialog(props: DatasetRecordDialogProps) {\n const { record, model, resolveReference, onClose, onEdit } = props\n const values = record?.values\n const fields = useMemo(\n () => (record ? datasetRecordFields(model, values, resolveReference) : []),\n [record, model, values, resolveReference],\n )\n /**\n * The same mismatch report the editor shows, for the same reason: a type\n * change never rewrites stored documents, so a record may legitimately hold\n * a value its model no longer describes. Reporting it beside the value is\n * what stops the view claiming the record conforms.\n */\n const mismatches = useMemo(\n () => (record ? validateDocument(model, values ?? {}) : {}),\n [record, model, values],\n )\n\n return (\n <Dialog\n open={Boolean(record)}\n onClose={onClose}\n maxWidth=\"sm\"\n fullWidth\n aria-labelledby=\"dataset-record-view-title\"\n >\n <DialogTitle id=\"dataset-record-view-title\">{'View record'}</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2}>\n <Box>\n <Typography\n variant=\"overline\"\n color=\"text.secondary\"\n component=\"div\"\n >\n {'Record ID'}\n </Typography>\n <Typography variant=\"body2\" sx={{ overflowWrap: 'anywhere' }}>\n {record?.$id ?? ''}\n </Typography>\n </Box>\n {fields.map((field) => (\n <Box key={field.fieldId}>\n <Stack\n direction=\"row\"\n spacing={1}\n sx={{ alignItems: 'baseline', flexWrap: 'wrap' }}\n >\n <Typography\n variant=\"overline\"\n color=\"text.secondary\"\n component=\"div\"\n >\n {field.label}\n </Typography>\n {field.source === 'extra' ? (\n <Tooltip\n title={\n 'Stored on this record with no field in the ' +\n 'collection’s schema. The table cannot show it, and ' +\n 'the next save through the editor removes it.'\n }\n >\n <Typography\n variant=\"caption\"\n color=\"warning.main\"\n sx={{ cursor: 'help' }}\n >\n {'not in schema'}\n </Typography>\n </Tooltip>\n ) : null}\n </Stack>\n <RecordFieldValue field={field} />\n {mismatches[field.fieldId] ? (\n <Typography variant=\"caption\" color=\"warning.main\">\n {mismatches[field.fieldId]}\n </Typography>\n ) : null}\n {field.description ? (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n component=\"div\"\n >\n {field.description}\n </Typography>\n ) : null}\n </Box>\n ))}\n {fields.length === 0 ? (\n <Alert severity=\"info\">{'This record holds no fields.'}</Alert>\n ) : null}\n </Stack>\n </DialogContent>\n <DialogActions>\n {onEdit ? <Button onClick={onEdit}>{'Edit record'}</Button> : null}\n <Button variant=\"contained\" color=\"primary\" onClick={onClose}>\n {'Close'}\n </Button>\n </DialogActions>\n </Dialog>\n )\n}\nDatasetRecordDialog.displayName = 'DatasetRecordDialog'\n\nexport default DatasetRecordDialog\n"],"names":["validateDocument","datasetRecordFields","Alert","Box","Button","Dialog","DialogActions","DialogContent","DialogTitle","Stack","Tooltip","Typography","useMemo","PLACEHOLDER","absent","null","RecordFieldValue","props","value","field","kind","variant","color","sx","fontStyle","text","references","direction","spacing","flexWrap","rowGap","map","reference","label","overflowWrap","id","items","component","m","pl","item","index","block","fontFamily","whiteSpace","displayName","DatasetRecordDialog","record","model","resolveReference","onClose","onEdit","values","fields","mismatches","open","Boolean","maxWidth","fullWidth","aria-labelledby","dividers","$id","alignItems","source","title","cursor","fieldId","description","length","severity","onClick"],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { type DatasetModel } from '@aglyn/aglyn';
2
+ export interface DatasetSchemaDialogProps {
3
+ /** Host context; resolves the owning org for the data scope. */
4
+ hostId?: string;
5
+ /** Direct org scope (AGL-239): wins over `hostId` resolution when set. */
6
+ orgId?: string;
7
+ dataset: {
8
+ $id: string;
9
+ displayName?: string;
10
+ fields?: string[];
11
+ model?: DatasetModel;
12
+ names?: {
13
+ singular?: string;
14
+ plural?: string;
15
+ };
16
+ } | null;
17
+ /** All host collections, for reference-field target pickers (AGL-180). */
18
+ datasets?: Array<{
19
+ $id: string;
20
+ displayName?: string;
21
+ fields?: string[];
22
+ model?: DatasetModel;
23
+ }>;
24
+ recordCount: number;
25
+ /**
26
+ * The listener that produced `dataset` has NOT been confirmed by the
27
+ * server (AGL-1358). Required rather than optional on purpose: the
28
+ * listener lives in the parent card, so this dialog cannot compute the
29
+ * verdict, and an optional prop a caller forgets is a guard that is off
30
+ * while looking present — which is exactly how AGL-1356 stayed open.
31
+ */
32
+ seedFromCache: boolean;
33
+ /** That listener FAILED (`status === 'error'`). */
34
+ seedUnreadable?: boolean;
35
+ onClose: () => void;
36
+ }
37
+ /**
38
+ * Model builder (AGL-178): edits the AGL-177 typed model on a dataset —
39
+ * singular/plural display names (dod.ts Schema.Name), add/edit/remove/
40
+ * reorder fields, per-field type/required/default/description/validation.
41
+ * Schema-change policies (documented per the issue): type changes never
42
+ * rewrite documents — non-conforming values surface in the editor when it
43
+ * validates (AGL-179); removed fields leave orphaned values that strip
44
+ * lazily on next document save; fieldIds are stable keys — only display
45
+ * names rename.
46
+ */
47
+ export declare function DatasetSchemaDialog(props: DatasetSchemaDialogProps): import("react").JSX.Element;
48
+ export declare namespace DatasetSchemaDialog {
49
+ var displayName: string;
50
+ }
51
+ export default DatasetSchemaDialog;