@wildo-ai/presets-components 1.1.5 → 1.1.6

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 (189) hide show
  1. package/dist/esm/.native.tsbuildinfo +1 -0
  2. package/dist/esm/components/actions/action-bar.d.ts.map +1 -1
  3. package/dist/esm/components/actions/action-bar.js +5 -2
  4. package/dist/esm/components/actions/action-bar.js.map +1 -1
  5. package/dist/esm/components/ai-elements/chat/suggestion.d.ts.map +1 -1
  6. package/dist/esm/components/ai-elements/chat/suggestion.js +8 -1
  7. package/dist/esm/components/ai-elements/chat/suggestion.js.map +1 -1
  8. package/dist/esm/components/ai-elements/decision/approval.d.ts +108 -13
  9. package/dist/esm/components/ai-elements/decision/approval.d.ts.map +1 -1
  10. package/dist/esm/components/ai-elements/decision/approval.js +60 -10
  11. package/dist/esm/components/ai-elements/decision/approval.js.map +1 -1
  12. package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts +3 -1
  13. package/dist/esm/components/ai-elements/graph/graph-runtime.d.ts.map +1 -1
  14. package/dist/esm/components/ai-elements/graph/graph-runtime.js +3 -1
  15. package/dist/esm/components/ai-elements/graph/graph-runtime.js.map +1 -1
  16. package/dist/esm/components/app/app-layout-main-container.d.ts +9 -0
  17. package/dist/esm/components/app/app-layout-main-container.d.ts.map +1 -1
  18. package/dist/esm/components/app/app-layout-main-container.js +17 -23
  19. package/dist/esm/components/app/app-layout-main-container.js.map +1 -1
  20. package/dist/esm/components/app/app-layout-main-container.labels.d.ts.map +1 -1
  21. package/dist/esm/components/app/app-layout-main-container.labels.js +27 -0
  22. package/dist/esm/components/app/app-layout-main-container.labels.js.map +1 -1
  23. package/dist/esm/components/billing/billing-plan-change-preview.d.ts.map +1 -1
  24. package/dist/esm/components/billing/billing-plan-change-preview.js +5 -2
  25. package/dist/esm/components/billing/billing-plan-change-preview.js.map +1 -1
  26. package/dist/esm/components/billing/billing-plan-change-preview.labels.d.ts.map +1 -1
  27. package/dist/esm/components/billing/billing-plan-change-preview.labels.js +3 -0
  28. package/dist/esm/components/billing/billing-plan-change-preview.labels.js.map +1 -1
  29. package/dist/esm/components/billing/billing-pricing-table.d.ts +1 -1
  30. package/dist/esm/components/billing/billing-pricing-table.d.ts.map +1 -1
  31. package/dist/esm/components/billing/billing-pricing-table.js +8 -4
  32. package/dist/esm/components/billing/billing-pricing-table.js.map +1 -1
  33. package/dist/esm/components/billing/billing-pricing-table.labels.d.ts.map +1 -1
  34. package/dist/esm/components/billing/billing-pricing-table.labels.js +7 -1
  35. package/dist/esm/components/billing/billing-pricing-table.labels.js.map +1 -1
  36. package/dist/esm/components/billing/billing-usage-dashboard.d.ts.map +1 -1
  37. package/dist/esm/components/billing/billing-usage-dashboard.js +6 -3
  38. package/dist/esm/components/billing/billing-usage-dashboard.js.map +1 -1
  39. package/dist/esm/components/billing/billing-usage-dashboard.labels.d.ts.map +1 -1
  40. package/dist/esm/components/billing/billing-usage-dashboard.labels.js +2 -1
  41. package/dist/esm/components/billing/billing-usage-dashboard.labels.js.map +1 -1
  42. package/dist/esm/components/data-display/formatters/display-field-enum.d.ts.map +1 -1
  43. package/dist/esm/components/data-display/formatters/display-field-enum.js +18 -4
  44. package/dist/esm/components/data-display/formatters/display-field-enum.js.map +1 -1
  45. package/dist/esm/components/data-display/formatters/display-field-file.d.ts.map +1 -1
  46. package/dist/esm/components/data-display/formatters/display-field-file.js +13 -14
  47. package/dist/esm/components/data-display/formatters/display-field-file.js.map +1 -1
  48. package/dist/esm/components/data-display/formatters/display-field-file.labels.d.ts.map +1 -1
  49. package/dist/esm/components/data-display/formatters/display-field-file.labels.js +1 -0
  50. package/dist/esm/components/data-display/formatters/display-field-file.labels.js.map +1 -1
  51. package/dist/esm/components/data-display/formatters/display-field-number.d.ts.map +1 -1
  52. package/dist/esm/components/data-display/formatters/display-field-number.js +6 -1
  53. package/dist/esm/components/data-display/formatters/display-field-number.js.map +1 -1
  54. package/dist/esm/components/data-display/formatters/display-field-number.labels.d.ts.map +1 -1
  55. package/dist/esm/components/data-display/formatters/display-field-number.labels.js +5 -2
  56. package/dist/esm/components/data-display/formatters/display-field-number.labels.js.map +1 -1
  57. package/dist/esm/components/data-display/formatters/display-field-string.d.ts +1 -1
  58. package/dist/esm/components/data-display/formatters/display-field-string.d.ts.map +1 -1
  59. package/dist/esm/components/data-display/formatters/display-field-string.js +51 -12
  60. package/dist/esm/components/data-display/formatters/display-field-string.js.map +1 -1
  61. package/dist/esm/components/data-display/untrusted-html-content.d.ts +55 -0
  62. package/dist/esm/components/data-display/untrusted-html-content.d.ts.map +1 -0
  63. package/dist/esm/components/data-display/untrusted-html-content.js +67 -0
  64. package/dist/esm/components/data-display/untrusted-html-content.js.map +1 -0
  65. package/dist/esm/components/form/chromes/form-primitive.labels.d.ts.map +1 -1
  66. package/dist/esm/components/form/chromes/form-primitive.labels.js +9 -0
  67. package/dist/esm/components/form/chromes/form-primitive.labels.js.map +1 -1
  68. package/dist/esm/components/form/combobox.d.ts.map +1 -1
  69. package/dist/esm/components/form/combobox.js +10 -10
  70. package/dist/esm/components/form/combobox.js.map +1 -1
  71. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts +42 -0
  72. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.d.ts.map +1 -0
  73. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js +120 -0
  74. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.adapter.js.map +1 -0
  75. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts +16 -0
  76. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.d.ts.map +1 -0
  77. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js +8 -0
  78. package/dist/esm/components/form/controls/address/providers/google-places-address-lookup.js.map +1 -0
  79. package/dist/esm/components/navigation/app-level/activity-bar.d.ts.map +1 -1
  80. package/dist/esm/components/navigation/app-level/activity-bar.js +2 -2
  81. package/dist/esm/components/navigation/app-level/activity-bar.js.map +1 -1
  82. package/dist/esm/components/navigation/app-level/menu-user-org.d.ts.map +1 -1
  83. package/dist/esm/components/navigation/app-level/menu-user-org.js +10 -4
  84. package/dist/esm/components/navigation/app-level/menu-user-org.js.map +1 -1
  85. package/dist/esm/components/navigation/app-level/menu-user-org.labels.d.ts.map +1 -1
  86. package/dist/esm/components/navigation/app-level/menu-user-org.labels.js +7 -0
  87. package/dist/esm/components/navigation/app-level/menu-user-org.labels.js.map +1 -1
  88. package/dist/esm/components/navigation/app-level/menubar.d.ts.map +1 -1
  89. package/dist/esm/components/navigation/app-level/menubar.js +6 -6
  90. package/dist/esm/components/navigation/app-level/menubar.js.map +1 -1
  91. package/dist/esm/components/navigation/app-level/navigation-back.d.ts.map +1 -1
  92. package/dist/esm/components/navigation/app-level/navigation-back.js +27 -9
  93. package/dist/esm/components/navigation/app-level/navigation-back.js.map +1 -1
  94. package/dist/esm/components/navigation/app-level/sidebar.js +3 -3
  95. package/dist/esm/components/navigation/app-level/sidebar.js.map +1 -1
  96. package/dist/esm/components/navigation/app-level/status-bar.js +2 -2
  97. package/dist/esm/components/navigation/app-level/status-bar.js.map +1 -1
  98. package/dist/esm/components/navigation/app-level/toolbar.d.ts.map +1 -1
  99. package/dist/esm/components/navigation/app-level/toolbar.js +2 -2
  100. package/dist/esm/components/navigation/app-level/toolbar.js.map +1 -1
  101. package/dist/esm/components/navigation/app-level/utility-panel.js +2 -2
  102. package/dist/esm/components/navigation/app-level/utility-panel.js.map +1 -1
  103. package/dist/esm/components/navigation/breadcrumb.js +1 -1
  104. package/dist/esm/components/navigation/breadcrumb.js.map +1 -1
  105. package/dist/esm/components/sections/stepper.d.ts.map +1 -1
  106. package/dist/esm/components/sections/stepper.js +5 -3
  107. package/dist/esm/components/sections/stepper.js.map +1 -1
  108. package/dist/esm/config/preset-navigation.d.ts.map +1 -1
  109. package/dist/esm/config/preset-navigation.js +23 -2
  110. package/dist/esm/config/preset-navigation.js.map +1 -1
  111. package/dist/esm/config/resources/agent-work.resource-presets.d.ts +4 -0
  112. package/dist/esm/config/resources/agent-work.resource-presets.d.ts.map +1 -0
  113. package/dist/esm/config/resources/agent-work.resource-presets.js +115 -0
  114. package/dist/esm/config/resources/agent-work.resource-presets.js.map +1 -0
  115. package/dist/esm/config/resources/api-key-rotation-window.d.ts +22 -0
  116. package/dist/esm/config/resources/api-key-rotation-window.d.ts.map +1 -0
  117. package/dist/esm/config/resources/api-key-rotation-window.js +45 -0
  118. package/dist/esm/config/resources/api-key-rotation-window.js.map +1 -0
  119. package/dist/esm/config/resources/application.resource-presets.d.ts.map +1 -1
  120. package/dist/esm/config/resources/application.resource-presets.js +147 -61
  121. package/dist/esm/config/resources/application.resource-presets.js.map +1 -1
  122. package/dist/esm/config/resources/billing.resource-presets.d.ts +4 -3
  123. package/dist/esm/config/resources/billing.resource-presets.d.ts.map +1 -1
  124. package/dist/esm/config/resources/billing.resource-presets.js +240 -111
  125. package/dist/esm/config/resources/billing.resource-presets.js.map +1 -1
  126. package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts +4 -0
  127. package/dist/esm/config/resources/conversation-threads.resource-presets.d.ts.map +1 -0
  128. package/dist/esm/config/resources/conversation-threads.resource-presets.js +105 -0
  129. package/dist/esm/config/resources/conversation-threads.resource-presets.js.map +1 -0
  130. package/dist/esm/config/resources/guidance.resource-presets.d.ts.map +1 -1
  131. package/dist/esm/config/resources/guidance.resource-presets.js +18 -11
  132. package/dist/esm/config/resources/guidance.resource-presets.js.map +1 -1
  133. package/dist/esm/config/resources/identity.resource-presets.d.ts +0 -13
  134. package/dist/esm/config/resources/identity.resource-presets.d.ts.map +1 -1
  135. package/dist/esm/config/resources/identity.resource-presets.js +48 -16
  136. package/dist/esm/config/resources/identity.resource-presets.js.map +1 -1
  137. package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts +6 -0
  138. package/dist/esm/config/resources/inbound-deliveries.resource-presets.d.ts.map +1 -0
  139. package/dist/esm/config/resources/inbound-deliveries.resource-presets.js +112 -0
  140. package/dist/esm/config/resources/inbound-deliveries.resource-presets.js.map +1 -0
  141. package/dist/esm/config/resources/inbound-email.resource-presets.d.ts +4 -0
  142. package/dist/esm/config/resources/inbound-email.resource-presets.d.ts.map +1 -0
  143. package/dist/esm/config/resources/inbound-email.resource-presets.js +182 -0
  144. package/dist/esm/config/resources/inbound-email.resource-presets.js.map +1 -0
  145. package/dist/esm/config/resources/index.d.ts.map +1 -1
  146. package/dist/esm/config/resources/index.js +9 -2
  147. package/dist/esm/config/resources/index.js.map +1 -1
  148. package/dist/esm/config/resources/legal-holds.resource-presets.d.ts +4 -0
  149. package/dist/esm/config/resources/legal-holds.resource-presets.d.ts.map +1 -0
  150. package/dist/esm/config/resources/legal-holds.resource-presets.js +76 -0
  151. package/dist/esm/config/resources/legal-holds.resource-presets.js.map +1 -0
  152. package/dist/esm/config/resources/organizations.resource-presets.d.ts.map +1 -1
  153. package/dist/esm/config/resources/organizations.resource-presets.js +139 -36
  154. package/dist/esm/config/resources/organizations.resource-presets.js.map +1 -1
  155. package/dist/esm/config/resources/resource.config.utils.d.ts +20 -0
  156. package/dist/esm/config/resources/resource.config.utils.d.ts.map +1 -1
  157. package/dist/esm/config/resources/resource.config.utils.js +20 -0
  158. package/dist/esm/config/resources/resource.config.utils.js.map +1 -1
  159. package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts +5 -0
  160. package/dist/esm/config/resources/retention-enforcement.resource-presets.d.ts.map +1 -0
  161. package/dist/esm/config/resources/retention-enforcement.resource-presets.js +74 -0
  162. package/dist/esm/config/resources/retention-enforcement.resource-presets.js.map +1 -0
  163. package/dist/esm/config/resources/security.resource-presets.d.ts +3 -1
  164. package/dist/esm/config/resources/security.resource-presets.d.ts.map +1 -1
  165. package/dist/esm/config/resources/security.resource-presets.js +563 -133
  166. package/dist/esm/config/resources/security.resource-presets.js.map +1 -1
  167. package/dist/esm/config/resources/service-providers.resource-presets.d.ts +4 -0
  168. package/dist/esm/config/resources/service-providers.resource-presets.d.ts.map +1 -0
  169. package/dist/esm/config/resources/service-providers.resource-presets.js +321 -0
  170. package/dist/esm/config/resources/service-providers.resource-presets.js.map +1 -0
  171. package/dist/esm/config/resources/webhooks.resource-presets.d.ts +4 -3
  172. package/dist/esm/config/resources/webhooks.resource-presets.d.ts.map +1 -1
  173. package/dist/esm/config/resources/webhooks.resource-presets.js +76 -25
  174. package/dist/esm/config/resources/webhooks.resource-presets.js.map +1 -1
  175. package/dist/esm/index.d.ts +1 -0
  176. package/dist/esm/index.d.ts.map +1 -1
  177. package/dist/esm/index.js +1 -0
  178. package/dist/esm/index.js.map +1 -1
  179. package/dist/esm/registration/register-common-enums.d.ts.map +1 -1
  180. package/dist/esm/registration/register-common-enums.js +15 -0
  181. package/dist/esm/registration/register-common-enums.js.map +1 -1
  182. package/dist/esm/registration/register-provider-components.d.ts.map +1 -1
  183. package/dist/esm/registration/register-provider-components.js +6 -0
  184. package/dist/esm/registration/register-provider-components.js.map +1 -1
  185. package/dist/esm/themes/dense.theme.d.ts.map +1 -1
  186. package/dist/esm/themes/dense.theme.js +22 -2
  187. package/dist/esm/themes/dense.theme.js.map +1 -1
  188. package/dist/tsconfig.build.tsbuildinfo +1 -1
  189. package/package.json +8 -6
