@pablo2410/shared-ui 0.18.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +18 -15
  2. package/dist/{HealthFooter-C5K9s38i.d.ts → HealthFooter-BoOozbWG.d.ts} +4 -4
  3. package/dist/{chunk-G7XJLTNY.js → chunk-5RY3AJKI.js} +8 -9
  4. package/dist/{chunk-G7XJLTNY.js.map → chunk-5RY3AJKI.js.map} +1 -1
  5. package/dist/{chunk-3G43UG63.js → chunk-A6UTXAPS.js} +11 -3
  6. package/dist/chunk-A6UTXAPS.js.map +1 -0
  7. package/dist/{chunk-R4NOLCSI.js → chunk-BKGUIIN2.js} +1 -1
  8. package/dist/{chunk-R4NOLCSI.js.map → chunk-BKGUIIN2.js.map} +1 -1
  9. package/dist/{chunk-IEBZGU6X.js → chunk-DMUQ5WNO.js} +2 -4
  10. package/dist/chunk-DMUQ5WNO.js.map +1 -0
  11. package/dist/{chunk-PLCWXXUE.js → chunk-K6FHU4HN.js} +9 -15
  12. package/dist/chunk-K6FHU4HN.js.map +1 -0
  13. package/dist/{chunk-KXUNOSMZ.js → chunk-NLQ45OYS.js} +193 -91
  14. package/dist/chunk-NLQ45OYS.js.map +1 -0
  15. package/dist/{chunk-WTR6SNOE.js → chunk-VJEXXX2P.js} +158 -40
  16. package/dist/chunk-VJEXXX2P.js.map +1 -0
  17. package/dist/components/index.d.ts +7 -8
  18. package/dist/components/index.js +85 -63
  19. package/dist/components/index.js.map +1 -1
  20. package/dist/hierarchy/core.js +1 -1
  21. package/dist/hierarchy/index.d.ts +3 -3
  22. package/dist/hierarchy/index.js +5 -5
  23. package/dist/insights/index.d.ts +8 -8
  24. package/dist/insights/index.js +150 -61
  25. package/dist/insights/index.js.map +1 -1
  26. package/dist/layout/index.d.ts +8 -8
  27. package/dist/layout/index.js +6 -6
  28. package/dist/primitives/index.d.ts +288 -289
  29. package/dist/primitives/index.js +2 -2
  30. package/dist/rbac/index.js.map +1 -1
  31. package/dist/reporting/index.d.ts +101 -43
  32. package/dist/reporting/index.js +208 -187
  33. package/dist/reporting/index.js.map +1 -1
  34. package/dist/services/index.js +2 -2
  35. package/dist/shell/index.d.ts +2 -3
  36. package/dist/shell/index.js +7 -7
  37. package/dist/shell/oplytics-shell.css +2 -2
  38. package/dist/theme/oplytics-theme.css +4 -4
  39. package/package.json +48 -46
  40. package/dist/chunk-3G43UG63.js.map +0 -1
  41. package/dist/chunk-IEBZGU6X.js.map +0 -1
  42. package/dist/chunk-KXUNOSMZ.js.map +0 -1
  43. package/dist/chunk-PLCWXXUE.js.map +0 -1
  44. package/dist/chunk-WTR6SNOE.js.map +0 -1
