@wildo-ai/presets-components 1.1.5 → 1.1.7
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/dist/esm/.native.tsbuildinfo +1 -0
- package/dist/esm/components/actions/action-bar.d.ts.map +1 -1
- package/dist/esm/components/actions/action-bar.js +5 -2
- package/dist/esm/components/actions/action-bar.js.map +1 -1
- package/dist/esm/components/ai-elements/chat/suggestion.d.ts.map +1 -1
- package/dist/esm/components/ai-elements/chat/suggestion.js +8 -1
- package/dist/esm/components/ai-elements/chat/suggestion.js.map +1 -1
- package/dist/esm/components/ai-elements/decision/approval.d.ts +108 -13
- package/dist/esm/components/ai-elements/decision/approval.d.ts.map +1 -1
- package/dist/esm/components/ai-elements/decision/approval.js +60 -10
- package/dist/esm/components/ai-elements/decision/approval.js.map +1 -1
- package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts +3 -1
- package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts.map +1 -1
- package/dist/esm/components/ai-elements/graph/graph-runtime.js +3 -1
- package/dist/esm/components/ai-elements/graph/graph-runtime.js.map +1 -1
- package/dist/esm/components/app/app-layout-main-container.d.ts +9 -0
- package/dist/esm/components/app/app-layout-main-container.d.ts.map +1 -1
- package/dist/esm/components/app/app-layout-main-container.js +17 -23
- package/dist/esm/components/app/app-layout-main-container.js.map +1 -1
- package/dist/esm/components/app/app-layout-main-container.labels.d.ts.map +1 -1
- package/dist/esm/components/app/app-layout-main-container.labels.js +27 -0
- package/dist/esm/components/app/app-layout-main-container.labels.js.map +1 -1
- package/dist/esm/components/billing/billing-plan-change-preview.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-plan-change-preview.js +5 -2
- package/dist/esm/components/billing/billing-plan-change-preview.js.map +1 -1
- package/dist/esm/components/billing/billing-plan-change-preview.labels.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-plan-change-preview.labels.js +3 -0
- package/dist/esm/components/billing/billing-plan-change-preview.labels.js.map +1 -1
- package/dist/esm/components/billing/billing-pricing-table.d.ts +1 -1
- package/dist/esm/components/billing/billing-pricing-table.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-pricing-table.js +8 -4
- package/dist/esm/components/billing/billing-pricing-table.js.map +1 -1
- package/dist/esm/components/billing/billing-pricing-table.labels.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-pricing-table.labels.js +7 -1
- package/dist/esm/components/billing/billing-pricing-table.labels.js.map +1 -1
- package/dist/esm/components/billing/billing-usage-dashboard.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-usage-dashboard.js +6 -3
- package/dist/esm/components/billing/billing-usage-dashboard.js.map +1 -1
- package/dist/esm/components/billing/billing-usage-dashboard.labels.d.ts.map +1 -1
- package/dist/esm/components/billing/billing-usage-dashboard.labels.js +2 -1
- package/dist/esm/components/billing/billing-usage-dashboard.labels.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-enum.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-enum.js +18 -4
- package/dist/esm/components/data-display/formatters/display-field-enum.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-file.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-file.js +13 -14
- package/dist/esm/components/data-display/formatters/display-field-file.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-file.labels.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-file.labels.js +1 -0
- package/dist/esm/components/data-display/formatters/display-field-file.labels.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-number.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-number.js +6 -1
- package/dist/esm/components/data-display/formatters/display-field-number.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-number.labels.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-number.labels.js +5 -2
- package/dist/esm/components/data-display/formatters/display-field-number.labels.js.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-string.d.ts +1 -1
- package/dist/esm/components/data-display/formatters/display-field-string.d.ts.map +1 -1
- package/dist/esm/components/data-display/formatters/display-field-string.js +51 -12
- package/dist/esm/components/data-display/formatters/display-field-string.js.map +1 -1
- package/dist/esm/components/data-display/untrusted-html-content.d.ts +55 -0
- package/dist/esm/components/data-display/untrusted-html-content.d.ts.map +1 -0
- package/dist/esm/components/data-display/untrusted-html-content.js +67 -0
- package/dist/esm/components/data-display/untrusted-html-content.js.map +1 -0
- package/dist/esm/components/form/chromes/form-primitive.labels.d.ts.map +1 -1
- package/dist/esm/components/form/chromes/form-primitive.labels.js +9 -0
- package/dist/esm/components/form/chromes/form-primitive.labels.js.map +1 -1
- package/dist/esm/components/form/combobox.d.ts.map +1 -1
- package/dist/esm/components/form/combobox.js +10 -10
- package/dist/esm/components/form/combobox.js.map +1 -1
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts +42 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts.map +1 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js +120 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js.map +1 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts +16 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts.map +1 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js +8 -0
- package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js.map +1 -0
- package/dist/esm/components/navigation/app-level/activity-bar.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/activity-bar.js +2 -2
- package/dist/esm/components/navigation/app-level/activity-bar.js.map +1 -1
- package/dist/esm/components/navigation/app-level/menu-user-org.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/menu-user-org.js +10 -4
- package/dist/esm/components/navigation/app-level/menu-user-org.js.map +1 -1
- package/dist/esm/components/navigation/app-level/menu-user-org.labels.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/menu-user-org.labels.js +7 -0
- package/dist/esm/components/navigation/app-level/menu-user-org.labels.js.map +1 -1
- package/dist/esm/components/navigation/app-level/menubar.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/menubar.js +6 -6
- package/dist/esm/components/navigation/app-level/menubar.js.map +1 -1
- package/dist/esm/components/navigation/app-level/navigation-back.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/navigation-back.js +27 -9
- package/dist/esm/components/navigation/app-level/navigation-back.js.map +1 -1
- package/dist/esm/components/navigation/app-level/sidebar.js +3 -3
- package/dist/esm/components/navigation/app-level/sidebar.js.map +1 -1
- package/dist/esm/components/navigation/app-level/status-bar.js +2 -2
- package/dist/esm/components/navigation/app-level/status-bar.js.map +1 -1
- package/dist/esm/components/navigation/app-level/toolbar.d.ts.map +1 -1
- package/dist/esm/components/navigation/app-level/toolbar.js +2 -2
- package/dist/esm/components/navigation/app-level/toolbar.js.map +1 -1
- package/dist/esm/components/navigation/app-level/utility-panel.js +2 -2
- package/dist/esm/components/navigation/app-level/utility-panel.js.map +1 -1
- package/dist/esm/components/navigation/breadcrumb.js +1 -1
- package/dist/esm/components/navigation/breadcrumb.js.map +1 -1
- package/dist/esm/components/sections/stepper.d.ts.map +1 -1
- package/dist/esm/components/sections/stepper.js +5 -3
- package/dist/esm/components/sections/stepper.js.map +1 -1
- package/dist/esm/config/preset-navigation.d.ts.map +1 -1
- package/dist/esm/config/preset-navigation.js +23 -2
- package/dist/esm/config/preset-navigation.js.map +1 -1
- package/dist/esm/config/resources/agent-work.resource-presets.d.ts +4 -0
- package/dist/esm/config/resources/agent-work.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/agent-work.resource-presets.js +115 -0
- package/dist/esm/config/resources/agent-work.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/api-key-rotation-window.d.ts +22 -0
- package/dist/esm/config/resources/api-key-rotation-window.d.ts.map +1 -0
- package/dist/esm/config/resources/api-key-rotation-window.js +45 -0
- package/dist/esm/config/resources/api-key-rotation-window.js.map +1 -0
- package/dist/esm/config/resources/application.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/application.resource-presets.js +147 -61
- package/dist/esm/config/resources/application.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/billing.resource-presets.d.ts +4 -3
- package/dist/esm/config/resources/billing.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/billing.resource-presets.js +240 -111
- package/dist/esm/config/resources/billing.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts +4 -0
- package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/conversation-threads.resource-presets.js +105 -0
- package/dist/esm/config/resources/conversation-threads.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/guidance.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/guidance.resource-presets.js +18 -11
- package/dist/esm/config/resources/guidance.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/identity.resource-presets.d.ts +0 -13
- package/dist/esm/config/resources/identity.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/identity.resource-presets.js +48 -16
- package/dist/esm/config/resources/identity.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts +6 -0
- package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/inbound-deliveries.resource-presets.js +112 -0
- package/dist/esm/config/resources/inbound-deliveries.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/inbound-email.resource-presets.d.ts +4 -0
- package/dist/esm/config/resources/inbound-email.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/inbound-email.resource-presets.js +182 -0
- package/dist/esm/config/resources/inbound-email.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/index.d.ts.map +1 -1
- package/dist/esm/config/resources/index.js +9 -2
- package/dist/esm/config/resources/index.js.map +1 -1
- package/dist/esm/config/resources/legal-holds.resource-presets.d.ts +4 -0
- package/dist/esm/config/resources/legal-holds.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/legal-holds.resource-presets.js +76 -0
- package/dist/esm/config/resources/legal-holds.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/organizations.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/organizations.resource-presets.js +139 -36
- package/dist/esm/config/resources/organizations.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/resource.config.utils.d.ts +20 -0
- package/dist/esm/config/resources/resource.config.utils.d.ts.map +1 -1
- package/dist/esm/config/resources/resource.config.utils.js +20 -0
- package/dist/esm/config/resources/resource.config.utils.js.map +1 -1
- package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts +5 -0
- package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/retention-enforcement.resource-presets.js +74 -0
- package/dist/esm/config/resources/retention-enforcement.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/security.resource-presets.d.ts +3 -1
- package/dist/esm/config/resources/security.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/security.resource-presets.js +563 -133
- package/dist/esm/config/resources/security.resource-presets.js.map +1 -1
- package/dist/esm/config/resources/service-providers.resource-presets.d.ts +4 -0
- package/dist/esm/config/resources/service-providers.resource-presets.d.ts.map +1 -0
- package/dist/esm/config/resources/service-providers.resource-presets.js +321 -0
- package/dist/esm/config/resources/service-providers.resource-presets.js.map +1 -0
- package/dist/esm/config/resources/webhooks.resource-presets.d.ts +4 -3
- package/dist/esm/config/resources/webhooks.resource-presets.d.ts.map +1 -1
- package/dist/esm/config/resources/webhooks.resource-presets.js +76 -25
- package/dist/esm/config/resources/webhooks.resource-presets.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/registration/register-common-enums.d.ts.map +1 -1
- package/dist/esm/registration/register-common-enums.js +15 -0
- package/dist/esm/registration/register-common-enums.js.map +1 -1
- package/dist/esm/registration/register-provider-components.d.ts.map +1 -1
- package/dist/esm/registration/register-provider-components.js +6 -0
- package/dist/esm/registration/register-provider-components.js.map +1 -1
- package/dist/esm/themes/dense.theme.d.ts.map +1 -1
- package/dist/esm/themes/dense.theme.js +22 -2
- package/dist/esm/themes/dense.theme.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +8 -6
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { RelatedResourceSections, resourceUIBehavior, resourceUIBehaviorFrom, SummaryFlow, SummaryMeta, SummaryTitle, ResourceLayoutInlineEditDefault, } from '@wildo-ai/saas-frontend-lib';
|
|
2
|
+
import { RelatedResourceSections, ResourceHeaderTitle, resourceUIBehavior, resourceUIBehaviorFrom, SummaryFlow, SummaryMeta, SummaryTitle, ResourceLayoutInlineEditDefault, } from '@wildo-ai/saas-frontend-lib';
|
|
3
3
|
import { DisplayField, DisplayLayout, FormField, FormLayout, ObjectScope, Section, SummaryLayout, SummaryTitlePlacement, } from '@wildo-ai/saas-frontend-lib';
|
|
4
|
-
import { BadgeSemanticVariant, DisplayChromeMode, EditChromeMode, EnumDisplayMode, SectionMode } from '@wildo-ai/zod-decorators';
|
|
5
|
-
import { CalendarPlus, ChartColumn, GitBranch, Key, KeyRound, ShieldCheck, ShieldX, Ban, Hourglass, LayoutGrid, Power, PowerOff, RefreshCw, RotateCcw, RotateCw, ToggleLeft, ToggleRight, } from 'lucide-react';
|
|
4
|
+
import { BadgeSemanticVariant, DisplayChromeMode, EditChromeMode, EnumDisplayMode, ForeignKeyDisplayMode, SectionMode, StringEditMode, } from '@wildo-ai/zod-decorators';
|
|
5
|
+
import { BadgeCheck, CalendarPlus, FileText, ChartColumn, GitBranch, Key, KeyRound, ShieldCheck, ShieldX, Ban, Hourglass, LayoutGrid, Power, PowerOff, RefreshCw, RotateCcw, RotateCw, ToggleLeft, ToggleRight, } from 'lucide-react';
|
|
6
6
|
import { CoreResourceType as R, CoreResourceOperation as Op, ApiKeyStatus, AppApiKeys_Operations, ApplicationFeatures_Operations, applicationResourceConfiguration_InitializationFactory as appFactory, applicationVersionsResourceConfiguration_InitializationFactory as appVersionsFactory, applicationMetadataResourceConfiguration_InitializationFactory as appMetadataFactory, appApiKeysResourceConfiguration_InitializationFactory as appApiKeysFactory, appOAuthClientsResourceConfiguration_InitializationFactory as appOAuthClientsFactory, applicationAccessGrantsResourceConfiguration_InitializationFactory as appAccessGrantsFactory, ApplicationAccessGrants_Operations, ApplicationAccessGrantSchema, PlatformAccessGrantStatus, AppOAuthClients_Operations, OAuthClientApplicationSchema, OAuthClientStatus, applicationFeaturesResourceConfiguration_InitializationFactory as appFeaturesFactory, ApplicationSchema, ApplicationVersionSchema, ApplicationMetadataSchema, ApiKeyApplicationSchema, ScopeFeaturesWithOverridesSchema, } from '@wildo-ai/saas-models';
|
|
7
|
-
import {
|
|
7
|
+
import { ApiKeyRotationWindowRows } from './api-key-rotation-window.js';
|
|
8
|
+
import { addressable, notAddressable, apiOnly, ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE } from './resource.config.utils.js';
|
|
8
9
|
/**
|
|
9
10
|
* Application — Resource frontend presets
|
|
10
11
|
*
|
|
@@ -67,19 +68,28 @@ export function buildApplicationAdminPresets(main) {
|
|
|
67
68
|
})),
|
|
68
69
|
[R.APPLICATION_VERSIONS]: resourceUIBehavior(appVersionsFactory, ApplicationVersionSchema, ({ schema, schemaShape, opsVariantResolver }) => ({
|
|
69
70
|
icon: GitBranch,
|
|
71
|
+
// A release is named by its version string, so the page title IS the version and no row repeats it.
|
|
70
72
|
getFrontendResourceLabel: ({ currentObject }) => currentObject.version,
|
|
71
73
|
layout: {
|
|
72
74
|
refs: {
|
|
73
75
|
sections: ['overview', 'releaseNotes'],
|
|
74
76
|
},
|
|
75
|
-
// Settings
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
// Settings rows on the read page, bare values on a card, and a STACKED form: a release is authored
|
|
78
|
+
// content (a version string and a paragraph of notes), not a list of settings.
|
|
79
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.STACKED },
|
|
80
|
+
display: () => (_jsxs(DisplayLayout, { children: [_jsx(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: _jsx(DisplayField, { name: "releaseDate" }) }), _jsx(Section, { name: "releaseNotes", appearance: SectionMode.CARD, chromeMode: DisplayChromeMode.HIDDEN, hideDescription: true, children: _jsx(DisplayField, { name: "releaseNotes" }) })] })),
|
|
78
81
|
summary: () => (
|
|
79
|
-
//
|
|
80
|
-
// field already renders. At AUTO the row read
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
// One line: the version and the day it shipped, bare. TEMPLATE_OWNED with no title, because the card's
|
|
83
|
+
// LABEL is the version string, which the first field already renders. At AUTO the row read
|
|
84
|
+
// "1.4.2 · Version: 1.4.2 · Released: …".
|
|
85
|
+
_jsxs(SummaryLayout, { flow: SummaryFlow.ROW, titlePlacement: SummaryTitlePlacement.TEMPLATE_OWNED, children: [_jsx(DisplayField, { name: "version", className: "w-auto" }), _jsx(DisplayField, { name: "releaseDate", className: "w-auto" })] })),
|
|
86
|
+
// One flat form: three fields need no headings, and "Release Notes" over the only field in its section
|
|
87
|
+
// said what the field's own label says.
|
|
88
|
+
edit: () => (_jsxs(FormLayout, { children: [_jsx(FormField, { name: "version", autoFocus: true }), _jsx(FormField, { name: "releaseDate" }), _jsx(FormField, { name: "releaseNotes" })] })),
|
|
89
|
+
},
|
|
90
|
+
fields: {
|
|
91
|
+
// Release notes are a paragraph, not a line.
|
|
92
|
+
releaseNotes: schemaShape.releaseNotes.stringUI({ edit: { editMode: StringEditMode.TEXTAREA } }),
|
|
83
93
|
},
|
|
84
94
|
views: [
|
|
85
95
|
// Versions are created by the app-version system (API-driven) — headless (API-only).
|
|
@@ -92,12 +102,14 @@ export function buildApplicationAdminPresets(main) {
|
|
|
92
102
|
],
|
|
93
103
|
})),
|
|
94
104
|
[R.APPLICATION_METADATA]: resourceUIBehavior(appMetadataFactory, ApplicationMetadataSchema, ({ schema, schemaShape, opsVariantResolver }) => ({
|
|
105
|
+
// The header showed the registry's missing-icon placeholder: nothing had ever named one.
|
|
106
|
+
icon: FileText,
|
|
95
107
|
layout: {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
//
|
|
100
|
-
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.
|
|
108
|
+
// No sections. The record is one field — the application's description — and an "Overview" card with a
|
|
109
|
+
// "Purpose, audience, and positioning" description over it was a heading and a prompt per field.
|
|
110
|
+
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows, bare on a card,
|
|
111
|
+
// and a STACKED form, because the description is a paragraph someone writes.
|
|
112
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.STACKED },
|
|
101
113
|
// Application metadata — the application’s own description. A settings pane is a list of decisions an operator came to TAKE, so its
|
|
102
114
|
// writable fields are offered in place rather than behind a whole-pane edit mode. The set is
|
|
103
115
|
// DERIVED (not primary key, not excludeFromUpdate, not hidden, not opted out), so a field
|
|
@@ -105,13 +117,16 @@ export function buildApplicationAdminPresets(main) {
|
|
|
105
117
|
defaultInlineEdit: ResourceLayoutInlineEditDefault.WRITABLE_FIELDS,
|
|
106
118
|
// And its empty rows say WHICH emptiness they are — "None yet" for a list with no members,
|
|
107
119
|
// "Not available" for a computed value, "No value" for a field awaiting input — instead of one
|
|
108
|
-
// em dash standing for all three.
|
|
109
|
-
//
|
|
110
|
-
// refuses to answer.
|
|
120
|
+
// em dash standing for all three. Here the empty description IS the information: the seed writes
|
|
121
|
+
// an empty one, and the pane is where somebody fills it in.
|
|
111
122
|
defaultEmptyValue: 'placeholder',
|
|
112
|
-
display: () => (_jsx(DisplayLayout, { children: _jsx(
|
|
123
|
+
display: () => (_jsx(DisplayLayout, { children: _jsx(DisplayField, { name: "description" }) })),
|
|
113
124
|
summary: () => (_jsx(SummaryLayout, { children: _jsx(DisplayField, { name: "description" }) })),
|
|
114
|
-
edit: () => (_jsx(FormLayout, { children: _jsx(
|
|
125
|
+
edit: () => (_jsx(FormLayout, { children: _jsx(FormField, { name: "description", autoFocus: true }) })),
|
|
126
|
+
},
|
|
127
|
+
fields: {
|
|
128
|
+
// A description is a paragraph, not a line.
|
|
129
|
+
description: schemaShape.description.stringUI({ edit: { editMode: StringEditMode.TEXTAREA } }),
|
|
115
130
|
},
|
|
116
131
|
views: [
|
|
117
132
|
// Metadata is system-managed, auto-initialized with the app — headless (API-only).
|
|
@@ -122,13 +137,21 @@ export function buildApplicationAdminPresets(main) {
|
|
|
122
137
|
],
|
|
123
138
|
})),
|
|
124
139
|
[R.APPLICATION_FEATURES]: resourceUIBehavior(appFeaturesFactory, ScopeFeaturesWithOverridesSchema, ({ schema, schemaShape, opsVariantResolver }) => ({
|
|
140
|
+
// The header showed the registry's missing-icon placeholder: nothing had ever named one. The same glyph as
|
|
141
|
+
// the organization's entitlements, because it is the same record at another scope.
|
|
142
|
+
icon: BadgeCheck,
|
|
125
143
|
layout: {
|
|
126
144
|
refs: { sections: ['overview', 'overrides'] },
|
|
127
|
-
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows
|
|
128
|
-
|
|
129
|
-
|
|
145
|
+
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows on read, bare
|
|
146
|
+
// values on a card. The form STACKS, because every field it edits is a list or a map of entries, which
|
|
147
|
+
// needs the full width a settings row gives to its label.
|
|
148
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.STACKED },
|
|
149
|
+
// An override list with nothing in it IS the answer on this pane — "no feature was granted or withdrawn
|
|
150
|
+
// by hand" — so it says "None yet" rather than an em dash that reads as missing data.
|
|
151
|
+
defaultEmptyValue: 'placeholder',
|
|
152
|
+
display: () => (_jsxs(DisplayLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: [_jsx(DisplayField, { name: "features" }), _jsx(DisplayField, { name: "limits" })] }), _jsx(Section, { name: "overrides", hideDescription: true, children: _jsxs(ObjectScope, { name: "manualOverrides", children: [_jsx(DisplayField, { name: "addedFeatures" }), _jsx(DisplayField, { name: "removedFeatures" }), _jsx(DisplayField, { name: "limitOverrides" })] }) })] })),
|
|
130
153
|
summary: () => (_jsxs(SummaryLayout, { children: [_jsx(DisplayField, { name: "features" }), _jsx(DisplayField, { name: "limits" })] })),
|
|
131
|
-
edit: () => (_jsxs(FormLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, children: [_jsx(FormField, { name: "features" }), _jsx(FormField, { name: "limits" })] }), _jsx(Section, { name: "overrides", children: _jsxs(ObjectScope, { name: "manualOverrides", children: [_jsx(FormField, { name: "addedFeatures" }), _jsx(FormField, { name: "removedFeatures" }), _jsx(FormField, { name: "limitOverrides" })] }) })] })),
|
|
154
|
+
edit: () => (_jsxs(FormLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: [_jsx(FormField, { name: "features" }), _jsx(FormField, { name: "limits" })] }), _jsx(Section, { name: "overrides", children: _jsxs(ObjectScope, { name: "manualOverrides", children: [_jsx(FormField, { name: "addedFeatures" }), _jsx(FormField, { name: "removedFeatures" }), _jsx(FormField, { name: "limitOverrides" })] }) })] })),
|
|
132
155
|
},
|
|
133
156
|
views: [
|
|
134
157
|
[Op.READ, notAddressable()],
|
|
@@ -143,17 +166,24 @@ export function buildApplicationAdminPresets(main) {
|
|
|
143
166
|
icon: Key,
|
|
144
167
|
layout: {
|
|
145
168
|
refs: {
|
|
146
|
-
sections: ['overview', '
|
|
169
|
+
sections: ['overview', 'lifecycle'],
|
|
147
170
|
},
|
|
148
|
-
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows on read and on the
|
|
172
|
+
// form — a credential is configured, not written — and bare values on a card.
|
|
173
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.SETTINGS_ROW },
|
|
174
|
+
// The identity line: the key's name (the page title) and its status beside it. Neither is repeated below.
|
|
175
|
+
header: () => (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-field", children: [_jsx(ResourceHeaderTitle, {}), _jsx(DisplayField, { name: "status", hideLabel: true, hideDescription: true, className: "w-auto" })] })),
|
|
176
|
+
display: () => (_jsxs(DisplayLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: [_jsx(DisplayField, { name: "keyPrefix" }), _jsx(DisplayField, { name: "description" }), _jsx(DisplayField, { name: "roles" })] }), _jsxs(Section, { name: "lifecycle", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "expiresAt" }), _jsx(DisplayField, { name: "lastUsedAt" }), _jsx(DisplayField, { name: "createdAt" }), _jsx(ApiKeyRotationWindowRows, {})] })] })),
|
|
177
|
+
summary: () => (_jsxs(SummaryLayout, { children: [_jsx(SummaryTitle, { name: "name" }), _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "keyPrefix" }), _jsx(DisplayField, { name: "expiresAt" })] })] })),
|
|
178
|
+
// One flat form. The name first, because it is what the key is called everywhere; the description as a
|
|
179
|
+
// paragraph. Headings over two or three fields of one short form separated nothing.
|
|
180
|
+
edit: () => (_jsxs(FormLayout, { children: [_jsx(FormField, { name: "name", autoFocus: true }), _jsx(FormField, { name: "description" }), _jsx(FormField, { name: "status" }), _jsx(FormField, { name: "expiresAt" }), _jsx(FormField, { name: "roles" })] })),
|
|
153
181
|
},
|
|
154
182
|
fields: {
|
|
183
|
+
// The badge's colour carries the state; the state's description is a form hint, not a line under every
|
|
184
|
+
// badge on a list.
|
|
155
185
|
status: schemaShape.status.enumUI({
|
|
156
|
-
display: { displayMode: EnumDisplayMode.BADGE
|
|
186
|
+
display: { displayMode: EnumDisplayMode.BADGE },
|
|
157
187
|
edit: { showDescription: true },
|
|
158
188
|
values: {
|
|
159
189
|
[ApiKeyStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },
|
|
@@ -161,6 +191,23 @@ export function buildApplicationAdminPresets(main) {
|
|
|
161
191
|
[ApiKeyStatus.EXPIRED]: { color: BadgeSemanticVariant.WARNING },
|
|
162
192
|
},
|
|
163
193
|
}),
|
|
194
|
+
description: schemaShape.description.stringUI({
|
|
195
|
+
display: { hideWhenEmpty: true },
|
|
196
|
+
edit: { editMode: StringEditMode.TEXTAREA },
|
|
197
|
+
}),
|
|
198
|
+
// A key with no expiry never expires, and one never used has no last use: an empty row says nothing.
|
|
199
|
+
// On a card the expiry keeps its label — a bare date beside a name and a status could be any of the key's
|
|
200
|
+
// dates.
|
|
201
|
+
expiresAt: schemaShape.expiresAt.dateUI({
|
|
202
|
+
display: { hideWhenEmpty: true },
|
|
203
|
+
summaryOverride: { chromeMode: DisplayChromeMode.INLINE },
|
|
204
|
+
}),
|
|
205
|
+
lastUsedAt: schemaShape.lastUsedAt.dateUI({ display: { hideWhenEmpty: true } }),
|
|
206
|
+
// The rotation window, rendered only while the previous secret still authenticates (`ApiKeyRotationWindowRows`).
|
|
207
|
+
// The prefix row says what an empty end date means — after a regenerate the old secret has none and keeps
|
|
208
|
+
// working — so it carries its description; the end-date row hides itself when there is no date.
|
|
209
|
+
previousKeyPrefix: schemaShape.previousKeyPrefix.stringUI({ display: { hideWhenEmpty: true, showDescription: true } }),
|
|
210
|
+
previousKeyInvalidationDate: schemaShape.previousKeyInvalidationDate.dateUI({ display: { hideWhenEmpty: true } }),
|
|
164
211
|
},
|
|
165
212
|
getFrontendResourceLabel: ({ currentObject }) => currentObject.name,
|
|
166
213
|
views: [
|
|
@@ -168,11 +215,11 @@ export function buildApplicationAdminPresets(main) {
|
|
|
168
215
|
[Op.LIST, notAddressable()],
|
|
169
216
|
[Op.SEARCH, notAddressable()],
|
|
170
217
|
[Op.CREATE, notAddressable()],
|
|
171
|
-
[AppApiKeys_Operations.ROTATE, notAddressable({ iconOverride: RotateCw })],
|
|
172
|
-
[AppApiKeys_Operations.REGENERATE, notAddressable({ iconOverride: RefreshCw })],
|
|
173
|
-
[AppApiKeys_Operations.DEACTIVATE, notAddressable({ iconOverride: PowerOff })],
|
|
174
|
-
[AppApiKeys_Operations.REACTIVATE, notAddressable({ iconOverride: Power })],
|
|
175
|
-
[AppApiKeys_Operations.EXTEND_EXPIRY, notAddressable({ iconOverride: CalendarPlus })],
|
|
218
|
+
[AppApiKeys_Operations.ROTATE, notAddressable({ iconOverride: RotateCw, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
219
|
+
[AppApiKeys_Operations.REGENERATE, notAddressable({ iconOverride: RefreshCw, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
220
|
+
[AppApiKeys_Operations.DEACTIVATE, notAddressable({ iconOverride: PowerOff, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
221
|
+
[AppApiKeys_Operations.REACTIVATE, notAddressable({ iconOverride: Power, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
222
|
+
[AppApiKeys_Operations.EXTEND_EXPIRY, notAddressable({ iconOverride: CalendarPlus, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
176
223
|
[AppApiKeys_Operations.USAGE_STATS, notAddressable({ iconOverride: ChartColumn })],
|
|
177
224
|
],
|
|
178
225
|
})),
|
|
@@ -201,18 +248,22 @@ export function buildApplicationAdminPresets(main) {
|
|
|
201
248
|
refs: {
|
|
202
249
|
sections: ['overview', 'access', 'redirects', 'lifecycle'],
|
|
203
250
|
},
|
|
204
|
-
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows
|
|
205
|
-
|
|
206
|
-
|
|
251
|
+
// Settings-page chrome (Settings Hub → Administration): label-left / value-right rows on read and on the
|
|
252
|
+
// form — a client is configured, not written — and bare values on a card.
|
|
253
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.SETTINGS_ROW },
|
|
254
|
+
// The identity line: the client's name (the page title) and its status beside it. Neither is repeated below.
|
|
255
|
+
header: () => (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-field", children: [_jsx(ResourceHeaderTitle, {}), _jsx(DisplayField, { name: "status", hideLabel: true, hideDescription: true, className: "w-auto" })] })),
|
|
256
|
+
display: () => (_jsxs(DisplayLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: [_jsx(DisplayField, { name: "secretPrefix" }), _jsx(DisplayField, { name: "description" })] }), _jsxs(Section, { name: "access", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "allowedGrants" }), _jsx(DisplayField, { name: "allowedScopes" }), _jsx(DisplayField, { name: "roles" }), _jsx(DisplayField, { name: "tokenEndpointAuthMethod" }), _jsx(DisplayField, { name: "requiresConsent" })] }), _jsxs(Section, { name: "redirects", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "redirectUris" }), _jsx(DisplayField, { name: "postLogoutRedirectUris" })] }), _jsxs(Section, { name: "lifecycle", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "expiresAt" }), _jsx(DisplayField, { name: "lastUsedAt" }), _jsx(DisplayField, { name: "createdAt" })] })] })),
|
|
207
257
|
summary: () => (_jsxs(SummaryLayout, { children: [_jsx(SummaryTitle, { name: "name" }), _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "secretPrefix" }), _jsx(DisplayField, { name: "expiresAt" })] })] })),
|
|
208
|
-
edit: () => (_jsxs(FormLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, children: [_jsx(FormField, { name: "name" }), _jsx(FormField, { name: "description" }), _jsx(FormField, { name: "expiresAt" })] }), _jsxs(Section, { name: "access", children: [_jsx(FormField, { name: "allowedGrants" }), _jsx(FormField, { name: "allowedScopes" }), _jsx(FormField, { name: "roles" }), _jsx(FormField, { name: "tokenEndpointAuthMethod" }), _jsx(FormField, { name: "requiresConsent" })] }), _jsxs(Section, { name: "redirects", children: [_jsx(FormField, { name: "redirectUris" }), _jsx(FormField, { name: "postLogoutRedirectUris" })] })] })),
|
|
258
|
+
edit: () => (_jsxs(FormLayout, { children: [_jsxs(Section, { name: "overview", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: [_jsx(FormField, { name: "name", autoFocus: true }), _jsx(FormField, { name: "description" }), _jsx(FormField, { name: "expiresAt" })] }), _jsxs(Section, { name: "access", hideDescription: true, children: [_jsx(FormField, { name: "allowedGrants" }), _jsx(FormField, { name: "allowedScopes" }), _jsx(FormField, { name: "roles" }), _jsx(FormField, { name: "tokenEndpointAuthMethod" }), _jsx(FormField, { name: "requiresConsent" })] }), _jsxs(Section, { name: "redirects", children: [_jsx(FormField, { name: "redirectUris" }), _jsx(FormField, { name: "postLogoutRedirectUris" })] })] })),
|
|
209
259
|
},
|
|
210
260
|
fields: {
|
|
211
261
|
// Same three states and the same colours as an API key, because they mean the same things.
|
|
212
262
|
// EXPIRED is a WARNING rather than a DESTRUCTIVE: it is the end of a validity window, not a
|
|
213
|
-
// failure, and it is the one state `reactivate` deliberately does NOT revive.
|
|
263
|
+
// failure, and it is the one state `reactivate` deliberately does NOT revive. The state's description
|
|
264
|
+
// is a form hint; under every badge on a list it read "Whether the client can obtain tokens…" per row.
|
|
214
265
|
status: schemaShape.status.enumUI({
|
|
215
|
-
display: { displayMode: EnumDisplayMode.BADGE
|
|
266
|
+
display: { displayMode: EnumDisplayMode.BADGE },
|
|
216
267
|
edit: { showDescription: true },
|
|
217
268
|
values: {
|
|
218
269
|
[OAuthClientStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },
|
|
@@ -220,6 +271,20 @@ export function buildApplicationAdminPresets(main) {
|
|
|
220
271
|
[OAuthClientStatus.EXPIRED]: { color: BadgeSemanticVariant.WARNING },
|
|
221
272
|
},
|
|
222
273
|
}),
|
|
274
|
+
description: schemaShape.description.stringUI({
|
|
275
|
+
display: { hideWhenEmpty: true },
|
|
276
|
+
edit: { editMode: StringEditMode.TEXTAREA },
|
|
277
|
+
}),
|
|
278
|
+
// A client-credentials client has no sign-out redirect, a client with no expiry never expires, and one
|
|
279
|
+
// never used has no last use: each empty row said nothing.
|
|
280
|
+
postLogoutRedirectUris: schemaShape.postLogoutRedirectUris.arrayUI({ display: { hideWhenEmpty: true } }),
|
|
281
|
+
// On a card the expiry keeps its label: a bare date beside a name and a status could be any of the
|
|
282
|
+
// client's dates.
|
|
283
|
+
expiresAt: schemaShape.expiresAt.dateUI({
|
|
284
|
+
display: { hideWhenEmpty: true },
|
|
285
|
+
summaryOverride: { chromeMode: DisplayChromeMode.INLINE },
|
|
286
|
+
}),
|
|
287
|
+
lastUsedAt: schemaShape.lastUsedAt.dateUI({ display: { hideWhenEmpty: true } }),
|
|
223
288
|
},
|
|
224
289
|
getFrontendResourceLabel: ({ currentObject }) => currentObject.name,
|
|
225
290
|
views: [
|
|
@@ -227,10 +292,10 @@ export function buildApplicationAdminPresets(main) {
|
|
|
227
292
|
[Op.LIST, notAddressable()],
|
|
228
293
|
[Op.SEARCH, notAddressable()],
|
|
229
294
|
[Op.CREATE, notAddressable()],
|
|
230
|
-
[AppOAuthClients_Operations.ROTATE, notAddressable({ iconOverride: RotateCw })],
|
|
231
|
-
[AppOAuthClients_Operations.REGENERATE, notAddressable({ iconOverride: RefreshCw })],
|
|
232
|
-
[AppOAuthClients_Operations.DEACTIVATE, notAddressable({ iconOverride: PowerOff })],
|
|
233
|
-
[AppOAuthClients_Operations.REACTIVATE, notAddressable({ iconOverride: Power })],
|
|
295
|
+
[AppOAuthClients_Operations.ROTATE, notAddressable({ iconOverride: RotateCw, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
296
|
+
[AppOAuthClients_Operations.REGENERATE, notAddressable({ iconOverride: RefreshCw, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
297
|
+
[AppOAuthClients_Operations.DEACTIVATE, notAddressable({ iconOverride: PowerOff, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
298
|
+
[AppOAuthClients_Operations.REACTIVATE, notAddressable({ iconOverride: Power, ...ROW_VERB_ON_RESOURCE_WITHOUT_UPDATE })],
|
|
234
299
|
// Dispatched by the expiry sweep rather than by a person — headless, so it must carry no
|
|
235
300
|
// view fields at all. An operator ends a client early with DEACTIVATE.
|
|
236
301
|
[AppOAuthClients_Operations.EXPIRE, apiOnly()],
|
|
@@ -257,30 +322,40 @@ export function buildApplicationAdminPresets(main) {
|
|
|
257
322
|
*/
|
|
258
323
|
[R.APPLICATION_ACCESS_GRANTS]: resourceUIBehavior(appAccessGrantsFactory, ApplicationAccessGrantSchema, ({ schema, schemaShape, opsVariantResolver }) => ({
|
|
259
324
|
icon: ShieldCheck,
|
|
260
|
-
//
|
|
261
|
-
//
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
|
|
325
|
+
// A request is named by the instant it was made, in the viewer's date-time format. It was named by the
|
|
326
|
+
// requesting operator's user id, which put a raw `6aa25215267f7e7758312323` at the top of the page and as the
|
|
327
|
+
// title of every card: this callback is synchronous over the record, and the record carries the operator's id
|
|
328
|
+
// alone, never their name. WHO asked is still the first thing the body and the card show, resolved to the
|
|
329
|
+
// person by the foreign-key renderer (see `operatorUserId` below). `createdAt` is optional on the row, so a
|
|
330
|
+
// row without it falls back to its id rather than to nothing.
|
|
331
|
+
//
|
|
332
|
+
// (History: this preset once declared no label strategy at all while the specification documented
|
|
333
|
+
// `frontend.label`, and that pair THROWS at module scope in `resourceSpecificationFromFrontendConfiguration`,
|
|
334
|
+
// taking the whole `@wildo-ai/saas-specifications` package down. Keep the two declared together.)
|
|
335
|
+
getFrontendResourceLabel: ({ currentObject, formatDateTime }) => currentObject.createdAt ? formatDateTime(currentObject.createdAt) : currentObject._id,
|
|
268
336
|
layout: {
|
|
269
337
|
refs: {
|
|
270
338
|
sections: ['request', 'decision', 'window'],
|
|
271
339
|
},
|
|
272
|
-
// Settings
|
|
273
|
-
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.
|
|
274
|
-
|
|
275
|
-
|
|
340
|
+
// Settings rows on the read page, bare values on a card. There is no form: every state change is a named verb.
|
|
341
|
+
defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.SETTINGS_ROW },
|
|
342
|
+
// The identity line: when it was asked (the title) and where it stands. Neither is repeated below.
|
|
343
|
+
header: () => (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-field", children: [_jsx(ResourceHeaderTitle, {}), _jsx(DisplayField, { name: "status", hideLabel: true, hideDescription: true, className: "w-auto" })] })),
|
|
344
|
+
// The three headings stay — they are what keeps the requester and the approver in separate blocks, which is
|
|
345
|
+
// the distinction this control exists for. Their descriptions do not: each explained the control to a
|
|
346
|
+
// reader who is looking at one of its records.
|
|
347
|
+
display: () => (_jsxs(DisplayLayout, { children: [_jsxs(Section, { name: "request", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "operatorUserId" }), _jsx(DisplayField, { name: "justification" })] }), _jsxs(Section, { name: "decision", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "approvedByUserId" }), _jsx(DisplayField, { name: "approvedAt" }), _jsx(DisplayField, { name: "decisionReason" })] }), _jsxs(Section, { name: "window", appearance: SectionMode.CARD, hideDescription: true, children: [_jsx(DisplayField, { name: "expiresAt" }), _jsx(DisplayField, { name: "grantedMachineCredential" })] })] })),
|
|
348
|
+
// The instant is the card's title (AUTO); below it, who asked, where it stands, and when the window ends.
|
|
349
|
+
summary: () => (_jsx(SummaryLayout, { children: _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "operatorUserId" }), _jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "expiresAt" })] }) })),
|
|
276
350
|
},
|
|
277
351
|
fields: {
|
|
278
352
|
// PENDING_APPROVAL is a WARNING rather than a neutral secondary: an unsigned request is the
|
|
279
353
|
// state a reviewer must act on, and the one state where the window does not yet exist.
|
|
280
354
|
// DENIED and REVOKED are both DESTRUCTIVE because both are a refusal; EXPIRED is not — it is
|
|
281
|
-
// the control working, a window closing on its own.
|
|
355
|
+
// the control working, a window closing on its own. The state's description ("Active status requires a
|
|
356
|
+
// valid, unexpired access window.") read under every badge on the queue, so it is not shown.
|
|
282
357
|
status: schemaShape.status.enumUI({
|
|
283
|
-
display: { displayMode: EnumDisplayMode.BADGE
|
|
358
|
+
display: { displayMode: EnumDisplayMode.BADGE },
|
|
284
359
|
values: {
|
|
285
360
|
[PlatformAccessGrantStatus.PENDING_APPROVAL]: { color: BadgeSemanticVariant.WARNING },
|
|
286
361
|
[PlatformAccessGrantStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },
|
|
@@ -289,6 +364,17 @@ export function buildApplicationAdminPresets(main) {
|
|
|
289
364
|
[PlatformAccessGrantStatus.EXPIRED]: { color: BadgeSemanticVariant.SECONDARY },
|
|
290
365
|
},
|
|
291
366
|
}),
|
|
367
|
+
// Both identities resolve to the PERSON, never an id: a reviewer is asking "who", and a hex id answers
|
|
368
|
+
// nobody.
|
|
369
|
+
operatorUserId: schemaShape.operatorUserId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
|
|
370
|
+
// Empty until somebody signs, and on a PENDING request that emptiness is the answer ("not signed yet"), so
|
|
371
|
+
// the approver row stays; the reason is optional even on a decision, and hides.
|
|
372
|
+
approvedByUserId: schemaShape.approvedByUserId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
|
|
373
|
+
decisionReason: schemaShape.decisionReason.stringUI({ display: { hideWhenEmpty: true } }),
|
|
374
|
+
// Present only when the grant was requested for a machine credential.
|
|
375
|
+
grantedMachineCredential: schemaShape.grantedMachineCredential.objectUI({ display: { hideWhenEmpty: true } }),
|
|
376
|
+
// On a card the expiry keeps its label: a bare date beside a name and a status could be the request's.
|
|
377
|
+
expiresAt: schemaShape.expiresAt.dateUI({ summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),
|
|
292
378
|
},
|
|
293
379
|
views: [
|
|
294
380
|
[Op.READ, notAddressable()],
|