@@ -0,0 +1,4 @@
1
+ import type { ResourceUIBehavior } from '@wildo-ai/saas-frontend-lib';
2
+ export declare function buildServiceProvidersMainPresets(): Partial<ResourceUIBehavior>;
3
+ export declare const serviceProvidersMainPresets: Partial<ResourceUIBehavior>;
4
+ //# sourceMappingURL=service-providers.resource-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-providers.resource-presets.d.ts","sourceRoot":"","sources":["../../../../../src/config/resources/service-providers.resource-presets.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAmC,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAoQvG,wBAAgB,gCAAgC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CA+N9E;AAED,eAAO,MAAM,2BAA2B,6BAAqC,CAAC"}
@@ -0,0 +1,321 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { LabellingTypes } from '@wildo-ai/presets-components-models';
3
+ import { ActionVisibility, CollectionDisplayMode, DisplayField, DisplayLayout, ResourceHeaderTitle, SummaryFlow, SummaryLayout, SummaryMeta, SummaryTitlePlacement, resourceUIBehavior, } from '@wildo-ai/saas-frontend-lib';
4
+ import { BadgeSemanticVariant, DisplayChromeMode, EditChromeMode, EnumDisplayMode, ForeignKeyDisplayMode } from '@wildo-ai/zod-decorators';
5
+ import { Activity, Ban, Check, CirclePause, Eye, Handshake, KeyRound, Play, Power, PowerOff, Scaling, Send, ShieldAlert, ShieldCheck, ShieldPlus, UserCheck, UserMinus, UserPlus, Users, X } from 'lucide-react';
6
+ import { CoreResourceType as R, CoreResourceOperation as Op, ServiceEngagementAssignmentSchema, ServiceEngagementAssignmentStatus, ServiceEngagementAssignments_Operations, ServiceEngagementSchema, ServiceEngagements_Operations, ServiceProviderRelationshipSchema, ServiceProviderRelationshipStatus, ServiceProviderRelationships_Operations, ServiceProviderCapabilityGrantSchema, ServiceProviderCapabilityGrantStatus, ServiceProviderCapabilityGrants_Operations, ServiceProviderActivityFeedEntrySchema, ServiceProviderActivityFeedSettingsSchema, ServiceProviderActivityFeedSettings_Operations, ServiceProviderActivityFeedStatus, ServiceProviderActivityOutcome, serviceProviderActivityFeedResourceConfiguration_InitializationFactory as activityFeedFactory, serviceProviderActivityFeedSettingsResourceConfiguration_InitializationFactory as activityFeedSettingsFactory, serviceProviderCapabilityGrantsResourceConfiguration_InitializationFactory as capabilityGrantsFactory, serviceEngagementAssignmentsResourceConfiguration_InitializationFactory as assignmentsFactory, serviceEngagementsResourceConfiguration_InitializationFactory as engagementsFactory, serviceProviderRelationshipsResourceConfiguration_InitializationFactory as relationshipsFactory, } from '@wildo-ai/saas-models';
7
+ import { addressable, notAddressable } from './resource.config.utils.js';
8
+ /** One colour vocabulary for the relationship's life, shared by the client's row and the firm's mirror. */
9
+ const RELATIONSHIP_STATUS_COLOURS = {
10
+ [ServiceProviderRelationshipStatus.PROPOSED]: { color: BadgeSemanticVariant.INFO },
11
+ [ServiceProviderRelationshipStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },
12
+ [ServiceProviderRelationshipStatus.SUSPENDED]: { color: BadgeSemanticVariant.WARNING },
13
+ [ServiceProviderRelationshipStatus.DECLINED]: { color: BadgeSemanticVariant.SECONDARY },
14
+ [ServiceProviderRelationshipStatus.WITHDRAWN]: { color: BadgeSemanticVariant.SECONDARY },
15
+ [ServiceProviderRelationshipStatus.TERMINATED]: { color: BadgeSemanticVariant.DESTRUCTIVE },
16
+ [ServiceProviderRelationshipStatus.EXPIRED]: { color: BadgeSemanticVariant.SECONDARY },
17
+ };
18
+ const LIST_BY_STATUS = {
19
+ collectionDisplayConfig: {
20
+ displayMode: CollectionDisplayMode.TABLE,
21
+ userSwitchableDisplayMode: true,
22
+ quickFilterField: 'status',
23
+ },
24
+ };
25
+ /**
26
+ * Settings rows on the read page, bare values on a card. There is no form on any of the three: every state change is
27
+ * a named verb with its own dialog.
28
+ */
29
+ const CHROME = {
30
+ display: DisplayChromeMode.SETTINGS_ROW,
31
+ summary: DisplayChromeMode.HIDDEN,
32
+ edit: EditChromeMode.SETTINGS_ROW,
33
+ };
34
+ const hideWhenEmpty = { display: { hideWhenEmpty: true } };
35
+ /** The identity line: the other organization's name (the title) and the relationship's status beside it. */
36
+ function StatusHeader() {
37
+ return (_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" })] }));
38
+ }
39
+ /*
40
+ * The client's record of one firm: the firm is the title and the status is beside it, so neither is a row. Then
41
+ * what the firm may do here (role, units, purpose, machine clients), until when, and who decided each step.
42
+ */
43
+ function RelationshipDisplayTemplate() {
44
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "role" }), _jsx(DisplayField, { name: "organizationUnitIds" }), _jsx(DisplayField, { name: "purpose" }), _jsx(DisplayField, { name: "endsAt" }), _jsx(DisplayField, { name: "expertAdmissionPolicy" }), _jsx(DisplayField, { name: "providerMfaTrust" }), _jsx(DisplayField, { name: "activityFeedDisclosure" }), _jsx(DisplayField, { name: "admittedMachineClientIds" }), _jsx(DisplayField, { name: "createdAt" }), _jsx(DisplayField, { name: "proposedByUserId" }), _jsx(DisplayField, { name: "acceptedAt" }), _jsx(DisplayField, { name: "acceptedByUserId" }), _jsx(DisplayField, { name: "endedAt" }), _jsx(DisplayField, { name: "endedByUserId" }), _jsx(DisplayField, { name: "decisionReason" })] }));
45
+ }
46
+ /* The firm's mirror of the same arrangement: the client is the title, the status beside it. */
47
+ function EngagementDisplayTemplate() {
48
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "role" }), _jsx(DisplayField, { name: "scopedToOrganizationUnits" }), _jsx(DisplayField, { name: "purpose" }), _jsx(DisplayField, { name: "endsAt" }), _jsx(DisplayField, { name: "expertAdmissionPolicy" }), _jsx(DisplayField, { name: "delegatedCapabilities" }), _jsx(DisplayField, { name: "createdAt" }), _jsx(DisplayField, { name: "endedAt" }), _jsx(DisplayField, { name: "decisionReason" })] }));
49
+ }
50
+ /* A card: the other organization (the title), the status badge, the role, and the end date labelled — a bare date
51
+ beside a status could be any of the relationship's dates. */
52
+ function RelationshipSummaryTemplate() {
53
+ return (_jsx(SummaryLayout, { children: _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "role" }), _jsx(DisplayField, { name: "endsAt" })] }) }));
54
+ }
55
+ /*
56
+ * One of the firm's people serving one client. The record has no name of its own, so the body leads with the two
57
+ * things it joins — the person and the engagement, each resolved to its label — then when it began and ended.
58
+ */
59
+ function AssignmentDisplayTemplate() {
60
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "userId" }), _jsx(DisplayField, { name: "serviceEngagementId" }), _jsx(DisplayField, { name: "assignedAt" }), _jsx(DisplayField, { name: "assignedByUserId" }), _jsx(DisplayField, { name: "approvalResolvedAt" }), _jsx(DisplayField, { name: "approvalDenialReason" }), _jsx(DisplayField, { name: "endedAt" }), _jsx(DisplayField, { name: "endedByUserId" })] }));
61
+ }
62
+ /* A lent capability's identity line: the capability (its translated name, not an identifier) and its status. */
63
+ function CapabilityGrantHeader() {
64
+ return (_jsxs("div", { className: "flex min-w-0 flex-wrap items-center gap-field", children: [_jsx(DisplayField, { name: "capability", hideLabel: true, hideDescription: true, className: "w-auto" }), _jsx(DisplayField, { name: "status", hideLabel: true, hideDescription: true, className: "w-auto" })] }));
65
+ }
66
+ /*
67
+ * One lent capability (#1631): WHAT was lent is the title, then through which relationship, until when, and who
68
+ * granted and revoked it — each decision row empty until it happens.
69
+ */
70
+ function CapabilityGrantDisplayTemplate() {
71
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "relationshipId" }), _jsx(DisplayField, { name: "endsAt" }), _jsx(DisplayField, { name: "grantedAt" }), _jsx(DisplayField, { name: "grantedByUserId" }), _jsx(DisplayField, { name: "revokedAt" }), _jsx(DisplayField, { name: "revokedByUserId" }), _jsx(DisplayField, { name: "endedAt" })] }));
72
+ }
73
+ /* A card: the capability's status and when it ends. */
74
+ function CapabilityGrantSummaryTemplate() {
75
+ return (_jsx(SummaryLayout, { children: _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "endsAt" })] }) }));
76
+ }
77
+ /*
78
+ * The firm's feed decision (#1632): on or off, then who decided, when, and that the consultation notice was
79
+ * acknowledged. The identity line is the status itself — there is one row per organization.
80
+ */
81
+ function ActivityFeedSettingsDisplayTemplate() {
82
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "decidedAt" }), _jsx(DisplayField, { name: "decidedByUserId" }), _jsx(DisplayField, { name: "acknowledgedWorkerConsultationNotice" })] }));
83
+ }
84
+ /*
85
+ * One feed entry (#1632): which expert, in which client, which kind of operation on which kind of resource, when,
86
+ * and — if the client allows it — whether it took effect. Nothing else exists to show: the entry holds no content.
87
+ */
88
+ function ActivityFeedEntryDisplayTemplate() {
89
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "occurredAt" }), _jsx(DisplayField, { name: "expertUserId" }), _jsx(DisplayField, { name: "clientOrganizationId" }), _jsx(DisplayField, { name: "operationKind" }), _jsx(DisplayField, { name: "resourceType" }), _jsx(DisplayField, { name: "outcome" })] }));
90
+ }
91
+ /* One line: who did what kind of thing, and how it ended. */
92
+ function ActivityFeedEntrySummaryTemplate() {
93
+ return (_jsxs(SummaryLayout, { flow: SummaryFlow.ROW, titlePlacement: SummaryTitlePlacement.TEMPLATE_OWNED, children: [_jsx(DisplayField, { name: "expertUserId", className: "w-auto" }), _jsx(DisplayField, { name: "operationKind", className: "w-auto" }), _jsx(DisplayField, { name: "resourceType", className: "w-auto" }), _jsx(DisplayField, { name: "outcome", className: "w-auto" })] }));
94
+ }
95
+ /* One line: who, for which client, and whether it still holds. */
96
+ function AssignmentSummaryTemplate() {
97
+ return (_jsxs(SummaryLayout, { flow: SummaryFlow.ROW, titlePlacement: SummaryTitlePlacement.TEMPLATE_OWNED, children: [_jsx(DisplayField, { name: "userId", className: "w-auto" }), _jsx(DisplayField, { name: "serviceEngagementId", className: "w-auto" }), _jsx(DisplayField, { name: "status", className: "w-auto" })] }));
98
+ }
99
+ /** A verb shown on a row only where its `enabledCondition` admits it — never greyed out on the others. */
100
+ const rowAction = (iconOverride) => notAddressable({ iconOverride, actionVisibility: ActionVisibility.WHEN_AVAILABLE });
101
+ export function buildServiceProvidersMainPresets() {
102
+ return {
103
+ // ── CLIENT side ──────────────────────────────────────────────────────────────────────────
104
+ [R.SERVICE_PROVIDER_RELATIONSHIPS]: resourceUIBehavior(relationshipsFactory, ServiceProviderRelationshipSchema, ({ schemaShape }) => ({
105
+ icon: Handshake,
106
+ // The firm by the name it had when the relationship was proposed: the client cannot read its row.
107
+ getFrontendResourceLabel: ({ currentObject }) => currentObject.providerOrganizationName || currentObject.providerOrganizationId,
108
+ layout: {
109
+ defaultChromeMode: CHROME,
110
+ header: StatusHeader,
111
+ display: RelationshipDisplayTemplate,
112
+ summary: RelationshipSummaryTemplate,
113
+ },
114
+ fields: {
115
+ status: schemaShape.status.enumUI({
116
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },
117
+ edit: { showDescription: true },
118
+ values: RELATIONSHIP_STATUS_COLOURS,
119
+ }),
120
+ // Open-ended, unconfined and machine-free are the usual case, and each decision row is empty until it is made.
121
+ endsAt: schemaShape.endsAt.dateUI({ display: { hideWhenEmpty: true }, summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),
122
+ organizationUnitIds: schemaShape.organizationUnitIds.arrayUI(hideWhenEmpty),
123
+ admittedMachineClientIds: schemaShape.admittedMachineClientIds.arrayUI(hideWhenEmpty),
124
+ proposedByUserId: schemaShape.proposedByUserId.stringUI(hideWhenEmpty),
125
+ acceptedByUserId: schemaShape.acceptedByUserId.stringUI(hideWhenEmpty),
126
+ acceptedAt: schemaShape.acceptedAt.dateUI(hideWhenEmpty),
127
+ endedByUserId: schemaShape.endedByUserId.stringUI(hideWhenEmpty),
128
+ endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),
129
+ decisionReason: schemaShape.decisionReason.stringUI(hideWhenEmpty),
130
+ // #1633 / #1632: the client's two per-relationship controls, as their translated value.
131
+ providerMfaTrust: schemaShape.providerMfaTrust.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),
132
+ activityFeedDisclosure: schemaShape.activityFeedDisclosure.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),
133
+ },
134
+ views: [
135
+ [Op.LIST, addressable(LIST_BY_STATUS)],
136
+ // Row click → the relationship in the companion drawer: scope, term, purpose, who decided what.
137
+ [Op.READ, notAddressable()],
138
+ [Op.COUNT, notAddressable()],
139
+ // The client's owner invites a firm from the collection toolbar.
140
+ [ServiceProviderRelationships_Operations.PROPOSE, notAddressable({ iconOverride: Send })],
141
+ [ServiceProviderRelationships_Operations.ACCEPT, rowAction(Check)],
142
+ [ServiceProviderRelationships_Operations.DECLINE, rowAction(X)],
143
+ [ServiceProviderRelationships_Operations.SUSPEND, rowAction(CirclePause)],
144
+ [ServiceProviderRelationships_Operations.RESUME, rowAction(Play)],
145
+ [ServiceProviderRelationships_Operations.AMEND_SCOPE, rowAction(Scaling)],
146
+ // #1612: whether each expert the firm assigns waits for an administrator's approval here.
147
+ [ServiceProviderRelationships_Operations.SET_EXPERT_ADMISSION_POLICY, rowAction(UserCheck)],
148
+ // #1633: whether the firm's enterprise IdP's second factor satisfies this organization's MFA requirement.
149
+ [ServiceProviderRelationships_Operations.SET_PROVIDER_MFA_TRUST, rowAction(ShieldCheck)],
150
+ // #1632: how much the firm's expert-activity feed may record about work here.
151
+ [ServiceProviderRelationships_Operations.SET_ACTIVITY_FEED_DISCLOSURE, rowAction(Eye)],
152
+ [ServiceProviderRelationships_Operations.TERMINATE, rowAction(Ban)],
153
+ [ServiceProviderRelationships_Operations.ADMIT_MACHINE_CLIENT, rowAction(UserPlus)],
154
+ [ServiceProviderRelationships_Operations.REMOVE_MACHINE_CLIENT, rowAction(UserMinus)],
155
+ ],
156
+ })),
157
+ // ── CLIENT side: delegated administrative capabilities (#1631) ──────────────────────────────
158
+ [R.SERVICE_PROVIDER_CAPABILITY_GRANTS]: resourceUIBehavior(capabilityGrantsFactory, ServiceProviderCapabilityGrantSchema, ({ schemaShape }) => ({
159
+ icon: KeyRound,
160
+ layout: {
161
+ defaultChromeMode: CHROME,
162
+ header: CapabilityGrantHeader,
163
+ display: CapabilityGrantDisplayTemplate,
164
+ summary: CapabilityGrantSummaryTemplate,
165
+ },
166
+ fields: {
167
+ capability: schemaShape.capability.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),
168
+ relationshipId: schemaShape.relationshipId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
169
+ status: schemaShape.status.enumUI({
170
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },
171
+ edit: { showDescription: true },
172
+ values: {
173
+ [ServiceProviderCapabilityGrantStatus.ACTIVE]: { color: BadgeSemanticVariant.WARNING },
174
+ [ServiceProviderCapabilityGrantStatus.REVOKED]: { color: BadgeSemanticVariant.SECONDARY },
175
+ [ServiceProviderCapabilityGrantStatus.EXPIRED]: { color: BadgeSemanticVariant.SECONDARY },
176
+ },
177
+ }),
178
+ endsAt: schemaShape.endsAt.dateUI({ summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),
179
+ grantedByUserId: schemaShape.grantedByUserId.stringUI(hideWhenEmpty),
180
+ revokedByUserId: schemaShape.revokedByUserId.stringUI(hideWhenEmpty),
181
+ revokedAt: schemaShape.revokedAt.dateUI(hideWhenEmpty),
182
+ endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),
183
+ },
184
+ views: [
185
+ [Op.LIST, addressable(LIST_BY_STATUS)],
186
+ [Op.READ, notAddressable()],
187
+ [Op.COUNT, notAddressable()],
188
+ // An administrator lends an ordinary capability; only an owner, with step-up, a security-critical one.
189
+ [ServiceProviderCapabilityGrants_Operations.GRANT, notAddressable({ iconOverride: ShieldPlus })],
190
+ [ServiceProviderCapabilityGrants_Operations.GRANT_SECURITY_CRITICAL, notAddressable({ iconOverride: ShieldAlert })],
191
+ [ServiceProviderCapabilityGrants_Operations.REVOKE, rowAction(Ban)],
192
+ ],
193
+ })),
194
+ // ── FIRM side ────────────────────────────────────────────────────────────────────────────
195
+ [R.SERVICE_ENGAGEMENTS]: resourceUIBehavior(engagementsFactory, ServiceEngagementSchema, ({ schemaShape }) => ({
196
+ icon: Handshake,
197
+ getFrontendResourceLabel: ({ currentObject }) => currentObject.clientOrganizationName || currentObject.clientOrganizationId,
198
+ layout: {
199
+ defaultChromeMode: CHROME,
200
+ header: StatusHeader,
201
+ display: EngagementDisplayTemplate,
202
+ summary: RelationshipSummaryTemplate,
203
+ },
204
+ fields: {
205
+ status: schemaShape.status.enumUI({
206
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },
207
+ edit: { showDescription: true },
208
+ values: RELATIONSHIP_STATUS_COLOURS,
209
+ }),
210
+ endsAt: schemaShape.endsAt.dateUI({ display: { hideWhenEmpty: true }, summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),
211
+ endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),
212
+ decisionReason: schemaShape.decisionReason.stringUI(hideWhenEmpty),
213
+ },
214
+ views: [
215
+ [Op.LIST, addressable(LIST_BY_STATUS)],
216
+ [Op.READ, notAddressable()],
217
+ [Op.COUNT, notAddressable()],
218
+ [ServiceEngagements_Operations.PROPOSE, notAddressable({ iconOverride: Send })],
219
+ [ServiceEngagements_Operations.ACCEPT, rowAction(Check)],
220
+ [ServiceEngagements_Operations.WITHDRAW, rowAction(X)],
221
+ ],
222
+ })),
223
+ // ── FIRM side: the expert-activity feed (#1632) ─────────────────────────────────────────────
224
+ // The firm's decision. Both verbs act on the organization's one row; either may be repeated, and each records a new
225
+ // decision.
226
+ [R.SERVICE_PROVIDER_ACTIVITY_FEED_SETTINGS]: resourceUIBehavior(activityFeedSettingsFactory, ServiceProviderActivityFeedSettingsSchema, ({ schemaShape }) => ({
227
+ icon: Activity,
228
+ // One row per organization and no name of its own: it is named by its resource's words.
229
+ getFrontendResourceLabel: ({ t, resourceType }) => t(`${LabellingTypes.RESOURCES}.${resourceType}.operations.read.title`),
230
+ layout: {
231
+ defaultChromeMode: CHROME,
232
+ display: ActivityFeedSettingsDisplayTemplate,
233
+ },
234
+ fields: {
235
+ status: schemaShape.status.enumUI({
236
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: true },
237
+ values: {
238
+ [ServiceProviderActivityFeedStatus.DISABLED]: { color: BadgeSemanticVariant.SECONDARY },
239
+ [ServiceProviderActivityFeedStatus.ENABLED]: { color: BadgeSemanticVariant.WARNING },
240
+ },
241
+ }),
242
+ decidedAt: schemaShape.decidedAt.dateUI(hideWhenEmpty),
243
+ decidedByUserId: schemaShape.decidedByUserId.stringUI(hideWhenEmpty),
244
+ },
245
+ // A singleton of the organization: the page IS its READ (materialized DISABLED on first access), and the two
246
+ // verbs act on that one row.
247
+ views: [
248
+ [Op.READ, addressable()],
249
+ [ServiceProviderActivityFeedSettings_Operations.ENABLE, notAddressable({ iconOverride: Power, actionVisibility: ActionVisibility.WHEN_AVAILABLE })],
250
+ [ServiceProviderActivityFeedSettings_Operations.DISABLE, notAddressable({ iconOverride: PowerOff, actionVisibility: ActionVisibility.WHEN_AVAILABLE })],
251
+ ],
252
+ })),
253
+ // The entries themselves: metadata only, newest first, read by the firm's administrators.
254
+ [R.SERVICE_PROVIDER_ACTIVITY_FEED]: resourceUIBehavior(activityFeedFactory, ServiceProviderActivityFeedEntrySchema, ({ schemaShape }) => ({
255
+ icon: Activity,
256
+ // An entry has no name of its own and must not carry client content: it is named by when it happened.
257
+ getFrontendResourceLabel: ({ currentObject, formatDateTime }) => formatDateTime(currentObject.occurredAt),
258
+ layout: {
259
+ defaultChromeMode: CHROME,
260
+ display: ActivityFeedEntryDisplayTemplate,
261
+ summary: ActivityFeedEntrySummaryTemplate,
262
+ },
263
+ fields: {
264
+ expertUserId: schemaShape.expertUserId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
265
+ operationKind: schemaShape.operationKind.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),
266
+ outcome: schemaShape.outcome.enumUI({
267
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: false, hideWhenEmpty: true },
268
+ values: {
269
+ [ServiceProviderActivityOutcome.SUCCEEDED]: { color: BadgeSemanticVariant.SUCCESS },
270
+ [ServiceProviderActivityOutcome.REFUSED]: { color: BadgeSemanticVariant.DESTRUCTIVE },
271
+ },
272
+ }),
273
+ },
274
+ views: [
275
+ [Op.LIST, addressable({ collectionDisplayConfig: { displayMode: CollectionDisplayMode.TABLE, userSwitchableDisplayMode: true } })],
276
+ [Op.READ, notAddressable()],
277
+ [Op.COUNT, notAddressable()],
278
+ ],
279
+ })),
280
+ [R.SERVICE_ENGAGEMENT_ASSIGNMENTS]: resourceUIBehavior(assignmentsFactory, ServiceEngagementAssignmentSchema, ({ schemaShape }) => ({
281
+ icon: Users,
282
+ layout: {
283
+ defaultChromeMode: CHROME,
284
+ display: AssignmentDisplayTemplate,
285
+ summary: AssignmentSummaryTemplate,
286
+ },
287
+ fields: {
288
+ // The person and the engagement resolve to their labels: an assignment read as two ids names nobody.
289
+ userId: schemaShape.userId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
290
+ serviceEngagementId: schemaShape.serviceEngagementId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),
291
+ assignedByUserId: schemaShape.assignedByUserId.stringUI(hideWhenEmpty),
292
+ endedByUserId: schemaShape.endedByUserId.stringUI(hideWhenEmpty),
293
+ endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),
294
+ // #1612: when the client answered, and why it admitted nobody — each empty until it happens.
295
+ approvalResolvedAt: schemaShape.approvalResolvedAt.dateUI(hideWhenEmpty),
296
+ approvalDenialReason: schemaShape.approvalDenialReason.enumUI({ display: { displayMode: EnumDisplayMode.TEXT, hideWhenEmpty: true } }),
297
+ status: schemaShape.status.enumUI({
298
+ display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },
299
+ edit: { showDescription: true },
300
+ values: {
301
+ [ServiceEngagementAssignmentStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },
302
+ [ServiceEngagementAssignmentStatus.ENDED]: { color: BadgeSemanticVariant.SECONDARY },
303
+ // #1612: waiting on the client, refused by it, or never answered.
304
+ [ServiceEngagementAssignmentStatus.PENDING_CLIENT_APPROVAL]: { color: BadgeSemanticVariant.WARNING },
305
+ [ServiceEngagementAssignmentStatus.DENIED]: { color: BadgeSemanticVariant.DESTRUCTIVE },
306
+ [ServiceEngagementAssignmentStatus.LAPSED]: { color: BadgeSemanticVariant.SECONDARY },
307
+ },
308
+ }),
309
+ },
310
+ views: [
311
+ [Op.LIST, addressable(LIST_BY_STATUS)],
312
+ [Op.READ, notAddressable()],
313
+ [Op.COUNT, notAddressable()],
314
+ [ServiceEngagementAssignments_Operations.ASSIGN, notAddressable({ iconOverride: UserPlus })],
315
+ [ServiceEngagementAssignments_Operations.UNASSIGN, rowAction(UserMinus)],
316
+ ],
317
+ })),
318
+ };
319
+ }
320
+ export const serviceProvidersMainPresets = buildServiceProvidersMainPresets();
321
+ //# sourceMappingURL=service-providers.resource-presets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-providers.resource-presets.js","sourceRoot":"","sources":["../../../../../src/config/resources/service-providers.resource-presets.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Service-provider relationships (#1597) — the two sides of one arrangement, each in its own tenant.\n *\n * - The CLIENT's surface is `serviceProviderRelationships`: every firm that works here, with its scope and\n * term, and the verbs that grant, confine, pause and end it. It IS the client's register of outside\n * parties working in its data (`WILDO.PRIVACY.THIRD_PARTY_PROCESSING`): which firm, what purpose, which\n * scope, since when.\n * - The FIRM's surface is `serviceEngagements` (its mirror of each relationship) and\n * `serviceEngagementAssignments` (which of its people serve which client).\n *\n * No sections, like the delivery logs: a status quick-filter tab strip on LIST, the row in the companion\n * drawer as one flat list of facts under a header that carries the status, and each verb as a per-row action\n * that appears only where its `enabledCondition` admits it. Every decision row (who accepted, who ended it, why)\n * is empty until that decision happens, and hides until then.\n * Surfaced in the Settings Hub by the `service-providers` and `service-clients` destinations, which an\n * application PLACES only when one of its organization types declares `servesAsProvider`.\n */\nimport React from 'react';\nimport type { ResourceOperationFrontendConfig, ResourceUIBehavior } from '@wildo-ai/saas-frontend-lib';\nimport { LabellingTypes } from '@wildo-ai/presets-components-models';\nimport {\n ActionVisibility,\n CollectionDisplayMode,\n DisplayField,\n DisplayLayout,\n ResourceHeaderTitle,\n SummaryFlow,\n SummaryLayout,\n SummaryMeta,\n SummaryTitlePlacement,\n resourceUIBehavior,\n} from '@wildo-ai/saas-frontend-lib';\nimport { BadgeSemanticVariant, DisplayChromeMode, EditChromeMode, EnumDisplayMode, ForeignKeyDisplayMode } from '@wildo-ai/zod-decorators';\nimport { Activity, Ban, Check, CirclePause, Eye, Handshake, KeyRound, Play, Power, PowerOff, Scaling, Send, ShieldAlert, ShieldCheck, ShieldPlus, UserCheck, UserMinus, UserPlus, Users, X } from 'lucide-react';\nimport {\n CoreResourceType as R,\n CoreResourceOperation as Op,\n ServiceEngagementAssignmentSchema,\n ServiceEngagementAssignmentStatus,\n ServiceEngagementAssignments_Operations,\n ServiceEngagementSchema,\n ServiceEngagements_Operations,\n ServiceProviderRelationshipSchema,\n ServiceProviderRelationshipStatus,\n ServiceProviderRelationships_Operations,\n ServiceProviderCapabilityGrantSchema,\n ServiceProviderCapabilityGrantStatus,\n ServiceProviderCapabilityGrants_Operations,\n ServiceProviderActivityFeedEntrySchema,\n ServiceProviderActivityFeedSettingsSchema,\n ServiceProviderActivityFeedSettings_Operations,\n ServiceProviderActivityFeedStatus,\n ServiceProviderActivityOutcome,\n serviceProviderActivityFeedResourceConfiguration_InitializationFactory as activityFeedFactory,\n serviceProviderActivityFeedSettingsResourceConfiguration_InitializationFactory as activityFeedSettingsFactory,\n serviceProviderCapabilityGrantsResourceConfiguration_InitializationFactory as capabilityGrantsFactory,\n serviceEngagementAssignmentsResourceConfiguration_InitializationFactory as assignmentsFactory,\n serviceEngagementsResourceConfiguration_InitializationFactory as engagementsFactory,\n serviceProviderRelationshipsResourceConfiguration_InitializationFactory as relationshipsFactory,\n} from '@wildo-ai/saas-models';\nimport { addressable, notAddressable } from './resource.config.utils';\n\n/** One colour vocabulary for the relationship's life, shared by the client's row and the firm's mirror. */\nconst RELATIONSHIP_STATUS_COLOURS = {\n [ServiceProviderRelationshipStatus.PROPOSED]: { color: BadgeSemanticVariant.INFO },\n [ServiceProviderRelationshipStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },\n [ServiceProviderRelationshipStatus.SUSPENDED]: { color: BadgeSemanticVariant.WARNING },\n [ServiceProviderRelationshipStatus.DECLINED]: { color: BadgeSemanticVariant.SECONDARY },\n [ServiceProviderRelationshipStatus.WITHDRAWN]: { color: BadgeSemanticVariant.SECONDARY },\n [ServiceProviderRelationshipStatus.TERMINATED]: { color: BadgeSemanticVariant.DESTRUCTIVE },\n [ServiceProviderRelationshipStatus.EXPIRED]: { color: BadgeSemanticVariant.SECONDARY },\n} as const;\n\nconst LIST_BY_STATUS = {\n collectionDisplayConfig: {\n displayMode: CollectionDisplayMode.TABLE,\n userSwitchableDisplayMode: true,\n quickFilterField: 'status',\n },\n} as const;\n\n/**\n * Settings rows on the read page, bare values on a card. There is no form on any of the three: every state change is\n * a named verb with its own dialog.\n */\nconst CHROME = {\n display: DisplayChromeMode.SETTINGS_ROW,\n summary: DisplayChromeMode.HIDDEN,\n edit: EditChromeMode.SETTINGS_ROW,\n} as const;\n\nconst hideWhenEmpty = { display: { hideWhenEmpty: true } } as const;\n\n/** The identity line: the other organization's name (the title) and the relationship's status beside it. */\nfunction StatusHeader(): React.JSX.Element {\n return (\n <div className=\"flex min-w-0 flex-wrap items-center gap-field\">\n <ResourceHeaderTitle />\n <DisplayField name=\"status\" hideLabel hideDescription className=\"w-auto\" />\n </div>\n );\n}\n\n/*\n * The client's record of one firm: the firm is the title and the status is beside it, so neither is a row. Then\n * what the firm may do here (role, units, purpose, machine clients), until when, and who decided each step.\n */\nfunction RelationshipDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"role\" />\n <DisplayField name=\"organizationUnitIds\" />\n <DisplayField name=\"purpose\" />\n <DisplayField name=\"endsAt\" />\n <DisplayField name=\"expertAdmissionPolicy\" />\n <DisplayField name=\"providerMfaTrust\" />\n <DisplayField name=\"activityFeedDisclosure\" />\n <DisplayField name=\"admittedMachineClientIds\" />\n <DisplayField name=\"createdAt\" />\n <DisplayField name=\"proposedByUserId\" />\n <DisplayField name=\"acceptedAt\" />\n <DisplayField name=\"acceptedByUserId\" />\n <DisplayField name=\"endedAt\" />\n <DisplayField name=\"endedByUserId\" />\n <DisplayField name=\"decisionReason\" />\n </DisplayLayout>\n );\n}\n\n/* The firm's mirror of the same arrangement: the client is the title, the status beside it. */\nfunction EngagementDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"role\" />\n <DisplayField name=\"scopedToOrganizationUnits\" />\n <DisplayField name=\"purpose\" />\n <DisplayField name=\"endsAt\" />\n <DisplayField name=\"expertAdmissionPolicy\" />\n <DisplayField name=\"delegatedCapabilities\" />\n <DisplayField name=\"createdAt\" />\n <DisplayField name=\"endedAt\" />\n <DisplayField name=\"decisionReason\" />\n </DisplayLayout>\n );\n}\n\n/* A card: the other organization (the title), the status badge, the role, and the end date labelled — a bare date\n beside a status could be any of the relationship's dates. */\nfunction RelationshipSummaryTemplate(): React.JSX.Element {\n return (\n <SummaryLayout>\n <SummaryMeta>\n <DisplayField name=\"status\" />\n <DisplayField name=\"role\" />\n <DisplayField name=\"endsAt\" />\n </SummaryMeta>\n </SummaryLayout>\n );\n}\n\n/*\n * One of the firm's people serving one client. The record has no name of its own, so the body leads with the two\n * things it joins — the person and the engagement, each resolved to its label — then when it began and ended.\n */\nfunction AssignmentDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"userId\" />\n <DisplayField name=\"serviceEngagementId\" />\n <DisplayField name=\"assignedAt\" />\n <DisplayField name=\"assignedByUserId\" />\n <DisplayField name=\"approvalResolvedAt\" />\n <DisplayField name=\"approvalDenialReason\" />\n <DisplayField name=\"endedAt\" />\n <DisplayField name=\"endedByUserId\" />\n </DisplayLayout>\n );\n}\n\n/* A lent capability's identity line: the capability (its translated name, not an identifier) and its status. */\nfunction CapabilityGrantHeader(): React.JSX.Element {\n return (\n <div className=\"flex min-w-0 flex-wrap items-center gap-field\">\n <DisplayField name=\"capability\" hideLabel hideDescription className=\"w-auto\" />\n <DisplayField name=\"status\" hideLabel hideDescription className=\"w-auto\" />\n </div>\n );\n}\n\n/*\n * One lent capability (#1631): WHAT was lent is the title, then through which relationship, until when, and who\n * granted and revoked it — each decision row empty until it happens.\n */\nfunction CapabilityGrantDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"relationshipId\" />\n <DisplayField name=\"endsAt\" />\n <DisplayField name=\"grantedAt\" />\n <DisplayField name=\"grantedByUserId\" />\n <DisplayField name=\"revokedAt\" />\n <DisplayField name=\"revokedByUserId\" />\n <DisplayField name=\"endedAt\" />\n </DisplayLayout>\n );\n}\n\n/* A card: the capability's status and when it ends. */\nfunction CapabilityGrantSummaryTemplate(): React.JSX.Element {\n return (\n <SummaryLayout>\n <SummaryMeta>\n <DisplayField name=\"status\" />\n <DisplayField name=\"endsAt\" />\n </SummaryMeta>\n </SummaryLayout>\n );\n}\n\n/*\n * The firm's feed decision (#1632): on or off, then who decided, when, and that the consultation notice was\n * acknowledged. The identity line is the status itself — there is one row per organization.\n */\nfunction ActivityFeedSettingsDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"status\" />\n <DisplayField name=\"decidedAt\" />\n <DisplayField name=\"decidedByUserId\" />\n <DisplayField name=\"acknowledgedWorkerConsultationNotice\" />\n </DisplayLayout>\n );\n}\n\n/*\n * One feed entry (#1632): which expert, in which client, which kind of operation on which kind of resource, when,\n * and — if the client allows it — whether it took effect. Nothing else exists to show: the entry holds no content.\n */\nfunction ActivityFeedEntryDisplayTemplate(): React.JSX.Element {\n return (\n <DisplayLayout>\n <DisplayField name=\"occurredAt\" />\n <DisplayField name=\"expertUserId\" />\n <DisplayField name=\"clientOrganizationId\" />\n <DisplayField name=\"operationKind\" />\n <DisplayField name=\"resourceType\" />\n <DisplayField name=\"outcome\" />\n </DisplayLayout>\n );\n}\n\n/* One line: who did what kind of thing, and how it ended. */\nfunction ActivityFeedEntrySummaryTemplate(): React.JSX.Element {\n return (\n <SummaryLayout flow={SummaryFlow.ROW} titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED}>\n <DisplayField name=\"expertUserId\" className=\"w-auto\" />\n <DisplayField name=\"operationKind\" className=\"w-auto\" />\n <DisplayField name=\"resourceType\" className=\"w-auto\" />\n <DisplayField name=\"outcome\" className=\"w-auto\" />\n </SummaryLayout>\n );\n}\n\n/* One line: who, for which client, and whether it still holds. */\nfunction AssignmentSummaryTemplate(): React.JSX.Element {\n return (\n <SummaryLayout flow={SummaryFlow.ROW} titlePlacement={SummaryTitlePlacement.TEMPLATE_OWNED}>\n <DisplayField name=\"userId\" className=\"w-auto\" />\n <DisplayField name=\"serviceEngagementId\" className=\"w-auto\" />\n <DisplayField name=\"status\" className=\"w-auto\" />\n </SummaryLayout>\n );\n}\n\n/** A verb shown on a row only where its `enabledCondition` admits it — never greyed out on the others. */\nconst rowAction = (iconOverride: ResourceOperationFrontendConfig['iconOverride']) =>\n notAddressable({ iconOverride, actionVisibility: ActionVisibility.WHEN_AVAILABLE });\n\nexport function buildServiceProvidersMainPresets(): Partial<ResourceUIBehavior> {\n return {\n // ── CLIENT side ──────────────────────────────────────────────────────────────────────────\n [R.SERVICE_PROVIDER_RELATIONSHIPS]: resourceUIBehavior(relationshipsFactory, ServiceProviderRelationshipSchema, ({ schemaShape }) => ({\n icon: Handshake,\n // The firm by the name it had when the relationship was proposed: the client cannot read its row.\n getFrontendResourceLabel: ({ currentObject }) => currentObject.providerOrganizationName || currentObject.providerOrganizationId,\n layout: {\n defaultChromeMode: CHROME,\n header: StatusHeader,\n display: RelationshipDisplayTemplate,\n summary: RelationshipSummaryTemplate,\n },\n fields: {\n status: schemaShape.status.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },\n edit: { showDescription: true },\n values: RELATIONSHIP_STATUS_COLOURS,\n }),\n // Open-ended, unconfined and machine-free are the usual case, and each decision row is empty until it is made.\n endsAt: schemaShape.endsAt.dateUI({ display: { hideWhenEmpty: true }, summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),\n organizationUnitIds: schemaShape.organizationUnitIds.arrayUI(hideWhenEmpty),\n admittedMachineClientIds: schemaShape.admittedMachineClientIds.arrayUI(hideWhenEmpty),\n proposedByUserId: schemaShape.proposedByUserId.stringUI(hideWhenEmpty),\n acceptedByUserId: schemaShape.acceptedByUserId.stringUI(hideWhenEmpty),\n acceptedAt: schemaShape.acceptedAt.dateUI(hideWhenEmpty),\n endedByUserId: schemaShape.endedByUserId.stringUI(hideWhenEmpty),\n endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),\n decisionReason: schemaShape.decisionReason.stringUI(hideWhenEmpty),\n // #1633 / #1632: the client's two per-relationship controls, as their translated value.\n providerMfaTrust: schemaShape.providerMfaTrust.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),\n activityFeedDisclosure: schemaShape.activityFeedDisclosure.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),\n },\n views: [\n [Op.LIST, addressable(LIST_BY_STATUS)],\n // Row click → the relationship in the companion drawer: scope, term, purpose, who decided what.\n [Op.READ, notAddressable()],\n [Op.COUNT, notAddressable()],\n // The client's owner invites a firm from the collection toolbar.\n [ServiceProviderRelationships_Operations.PROPOSE, notAddressable({ iconOverride: Send })],\n [ServiceProviderRelationships_Operations.ACCEPT, rowAction(Check)],\n [ServiceProviderRelationships_Operations.DECLINE, rowAction(X)],\n [ServiceProviderRelationships_Operations.SUSPEND, rowAction(CirclePause)],\n [ServiceProviderRelationships_Operations.RESUME, rowAction(Play)],\n [ServiceProviderRelationships_Operations.AMEND_SCOPE, rowAction(Scaling)],\n // #1612: whether each expert the firm assigns waits for an administrator's approval here.\n [ServiceProviderRelationships_Operations.SET_EXPERT_ADMISSION_POLICY, rowAction(UserCheck)],\n // #1633: whether the firm's enterprise IdP's second factor satisfies this organization's MFA requirement.\n [ServiceProviderRelationships_Operations.SET_PROVIDER_MFA_TRUST, rowAction(ShieldCheck)],\n // #1632: how much the firm's expert-activity feed may record about work here.\n [ServiceProviderRelationships_Operations.SET_ACTIVITY_FEED_DISCLOSURE, rowAction(Eye)],\n [ServiceProviderRelationships_Operations.TERMINATE, rowAction(Ban)],\n [ServiceProviderRelationships_Operations.ADMIT_MACHINE_CLIENT, rowAction(UserPlus)],\n [ServiceProviderRelationships_Operations.REMOVE_MACHINE_CLIENT, rowAction(UserMinus)],\n ],\n })),\n\n // ── CLIENT side: delegated administrative capabilities (#1631) ──────────────────────────────\n [R.SERVICE_PROVIDER_CAPABILITY_GRANTS]: resourceUIBehavior(capabilityGrantsFactory, ServiceProviderCapabilityGrantSchema, ({ schemaShape }) => ({\n icon: KeyRound,\n layout: {\n defaultChromeMode: CHROME,\n header: CapabilityGrantHeader,\n display: CapabilityGrantDisplayTemplate,\n summary: CapabilityGrantSummaryTemplate,\n },\n fields: {\n capability: schemaShape.capability.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),\n relationshipId: schemaShape.relationshipId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),\n status: schemaShape.status.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },\n edit: { showDescription: true },\n values: {\n [ServiceProviderCapabilityGrantStatus.ACTIVE]: { color: BadgeSemanticVariant.WARNING },\n [ServiceProviderCapabilityGrantStatus.REVOKED]: { color: BadgeSemanticVariant.SECONDARY },\n [ServiceProviderCapabilityGrantStatus.EXPIRED]: { color: BadgeSemanticVariant.SECONDARY },\n },\n }),\n endsAt: schemaShape.endsAt.dateUI({ summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),\n grantedByUserId: schemaShape.grantedByUserId.stringUI(hideWhenEmpty),\n revokedByUserId: schemaShape.revokedByUserId.stringUI(hideWhenEmpty),\n revokedAt: schemaShape.revokedAt.dateUI(hideWhenEmpty),\n endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),\n },\n views: [\n [Op.LIST, addressable(LIST_BY_STATUS)],\n [Op.READ, notAddressable()],\n [Op.COUNT, notAddressable()],\n // An administrator lends an ordinary capability; only an owner, with step-up, a security-critical one.\n [ServiceProviderCapabilityGrants_Operations.GRANT, notAddressable({ iconOverride: ShieldPlus })],\n [ServiceProviderCapabilityGrants_Operations.GRANT_SECURITY_CRITICAL, notAddressable({ iconOverride: ShieldAlert })],\n [ServiceProviderCapabilityGrants_Operations.REVOKE, rowAction(Ban)],\n ],\n })),\n\n // ── FIRM side ────────────────────────────────────────────────────────────────────────────\n [R.SERVICE_ENGAGEMENTS]: resourceUIBehavior(engagementsFactory, ServiceEngagementSchema, ({ schemaShape }) => ({\n icon: Handshake,\n getFrontendResourceLabel: ({ currentObject }) => currentObject.clientOrganizationName || currentObject.clientOrganizationId,\n layout: {\n defaultChromeMode: CHROME,\n header: StatusHeader,\n display: EngagementDisplayTemplate,\n summary: RelationshipSummaryTemplate,\n },\n fields: {\n status: schemaShape.status.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },\n edit: { showDescription: true },\n values: RELATIONSHIP_STATUS_COLOURS,\n }),\n endsAt: schemaShape.endsAt.dateUI({ display: { hideWhenEmpty: true }, summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),\n endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),\n decisionReason: schemaShape.decisionReason.stringUI(hideWhenEmpty),\n },\n views: [\n [Op.LIST, addressable(LIST_BY_STATUS)],\n [Op.READ, notAddressable()],\n [Op.COUNT, notAddressable()],\n [ServiceEngagements_Operations.PROPOSE, notAddressable({ iconOverride: Send })],\n [ServiceEngagements_Operations.ACCEPT, rowAction(Check)],\n [ServiceEngagements_Operations.WITHDRAW, rowAction(X)],\n ],\n })),\n\n // ── FIRM side: the expert-activity feed (#1632) ─────────────────────────────────────────────\n // The firm's decision. Both verbs act on the organization's one row; either may be repeated, and each records a new\n // decision.\n [R.SERVICE_PROVIDER_ACTIVITY_FEED_SETTINGS]: resourceUIBehavior(activityFeedSettingsFactory, ServiceProviderActivityFeedSettingsSchema, ({ schemaShape }) => ({\n icon: Activity,\n // One row per organization and no name of its own: it is named by its resource's words.\n getFrontendResourceLabel: ({ t, resourceType }) => t(`${LabellingTypes.RESOURCES}.${resourceType}.operations.read.title`),\n layout: {\n defaultChromeMode: CHROME,\n display: ActivityFeedSettingsDisplayTemplate,\n },\n fields: {\n status: schemaShape.status.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: true },\n values: {\n [ServiceProviderActivityFeedStatus.DISABLED]: { color: BadgeSemanticVariant.SECONDARY },\n [ServiceProviderActivityFeedStatus.ENABLED]: { color: BadgeSemanticVariant.WARNING },\n },\n }),\n decidedAt: schemaShape.decidedAt.dateUI(hideWhenEmpty),\n decidedByUserId: schemaShape.decidedByUserId.stringUI(hideWhenEmpty),\n },\n // A singleton of the organization: the page IS its READ (materialized DISABLED on first access), and the two\n // verbs act on that one row.\n views: [\n [Op.READ, addressable()],\n [ServiceProviderActivityFeedSettings_Operations.ENABLE, notAddressable({ iconOverride: Power, actionVisibility: ActionVisibility.WHEN_AVAILABLE })],\n [ServiceProviderActivityFeedSettings_Operations.DISABLE, notAddressable({ iconOverride: PowerOff, actionVisibility: ActionVisibility.WHEN_AVAILABLE })],\n ],\n })),\n\n // The entries themselves: metadata only, newest first, read by the firm's administrators.\n [R.SERVICE_PROVIDER_ACTIVITY_FEED]: resourceUIBehavior(activityFeedFactory, ServiceProviderActivityFeedEntrySchema, ({ schemaShape }) => ({\n icon: Activity,\n // An entry has no name of its own and must not carry client content: it is named by when it happened.\n getFrontendResourceLabel: ({ currentObject, formatDateTime }) => formatDateTime(currentObject.occurredAt),\n layout: {\n defaultChromeMode: CHROME,\n display: ActivityFeedEntryDisplayTemplate,\n summary: ActivityFeedEntrySummaryTemplate,\n },\n fields: {\n expertUserId: schemaShape.expertUserId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),\n operationKind: schemaShape.operationKind.enumUI({ display: { displayMode: EnumDisplayMode.TEXT } }),\n outcome: schemaShape.outcome.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: false, hideWhenEmpty: true },\n values: {\n [ServiceProviderActivityOutcome.SUCCEEDED]: { color: BadgeSemanticVariant.SUCCESS },\n [ServiceProviderActivityOutcome.REFUSED]: { color: BadgeSemanticVariant.DESTRUCTIVE },\n },\n }),\n },\n views: [\n [Op.LIST, addressable({ collectionDisplayConfig: { displayMode: CollectionDisplayMode.TABLE, userSwitchableDisplayMode: true } })],\n [Op.READ, notAddressable()],\n [Op.COUNT, notAddressable()],\n ],\n })),\n\n [R.SERVICE_ENGAGEMENT_ASSIGNMENTS]: resourceUIBehavior(assignmentsFactory, ServiceEngagementAssignmentSchema, ({ schemaShape }) => ({\n icon: Users,\n layout: {\n defaultChromeMode: CHROME,\n display: AssignmentDisplayTemplate,\n summary: AssignmentSummaryTemplate,\n },\n fields: {\n // The person and the engagement resolve to their labels: an assignment read as two ids names nobody.\n userId: schemaShape.userId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),\n serviceEngagementId: schemaShape.serviceEngagementId.foreignKeyUI({ display: { mode: ForeignKeyDisplayMode.LABEL } }),\n assignedByUserId: schemaShape.assignedByUserId.stringUI(hideWhenEmpty),\n endedByUserId: schemaShape.endedByUserId.stringUI(hideWhenEmpty),\n endedAt: schemaShape.endedAt.dateUI(hideWhenEmpty),\n // #1612: when the client answered, and why it admitted nobody — each empty until it happens.\n approvalResolvedAt: schemaShape.approvalResolvedAt.dateUI(hideWhenEmpty),\n approvalDenialReason: schemaShape.approvalDenialReason.enumUI({ display: { displayMode: EnumDisplayMode.TEXT, hideWhenEmpty: true } }),\n status: schemaShape.status.enumUI({\n display: { displayMode: EnumDisplayMode.BADGE, showDescription: false },\n edit: { showDescription: true },\n values: {\n [ServiceEngagementAssignmentStatus.ACTIVE]: { color: BadgeSemanticVariant.SUCCESS },\n [ServiceEngagementAssignmentStatus.ENDED]: { color: BadgeSemanticVariant.SECONDARY },\n // #1612: waiting on the client, refused by it, or never answered.\n [ServiceEngagementAssignmentStatus.PENDING_CLIENT_APPROVAL]: { color: BadgeSemanticVariant.WARNING },\n [ServiceEngagementAssignmentStatus.DENIED]: { color: BadgeSemanticVariant.DESTRUCTIVE },\n [ServiceEngagementAssignmentStatus.LAPSED]: { color: BadgeSemanticVariant.SECONDARY },\n },\n }),\n },\n views: [\n [Op.LIST, addressable(LIST_BY_STATUS)],\n [Op.READ, notAddressable()],\n [Op.COUNT, notAddressable()],\n [ServiceEngagementAssignments_Operations.ASSIGN, notAddressable({ iconOverride: UserPlus })],\n [ServiceEngagementAssignments_Operations.UNASSIGN, rowAction(UserMinus)],\n ],\n })),\n };\n}\n\nexport const serviceProvidersMainPresets = buildServiceProvidersMainPresets();\n"]}
@@ -14,9 +14,10 @@
14
14
  * sync or the companion crash-loops at load (`validateStructuralSlotDescriptions`,
15
15
  * bidirectional). Edit both sides together.