@@ -269,7 +269,7 @@ import {
269
269
  useFormField,
270
270
  useIsMobile,
271
271
  useSidebar
272
- } from "../chunk-PLCWXXUE.js";
272
+ } from "../chunk-K6FHU4HN.js";
273
273
  import {
274
274
  Button,
275
275
  Dialog,
@@ -288,7 +288,7 @@ import {
288
288
  buttonVariants,
289
289
  cn,
290
290
  useDialogComposition
291
- } from "../chunk-R4NOLCSI.js";
291
+ } from "../chunk-BKGUIIN2.js";
292
292
  export {
293
293
  Accordion,
294
294
  AccordionContent,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/rbac/index.ts"],"sourcesContent":["/**\n * @oplytics/shared-ui/rbac\n *\n * Standardised Role-Based Access Control for all Oplytics.digital subdomains.\n * Single source of truth for the 7-role model, permission checks, and error messages.\n */\n\n// ─── Session & Transport Constants ───────────────────────────────────────────\n\nexport const COOKIE_NAME = \"app_session_id\";\nexport const ONE_YEAR_MS = 1000 * 60 * 60 * 24 * 365;\nexport const AXIOS_TIMEOUT_MS = 30_000;\n\n// ─── Error Message Constants ─────────────────────────────────────────────────\n\nexport const UNAUTHED_ERR_MSG = \"Please login (10001)\";\nexport const NOT_ADMIN_ERR_MSG =\n \"You do not have required permission (10002)\";\nexport const NOT_PLATFORM_ADMIN_ERR_MSG =\n \"Platform admin access required (10003)\";\nexport const NOT_ENTERPRISE_ADMIN_ERR_MSG =\n \"Enterprise admin access required (10004)\";\nexport const NO_ENTERPRISE_ERR_MSG =\n \"Enterprise context not resolved. Please ensure your account is linked to an enterprise in the portal. (10005)\";\nexport const NOT_SUPERUSER_ERR_MSG =\n \"This action requires superuser access or above (10006)\";\n\n// ─── Service Visibility ──────────────────────────────────────────────────────\n\n/**\n * Services restricted to platform_admin role only.\n * These services are NOT visible in ServiceHub, Portal, marketing pages, or footer.\n * They can only be assigned/revoked by platform_admin users.\n * Non-platform-admin users cannot see or interact with these services.\n */\nexport const PLATFORM_ADMIN_ONLY_SERVICES: readonly string[] = [\"business-hub\"];\n\n// ─── 7-Role Model ────────────────────────────────────────────────────────────\n\n/**\n * Standardised 7-role model (platform-wide, same in all subdomains).\n * Ordered from highest to lowest privilege.\n *\n * platform_admin — Oplytics staff, cross-enterprise, Business Hub\n * enterprise_admin — manages users/hierarchy/settings within their enterprise\n * superuser — cross-functional read-write within enterprise (all hierarchy levels);\n * can manage operational data but NOT users or enterprise settings\n * bu_user — scoped to assigned Business Unit(s) and children\n * site_user — scoped to assigned Site(s) and children\n * area_user — scoped to assigned Area(s) and children\n * asset_user — scoped to assigned Asset(s) only\n */\nexport const ALL_ROLES = [\n \"platform_admin\",\n \"enterprise_admin\",\n \"superuser\",\n \"bu_user\",\n \"site_user\",\n \"area_user\",\n \"asset_user\",\n] as const;\n\nexport type RoleType = (typeof ALL_ROLES)[number];\n\n/**\n * Role hierarchy from lowest to highest privilege.\n * Used for hasMinimumRole() checks.\n */\nexport const ROLE_HIERARCHY: readonly RoleType[] = [\n \"asset_user\",\n \"area_user\",\n \"site_user\",\n \"bu_user\",\n \"superuser\",\n \"enterprise_admin\",\n \"platform_admin\",\n];\n\n// ─── Permission Helpers ──────────────────────────────────────────────────────\n\n/** Check if a role meets or exceeds the minimum required role */\nexport function hasMinimumRole(\n userRole: RoleType,\n minimumRole: RoleType,\n): boolean {\n return ROLE_HIERARCHY.indexOf(userRole) >= ROLE_HIERARCHY.indexOf(minimumRole);\n}\n\n/** Check if a role is one of the admin roles */\nexport function isAdmin(role: RoleType): boolean {\n return ADMIN_ROLES.includes(role);\n}\n\n/** Check if a role is superuser-level or above */\nexport function isSuperuserOrAbove(role: RoleType): boolean {\n return SUPERUSER_ROLES.includes(role);\n}\n\n// ─── Role Groups ─────────────────────────────────────────────────────────────\n\n/** Roles that grant admin-level access (can manage users, hierarchy, etc.) */\nexport const ADMIN_ROLES: readonly RoleType[] = [\n \"platform_admin\",\n \"enterprise_admin\",\n];\n\n/** Roles that grant superuser-level access (can manage operational data across enterprise) */\nexport const SUPERUSER_ROLES: readonly RoleType[] = [\n \"platform_admin\",\n \"enterprise_admin\",\n \"superuser\",\n];\n\n/** Roles that require the area level to be enabled on the enterprise */\nexport const AREA_DEPENDENT_ROLES: readonly RoleType[] = [\"area_user\"];\n\n/** Roles that require the asset level to be enabled on the enterprise */\nexport const ASSET_DEPENDENT_ROLES: readonly RoleType[] = [\"asset_user\"];\n\n// ─── Access Levels ───────────────────────────────────────────────────────────\n\n/** Access levels for user_access_scopes */\nexport const ACCESS_LEVELS = [\n \"enterprise\",\n \"business_unit\",\n \"site\",\n \"area\",\n \"asset\",\n] as const;\n\nexport type AccessLevelType = (typeof ACCESS_LEVELS)[number];\n\n/** Access levels that depend on optional hierarchy toggles */\nexport const AREA_DEPENDENT_ACCESS_LEVELS: readonly AccessLevelType[] = [\n \"area\",\n];\nexport const ASSET_DEPENDENT_ACCESS_LEVELS: readonly AccessLevelType[] = [\n \"asset\",\n];\n"],"mappings":";AASO,IAAM,cAAc;AACpB,IAAM,cAAc,MAAO,KAAK,KAAK,KAAK;AAC1C,IAAM,mBAAmB;AAIzB,IAAM,mBAAmB;AACzB,IAAM,oBACX;AACK,IAAM,6BACX;AACK,IAAM,+BACX;AACK,IAAM,wBACX;AACK,IAAM,wBACX;AAUK,IAAM,+BAAkD,CAAC,cAAc;AAiBvE,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,iBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,eACd,UACA,aACS;AACT,SAAO,eAAe,QAAQ,QAAQ,KAAK,eAAe,QAAQ,WAAW;AAC/E;AAGO,SAAS,QAAQ,MAAyB;AAC/C,SAAO,YAAY,SAAS,IAAI;AAClC;AAGO,SAAS,mBAAmB,MAAyB;AAC1D,SAAO,gBAAgB,SAAS,IAAI;AACtC;AAKO,IAAM,cAAmC;AAAA,EAC9C;AAAA,EACA;AACF;AAGO,IAAM,kBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,uBAA4C,CAAC,WAAW;AAG9D,IAAM,wBAA6C,CAAC,YAAY;AAKhE,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,+BAA2D;AAAA,EACtE;AACF;AACO,IAAM,gCAA4D;AAAA,EACvE;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/rbac/index.ts"],"sourcesContent":["/**\n * @oplytics/shared-ui/rbac\n *\n * Standardised Role-Based Access Control for all Oplytics.digital subdomains.\n * Single source of truth for the 7-role model, permission checks, and error messages.\n */\n\n// ─── Session & Transport Constants ───────────────────────────────────────────\n\nexport const COOKIE_NAME = \"app_session_id\";\nexport const ONE_YEAR_MS = 1000 * 60 * 60 * 24 * 365;\nexport const AXIOS_TIMEOUT_MS = 30_000;\n\n// ─── Error Message Constants ─────────────────────────────────────────────────\n\nexport const UNAUTHED_ERR_MSG = \"Please login (10001)\";\nexport const NOT_ADMIN_ERR_MSG = \"You do not have required permission (10002)\";\nexport const NOT_PLATFORM_ADMIN_ERR_MSG =\n \"Platform admin access required (10003)\";\nexport const NOT_ENTERPRISE_ADMIN_ERR_MSG =\n \"Enterprise admin access required (10004)\";\nexport const NO_ENTERPRISE_ERR_MSG =\n \"Enterprise context not resolved. Please ensure your account is linked to an enterprise in the portal. (10005)\";\nexport const NOT_SUPERUSER_ERR_MSG =\n \"This action requires superuser access or above (10006)\";\n\n// ─── Service Visibility ──────────────────────────────────────────────────────\n\n/**\n * Services restricted to platform_admin role only.\n * These services are NOT visible in ServiceHub, Portal, marketing pages, or footer.\n * They can only be assigned/revoked by platform_admin users.\n * Non-platform-admin users cannot see or interact with these services.\n */\nexport const PLATFORM_ADMIN_ONLY_SERVICES: readonly string[] = [\"business-hub\"];\n\n// ─── 7-Role Model ────────────────────────────────────────────────────────────\n\n/**\n * Standardised 7-role model (platform-wide, same in all subdomains).\n * Ordered from highest to lowest privilege.\n *\n * platform_admin — Oplytics staff, cross-enterprise, Business Hub\n * enterprise_admin — manages users/hierarchy/settings within their enterprise\n * superuser — cross-functional read-write within enterprise (all hierarchy levels);\n * can manage operational data but NOT users or enterprise settings\n * bu_user — scoped to assigned Business Unit(s) and children\n * site_user — scoped to assigned Site(s) and children\n * area_user — scoped to assigned Area(s) and children\n * asset_user — scoped to assigned Asset(s) only\n */\nexport const ALL_ROLES = [\n \"platform_admin\",\n \"enterprise_admin\",\n \"superuser\",\n \"bu_user\",\n \"site_user\",\n \"area_user\",\n \"asset_user\",\n] as const;\n\nexport type RoleType = (typeof ALL_ROLES)[number];\n\n/**\n * Role hierarchy from lowest to highest privilege.\n * Used for hasMinimumRole() checks.\n */\nexport const ROLE_HIERARCHY: readonly RoleType[] = [\n \"asset_user\",\n \"area_user\",\n \"site_user\",\n \"bu_user\",\n \"superuser\",\n \"enterprise_admin\",\n \"platform_admin\",\n];\n\n// ─── Permission Helpers ──────────────────────────────────────────────────────\n\n/** Check if a role meets or exceeds the minimum required role */\nexport function hasMinimumRole(\n userRole: RoleType,\n minimumRole: RoleType\n): boolean {\n return (\n ROLE_HIERARCHY.indexOf(userRole) >= ROLE_HIERARCHY.indexOf(minimumRole)\n );\n}\n\n/** Check if a role is one of the admin roles */\nexport function isAdmin(role: RoleType): boolean {\n return ADMIN_ROLES.includes(role);\n}\n\n/** Check if a role is superuser-level or above */\nexport function isSuperuserOrAbove(role: RoleType): boolean {\n return SUPERUSER_ROLES.includes(role);\n}\n\n// ─── Role Groups ─────────────────────────────────────────────────────────────\n\n/** Roles that grant admin-level access (can manage users, hierarchy, etc.) */\nexport const ADMIN_ROLES: readonly RoleType[] = [\n \"platform_admin\",\n \"enterprise_admin\",\n];\n\n/** Roles that grant superuser-level access (can manage operational data across enterprise) */\nexport const SUPERUSER_ROLES: readonly RoleType[] = [\n \"platform_admin\",\n \"enterprise_admin\",\n \"superuser\",\n];\n\n/** Roles that require the area level to be enabled on the enterprise */\nexport const AREA_DEPENDENT_ROLES: readonly RoleType[] = [\"area_user\"];\n\n/** Roles that require the asset level to be enabled on the enterprise */\nexport const ASSET_DEPENDENT_ROLES: readonly RoleType[] = [\"asset_user\"];\n\n// ─── Access Levels ───────────────────────────────────────────────────────────\n\n/** Access levels for user_access_scopes */\nexport const ACCESS_LEVELS = [\n \"enterprise\",\n \"business_unit\",\n \"site\",\n \"area\",\n \"asset\",\n] as const;\n\nexport type AccessLevelType = (typeof ACCESS_LEVELS)[number];\n\n/** Access levels that depend on optional hierarchy toggles */\nexport const AREA_DEPENDENT_ACCESS_LEVELS: readonly AccessLevelType[] = [\n \"area\",\n];\nexport const ASSET_DEPENDENT_ACCESS_LEVELS: readonly AccessLevelType[] = [\n \"asset\",\n];\n"],"mappings":";AASO,IAAM,cAAc;AACpB,IAAM,cAAc,MAAO,KAAK,KAAK,KAAK;AAC1C,IAAM,mBAAmB;AAIzB,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,6BACX;AACK,IAAM,+BACX;AACK,IAAM,wBACX;AACK,IAAM,wBACX;AAUK,IAAM,+BAAkD,CAAC,cAAc;AAiBvE,IAAM,YAAY;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,iBAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,eACd,UACA,aACS;AACT,SACE,eAAe,QAAQ,QAAQ,KAAK,eAAe,QAAQ,WAAW;AAE1E;AAGO,SAAS,QAAQ,MAAyB;AAC/C,SAAO,YAAY,SAAS,IAAI;AAClC;AAGO,SAAS,mBAAmB,MAAyB;AAC1D,SAAO,gBAAgB,SAAS,IAAI;AACtC;AAKO,IAAM,cAAmC;AAAA,EAC9C;AAAA,EACA;AACF;AAGO,IAAM,kBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,uBAA4C,CAAC,WAAW;AAG9D,IAAM,wBAA6C,CAAC,YAAY;AAKhE,IAAM,gBAAgB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKO,IAAM,+BAA2D;AAAA,EACtE;AACF;AACO,IAAM,gCAA4D;AAAA,EACvE;AACF;","names":[]}
@@ -1,36 +1,72 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
1
+ import * as React from 'react';
2
2
 
3
3
  interface ReportingToolbarProps extends Omit<ReportingToolbarConfig, "moduleName"> {
4
- /** Service/module name (e.g. "Connect", "Policy Deployment"). Defaults to "Oplytics". */
4
+ /** Service/module name (e.g. "Connect"). Defaults to "Oplytics". */
5
5
  moduleName?: string;
6
- /** Optional pre-fill for the report dialog's Location/Area field. */
7
- defaultLocation?: string;
6
+ /** The current org-hierarchy selection, forwarded on every submission. */
7
+ hierarchyContext?: ReportHierarchyContext;
8
+ /** The authenticated user — openId is authoritative, name/email are hints. */
9
+ currentUser?: ReportSubmitter;
10
+ /** Service list for the feedback picker. Defaults to OPLYTICS_SERVICES. */
11
+ services?: OplyticsService[];
12
+ /** Pre-selected service slug in the feedback picker. */
13
+ defaultServiceSlug?: string;
14
+ /** Show the "attach screenshot" control (default: true). */
15
+ enableScreenshot?: boolean;
8
16
  /**
9
- * Compact mode — currently a no-op (the new design always responsive-collapses
10
- * the labels at small breakpoints). Kept on the prop type so callers that
11
- * still pass it continue to type-check.
12
- * @deprecated The toolbar handles responsive collapse on its own.
17
+ * While true (the DEFAULT), the Report items are disabled with a "Coming
18
+ * soon" badge and `onReportSubmit` is never called. A later release wires the
19
+ * per-type forms and passes `false`.
20
+ */
21
+ reportsComingSoon?: boolean;
22
+ /**
23
+ * @deprecated the toolbar handles responsive collapse itself.
13
24
  */
14
25
  compact?: boolean;
15
26
  /** CSS class for the container. */
16
27
  className?: string;
17
28
  }
18
- declare function ReportingToolbar({ moduleName, showIncidentReporting, showFeedback, reportCategories, feedbackCategories, onReportSubmit, onFeedbackSubmit, defaultLocation, className, }: ReportingToolbarProps): react_jsx_runtime.JSX.Element;
29
+ declare function ReportingToolbar({ moduleName, showIncidentReporting, showFeedback, reportCategories, feedbackCategories, onReportSubmit, onFeedbackSubmit, hierarchyContext, currentUser, services, defaultServiceSlug, enableScreenshot, reportsComingSoon, className, }: ReportingToolbarProps): React.JSX.Element | null;
19
30
 
20
31
  /**
21
32
  * @oplytics/shared-ui/reporting
22
33
  *
23
- * Reporting and feedback toolbar types and configuration for all Oplytics subdomains.
24
- * Provides the standard Safety/Environmental/Stop Work incident reporting buttons
25
- * and Problem/Suggestion feedback buttons.
34
+ * Reporting and feedback toolbar types + configuration for all Oplytics
35
+ * subdomains — the header "User Actions" dropdown (ReportingToolbar).
26
36
  *
27
- * The actual ReportingToolbar React component depends on shadcn/ui primitives
28
- * (Dialog, Button, Textarea, Select) which vary across subdomains until
29
- * consolidation. This module provides the types, configuration, and submission
30
- * logic that are shared.
37
+ * Feedback (Report Problem / Suggestion) is fully wired: the dialog collects a
38
+ * service, an "is this blocking you?" signal, a short summary, the detail, and
39
+ * an optional screenshot, then calls `onFeedbackSubmit` with the canonical
40
+ * `FeedbackReport` shape. The host owns the transport (it POSTs to Portal's
41
+ * `/api/service/feedback`).
42
+ *
43
+ * Report (Safety / Environmental / Stop Work) is not wired yet — while
44
+ * `reportsComingSoon` is true (the default), those items render disabled with a
45
+ * "Coming soon" badge. A later release adds the per-type forms and flips the
46
+ * default.
31
47
  */
32
48
  type ReportCategory = "safety" | "environmental" | "stop-work";
33
49
  type FeedbackCategory = "problem" | "suggestion";
50
+ /** Where in the org hierarchy the submission was made. */
51
+ interface ReportHierarchyContext {
52
+ enterpriseId?: number;
53
+ businessUnitId?: number;
54
+ siteId?: number;
55
+ areaId?: number;
56
+ assetId?: number;
57
+ }
58
+ /** The authenticated user, as much as the host can supply. */
59
+ interface ReportSubmitter {
60
+ /** JWT `openId` claim — the host must NOT trust name/email over this. */
61
+ openId?: string;
62
+ name?: string;
63
+ email?: string;
64
+ }
65
+ /** An attached screenshot: base64 WITHOUT the `data:...;base64,` prefix. */
66
+ interface ReportScreenshot {
67
+ dataBase64: string;
68
+ mime: string;
69
+ }
34
70
  interface IncidentReport {
35
71
  category: ReportCategory;
36
72
  description: string;
@@ -41,44 +77,52 @@ interface IncidentReport {
41
77
  moduleName: string;
42
78
  /** ISO timestamp */
43
79
  timestamp: string;
44
- /** User who submitted */
45
- submittedBy?: string;
46
- /** Hierarchy context at time of submission */
47
- hierarchyContext?: {
48
- enterpriseId?: number;
49
- businessUnitId?: number;
50
- siteId?: number;
51
- areaId?: number;
52
- assetId?: number;
53
- };
80
+ submittedBy?: ReportSubmitter;
81
+ hierarchyContext?: ReportHierarchyContext;
54
82
  }
55
83
  interface FeedbackReport {
56
84
  category: FeedbackCategory;
57
- /** Optional — short summary entered in the dialog before the description. */
58
- subject?: string;
59
- description: string;
85
+ /** Canonical service slug the feedback is about (from the picker). */
86
+ serviceSlug: string;
87
+ /** Optional short one-liner shown above the detail. */
88
+ summary?: string;
89
+ /** Required detail body. */
90
+ details: string;
91
+ /** "Is this blocking you?" — drives priority server-side. */
92
+ isBlocking: boolean;
93
+ /** Human-readable originating module ("OEE Manager", "SQDCP", …). */
60
94
  moduleName: string;
61
95
  /** ISO timestamp */
62
96
  timestamp: string;
63
- /** User who submitted */
64
- submittedBy?: string;
65
- /** Page/route where feedback was submitted */
97
+ /** Route the submitter was on. */
66
98
  pageContext?: string;
99
+ submittedBy?: ReportSubmitter;
100
+ screenshot?: ReportScreenshot;
67
101
  }
102
+ interface OplyticsService {
103
+ slug: string;
104
+ label: string;
105
+ }
106
+ /**
107
+ * The services a user can attribute feedback to. Kept here so every subdomain's
108
+ * picker shows the same list; a host can narrow or override it via the
109
+ * `services` prop. Slugs match Portal's `platform_feedback.serviceSlug`.
110
+ */
111
+ declare const OPLYTICS_SERVICES: OplyticsService[];
68
112
  interface ReportingToolbarConfig {
69
- /** Service/module name (e.g., "SQDCP", "OEE Manager") */
113
+ /** Service/module name (e.g. "SQDCP", "OEE Manager"). */
70
114
  moduleName: string;
71
- /** Whether to show incident reporting buttons (default: true) */
115
+ /** Whether to show the Report group at all (default: true). */
72
116
  showIncidentReporting?: boolean;
73
- /** Whether to show feedback buttons (default: true) */
117
+ /** Whether to show the Feedback group at all (default: true). */
74
118
  showFeedback?: boolean;
75
- /** Custom report categories to show (default: all three) */
119
+ /** Report categories to show (default: all three). */
76
120
  reportCategories?: ReportCategory[];
77
- /** Custom feedback categories to show (default: both) */
121
+ /** Feedback categories to show (default: both). */
78
122
  feedbackCategories?: FeedbackCategory[];
79
- /** Handler called when an incident report is submitted */
123
+ /** Called when an incident report is submitted (not wired yet). */
80
124
  onReportSubmit: (report: IncidentReport) => Promise<void> | void;
81
- /** Handler called when feedback is submitted */
125
+ /** Called when feedback is submitted — the host POSTs it to Portal. */
82
126
  onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;
83
127
  }
84
128
  interface ReportButtonDef {
@@ -95,14 +139,28 @@ interface FeedbackButtonDef {
95
139
  color: string;
96
140
  description: string;
97
141
  }
98
- /** Standard incident report buttons — consistent across all subdomains */
99
142
  declare const REPORT_BUTTONS: ReportButtonDef[];
100
- /** Standard feedback buttons — consistent across all subdomains */
101
143
  declare const FEEDBACK_BUTTONS: FeedbackButtonDef[];
102
- /** Create a default ReportingToolbarConfig with sensible defaults */
144
+ /** Create a default ReportingToolbarConfig with sensible defaults. */
103
145
  declare function createReportingConfig(moduleName: string, handlers: {
104
146
  onReportSubmit: (report: IncidentReport) => Promise<void> | void;
105
147
  onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;
106
148
  }): ReportingToolbarConfig;
149
+ /**
150
+ * Read a picked File into `{ dataBase64, mime }` (no data: prefix), rejecting
151
+ * non-images and anything over `maxBytes` decoded. Pure-ish (needs FileReader);
152
+ * exported so the size rule can be unit-tested and reused.
153
+ */
154
+ declare const FEEDBACK_SCREENSHOT_MAX_BYTES: number;
155
+ declare function isAcceptableScreenshot(file: {
156
+ type: string;
157
+ size: number;
158
+ }, maxBytes?: number): {
159
+ ok: true;
160
+ } | {
161
+ ok: false;
162
+ reason: string;
163
+ };
164
+ declare function readFileAsScreenshot(file: File): Promise<ReportScreenshot>;
107
165
 
108
- export { FEEDBACK_BUTTONS, type FeedbackButtonDef, type FeedbackCategory, type FeedbackReport, type IncidentReport, REPORT_BUTTONS, type ReportButtonDef, type ReportCategory, ReportingToolbar, type ReportingToolbarConfig, type ReportingToolbarProps, createReportingConfig };
166
+ export { FEEDBACK_BUTTONS, FEEDBACK_SCREENSHOT_MAX_BYTES, type FeedbackButtonDef, type FeedbackCategory, type FeedbackReport, type IncidentReport, OPLYTICS_SERVICES, type OplyticsService, REPORT_BUTTONS, type ReportButtonDef, type ReportCategory, type ReportHierarchyContext, type ReportScreenshot, type ReportSubmitter, ReportingToolbar, type ReportingToolbarConfig, type ReportingToolbarProps, createReportingConfig, isAcceptableScreenshot, readFileAsScreenshot };