@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.
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/package.json +47 -0
- package/src/index.d.ts +19 -0
- package/src/index.js +20 -0
- package/src/index.js.map +1 -0
- package/src/lib/components/data-console-page.d.ts +13 -0
- package/src/lib/components/data-console-page.js +63 -0
- package/src/lib/components/data-console-page.js.map +1 -0
- package/src/lib/components/dataset-record-dialog.component.d.ts +52 -0
- package/src/lib/components/dataset-record-dialog.component.js +249 -0
- package/src/lib/components/dataset-record-dialog.component.js.map +1 -0
- package/src/lib/components/dataset-schema-dialog.component.d.ts +51 -0
- package/src/lib/components/dataset-schema-dialog.component.js +979 -0
- package/src/lib/components/dataset-schema-dialog.component.js.map +1 -0
- package/src/lib/components/host-datasets-card.component.d.ts +39 -0
- package/src/lib/components/host-datasets-card.component.js +1831 -0
- package/src/lib/components/host-datasets-card.component.js.map +1 -0
- package/src/lib/constants/bundle-common.d.ts +8 -0
- package/src/lib/constants/bundle-common.js +9 -0
- package/src/lib/constants/bundle-common.js.map +1 -0
- package/src/lib/model/dataset-io.d.ts +43 -0
- package/src/lib/model/dataset-io.js +84 -0
- package/src/lib/model/dataset-io.js.map +1 -0
- package/src/lib/model/dataset-record-view.d.ts +157 -0
- package/src/lib/model/dataset-record-view.js +293 -0
- package/src/lib/model/dataset-record-view.js.map +1 -0
- package/src/lib/model/index.d.ts +22 -0
- package/src/lib/model/index.js +22 -0
- package/src/lib/model/index.js.map +1 -0
- package/src/lib/plugin.d.ts +35 -0
- package/src/lib/plugin.js +78 -0
- package/src/lib/plugin.js.map +1 -0
- package/src/lib/repeat/dataset-repeat-rows.d.ts +45 -0
- package/src/lib/repeat/dataset-repeat-rows.js +108 -0
- package/src/lib/repeat/dataset-repeat-rows.js.map +1 -0
- package/src/lib/repeat/dataset-repeat-source.d.ts +39 -0
- package/src/lib/repeat/dataset-repeat-source.js +95 -0
- package/src/lib/repeat/dataset-repeat-source.js.map +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/data/src/lib/components/dataset-schema-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 {\n DATASET_FIELD_TYPE_LABELS,\n DATASET_FIELD_TYPES,\n defaultDatasetFieldId,\n getCustomFieldType,\n listCustomFieldTypes,\n validateDatasetFieldId,\n type DatasetFieldDefinition,\n type DatasetFieldType,\n type DatasetModel,\n describeScope,\n effectiveDatasetModel,\n HOST_ACCESS_ROLES,\n hostScopeToken,\n narrowsScope,\n scopeCovers,\n ORG_SCOPE_TOKEN,\n scopeToStore,\n storedScope,\n visibleToHost,\n} from '@aglyn/aglyn'\nimport { useConfirmationContext } from '@aglyn/shared-ui-jsx'\nimport { useSnackbar } from '@aglyn/shared-ui-snackstack'\nimport {\n Button,\n Checkbox,\n Alert,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControlLabel,\n IconButton,\n MenuItem,\n Select,\n Stack,\n TextField,\n Typography,\n} from '@mui/material'\nimport { collection, doc, limit, query, updateDoc, where } from 'firebase/firestore'\nimport { useCallback, useEffect, useState } from 'react'\nimport {\n useFirestore,\n useFirestoreCollection,\n useOrgDataScope,\n useScopeTokens,\n useUser,\n writeGuardedBySeed,\n} from '@aglyn/tenant-feature-instance'\n\n/** Types surfaced in the picker; the rest exist for compat, not authoring. */\nconst AUTHORABLE_TYPES: DatasetFieldType[] = [\n 'text',\n 'bool',\n 'int32',\n 'float',\n 'timestamp',\n 'coordinates',\n 'sorted',\n 'reference',\n]\n\nexport interface DatasetSchemaDialogProps {\n /** Host context; resolves the owning org for the data scope. */\n hostId?: string\n /** Direct org scope (AGL-239): wins over `hostId` resolution when set. */\n orgId?: string\n dataset: {\n $id: string\n displayName?: string\n fields?: string[]\n model?: DatasetModel\n names?: { singular?: string; plural?: string }\n } | null\n /** All host collections, for reference-field target pickers (AGL-180). */\n datasets?: Array<{\n $id: string\n displayName?: string\n fields?: string[]\n model?: DatasetModel\n }>\n recordCount: number\n /**\n * The listener that produced `dataset` has NOT been confirmed by the\n * server (AGL-1358). Required rather than optional on purpose: the\n * listener lives in the parent card, so this dialog cannot compute the\n * verdict, and an optional prop a caller forgets is a guard that is off\n * while looking present — which is exactly how AGL-1356 stayed open.\n */\n seedFromCache: boolean\n /** That listener FAILED (`status === 'error'`). */\n seedUnreadable?: boolean\n onClose: () => void\n}\n\n/**\n * Model builder (AGL-178): edits the AGL-177 typed model on a dataset —\n * singular/plural display names (dod.ts Schema.Name), add/edit/remove/\n * reorder fields, per-field type/required/default/description/validation.\n * Schema-change policies (documented per the issue): type changes never\n * rewrite documents — non-conforming values surface in the editor when it\n * validates (AGL-179); removed fields leave orphaned values that strip\n * lazily on next document save; fieldIds are stable keys — only display\n * names rename.\n */\nexport function DatasetSchemaDialog(props: DatasetSchemaDialogProps) {\n const {\n hostId,\n dataset,\n datasets,\n recordCount,\n seedFromCache,\n seedUnreadable,\n onClose,\n } = props\n // Org-shared data root (AGL-237/239). Null until the async org lookup\n // settles (AGL-1061), and for a host with no owning org. Saving is held\n // on it rather than redirected: the host path this used to fall back to\n // is now denied by the rules outright (AGL-1050), so a save there would\n // fail loudly instead of quietly — but it should not be attempted at all.\n const { scope: dataScope, orgId } = useOrgDataScope({\n hostId,\n orgId: props.orgId,\n })\n const firestore = useFirestore()\n const { enqueueSnackbar } = useSnackbar()\n const { confirm } = useConfirmationContext()\n\n // Sharing scope (AGL-1044) — org datasets only; the legacy host path is\n // site-private by construction.\n // `orgWide` reads TRUE while the member doc loads (AGL-1047), which would\n // offer a scoped collaborator the scope Select for a beat before replacing\n // it with the read-only summary — and offering a control the AGL-1041\n // rules will reject is the thing the branch below exists to avoid. Hold\n // the whole block until `loaded` rather than flash the wrong one.\n const { orgWide: viewerOrgWide, loaded: scopeLoaded } = useScopeTokens(\n orgId ?? undefined,\n )\n // Sites in this org, for naming what a narrowing would cost. Queried\n // here rather than via the console's useOrgHosts — this component lives\n // in a lib and cannot import from an app — so it must repeat that hook's\n // membership filter, which is the part this was missing (AGL-1145).\n //\n // `/hosts/{hostId}` is gated per document on `memberRoles.{uid}`, and\n // Firestore evaluates a LIST against the QUERY rather than its results: it\n // refuses to run one that COULD return a denied document, whatever today's\n // data happens to hold. So filtering on `orgId` alone was not a partial\n // result, it was a flat denial for every non-staff caller — including one\n // who is a member of every site in the org. Proved in the emulator\n // (cloud/hosts-list-constraint.spec.mjs); the reason nobody hit it is that\n // staff match the rule's other branch, and staff are who tested it.\n const { data: user } = useUser()\n const uid = (user as { uid?: string } | undefined)?.uid\n const { data: orgHostDocs } = useFirestoreCollection<any>(\n // Hold rather than substitute a placeholder while the uid resolves. The\n // old `orgId ?? '-none-'` fired a real query on every mount before the\n // scope was known; a sentinel is still a question asked of the server,\n // and here it is one that gets denied.\n () =>\n uid && orgId\n ? query(\n collection(firestore, 'hosts'),\n where(`memberRoles.${uid}`, 'in', HOST_ACCESS_ROLES),\n where('orgId', '==', orgId),\n limit(200),\n )\n : null,\n [firestore, orgId, uid],\n { idField: '$id' },\n )\n const orgHostList: Array<{ $id: string; name?: string; subdomain?: string }> =\n orgHostDocs ?? []\n const [visibleTo, setVisibleTo] = useState<string[]>([])\n /**\n * The dataset stores NO scope (AGL-1484) — as opposed to storing `['org']`.\n *\n * The dialog used to render the two identically, which for a dataset is a\n * worse lie than it was for a media file: `orgs/{orgId}/datasets` is read\n * with `array-contains-any` in `resolve-dataset.ts` and in the console's\n * own `organizations.ts`, so an unstamped dataset is matched by no reader\n * in the product. It renders on no site and is missing from the reference\n * cards even for an org-wide member — while this control said \"All sites\".\n */\n const [scopeUnset, setScopeUnset] = useState(false)\n\n const [model, setModel] = useState<DatasetModel>({ fields: {}, order: [] })\n const [names, setNames] = useState<{ singular: string; plural: string }>({\n singular: '',\n plural: '',\n })\n useEffect(() => {\n if (!dataset) return\n // The fourth copy of the AGL-1466 substitution (AGL-1484), and the seed\n // half of it. Persisting the default on open was the other option and\n // AGL-1466 ruled it out: opening a dialog would write, the AGL-1042\n // rules refuse that write from anyone who is not org-wide, and it\n // repairs only what somebody happens to look at — a repair mechanism\n // wearing a UI. `previousScope` in `handleSave` reads the SAME helper;\n // see the note there for why the pair is the safety property.\n const storedDatasetScope = storedScope((dataset as { visibleTo?: string[] }).visibleTo)\n setVisibleTo(storedDatasetScope ?? [])\n setScopeUnset(!storedDatasetScope)\n const effective = effectiveDatasetModel(dataset)\n setModel({\n fields: JSON.parse(JSON.stringify(effective.fields)),\n order: [...effective.order],\n })\n setNames({\n singular: dataset.names?.singular ?? '',\n plural: dataset.names?.plural ?? dataset.displayName ?? '',\n })\n }, [dataset])\n\n // Per-field editor (null fieldId = new field). `idDraft`/`idTouched` back\n // the editable Reference ID (AGL-578): for a new field the draft follows\n // the display name until the user edits it; existing fields keep the id\n // frozen (idTouched=true, input disabled).\n const [fieldEditor, setFieldEditor] = useState<{\n fieldId: string | null\n definition: DatasetFieldDefinition\n optionsText: string\n idDraft: string\n idTouched: boolean\n } | null>(null)\n\n const openFieldEditor = useCallback(\n (fieldId: string | null) => () => {\n const definition: DatasetFieldDefinition = fieldId\n ? JSON.parse(JSON.stringify(model.fields[fieldId]))\n : { name: '', type: 'text' }\n setFieldEditor({\n fieldId,\n definition,\n optionsText: (definition.validation?.options ?? []).join(', '),\n idDraft: fieldId ?? '',\n idTouched: fieldId != null,\n })\n },\n [model],\n )\n\n const handleFieldSave = useCallback(async () => {\n if (!fieldEditor) return\n const definition = { ...fieldEditor.definition }\n if (!definition.name.trim()) return\n definition.name = definition.name.trim()\n // Descriptions (AGL-560) surface as hints wherever the field appears;\n // blank ones are dropped so the model doesn't accrete empty strings.\n const description = definition.description?.trim()\n if (description) definition.description = description\n else delete definition.description\n const options = fieldEditor.optionsText\n .split(',')\n .map((option) => option.trim())\n .filter(Boolean)\n definition.validation = {\n ...(definition.validation ?? {}),\n ...(options.length ? { options } : {}),\n }\n if (!options.length) delete definition.validation.options\n if (!Object.keys(definition.validation).length) delete definition.validation\n\n let fieldId = fieldEditor.fieldId\n if (!fieldId) {\n // New field: the reference id comes from the (editable) draft, which\n // defaulted from the display name. Validate before it becomes a key.\n const id = fieldEditor.idDraft.trim()\n const idError = validateDatasetFieldId(\n id,\n new Set(model.order.map((existing) => existing.toLowerCase())),\n )\n if (idError) {\n return void enqueueSnackbar(idError, {\n variant: 'warning',\n persist: false,\n })\n }\n fieldId = id\n } else if (\n recordCount > 0 &&\n model.fields[fieldId] &&\n model.fields[fieldId].type !== definition.type\n ) {\n // Documented policy: changing a type never rewrites documents;\n // existing values that no longer conform get flagged when edited.\n const confirmed = await confirm({\n title: 'Change field type?',\n description:\n `${recordCount} document${recordCount === 1 ? '' : 's'} exist. ` +\n 'Stored values are not rewritten — ones that no longer match ' +\n `\"${DATASET_FIELD_TYPE_LABELS[definition.type]}\" will be flagged ` +\n 'when documents are next edited.',\n confirmationText: 'Change type',\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n }\n setModel((prev) => ({\n fields: { ...prev.fields, [fieldId as string]: definition },\n order: prev.order.includes(fieldId as string)\n ? prev.order\n : [...prev.order, fieldId as string],\n }))\n setFieldEditor(null)\n }, [fieldEditor, model, recordCount, confirm, enqueueSnackbar])\n\n const handleFieldRemove = useCallback(\n (fieldId: string) => async () => {\n const confirmed = await confirm({\n title: `Remove field \"${model.fields[fieldId]?.name ?? fieldId}\"?`,\n description:\n 'Existing documents keep their stored value until they are next ' +\n 'saved (it is stripped then). Bindings using this field stop ' +\n 'resolving.',\n confirmationText: 'Remove',\n confirmationButtonProps: { color: 'error' },\n })\n .then(() => true)\n .catch(() => false)\n if (!confirmed) return\n setModel((prev) => {\n const fields = { ...prev.fields }\n delete fields[fieldId]\n return { fields, order: prev.order.filter((id) => id !== fieldId) }\n })\n },\n [model, confirm],\n )\n\n const moveField = useCallback(\n (fieldId: string, delta: number) => () =>\n setModel((prev) => {\n const index = prev.order.indexOf(fieldId)\n const target = index + delta\n if (index < 0 || target < 0 || target >= prev.order.length) return prev\n const order = [...prev.order]\n order.splice(index, 1)\n order.splice(target, 0, fieldId)\n return { ...prev, order }\n }),\n [],\n )\n\n const handleSave = useCallback(async () => {\n if (!dataset || !dataScope) return\n /**\n * What the document actually carries, `[]` when it carries nothing\n * (AGL-1484) — matching the seed above, through the same helper.\n *\n * The pairing is the whole safety property, not tidiness. Both sides\n * used to substitute `[ORG_SCOPE_TOKEN]`, so an unset dataset compared\n * equal to itself and merely OPENING the dialog wrote nothing; the\n * damage was confined to the screen. Correcting the seed alone would\n * make `scopeChanged` true for every unset dataset the moment its\n * dialog opened, turning a lie on screen into a write nobody asked for\n * — one the AGL-1041 rules then reject for any member who is not\n * org-wide, failing the WHOLE schema save with it.\n *\n * `[]` is also the honest previous value in the other direction: a\n * deliberate save of exactly `['org']` on an unset dataset used to\n * compare equal to the default and be dropped, and that is the one save\n * an unstamped dataset most needs to land.\n */\n const previousScope: string[] = storedScope((dataset as { visibleTo?: string[] }).visibleTo) ?? []\n const scopeChanged =\n JSON.stringify([...previousScope].sort()) !==\n JSON.stringify([...visibleTo].sort())\n /**\n * The scope this save writes, or null when it writes none.\n *\n * Only an org-wide member may change the scope — the AGL-1041 rules deny\n * anyone else, and a rejected field fails the WHOLE write.\n *\n * A selection `scopeToStore` cannot store — \"Selected sites…\" with no site\n * picked, or more sites than one query can match — refuses the save rather\n * than substituting a scope: the org token would share the collection with\n * every site, and anything narrower would drop sites somebody picked.\n */\n const scopeWrite =\n orgId && viewerOrgWide && scopeChanged ? scopeToStore(visibleTo) : null\n if (scopeWrite?.problem) {\n return void enqueueSnackbar(scopeWrite.problem, {\n variant: 'warning',\n persist: false,\n })\n }\n if (scopeChanged && narrowsScope(previousScope, visibleTo)) {\n // Narrowing takes a dataset away from sites whose pages may bind it,\n // and a repeatable bound to a dataset it can no longer see renders\n // nothing (AGL-1039). Name the cost before paying it.\n const losing = orgHostList\n .filter((host) => visibleToHost(previousScope, host.$id))\n .filter((host) => !visibleToHost(visibleTo, host.$id))\n .map((host) => host.name ?? host.subdomain ?? host.$id)\n const proceed = await confirm({\n title: 'Limit which sites can use this collection?',\n description: losing.length\n ? `${losing.join(', ')} will stop seeing this collection. Pages ` +\n 'that repeat over it will render nothing. No data is deleted.'\n : 'No site loses access, so nothing breaks today.',\n confirmationText: 'Limit access',\n })\n .then(() => true)\n .catch(() => false)\n if (!proceed) return\n }\n if (!model.order.length) {\n return void enqueueSnackbar('A collection needs at least one field', {\n variant: 'warning',\n persist: false,\n })\n }\n /**\n * Refuse the write when the seeding listener is unconfirmed (AGL-1358).\n *\n * Everything below is seeded from `dataset` and written back whole, so\n * `updateDoc` field-level merging protects nothing — the untouched\n * fields are all in the payload. Two of them make a stale seed worse\n * than an inconvenience:\n *\n * - `visibleTo` is the AGL-1041/1042 scoping PREDICATE. Rewriting it\n * from a cached seed re-exposes a collection that was narrowed, or\n * hides one that was widened, and the confirmation above is computed\n * against `previousScope` read from that same stale seed — so it does\n * not even warn about the sites it is really taking access from.\n * - `model` is the entire schema. A cached seed reinstates fields that\n * were deleted and drops fields that were added.\n */\n await writeGuardedBySeed(\n {\n subject: 'collection schema',\n unreadable: seedUnreadable,\n fromCache: seedFromCache,\n },\n async () =>\n void (await updateDoc(\n doc(firestore, dataScope[0], dataScope[1], 'datasets', dataset.$id),\n {\n model,\n names: {\n singular: names.singular.trim(),\n plural: names.plural.trim(),\n },\n ...(names.plural.trim()\n ? { displayName: names.plural.trim() }\n : {}),\n // v1 compat: keep the flat column list mirroring the model order\n // so unmigrated consumers (AGL-103 bindings) keep working.\n fields: model.order,\n ...(scopeWrite?.scope ? { visibleTo: scopeWrite.scope } : {}),\n },\n )),\n )\n .then((result) => {\n // A refusal leaves the dialog open with the edited schema intact.\n if (!result.ok) {\n return void enqueueSnackbar(result.message, {\n variant: 'warning',\n persist: false,\n })\n }\n enqueueSnackbar('Schema saved', { variant: 'success', persist: false })\n onClose()\n })\n .catch(() =>\n enqueueSnackbar('An error has occurred', { variant: 'error' }),\n )\n }, [\n dataset,\n model,\n names,\n visibleTo,\n viewerOrgWide,\n orgHostList,\n confirm,\n firestore,\n dataScope,\n orgId,\n seedFromCache,\n seedUnreadable,\n enqueueSnackbar,\n onClose,\n ])\n\n const editorDefinition = fieldEditor?.definition\n // Reference ID editing (AGL-578): the id is editable only while creating a\n // field; live-validate the draft so the input and Save button can react.\n const isNewField = fieldEditor != null && fieldEditor.fieldId == null\n const fieldIdError =\n fieldEditor && isNewField\n ? validateDatasetFieldId(\n fieldEditor.idDraft,\n new Set(model.order.map((id) => id.toLowerCase())),\n )\n : null\n\n return (\n <>\n <Dialog\n open={Boolean(dataset)}\n onClose={onClose}\n maxWidth=\"sm\"\n fullWidth\n >\n <DialogTitle>{`Schema — ${dataset?.displayName ?? ''}`}</DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}\n >\n <Stack direction=\"row\" spacing={1} sx={{ mt: 1 }}>\n <TextField\n size=\"small\"\n label=\"Singular name\"\n value={names.singular}\n onChange={(event) =>\n setNames((prev) => ({ ...prev, singular: event.target.value }))\n }\n helperText=\"e.g. Product\"\n />\n <TextField\n size=\"small\"\n label=\"Plural name\"\n value={names.plural}\n onChange={(event) =>\n setNames((prev) => ({ ...prev, plural: event.target.value }))\n }\n helperText=\"e.g. Products (shown as the title)\"\n />\n </Stack>\n {/* Sharing scope (AGL-1044). Org datasets only; the legacy host\n path is site-private already. Read-only for scoped members —\n the rules deny them the write and it would fail the whole\n document, so a control that always errors is worse than the\n value. */}\n {orgId ? (\n <Stack spacing={0.5}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {'Shared with'}\n </Typography>\n {!scopeLoaded ? (\n <Typography variant=\"body2\" color=\"text.secondary\">\n {'Checking your access…'}\n </Typography>\n ) : viewerOrgWide ? (\n <>\n {/*\n The state this dialog used to hide (AGL-1484), in the\n words the folder dialog and the media drawer already\n use. It costs a sentence, and it is the difference\n between reading \"All sites\" off a collection no site can\n see and being told to choose.\n */}\n {scopeUnset ? (\n <Alert severity=\"warning\">\n {'This collection has never been shared. Nothing is ' +\n 'stored, so it is hidden from every site and any ' +\n 'page repeating over it renders nothing. Choose who ' +\n 'it is shared with to fix that.'}\n </Alert>\n ) : null}\n <Select\n size=\"small\"\n value={\n visibleTo.includes(ORG_SCOPE_TOKEN)\n ? 'org'\n : scopeUnset\n ? 'unset'\n : 'hosts'\n }\n onChange={(event) => {\n // Any choice ends the unset state — from here the\n // control shows what was picked, not what was (not)\n // stored.\n setScopeUnset(false)\n setVisibleTo(\n event.target.value === 'org' ? [ORG_SCOPE_TOKEN] : [],\n )\n }}\n >\n {/*\n A real sentinel, never '' — MUI cannot hold an empty\n string as a selected value and a corpus spec forbids\n one. Rendered only while unset and disabled, so the\n control cannot be set back into \"nobody has decided\".\n */}\n {scopeUnset ? (\n <MenuItem value=\"unset\" disabled>\n {'Not shared with any site'}\n </MenuItem>\n ) : null}\n <MenuItem value=\"org\">{'All sites'}</MenuItem>\n <MenuItem value=\"hosts\">{'Selected sites…'}</MenuItem>\n </Select>\n {/* Says what sharing does NOT do, which is the part\n people get wrong (AGL-1046). It controls which sites\n may use the data; it is not a permission on the rows\n a published page already renders. */}\n <Typography variant=\"caption\" color=\"text.secondary\">\n {\n 'Sites you exclude cannot see or use this dataset — in the console or on their pages.'\n }\n </Typography>\n {/*\n The host chips are the \"Selected sites…\" detail. Showing\n them under an unset collection would invite a save of\n the empty selection already sitting there, which is the\n widening-by-accident this class keeps producing.\n */}\n {!scopeUnset && !visibleTo.includes(ORG_SCOPE_TOKEN) ? (\n <Stack\n direction=\"row\"\n spacing={0.5}\n useFlexGap\n sx={{ flexWrap: 'wrap' }}\n >\n {orgHostList.map((host) => {\n const token = hostScopeToken(host.$id)\n const on = visibleTo.includes(token)\n return (\n <Chip\n key={host.$id}\n size=\"small\"\n label={host.name ?? host.subdomain ?? host.$id}\n color={on ? 'primary' : 'default'}\n variant={on ? 'filled' : 'outlined'}\n onClick={() =>\n setVisibleTo((prev) =>\n on\n ? prev.filter((t) => t !== token)\n : [...prev, token],\n )\n }\n />\n )\n })}\n </Stack>\n ) : null}\n {!scopeUnset && scopeToStore(visibleTo).problem ? (\n <Typography variant=\"caption\" color=\"error\">\n {scopeToStore(visibleTo).problem}\n </Typography>\n ) : null}\n </>\n ) : (\n <Typography variant=\"body2\">\n {/*\n A scoped collaborator cannot fix this — the AGL-1041\n rules deny them the write — but they are the ones who\n notice a repeatable rendering nothing on their site, so\n they get the reason rather than `describeScope`'s \"No\n sites\", which reads like a setting somebody chose\n (AGL-1484).\n */}\n {scopeUnset\n ? 'Never shared — hidden from every site'\n : describeScope(\n visibleTo,\n Object.fromEntries(\n orgHostList.map((host) => [\n host.$id,\n host.name ?? host.subdomain ?? host.$id,\n ]),\n ),\n )}\n </Typography>\n )}\n </Stack>\n ) : null}\n <Stack spacing={0.5}>\n {model.order.map((fieldId, index) => {\n const field = model.fields[fieldId]\n if (!field) return null\n return (\n <Stack\n key={fieldId}\n direction=\"row\"\n spacing={1}\n sx={{\n alignItems: 'center',\n px: 1,\n py: 0.5,\n border: '1px solid',\n borderColor: 'divider',\n borderRadius: 1,\n }}\n >\n <Stack sx={{ flex: 1, minWidth: 0 }}>\n <Typography variant=\"body2\" noWrap>\n {field.name}\n <Typography\n component=\"span\"\n variant=\"caption\"\n color=\"text.secondary\"\n >\n {` · ${fieldId}`}\n </Typography>\n </Typography>\n {field.description ? (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n noWrap\n >\n {field.description}\n </Typography>\n ) : null}\n </Stack>\n <Chip\n size=\"small\"\n label={DATASET_FIELD_TYPE_LABELS[field.type] ?? field.type}\n />\n {field.required || field.validation?.required ? (\n <Chip size=\"small\" color=\"primary\" label=\"required\" />\n ) : null}\n <IconButton\n size=\"small\"\n disabled={index === 0}\n onClick={moveField(fieldId, -1)}\n aria-label=\"Move up\"\n >\n {'▲'}\n </IconButton>\n <IconButton\n size=\"small\"\n disabled={index === model.order.length - 1}\n onClick={moveField(fieldId, 1)}\n aria-label=\"Move down\"\n >\n {'▼'}\n </IconButton>\n <Button size=\"small\" onClick={openFieldEditor(fieldId)}>\n {'Edit'}\n </Button>\n <Button\n size=\"small\"\n color=\"error\"\n onClick={handleFieldRemove(fieldId)}\n >\n {'Remove'}\n </Button>\n </Stack>\n )\n })}\n </Stack>\n <Button\n size=\"small\"\n variant=\"outlined\"\n color=\"primary\"\n onClick={openFieldEditor(null)}\n sx={{ alignSelf: 'flex-start' }}\n >\n {'Add field'}\n </Button>\n </DialogContent>\n <DialogActions>\n <Button onClick={onClose}>{'Cancel'}</Button>\n {/* Held until the data scope resolves (AGL-1061) — a save in that\n window writes the schema to the legacy host path. */}\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!dataScope}\n onClick={handleSave}\n >\n {'Save schema'}\n </Button>\n </DialogActions>\n </Dialog>\n\n <Dialog\n open={Boolean(fieldEditor)}\n onClose={() => setFieldEditor(null)}\n maxWidth=\"xs\"\n fullWidth\n >\n <DialogTitle>\n {fieldEditor?.fieldId ? 'Edit field' : 'New field'}\n </DialogTitle>\n <DialogContent\n sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}\n >\n <TextField\n size=\"small\"\n label=\"Display name\"\n value={editorDefinition?.name ?? ''}\n autoFocus\n onChange={(event) => {\n const name = event.target.value\n setFieldEditor((prev) => {\n if (!prev) return prev\n const next = {\n ...prev,\n definition: { ...prev.definition, name },\n }\n // The reference id follows the display name until the user\n // edits it (new fields only) — AGL-578.\n if (prev.fieldId == null && !prev.idTouched) {\n next.idDraft = defaultDatasetFieldId(\n name,\n new Set(model.order.map((id) => id.toLowerCase())),\n )\n }\n return next\n })\n }}\n sx={{ mt: 1 }}\n helperText=\"Shown to people editing records and wherever the field appears\"\n />\n <TextField\n size=\"small\"\n label=\"Reference ID\"\n value={\n isNewField\n ? (fieldEditor?.idDraft ?? '')\n : (fieldEditor?.fieldId ?? '')\n }\n disabled={!isNewField}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? { ...prev, idDraft: event.target.value, idTouched: true }\n : prev,\n )\n }\n error={Boolean(fieldIdError)}\n helperText={\n isNewField\n ? (fieldIdError ??\n 'Stable key used in bindings ({{item.id}}), forms, and imports. Auto-filled from the display name — edit to override. Fixed once the field is created.')\n : 'Reference IDs are stable keys and cannot change after creation'\n }\n />\n <TextField\n size=\"small\"\n label=\"Description\"\n multiline\n minRows={2}\n value={editorDefinition?.description ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n description: event.target.value,\n },\n }\n : prev,\n )\n }\n helperText=\"What this field is for — shown as a hint wherever the field appears\"\n />\n <TextField\n select\n size=\"small\"\n label=\"Type\"\n value={\n editorDefinition?.customType\n ? `custom:${editorDefinition.customType}`\n : (editorDefinition?.type ?? 'text')\n }\n onChange={(event) =>\n setFieldEditor((prev) => {\n if (!prev) return prev\n const selected = event.target.value\n // Custom field types (AGL-434): ride a base storage type\n // and stamp customType so the record editor + validators\n // pick up the plugin behavior.\n if (selected.startsWith('custom:')) {\n const fieldType = getCustomFieldType(selected.slice(7))\n if (!fieldType) return prev\n return {\n ...prev,\n definition: {\n ...prev.definition,\n type: fieldType.baseType as DatasetFieldType,\n customType: fieldType.name,\n },\n }\n }\n const definition = {\n ...prev.definition,\n type: selected as DatasetFieldType,\n }\n delete definition.customType\n return { ...prev, definition }\n })\n }\n >\n {(fieldEditor?.fieldId &&\n editorDefinition &&\n !AUTHORABLE_TYPES.includes(editorDefinition.type)\n ? DATASET_FIELD_TYPES\n : AUTHORABLE_TYPES\n ).map((type) => (\n <MenuItem key={type} value={type}>\n {DATASET_FIELD_TYPE_LABELS[type]}\n </MenuItem>\n ))}\n {listCustomFieldTypes().map((fieldType) => (\n <MenuItem\n key={`custom:${fieldType.name}`}\n value={`custom:${fieldType.name}`}\n >\n {`${fieldType.label} (${fieldType.pluginId})`}\n </MenuItem>\n ))}\n </TextField>\n {editorDefinition?.type === 'reference' ? (\n <>\n <TextField\n select\n size=\"small\"\n label=\"Target collection\"\n value={editorDefinition?.reference?.datasetId ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n reference: {\n ...(prev.definition.reference ?? {\n datasetId: '',\n }),\n datasetId: event.target.value,\n },\n },\n }\n : prev,\n )\n }\n >\n {(datasets ?? [])\n .filter((target) => target.$id !== dataset?.$id)\n // Only targets this dataset's sites can actually resolve\n // (AGL-1044). A reference to a dataset a site cannot see\n // renders blank with nothing to say why, so an\n // unresolvable target is not offered. The currently\n // selected one always stays listed — otherwise changing\n // scope would silently blank an existing field.\n .filter(\n (target) =>\n target.$id ===\n editorDefinition?.reference?.datasetId ||\n scopeCovers(\n (target as { visibleTo?: string[] }).visibleTo,\n visibleTo,\n ),\n )\n .map((target) => (\n <MenuItem key={target.$id} value={target.$id}>\n {target.displayName ?? target.$id}\n </MenuItem>\n ))}\n </TextField>\n {(() => {\n // Flag an EXISTING reference that this dataset's scope has\n // outgrown — the field was valid when created and quietly\n // is not any more.\n const targetId = editorDefinition?.reference?.datasetId\n const target = (datasets ?? []).find((d) => d.$id === targetId)\n if (\n !target ||\n scopeCovers(\n (target as { visibleTo?: string[] }).visibleTo,\n visibleTo,\n )\n ) {\n return null\n }\n return (\n <Alert severity=\"warning\">\n {`\"${target.displayName ?? target.$id}\" is not shared with ` +\n 'every site this collection is. Those sites will show ' +\n 'this field blank. Widen its sharing, or narrow this ' +\n \"collection's.\"}\n </Alert>\n )\n })()}\n <TextField\n select\n size=\"small\"\n label=\"Display field\"\n value={editorDefinition?.reference?.displayFieldId ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev?.definition.reference\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n reference: {\n ...prev.definition.reference,\n displayFieldId: event.target.value,\n },\n },\n }\n : prev,\n )\n }\n helperText=\"Shown in pickers and grid cells\"\n >\n {effectiveDatasetModel(\n (datasets ?? []).find(\n (target) =>\n target.$id === editorDefinition?.reference?.datasetId,\n ) ?? {},\n ).order.map((targetFieldId) => (\n <MenuItem key={targetFieldId} value={targetFieldId}>\n {targetFieldId}\n </MenuItem>\n ))}\n </TextField>\n <TextField\n select\n size=\"small\"\n label=\"When a referenced document is deleted\"\n value={editorDefinition?.reference?.onDelete ?? 'setNull'}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev?.definition.reference\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n reference: {\n ...prev.definition.reference,\n onDelete: event.target.value as\n | 'restrict'\n | 'setNull',\n },\n },\n }\n : prev,\n )\n }\n >\n <MenuItem value=\"setNull\">{'Clear the reference'}</MenuItem>\n <MenuItem value=\"restrict\">{'Block the delete'}</MenuItem>\n </TextField>\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={Boolean(editorDefinition?.reference?.multiple)}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev?.definition.reference\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n reference: {\n ...prev.definition.reference,\n multiple: event.target.checked,\n },\n },\n }\n : prev,\n )\n }\n />\n }\n label=\"Allow multiple (many-to-many)\"\n />\n </>\n ) : null}\n <FormControlLabel\n control={\n <Checkbox\n size=\"small\"\n checked={Boolean(editorDefinition?.required)}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n required: event.target.checked,\n },\n }\n : prev,\n )\n }\n />\n }\n label=\"Required\"\n />\n <TextField\n size=\"small\"\n label=\"Default value\"\n value={String(editorDefinition?.default ?? '')}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n ...(event.target.value\n ? { default: event.target.value }\n : { default: undefined }),\n },\n }\n : prev,\n )\n }\n helperText=\"Pre-filled when creating documents\"\n />\n {editorDefinition?.type === 'text' ? (\n <>\n <TextField\n size=\"small\"\n label=\"Pattern (regex)\"\n value={editorDefinition?.validation?.regex ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n validation: {\n ...(prev.definition.validation ?? {}),\n ...(event.target.value\n ? { regex: event.target.value }\n : { regex: undefined }),\n },\n },\n }\n : prev,\n )\n }\n />\n <TextField\n size=\"small\"\n label=\"Options\"\n value={fieldEditor?.optionsText ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev ? { ...prev, optionsText: event.target.value } : prev,\n )\n }\n helperText=\"Comma-separated enum, e.g. basic, plus\"\n />\n </>\n ) : null}\n {editorDefinition &&\n ['int32', 'int64', 'float', 'timestamp', 'text'].includes(\n editorDefinition.type,\n ) ? (\n <Stack direction=\"row\" spacing={1}>\n {(['min', 'max'] as const).map((bound) => (\n <TextField\n key={bound}\n size=\"small\"\n type=\"number\"\n label={\n editorDefinition.type === 'text'\n ? `${bound === 'min' ? 'Min' : 'Max'} length`\n : bound === 'min'\n ? 'Min'\n : 'Max'\n }\n value={editorDefinition.validation?.[bound] ?? ''}\n onChange={(event) =>\n setFieldEditor((prev) =>\n prev\n ? {\n ...prev,\n definition: {\n ...prev.definition,\n validation: {\n ...(prev.definition.validation ?? {}),\n ...(event.target.value === ''\n ? { [bound]: undefined }\n : { [bound]: Number(event.target.value) }),\n },\n },\n }\n : prev,\n )\n }\n />\n ))}\n </Stack>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={() => setFieldEditor(null)}>{'Cancel'}</Button>\n <Button\n variant=\"contained\"\n color=\"primary\"\n disabled={!editorDefinition?.name.trim() || Boolean(fieldIdError)}\n onClick={handleFieldSave}\n >\n {fieldEditor?.fieldId ? 'Save field' : 'Add field'}\n </Button>\n </DialogActions>\n </Dialog>\n </>\n )\n}\nDatasetSchemaDialog.displayName = 'DatasetSchemaDialog'\n\nexport default DatasetSchemaDialog\n"],"names":["DATASET_FIELD_TYPE_LABELS","DATASET_FIELD_TYPES","defaultDatasetFieldId","getCustomFieldType","listCustomFieldTypes","validateDatasetFieldId","describeScope","effectiveDatasetModel","HOST_ACCESS_ROLES","hostScopeToken","narrowsScope","scopeCovers","ORG_SCOPE_TOKEN","scopeToStore","storedScope","visibleToHost","useConfirmationContext","useSnackbar","Button","Checkbox","Alert","Chip","Dialog","DialogActions","DialogContent","DialogTitle","FormControlLabel","IconButton","MenuItem","Select","Stack","TextField","Typography","collection","doc","limit","query","updateDoc","where","useCallback","useEffect","useState","useFirestore","useFirestoreCollection","useOrgDataScope","useScopeTokens","useUser","writeGuardedBySeed","AUTHORABLE_TYPES","DatasetSchemaDialog","props","editorDefinition","hostId","dataset","datasets","recordCount","seedFromCache","seedUnreadable","onClose","scope","dataScope","orgId","firestore","enqueueSnackbar","confirm","orgWide","viewerOrgWide","loaded","scopeLoaded","undefined","data","user","uid","orgHostDocs","idField","orgHostList","visibleTo","setVisibleTo","scopeUnset","setScopeUnset","model","setModel","fields","order","names","setNames","singular","plural","storedDatasetScope","effective","JSON","parse","stringify","displayName","fieldEditor","setFieldEditor","openFieldEditor","fieldId","definition","name","type","optionsText","validation","options","join","idDraft","idTouched","handleFieldSave","trim","description","split","map","option","filter","Boolean","length","Object","keys","id","idError","Set","existing","toLowerCase","variant","persist","confirmed","title","confirmationText","then","catch","prev","includes","handleFieldRemove","confirmationButtonProps","color","moveField","delta","index","indexOf","target","splice","handleSave","previousScope","scopeChanged","sort","scopeWrite","problem","losing","host","$id","subdomain","proceed","subject","unreadable","fromCache","result","ok","message","isNewField","fieldIdError","open","maxWidth","fullWidth","sx","display","flexDirection","gap","direction","spacing","mt","size","label","value","onChange","event","helperText","severity","disabled","useFlexGap","flexWrap","token","on","onClick","t","fromEntries","field","alignItems","px","py","border","borderColor","borderRadius","flex","minWidth","noWrap","component","required","aria-label","alignSelf","autoFocus","next","error","multiline","minRows","select","customType","selected","startsWith","fieldType","slice","baseType","pluginId","reference","datasetId","targetId","find","d","displayFieldId","targetFieldId","onDelete","control","checked","multiple","String","default","regex","bound","Number"],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type AglynOrgBilling } from '@aglyn/aglyn';
|
|
2
|
+
export interface HostDatasetsCardProps {
|
|
3
|
+
/** Host context: resolves the owning org and logs host activity. */
|
|
4
|
+
hostId?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Direct org scope (AGL-239): the org Data page renders the editor
|
|
7
|
+
* without any host context. Wins over `hostId` resolution when set.
|
|
8
|
+
*/
|
|
9
|
+
orgId?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The resolved entitlement source (org billing doc). Passed in by both
|
|
12
|
+
* callers (the plugin Data page via the shell, the org Data page via its
|
|
13
|
+
* own resolver) so this relocated card runs entitlement/quota checks
|
|
14
|
+
* without console-app org/session hooks (AGL-395).
|
|
15
|
+
*/
|
|
16
|
+
org?: Partial<AglynOrgBilling>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The sentence that says who a NEW dataset is shared with, for the card and
|
|
20
|
+
* for the site Data page's banner above it.
|
|
21
|
+
*
|
|
22
|
+
* `siteOnly` is true only on a site's Data page in an org whose Default
|
|
23
|
+
* sharing is "Only the site they were created in". Everywhere else a new
|
|
24
|
+
* dataset starts on All sites: the org Data page has no site to limit it to.
|
|
25
|
+
*/
|
|
26
|
+
export declare function newDatasetSharingNote(siteOnly: boolean): string;
|
|
27
|
+
/**
|
|
28
|
+
* Datasets editor (AGL-102): org-shared document collections at
|
|
29
|
+
* `orgs/{orgId}/datasets` (AGL-237/239) with a `records` subcollection,
|
|
30
|
+
* consumed by repeatable components (AGL-103) via `{{item.field}}`.
|
|
31
|
+
* Starter+ (`data-store` flag) with per-plan dataset and record caps —
|
|
32
|
+
* dark-launch rule as everywhere (no plan, no gate). The host path is
|
|
33
|
+
* the pre-migration fallback for hosts not yet org-wired.
|
|
34
|
+
*/
|
|
35
|
+
export declare function HostDatasetsCard(props: HostDatasetsCardProps): import("react").JSX.Element;
|
|
36
|
+
export declare namespace HostDatasetsCard {
|
|
37
|
+
var displayName: string;
|
|
38
|
+
}
|
|
39
|
+
export default HostDatasetsCard;
|