16
16
  *
17
- * The delivery LOG stays LAYOUT-LESS: it gets its dashboard richness from GENERIC
18
- * collection capabilities (Stripe/Ignisign webhook-dashboard idiom, no layout
19
- * sections needed):
17
+ * The delivery LOG declares no SECTIONS — its read page is one flat list of facts
18
+ * (`M2MWebhookDeliveryLogDisplayTemplate`) under a header carrying the status — and
19
+ * gets its dashboard richness from GENERIC collection capabilities
20
+ * (Stripe/Ignisign webhook-dashboard idiom):
20
21
  * - `collectionDisplayConfig.quickFilterField: 'status'` — All/Pending/
21
22
  * In-flight/Delivered/Failed tab strip above the toolbar (server-side
22
23
  * filter, shares the panel's filter state).
@@ -1 +1 @@
1
- {"version":3,"file":"webhooks.resource-presets.d.ts","sourceRoot":"","sources":["../../../../../src/config/resources/webhooks.resource-presets.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAkDtE,wBAAgB,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAgHtE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiFxG;AAED,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,oBAAoB,6BAAiD,CAAC"}
1
+ {"version":3,"file":"webhooks.resource-presets.d.ts","sourceRoot":"","sources":["../../../../../src/config/resources/webhooks.resource-presets.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAuItE,wBAAgB,wBAAwB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAiHtE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAkFxG;AAED,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAC9D,eAAO,MAAM,oBAAoB,6BAAiD,CAAC"}
@@ -1,20 +1,74 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { DisplayField, DisplayLayout, Section, polymorphicResourceUIBehavior, polymorphicResourceUIBehaviorFrom, ResourceOperationActionScope, ResourceLayoutInlineEditDefault, } from '@wildo-ai/saas-frontend-lib';
2
+ import { DisplayField, DisplayLayout, ResourceHeaderTitle, Section, SummaryLayout, SummaryMeta, polymorphicResourceUIBehavior, polymorphicResourceUIBehaviorFrom, ResourceOperationActionScope, ResourceLayoutInlineEditDefault, } from '@wildo-ai/saas-frontend-lib';
3
3
  import { BadgeSemanticVariant, DisplayChromeMode, EditChromeMode, EnumDisplayMode, SectionMode } from '@wildo-ai/zod-decorators';
4
4
  import { Webhook, Activity, PlugZap, RotateCw, Trash2 } from 'lucide-react';
5
5
  import { CoreResourceType as R, CoreResourceOperation as Op, WebhookConfig_Operations, M2MWebhookDeliveryLog_Operations, M2MWebhookDeliveryLogStatus, webhookConfigPolymorphicFactories, m2mWebhookDeliveryLogPolymorphicFactories, WebhookConfigBaseSchema, M2MWebhookDeliveryLogBaseSchema, } from '@wildo-ai/saas-models';
6
6
  import { addressable, notAddressable } from './resource.config.utils.js';
7
7
  /**
8
- * READ display for the webhook config singleton — three sections:
9
- * - `status`: the master `enabled` kill-switch.
10
- * - `endpoints`: the destination list (`endpoints[]`).
11
- * - `verification`: the derived `applicationPublicKeyPem` customers verify signatures with.
8
+ * READ display for the webhook config singleton — three sections, none with a description on read (each was a
9
+ * prompt: "Control webhook delivery for this scope" over the one switch that does it):
10
+ * - `status`: the master `enabled` kill-switch. One row, so no heading: the row's own label says it.
11
+ * - `endpoints`: the destination list (`endpoints[]`). The heading names the list, so the list carries no label of
12
+ * its own — it read "Endpoints" twice, the heading and then the field.
13
+ * - `verification`: the derived `applicationPublicKeyPem` customers verify signatures with. STACKED, label above
14
+ * the key: a PEM block is several lines, and as a settings row it was wrapped into half the card beside its label.
12
15
  * `_id` is hidden and the create/update timestamps are intentionally omitted from
13
16
  * the curated admin read. Section refs are mirrored in the resource spec's
14
17
  * `frontend.layout.sections` — keep them in lockstep.
15
18
  */
16
19
  function WebhookConfigDisplayTemplate() {
17
- return (_jsxs(DisplayLayout, { children: [_jsx(Section, { name: "status", appearance: SectionMode.CARD, children: _jsx(DisplayField, { name: "enabled" }) }), _jsx(Section, { name: "endpoints", children: _jsx(DisplayField, { name: "endpoints" }) }), _jsx(Section, { name: "verification", children: _jsx(DisplayField, { name: "applicationPublicKeyPem" }) })] }));
20
+ return (_jsxs(DisplayLayout, { children: [_jsx(Section, { name: "status", appearance: SectionMode.CARD, hideTitle: true, hideDescription: true, children: _jsx(DisplayField, { name: "enabled" }) }), _jsx(Section, { name: "endpoints", chromeMode: DisplayChromeMode.HIDDEN, hideDescription: true, children: _jsx(DisplayField, { name: "endpoints" }) }), _jsx(Section, { name: "verification", chromeMode: DisplayChromeMode.STACKED, hideDescription: true, children: _jsx(DisplayField, { name: "applicationPublicKeyPem" }) })] }));
21
+ }
22
+ /*
23
+ * One outbound delivery attempt, read once. The header is its NAME — the resource and operation that produced it —
24
+ * with its status beside it, so neither is a row below. No sections: the facts are one list, in the order an
25
+ * operator asks them (where did it go, how many tries, what came back, when did it end), and every row that is
26
+ * empty for most deliveries hides. The payload comes last and takes the full width without a label: it is the
27
+ * body that was sent, and a label beside a JSON block squeezed it into half the page.
28
+ */
29
+ function M2MWebhookDeliveryLogDisplayTemplate() {
30
+ return (_jsxs(DisplayLayout, { children: [_jsx(DisplayField, { name: "httpUrl" }), _jsx(DisplayField, { name: "endpointId" }), _jsx(DisplayField, { name: "channel" }), _jsx(DisplayField, { name: "variantKey" }), _jsx(DisplayField, { name: "attemptCount" }), _jsx(DisplayField, { name: "lastAttemptAt" }), _jsx(DisplayField, { name: "nextAttemptAt" }), _jsx(DisplayField, { name: "responseStatus" }), _jsx(DisplayField, { name: "failureReason" }), _jsx(DisplayField, { name: "responseBodyTruncated" }), _jsx(DisplayField, { name: "deliveredAt" }), _jsx(DisplayField, { name: "failedAt" }), _jsx(DisplayField, { name: "payload", hideLabel: true, hideDescription: true })] }));
31
+ }
32
+ /*
33
+ * A card in a list grouped by DAY: the resource and operation (the title), then the status badge, where it was sent,
34
+ * and — only when it failed — why. The day is the group heading above the card, so the card does not repeat it.
35
+ * The attempt count keeps its label: a bare "3" says nothing.
36
+ */
37
+ function M2MWebhookDeliveryLogSummaryTemplate() {
38
+ return (_jsx(SummaryLayout, { children: _jsxs(SummaryMeta, { children: [_jsx(DisplayField, { name: "status" }), _jsx(DisplayField, { name: "httpUrl" }), _jsx(DisplayField, { name: "attemptCount" }), _jsx(DisplayField, { name: "failureReason" })] }) }));
39
+ }
40
+ /**
41
+ * Chrome and field decorators shared by both delivery-log scopes: settings rows on the read page, bare values on a
42
+ * card, the status as a coloured badge, and every row that is empty for most deliveries hidden.
43
+ */
44
+ function m2mWebhookDeliveryLogPresentation(schemaShape) {
45
+ const hideWhenEmpty = { display: { hideWhenEmpty: true } };
46
+ return {
47
+ defaultChromeMode: { display: DisplayChromeMode.SETTINGS_ROW, summary: DisplayChromeMode.HIDDEN, edit: EditChromeMode.SETTINGS_ROW },
48
+ fields: {
49
+ // The badge's colour carries the state. The state's description is not shown under it: on a list it read
50
+ // once per row.
51
+ status: schemaShape.status.enumUI({
52
+ display: { displayMode: EnumDisplayMode.BADGE },
53
+ values: {
54
+ [M2MWebhookDeliveryLogStatus.PENDING]: { color: BadgeSemanticVariant.SECONDARY },
55
+ [M2MWebhookDeliveryLogStatus.IN_FLIGHT]: { color: BadgeSemanticVariant.INFO },
56
+ [M2MWebhookDeliveryLogStatus.DELIVERED]: { color: BadgeSemanticVariant.SUCCESS },
57
+ [M2MWebhookDeliveryLogStatus.FAILED]: { color: BadgeSemanticVariant.DESTRUCTIVE },
58
+ },
59
+ }),
60
+ // On a card the count keeps its label: a bare number beside a URL could be anything.
61
+ attemptCount: schemaShape.attemptCount.numberUI({ summaryOverride: { chromeMode: DisplayChromeMode.INLINE } }),
62
+ variantKey: schemaShape.variantKey.stringUI(hideWhenEmpty),
63
+ lastAttemptAt: schemaShape.lastAttemptAt.dateUI(hideWhenEmpty),
64
+ nextAttemptAt: schemaShape.nextAttemptAt.dateUI(hideWhenEmpty),
65
+ responseStatus: schemaShape.responseStatus.numberUI(hideWhenEmpty),
66
+ failureReason: schemaShape.failureReason.stringUI(hideWhenEmpty),
67
+ responseBodyTruncated: schemaShape.responseBodyTruncated.stringUI(hideWhenEmpty),
68
+ deliveredAt: schemaShape.deliveredAt.dateUI(hideWhenEmpty),
69
+ failedAt: schemaShape.failedAt.dateUI(hideWhenEmpty),
70
+ },
71
+ };
18
72
  }
19
73
  export function buildWebhooksMainPresets() {
20
74
  return {
@@ -78,18 +132,14 @@ export function buildWebhooksMainPresets() {
78
132
  ],
79
133
  }, m2mWebhookDeliveryLogPolymorphicFactories[R.ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG], M2MWebhookDeliveryLogBaseSchema, ({ schema, schemaShape, opsVariantResolver }) => ({
80
134
  icon: Activity,
81
- fields: {
82
- status: schema.shape.status.enumUI({
83
- display: { displayMode: EnumDisplayMode.BADGE, showDescription: true },
84
- edit: { showDescription: true },
85
- values: {
86
- [M2MWebhookDeliveryLogStatus.PENDING]: { color: BadgeSemanticVariant.SECONDARY },
87
- [M2MWebhookDeliveryLogStatus.IN_FLIGHT]: { color: BadgeSemanticVariant.INFO },
88
- [M2MWebhookDeliveryLogStatus.DELIVERED]: { color: BadgeSemanticVariant.SUCCESS },
89
- [M2MWebhookDeliveryLogStatus.FAILED]: { color: BadgeSemanticVariant.DESTRUCTIVE },
90
- },
91
- }),
135
+ layout: {
136
+ defaultChromeMode: m2mWebhookDeliveryLogPresentation(M2MWebhookDeliveryLogBaseSchema.shape).defaultChromeMode,
137
+ // The identity line: the resource and operation (the title) and the delivery's status beside it.
138
+ 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" })] })),
139
+ display: M2MWebhookDeliveryLogDisplayTemplate,
140
+ summary: M2MWebhookDeliveryLogSummaryTemplate,
92
141
  },
142
+ fields: m2mWebhookDeliveryLogPresentation(M2MWebhookDeliveryLogBaseSchema.shape).fields,
93
143
  getFrontendResourceLabel: ({ currentObject }) => `${currentObject.resourceIdentifier} · ${currentObject.operationIdentifier}`,
94
144
  views: [
95
145
  [Op.LIST, addressable({
@@ -101,10 +151,10 @@ export function buildWebhooksMainPresets() {
101
151
  // Row click → per-delivery detail in the companion drawer: status,
102
152
  // attempts, response, and the opaque `payload` as pretty JSON.
103
153
  [Op.READ, notAddressable()],
104
- // Per-row retry: backend reads the target from the request-DTO
105
- // `deliveryLogId` (not the URL id), so the clicked row's id is injected
106
- // into that body field and the op executes in place (no form).
107
- [M2MWebhookDeliveryLog_Operations.RETRY, notAddressable({ iconOverride: RotateCw, rowTargetRequestField: 'deliveryLogId' })],
154
+ // Per-row retry, addressed by the ROUTE: the backend uses the framework-resolved
155
+ // row id and the request body must be empty (`M2MWebhookDeliveryLog_RetryRequestDto`
156
+ // is strict), so no body field is injected. Executes in place (no form).
157
+ [M2MWebhookDeliveryLog_Operations.RETRY, notAddressable({ iconOverride: RotateCw })],
108
158
  // Whole-scope maintenance: rendered once in the collection-action bar.
109
159
  // It keeps its `{ olderThanDays }` form (real operator input), so the
110
160
  // collection surface routes it to that form host, which now builds a
@@ -152,6 +202,7 @@ export function buildWebhooksAdminPresets(main) {
152
202
  ],
153
203
  }, m2mWebhookDeliveryLogPolymorphicFactories[R.ORGANIZATION_M2M_WEBHOOK_DELIVERY_LOG], main, ({ base }) => ({
154
204
  icon: base.icon,
205
+ layout: base.layout,
155
206
  fields: base.fields,
156
207
  getFrontendResourceLabel: base.getFrontendResourceLabel,
157
208
  views: [
@@ -162,10 +213,10 @@ export function buildWebhooksAdminPresets(main) {
162
213
  },
163
214
  })],
164
215
  [Op.READ, notAddressable()],
165
- // Per-row retry: backend reads the target from the request-DTO
166
- // `deliveryLogId` (not the URL id), so the clicked row's id is injected
167
- // into that body field and the op executes in place (no form).
168
- [M2MWebhookDeliveryLog_Operations.RETRY, notAddressable({ iconOverride: RotateCw, rowTargetRequestField: 'deliveryLogId' })],
216
+ // Per-row retry, addressed by the ROUTE: the backend uses the framework-resolved
217
+ // row id and the request body must be empty (`M2MWebhookDeliveryLog_RetryRequestDto`
218
+ // is strict), so no body field is injected. Executes in place (no form).
219
+ [M2MWebhookDeliveryLog_Operations.RETRY, notAddressable({ iconOverride: RotateCw })],
169
220
  // Whole-scope maintenance: rendered once in the collection-action bar.
170
221
  // It keeps its `{ olderThanDays }` form (real operator input), so the
171
222
  // collection surface routes it to that form host, which now builds a