@pablo2410/shared-ui 0.13.1 → 0.14.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.
- package/dist/{chunk-L2N36IW6.js → chunk-7I4ADEJY.js} +10 -10
- package/dist/chunk-7I4ADEJY.js.map +1 -0
- package/dist/{chunk-J7LWAIQK.js → chunk-CYIMXOQW.js} +37 -2
- package/dist/chunk-CYIMXOQW.js.map +1 -0
- package/dist/{chunk-HR77H6PE.js → chunk-NTFR5ZIF.js} +6 -6
- package/dist/{chunk-HR77H6PE.js.map → chunk-NTFR5ZIF.js.map} +1 -1
- package/dist/hierarchy/index.d.ts +35 -2
- package/dist/hierarchy/index.js +4 -2
- package/dist/layout/index.js +3 -3
- package/dist/primitives/index.js +1 -1
- package/dist/reporting/index.js +3 -3
- package/dist/reporting/index.js.map +1 -1
- package/dist/shell/index.js +3 -3
- package/dist/shell/oplytics-shell.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-J7LWAIQK.js.map +0 -1
- package/dist/chunk-L2N36IW6.js.map +0 -1
|
@@ -1,9 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as OrgHierarchyData, O as OrgHierarchySelection, b as OrgHierarchyContextValue } from '../orgHierarchy-BLW4dt8Q.js';
|
|
2
2
|
export { c as ORG_HIERARCHY_DATA_EMPTY, d as ORG_HIERARCHY_EMPTY, e as ORG_HIERARCHY_LABELS, f as ORG_HIERARCHY_LEVELS, g as OrgHierarchyArea, h as OrgHierarchyAsset, i as OrgHierarchyBusinessUnit, j as OrgHierarchyEnterprise, k as OrgHierarchyLevel, l as OrgHierarchyNode, m as OrgHierarchySite } from '../orgHierarchy-BLW4dt8Q.js';
|
|
3
3
|
export { ACTIVE_ENTERPRISE_COOKIE, applyEnterpriseOverride, scopeHierarchyToEnterprise } from './core.js';
|
|
4
4
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
5
|
import { ReactNode } from 'react';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* @oplytics/shared-ui/hierarchy — Hierarchy Attribution Code
|
|
9
|
+
*
|
|
10
|
+
* A human-readable, computed-not-stored label identifying which hierarchy
|
|
11
|
+
* node a piece of data belongs to: `E{enterpriseId}-B{ii}-S{ii}-A{ii}-X{iii}`.
|
|
12
|
+
*
|
|
13
|
+
* This is a *display/debug/attribution* label only — the permanent identity
|
|
14
|
+
* of every node stays its Portal-issued `int` id. Re-parenting a node changes
|
|
15
|
+
* its code (sibling index can shift) but never changes historical records,
|
|
16
|
+
* since nothing stores this string as a join key. Mirrors Policy Deployment's
|
|
17
|
+
* `generatePolicyCode` precedent: computed lineage, not stored structure.
|
|
18
|
+
*
|
|
19
|
+
* Sibling index is 1-based position when siblings are sorted by `id` —
|
|
20
|
+
* deterministic and stable, since there's no reorder-hierarchy UI that could
|
|
21
|
+
* change insertion order without changing the id.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
interface HierarchyCodeInput {
|
|
25
|
+
enterpriseId: number;
|
|
26
|
+
businessUnitId?: number | null;
|
|
27
|
+
siteId?: number | null;
|
|
28
|
+
areaId?: number | null;
|
|
29
|
+
assetId?: number | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Computes a hierarchy attribution code for a node, given the full org tree.
|
|
33
|
+
* Returns as much of the code as can be resolved — e.g. if `siteId` is set
|
|
34
|
+
* but not found in `tree.sites`, the code stops at the last resolved segment
|
|
35
|
+
* rather than throwing, since stale/cross-enterprise ids can occur during
|
|
36
|
+
* migration/backfill windows.
|
|
37
|
+
*/
|
|
38
|
+
declare function computeHierarchyCode(node: HierarchyCodeInput, tree: OrgHierarchyData): string;
|
|
39
|
+
|
|
7
40
|
/**
|
|
8
41
|
* selectionParams — serialize/deserialize the org-hierarchy selection through
|
|
9
42
|
* a URL query param so it can travel across subdomains (cross-service links).
|
|
@@ -124,4 +157,4 @@ interface HierarchyNavigatorProps {
|
|
|
124
157
|
}
|
|
125
158
|
declare function HierarchyNavigator({ hierarchy: ctx, compact, maxDepth, className, renderDropdown, }: HierarchyNavigatorProps): react_jsx_runtime.JSX.Element;
|
|
126
159
|
|
|
127
|
-
export { type CreateOrgHierarchyContextOptions, type DropdownRenderProps, HierarchyNavigator, type HierarchyNavigatorProps, ORG_HIERARCHY_PARAM, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchySelection, type OrgSelectionIds, appendSelectionParam, createOrgHierarchyContext, parseSelectionParam, readActiveEnterpriseCookie, readSelectionParamFromLocation, resolveSelectionFromIds, serializeSelectionParam, stripSelectionParamFromLocation };
|
|
160
|
+
export { type CreateOrgHierarchyContextOptions, type DropdownRenderProps, type HierarchyCodeInput, HierarchyNavigator, type HierarchyNavigatorProps, ORG_HIERARCHY_PARAM, OrgHierarchyContextValue, OrgHierarchyData, OrgHierarchySelection, type OrgSelectionIds, appendSelectionParam, computeHierarchyCode, createOrgHierarchyContext, parseSelectionParam, readActiveEnterpriseCookie, readSelectionParamFromLocation, resolveSelectionFromIds, serializeSelectionParam, stripSelectionParamFromLocation };
|
package/dist/hierarchy/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
HierarchyNavigator,
|
|
3
|
+
computeHierarchyCode,
|
|
3
4
|
createOrgHierarchyContext,
|
|
4
5
|
readActiveEnterpriseCookie
|
|
5
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-CYIMXOQW.js";
|
|
6
7
|
import {
|
|
7
8
|
ORG_HIERARCHY_PARAM,
|
|
8
9
|
appendSelectionParam,
|
|
@@ -23,7 +24,7 @@ import {
|
|
|
23
24
|
ORG_HIERARCHY_LABELS,
|
|
24
25
|
ORG_HIERARCHY_LEVELS
|
|
25
26
|
} from "../chunk-PS4K7FKB.js";
|
|
26
|
-
import "../chunk-
|
|
27
|
+
import "../chunk-NTFR5ZIF.js";
|
|
27
28
|
import "../chunk-JT3XLKKD.js";
|
|
28
29
|
import "../chunk-R4NOLCSI.js";
|
|
29
30
|
export {
|
|
@@ -36,6 +37,7 @@ export {
|
|
|
36
37
|
ORG_HIERARCHY_PARAM,
|
|
37
38
|
appendSelectionParam,
|
|
38
39
|
applyEnterpriseOverride,
|
|
40
|
+
computeHierarchyCode,
|
|
39
41
|
createOrgHierarchyContext,
|
|
40
42
|
parseSelectionParam,
|
|
41
43
|
readActiveEnterpriseCookie,
|
package/dist/layout/index.js
CHANGED
|
@@ -19,13 +19,13 @@ import {
|
|
|
19
19
|
policyDeploymentConfig,
|
|
20
20
|
sqdcpConfig,
|
|
21
21
|
useSidebarResize
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-7I4ADEJY.js";
|
|
23
23
|
import "../chunk-4QJMLQSH.js";
|
|
24
|
-
import "../chunk-
|
|
24
|
+
import "../chunk-CYIMXOQW.js";
|
|
25
25
|
import "../chunk-3E3GLIQV.js";
|
|
26
26
|
import "../chunk-3G43UG63.js";
|
|
27
27
|
import "../chunk-PS4K7FKB.js";
|
|
28
|
-
import "../chunk-
|
|
28
|
+
import "../chunk-NTFR5ZIF.js";
|
|
29
29
|
import "../chunk-JT3XLKKD.js";
|
|
30
30
|
import "../chunk-R4NOLCSI.js";
|
|
31
31
|
export {
|
package/dist/primitives/index.js
CHANGED
package/dist/reporting/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
SelectTrigger,
|
|
13
13
|
SelectValue,
|
|
14
14
|
Textarea
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-NTFR5ZIF.js";
|
|
16
16
|
import {
|
|
17
17
|
cn
|
|
18
18
|
} from "../chunk-JT3XLKKD.js";
|
|
@@ -197,7 +197,7 @@ function ReportingToolbar({
|
|
|
197
197
|
className: "h-9 gap-1.5 text-xs font-medium text-[#EF4444] hover:bg-[#EF4444]/10 hover:text-[#EF4444] border border-[#EF4444]/20",
|
|
198
198
|
children: [
|
|
199
199
|
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-3.5 w-3.5" }),
|
|
200
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Report" }),
|
|
200
|
+
/* @__PURE__ */ jsx("span", { className: "shell-hidden shell-sm:inline", children: "Report" }),
|
|
201
201
|
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" })
|
|
202
202
|
]
|
|
203
203
|
}
|
|
@@ -227,7 +227,7 @@ function ReportingToolbar({
|
|
|
227
227
|
className: "h-9 gap-1.5 text-xs font-medium text-[#8C34E9] hover:bg-[#8C34E9]/10 hover:text-[#8C34E9] border border-[#8C34E9]/20",
|
|
228
228
|
children: [
|
|
229
229
|
/* @__PURE__ */ jsx(Lightbulb, { className: "h-3.5 w-3.5" }),
|
|
230
|
-
/* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: "Feedback" }),
|
|
230
|
+
/* @__PURE__ */ jsx("span", { className: "shell-hidden shell-sm:inline", children: "Feedback" }),
|
|
231
231
|
/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" })
|
|
232
232
|
]
|
|
233
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/reporting/ReportingToolbar.tsx","../../src/reporting/index.ts"],"sourcesContent":["/**\n * ReportingToolbar — standard Safety / Environmental / Stop Work incident\n * reporting and Problem / Suggestion feedback for all Oplytics subdomains.\n *\n * Visual model — two grouped dropdown buttons in the top-right of the header:\n * ⚠ Report ▾ → Safety Incident | Environmental | Stop Work\n * 💡 Feedback ▾ → Report Problem | Suggestion\n *\n * Selecting an option opens a self-contained dialog with the right form for\n * that report/feedback type (severity / location / description / immediate\n * action for incidents; subject / description for feedback). On submit the\n * configured `onReportSubmit` / `onFeedbackSubmit` handler is called with\n * the canonical `IncidentReport` / `FeedbackReport` shape.\n *\n * Ported from the Policy Deployment subdomain — the canonical visual\n * reference. Replaces the previous headless / individual-icon-button design.\n *\n * Oplytics dark theme: #0A0E1A bg, #8C34E9 accent.\n */\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport {\n Button,\n Badge,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Input,\n Label,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../primitives\";\nimport {\n ShieldAlert,\n Leaf,\n OctagonX,\n Bug,\n Lightbulb,\n ChevronDown,\n Send,\n AlertTriangle,\n} from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport type {\n ReportCategory,\n FeedbackCategory,\n IncidentReport,\n FeedbackReport,\n ReportingToolbarConfig,\n} from \"./index\";\n\n/* ── Report / feedback option catalogues ── */\n\ninterface ReportOption {\n category: ReportCategory;\n label: string;\n description: string;\n icon: React.ElementType;\n color: string;\n}\n\ninterface FeedbackOption {\n category: FeedbackCategory;\n label: string;\n description: string;\n icon: React.ElementType;\n color: string;\n}\n\nconst ALL_REPORT_OPTIONS: ReportOption[] = [\n {\n category: \"safety\",\n label: \"Safety Incident\",\n description: \"Report a safety hazard, near miss, or injury\",\n icon: ShieldAlert,\n color: \"#EF4444\",\n },\n {\n category: \"environmental\",\n label: \"Environmental\",\n description: \"Report an environmental concern or spill\",\n icon: Leaf,\n color: \"#22C55E\",\n },\n {\n category: \"stop-work\",\n label: \"Stop Work\",\n description: \"Raise a stop work authority — immediate halt\",\n icon: OctagonX,\n color: \"#F59E0B\",\n },\n];\n\nconst ALL_FEEDBACK_OPTIONS: FeedbackOption[] = [\n {\n category: \"problem\",\n label: \"Report Problem\",\n description: \"Something isn't working\",\n icon: Bug,\n color: \"#EF4444\",\n },\n {\n category: \"suggestion\",\n label: \"Suggestion\",\n description: \"Idea for improvement\",\n icon: Lightbulb,\n color: \"#8C34E9\",\n },\n];\n\nconst SEVERITY_OPTIONS: {\n value: NonNullable<IncidentReport[\"severity\"]>;\n label: string;\n color: string;\n}[] = [\n { value: \"critical\", label: \"Critical\", color: \"#EF4444\" },\n { value: \"high\", label: \"High\", color: \"#F59E0B\" },\n { value: \"medium\", label: \"Medium\", color: \"#3b82f6\" },\n { value: \"low\", label: \"Low\", color: \"#22C55E\" },\n];\n\n/* ── Props ── */\n\nexport interface ReportingToolbarProps extends Omit<ReportingToolbarConfig, \"moduleName\"> {\n /** Service/module name (e.g. \"Connect\", \"Policy Deployment\"). Defaults to \"Oplytics\". */\n moduleName?: string;\n /** Optional pre-fill for the report dialog's Location/Area field. */\n defaultLocation?: string;\n /**\n * Compact mode — currently a no-op (the new design always responsive-collapses\n * the labels at small breakpoints). Kept on the prop type so callers that\n * still pass it continue to type-check.\n * @deprecated The toolbar handles responsive collapse on its own.\n */\n compact?: boolean;\n /** CSS class for the container. */\n className?: string;\n}\n\n/* ── Component ── */\n\nexport function ReportingToolbar({\n moduleName = \"Oplytics\",\n showIncidentReporting = true,\n showFeedback = true,\n reportCategories = [\"safety\", \"environmental\", \"stop-work\"],\n feedbackCategories = [\"problem\", \"suggestion\"],\n onReportSubmit,\n onFeedbackSubmit,\n defaultLocation = \"\",\n className,\n}: ReportingToolbarProps) {\n const reportOptions = ALL_REPORT_OPTIONS.filter((opt) =>\n reportCategories.includes(opt.category),\n );\n const feedbackOptions = ALL_FEEDBACK_OPTIONS.filter((opt) =>\n feedbackCategories.includes(opt.category),\n );\n\n /* ── Report dialog state ── */\n const [reportDialogOpen, setReportDialogOpen] = useState(false);\n const [selectedReportCategory, setSelectedReportCategory] =\n useState<ReportCategory>(\"safety\");\n const [reportSeverity, setReportSeverity] =\n useState<NonNullable<IncidentReport[\"severity\"]>>(\"medium\");\n const [reportLocation, setReportLocation] = useState(defaultLocation);\n const [reportDescription, setReportDescription] = useState(\"\");\n const [reportImmediateAction, setReportImmediateAction] = useState(\"\");\n\n /* ── Feedback dialog state ── */\n const [feedbackDialogOpen, setFeedbackDialogOpen] = useState(false);\n const [selectedFeedbackCategory, setSelectedFeedbackCategory] =\n useState<FeedbackCategory>(\"problem\");\n const [feedbackSubject, setFeedbackSubject] = useState(\"\");\n const [feedbackDescription, setFeedbackDescription] = useState(\"\");\n\n const [submitting, setSubmitting] = useState(false);\n\n const openReportDialog = (category: ReportCategory) => {\n setSelectedReportCategory(category);\n setReportSeverity(category === \"stop-work\" ? \"critical\" : \"medium\");\n setReportLocation(defaultLocation);\n setReportDescription(\"\");\n setReportImmediateAction(\"\");\n setReportDialogOpen(true);\n };\n\n const openFeedbackDialog = (category: FeedbackCategory) => {\n setSelectedFeedbackCategory(category);\n setFeedbackSubject(\"\");\n setFeedbackDescription(\"\");\n setFeedbackDialogOpen(true);\n };\n\n const handleReportSubmit = async () => {\n if (!reportDescription.trim()) {\n toast.error(\"Please provide a description\");\n return;\n }\n setSubmitting(true);\n try {\n const report: IncidentReport = {\n category: selectedReportCategory,\n description: reportDescription,\n location: reportLocation || undefined,\n severity: reportSeverity,\n immediateAction: reportImmediateAction || undefined,\n moduleName,\n timestamp: new Date().toISOString(),\n };\n await onReportSubmit(report);\n toast.success(\"Report submitted successfully\", {\n description:\n selectedReportCategory === \"stop-work\"\n ? \"Stop Work authority raised — management has been notified\"\n : \"Your report has been logged and assigned for review\",\n });\n setReportDialogOpen(false);\n } catch (err) {\n console.error(\"[ReportingToolbar] report submit failed:\", err);\n toast.error(\"Failed to submit report. Please try again.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleFeedbackSubmit = async () => {\n if (!feedbackDescription.trim()) {\n toast.error(\"Please provide a description\");\n return;\n }\n setSubmitting(true);\n try {\n const feedback: FeedbackReport = {\n category: selectedFeedbackCategory,\n subject: feedbackSubject || undefined,\n description: feedbackDescription,\n moduleName,\n timestamp: new Date().toISOString(),\n pageContext:\n typeof window !== \"undefined\" ? window.location.pathname : undefined,\n };\n await onFeedbackSubmit(feedback);\n toast.success(\n selectedFeedbackCategory === \"problem\"\n ? \"Problem reported — Oplytics team will review\"\n : \"Suggestion submitted — thank you for your feedback\",\n );\n setFeedbackDialogOpen(false);\n } catch (err) {\n console.error(\"[ReportingToolbar] feedback submit failed:\", err);\n toast.error(\"Failed to submit feedback. Please try again.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const reportConfig = ALL_REPORT_OPTIONS.find(\n (r) => r.category === selectedReportCategory,\n );\n\n return (\n <>\n {/* Toolbar buttons */}\n <div className={cn(\"flex items-center gap-2\", className)}>\n {/* Report dropdown */}\n {showIncidentReporting && reportOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 gap-1.5 text-xs font-medium text-[#EF4444] hover:bg-[#EF4444]/10 hover:text-[#EF4444] border border-[#EF4444]/20\"\n >\n <AlertTriangle className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">Report</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {reportOptions.map((opt) => (\n <DropdownMenuItem\n key={opt.category}\n onClick={() => openReportDialog(opt.category)}\n className=\"gap-3 py-2.5\"\n >\n <opt.icon className=\"h-4 w-4\" style={{ color: opt.color }} />\n <div>\n <p className=\"text-sm font-medium\">{opt.label}</p>\n <p className=\"text-[10px] text-muted-foreground\">{opt.description}</p>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Feedback dropdown */}\n {showFeedback && feedbackOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 gap-1.5 text-xs font-medium text-[#8C34E9] hover:bg-[#8C34E9]/10 hover:text-[#8C34E9] border border-[#8C34E9]/20\"\n >\n <Lightbulb className=\"h-3.5 w-3.5\" />\n <span className=\"hidden sm:inline\">Feedback</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n {feedbackOptions.map((opt, idx) => (\n <span key={opt.category}>\n {idx > 0 && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => openFeedbackDialog(opt.category)}\n className=\"gap-3 py-2.5\"\n >\n <opt.icon className=\"h-4 w-4\" style={{ color: opt.color }} />\n <div>\n <p className=\"text-sm font-medium\">{opt.label}</p>\n <p className=\"text-[10px] text-muted-foreground\">{opt.description}</p>\n </div>\n </DropdownMenuItem>\n </span>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n\n {/* Report Dialog */}\n <Dialog open={reportDialogOpen} onOpenChange={setReportDialogOpen}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n {reportConfig && (\n <reportConfig.icon className=\"h-5 w-5\" style={{ color: reportConfig.color }} />\n )}\n {reportConfig?.label || \"Report\"}\n {selectedReportCategory === \"stop-work\" && (\n <Badge className=\"bg-[#F59E0B] text-white text-[9px] border-0\">URGENT</Badge>\n )}\n </DialogTitle>\n <DialogDescription>\n {reportConfig?.description}. All reports are logged and tracked.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Severity</Label>\n <Select\n value={reportSeverity}\n onValueChange={(v) =>\n setReportSeverity(v as NonNullable<IncidentReport[\"severity\"]>)\n }\n >\n <SelectTrigger className=\"h-9\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SEVERITY_OPTIONS.map((s) => (\n <SelectItem key={s.value} value={s.value}>\n <div className=\"flex items-center gap-2\">\n <div\n className=\"h-2 w-2 rounded-full\"\n style={{ backgroundColor: s.color }}\n />\n {s.label}\n </div>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Location / Area</Label>\n <Input\n value={reportLocation}\n onChange={(e) => setReportLocation(e.target.value)}\n placeholder=\"e.g., Production Line 3, Warehouse B\"\n className=\"h-9\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Description *</Label>\n <Textarea\n value={reportDescription}\n onChange={(e) => setReportDescription(e.target.value)}\n placeholder=\"Describe what happened or what you observed...\"\n rows={4}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Immediate Action Taken</Label>\n <Textarea\n value={reportImmediateAction}\n onChange={(e) => setReportImmediateAction(e.target.value)}\n placeholder=\"Describe any immediate action taken to make the area safe...\"\n rows={2}\n />\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setReportDialogOpen(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleReportSubmit}\n disabled={submitting || !reportDescription.trim()}\n className=\"gap-2\"\n style={{\n backgroundColor: reportConfig?.color,\n color: \"white\",\n }}\n >\n <Send className=\"h-3.5 w-3.5\" />\n {submitting ? \"Submitting...\" : \"Submit Report\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Feedback Dialog */}\n <Dialog open={feedbackDialogOpen} onOpenChange={setFeedbackDialogOpen}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n {selectedFeedbackCategory === \"problem\" ? (\n <Bug className=\"h-5 w-5 text-[#EF4444]\" />\n ) : (\n <Lightbulb className=\"h-5 w-5 text-[#8C34E9]\" />\n )}\n {selectedFeedbackCategory === \"problem\"\n ? \"Report a Problem\"\n : \"Submit a Suggestion\"}\n </DialogTitle>\n <DialogDescription>\n {selectedFeedbackCategory === \"problem\"\n ? \"Help us fix issues — describe what went wrong.\"\n : \"We'd love to hear your ideas for improving Oplytics.\"}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Subject</Label>\n <Input\n value={feedbackSubject}\n onChange={(e) => setFeedbackSubject(e.target.value)}\n placeholder={\n selectedFeedbackCategory === \"problem\"\n ? \"Brief summary of the issue\"\n : \"Brief summary of your idea\"\n }\n className=\"h-9\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Description *</Label>\n <Textarea\n value={feedbackDescription}\n onChange={(e) => setFeedbackDescription(e.target.value)}\n placeholder={\n selectedFeedbackCategory === \"problem\"\n ? \"What were you trying to do? What happened instead?\"\n : \"Describe your suggestion and how it would help...\"\n }\n rows={5}\n />\n </div>\n\n <div className=\"text-[10px] text-muted-foreground\">\n Module: {moduleName} — Feedback is reviewed by the Oplytics team\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setFeedbackDialogOpen(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleFeedbackSubmit}\n disabled={submitting || !feedbackDescription.trim()}\n className=\"gap-2\"\n style={{\n backgroundColor:\n selectedFeedbackCategory === \"problem\" ? \"#EF4444\" : \"#8C34E9\",\n color: \"white\",\n }}\n >\n <Send className=\"h-3.5 w-3.5\" />\n {submitting ? \"Submitting...\" : \"Submit\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","/**\n * @oplytics/shared-ui/reporting\n *\n * Reporting and feedback toolbar types and configuration for all Oplytics subdomains.\n * Provides the standard Safety/Environmental/Stop Work incident reporting buttons\n * and Problem/Suggestion feedback buttons.\n *\n * The actual ReportingToolbar React component depends on shadcn/ui primitives\n * (Dialog, Button, Textarea, Select) which vary across subdomains until\n * consolidation. This module provides the types, configuration, and submission\n * logic that are shared.\n */\n\n// ─── Report Types ────────────────────────────────────────────────────────────\n\nexport type ReportCategory = \"safety\" | \"environmental\" | \"stop-work\";\nexport type FeedbackCategory = \"problem\" | \"suggestion\";\n\nexport interface IncidentReport {\n category: ReportCategory;\n description: string;\n location?: string;\n severity?: \"low\" | \"medium\" | \"high\" | \"critical\";\n /** Optional — what was done at the scene to make the area safe. */\n immediateAction?: string;\n moduleName: string;\n /** ISO timestamp */\n timestamp: string;\n /** User who submitted */\n submittedBy?: string;\n /** Hierarchy context at time of submission */\n hierarchyContext?: {\n enterpriseId?: number;\n businessUnitId?: number;\n siteId?: number;\n areaId?: number;\n assetId?: number;\n };\n}\n\nexport interface FeedbackReport {\n category: FeedbackCategory;\n /** Optional — short summary entered in the dialog before the description. */\n subject?: string;\n description: string;\n moduleName: string;\n /** ISO timestamp */\n timestamp: string;\n /** User who submitted */\n submittedBy?: string;\n /** Page/route where feedback was submitted */\n pageContext?: string;\n}\n\n// ─── Toolbar Configuration ───────────────────────────────────────────────────\n\nexport interface ReportingToolbarConfig {\n /** Service/module name (e.g., \"SQDCP\", \"OEE Manager\") */\n moduleName: string;\n /** Whether to show incident reporting buttons (default: true) */\n showIncidentReporting?: boolean;\n /** Whether to show feedback buttons (default: true) */\n showFeedback?: boolean;\n /** Custom report categories to show (default: all three) */\n reportCategories?: ReportCategory[];\n /** Custom feedback categories to show (default: both) */\n feedbackCategories?: FeedbackCategory[];\n /** Handler called when an incident report is submitted */\n onReportSubmit: (report: IncidentReport) => Promise<void> | void;\n /** Handler called when feedback is submitted */\n onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;\n}\n\n// ─── Report Button Definitions ───────────────────────────────────────────────\n\nexport interface ReportButtonDef {\n category: ReportCategory;\n label: string;\n iconName: string;\n color: string;\n description: string;\n}\n\nexport interface FeedbackButtonDef {\n category: FeedbackCategory;\n label: string;\n iconName: string;\n color: string;\n description: string;\n}\n\n/** Standard incident report buttons — consistent across all subdomains */\nexport const REPORT_BUTTONS: ReportButtonDef[] = [\n {\n category: \"safety\",\n label: \"Safety\",\n iconName: \"ShieldAlert\",\n color: \"#ef4444\",\n description: \"Report a safety incident, near-miss, or hazard\",\n },\n {\n category: \"environmental\",\n label: \"Environmental\",\n iconName: \"Leaf\",\n color: \"#22c55e\",\n description: \"Report an environmental incident or concern\",\n },\n {\n category: \"stop-work\",\n label: \"Stop Work\",\n iconName: \"OctagonX\",\n color: \"#f59e0b\",\n description: \"Raise a stop work authority — immediate safety concern\",\n },\n];\n\n/** Standard feedback buttons — consistent across all subdomains */\nexport const FEEDBACK_BUTTONS: FeedbackButtonDef[] = [\n {\n category: \"problem\",\n label: \"Problem\",\n iconName: \"AlertTriangle\",\n color: \"#ef4444\",\n description: \"Report a problem with the platform\",\n },\n {\n category: \"suggestion\",\n label: \"Suggestion\",\n iconName: \"Lightbulb\",\n color: \"#8C34E9\",\n description: \"Suggest an improvement or new feature\",\n },\n];\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/** Create a default ReportingToolbarConfig with sensible defaults */\nexport function createReportingConfig(\n moduleName: string,\n handlers: {\n onReportSubmit: (report: IncidentReport) => Promise<void> | void;\n onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;\n },\n): ReportingToolbarConfig {\n return {\n moduleName,\n showIncidentReporting: true,\n showFeedback: true,\n reportCategories: [\"safety\", \"environmental\", \"stop-work\"],\n feedbackCategories: [\"problem\", \"suggestion\"],\n ...handlers,\n };\n}\n\n// ─── ReportingToolbar Component ─────────────────────────────────────────────\n\nexport {\n ReportingToolbar,\n type ReportingToolbarProps,\n} from \"./ReportingToolbar\";\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/reporting/ReportingToolbar.tsx","../../src/reporting/index.ts"],"sourcesContent":["/**\n * ReportingToolbar — standard Safety / Environmental / Stop Work incident\n * reporting and Problem / Suggestion feedback for all Oplytics subdomains.\n *\n * Visual model — two grouped dropdown buttons in the top-right of the header:\n * ⚠ Report ▾ → Safety Incident | Environmental | Stop Work\n * 💡 Feedback ▾ → Report Problem | Suggestion\n *\n * Selecting an option opens a self-contained dialog with the right form for\n * that report/feedback type (severity / location / description / immediate\n * action for incidents; subject / description for feedback). On submit the\n * configured `onReportSubmit` / `onFeedbackSubmit` handler is called with\n * the canonical `IncidentReport` / `FeedbackReport` shape.\n *\n * Ported from the Policy Deployment subdomain — the canonical visual\n * reference. Replaces the previous headless / individual-icon-button design.\n *\n * Oplytics dark theme: #0A0E1A bg, #8C34E9 accent.\n */\nimport { useState } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport {\n Button,\n Badge,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Input,\n Label,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogFooter,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"../primitives\";\nimport {\n ShieldAlert,\n Leaf,\n OctagonX,\n Bug,\n Lightbulb,\n ChevronDown,\n Send,\n AlertTriangle,\n} from \"lucide-react\";\nimport { toast } from \"sonner\";\nimport type {\n ReportCategory,\n FeedbackCategory,\n IncidentReport,\n FeedbackReport,\n ReportingToolbarConfig,\n} from \"./index\";\n\n/* ── Report / feedback option catalogues ── */\n\ninterface ReportOption {\n category: ReportCategory;\n label: string;\n description: string;\n icon: React.ElementType;\n color: string;\n}\n\ninterface FeedbackOption {\n category: FeedbackCategory;\n label: string;\n description: string;\n icon: React.ElementType;\n color: string;\n}\n\nconst ALL_REPORT_OPTIONS: ReportOption[] = [\n {\n category: \"safety\",\n label: \"Safety Incident\",\n description: \"Report a safety hazard, near miss, or injury\",\n icon: ShieldAlert,\n color: \"#EF4444\",\n },\n {\n category: \"environmental\",\n label: \"Environmental\",\n description: \"Report an environmental concern or spill\",\n icon: Leaf,\n color: \"#22C55E\",\n },\n {\n category: \"stop-work\",\n label: \"Stop Work\",\n description: \"Raise a stop work authority — immediate halt\",\n icon: OctagonX,\n color: \"#F59E0B\",\n },\n];\n\nconst ALL_FEEDBACK_OPTIONS: FeedbackOption[] = [\n {\n category: \"problem\",\n label: \"Report Problem\",\n description: \"Something isn't working\",\n icon: Bug,\n color: \"#EF4444\",\n },\n {\n category: \"suggestion\",\n label: \"Suggestion\",\n description: \"Idea for improvement\",\n icon: Lightbulb,\n color: \"#8C34E9\",\n },\n];\n\nconst SEVERITY_OPTIONS: {\n value: NonNullable<IncidentReport[\"severity\"]>;\n label: string;\n color: string;\n}[] = [\n { value: \"critical\", label: \"Critical\", color: \"#EF4444\" },\n { value: \"high\", label: \"High\", color: \"#F59E0B\" },\n { value: \"medium\", label: \"Medium\", color: \"#3b82f6\" },\n { value: \"low\", label: \"Low\", color: \"#22C55E\" },\n];\n\n/* ── Props ── */\n\nexport interface ReportingToolbarProps extends Omit<ReportingToolbarConfig, \"moduleName\"> {\n /** Service/module name (e.g. \"Connect\", \"Policy Deployment\"). Defaults to \"Oplytics\". */\n moduleName?: string;\n /** Optional pre-fill for the report dialog's Location/Area field. */\n defaultLocation?: string;\n /**\n * Compact mode — currently a no-op (the new design always responsive-collapses\n * the labels at small breakpoints). Kept on the prop type so callers that\n * still pass it continue to type-check.\n * @deprecated The toolbar handles responsive collapse on its own.\n */\n compact?: boolean;\n /** CSS class for the container. */\n className?: string;\n}\n\n/* ── Component ── */\n\nexport function ReportingToolbar({\n moduleName = \"Oplytics\",\n showIncidentReporting = true,\n showFeedback = true,\n reportCategories = [\"safety\", \"environmental\", \"stop-work\"],\n feedbackCategories = [\"problem\", \"suggestion\"],\n onReportSubmit,\n onFeedbackSubmit,\n defaultLocation = \"\",\n className,\n}: ReportingToolbarProps) {\n const reportOptions = ALL_REPORT_OPTIONS.filter((opt) =>\n reportCategories.includes(opt.category),\n );\n const feedbackOptions = ALL_FEEDBACK_OPTIONS.filter((opt) =>\n feedbackCategories.includes(opt.category),\n );\n\n /* ── Report dialog state ── */\n const [reportDialogOpen, setReportDialogOpen] = useState(false);\n const [selectedReportCategory, setSelectedReportCategory] =\n useState<ReportCategory>(\"safety\");\n const [reportSeverity, setReportSeverity] =\n useState<NonNullable<IncidentReport[\"severity\"]>>(\"medium\");\n const [reportLocation, setReportLocation] = useState(defaultLocation);\n const [reportDescription, setReportDescription] = useState(\"\");\n const [reportImmediateAction, setReportImmediateAction] = useState(\"\");\n\n /* ── Feedback dialog state ── */\n const [feedbackDialogOpen, setFeedbackDialogOpen] = useState(false);\n const [selectedFeedbackCategory, setSelectedFeedbackCategory] =\n useState<FeedbackCategory>(\"problem\");\n const [feedbackSubject, setFeedbackSubject] = useState(\"\");\n const [feedbackDescription, setFeedbackDescription] = useState(\"\");\n\n const [submitting, setSubmitting] = useState(false);\n\n const openReportDialog = (category: ReportCategory) => {\n setSelectedReportCategory(category);\n setReportSeverity(category === \"stop-work\" ? \"critical\" : \"medium\");\n setReportLocation(defaultLocation);\n setReportDescription(\"\");\n setReportImmediateAction(\"\");\n setReportDialogOpen(true);\n };\n\n const openFeedbackDialog = (category: FeedbackCategory) => {\n setSelectedFeedbackCategory(category);\n setFeedbackSubject(\"\");\n setFeedbackDescription(\"\");\n setFeedbackDialogOpen(true);\n };\n\n const handleReportSubmit = async () => {\n if (!reportDescription.trim()) {\n toast.error(\"Please provide a description\");\n return;\n }\n setSubmitting(true);\n try {\n const report: IncidentReport = {\n category: selectedReportCategory,\n description: reportDescription,\n location: reportLocation || undefined,\n severity: reportSeverity,\n immediateAction: reportImmediateAction || undefined,\n moduleName,\n timestamp: new Date().toISOString(),\n };\n await onReportSubmit(report);\n toast.success(\"Report submitted successfully\", {\n description:\n selectedReportCategory === \"stop-work\"\n ? \"Stop Work authority raised — management has been notified\"\n : \"Your report has been logged and assigned for review\",\n });\n setReportDialogOpen(false);\n } catch (err) {\n console.error(\"[ReportingToolbar] report submit failed:\", err);\n toast.error(\"Failed to submit report. Please try again.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const handleFeedbackSubmit = async () => {\n if (!feedbackDescription.trim()) {\n toast.error(\"Please provide a description\");\n return;\n }\n setSubmitting(true);\n try {\n const feedback: FeedbackReport = {\n category: selectedFeedbackCategory,\n subject: feedbackSubject || undefined,\n description: feedbackDescription,\n moduleName,\n timestamp: new Date().toISOString(),\n pageContext:\n typeof window !== \"undefined\" ? window.location.pathname : undefined,\n };\n await onFeedbackSubmit(feedback);\n toast.success(\n selectedFeedbackCategory === \"problem\"\n ? \"Problem reported — Oplytics team will review\"\n : \"Suggestion submitted — thank you for your feedback\",\n );\n setFeedbackDialogOpen(false);\n } catch (err) {\n console.error(\"[ReportingToolbar] feedback submit failed:\", err);\n toast.error(\"Failed to submit feedback. Please try again.\");\n } finally {\n setSubmitting(false);\n }\n };\n\n const reportConfig = ALL_REPORT_OPTIONS.find(\n (r) => r.category === selectedReportCategory,\n );\n\n return (\n <>\n {/* Toolbar buttons */}\n <div className={cn(\"flex items-center gap-2\", className)}>\n {/* Report dropdown */}\n {showIncidentReporting && reportOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 gap-1.5 text-xs font-medium text-[#EF4444] hover:bg-[#EF4444]/10 hover:text-[#EF4444] border border-[#EF4444]/20\"\n >\n <AlertTriangle className=\"h-3.5 w-3.5\" />\n <span className=\"shell-hidden shell-sm:inline\">Report</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {reportOptions.map((opt) => (\n <DropdownMenuItem\n key={opt.category}\n onClick={() => openReportDialog(opt.category)}\n className=\"gap-3 py-2.5\"\n >\n <opt.icon className=\"h-4 w-4\" style={{ color: opt.color }} />\n <div>\n <p className=\"text-sm font-medium\">{opt.label}</p>\n <p className=\"text-[10px] text-muted-foreground\">{opt.description}</p>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n\n {/* Feedback dropdown */}\n {showFeedback && feedbackOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 gap-1.5 text-xs font-medium text-[#8C34E9] hover:bg-[#8C34E9]/10 hover:text-[#8C34E9] border border-[#8C34E9]/20\"\n >\n <Lightbulb className=\"h-3.5 w-3.5\" />\n <span className=\"shell-hidden shell-sm:inline\">Feedback</span>\n <ChevronDown className=\"h-3 w-3\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n {feedbackOptions.map((opt, idx) => (\n <span key={opt.category}>\n {idx > 0 && <DropdownMenuSeparator />}\n <DropdownMenuItem\n onClick={() => openFeedbackDialog(opt.category)}\n className=\"gap-3 py-2.5\"\n >\n <opt.icon className=\"h-4 w-4\" style={{ color: opt.color }} />\n <div>\n <p className=\"text-sm font-medium\">{opt.label}</p>\n <p className=\"text-[10px] text-muted-foreground\">{opt.description}</p>\n </div>\n </DropdownMenuItem>\n </span>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n </div>\n\n {/* Report Dialog */}\n <Dialog open={reportDialogOpen} onOpenChange={setReportDialogOpen}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n {reportConfig && (\n <reportConfig.icon className=\"h-5 w-5\" style={{ color: reportConfig.color }} />\n )}\n {reportConfig?.label || \"Report\"}\n {selectedReportCategory === \"stop-work\" && (\n <Badge className=\"bg-[#F59E0B] text-white text-[9px] border-0\">URGENT</Badge>\n )}\n </DialogTitle>\n <DialogDescription>\n {reportConfig?.description}. All reports are logged and tracked.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Severity</Label>\n <Select\n value={reportSeverity}\n onValueChange={(v) =>\n setReportSeverity(v as NonNullable<IncidentReport[\"severity\"]>)\n }\n >\n <SelectTrigger className=\"h-9\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SEVERITY_OPTIONS.map((s) => (\n <SelectItem key={s.value} value={s.value}>\n <div className=\"flex items-center gap-2\">\n <div\n className=\"h-2 w-2 rounded-full\"\n style={{ backgroundColor: s.color }}\n />\n {s.label}\n </div>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Location / Area</Label>\n <Input\n value={reportLocation}\n onChange={(e) => setReportLocation(e.target.value)}\n placeholder=\"e.g., Production Line 3, Warehouse B\"\n className=\"h-9\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Description *</Label>\n <Textarea\n value={reportDescription}\n onChange={(e) => setReportDescription(e.target.value)}\n placeholder=\"Describe what happened or what you observed...\"\n rows={4}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Immediate Action Taken</Label>\n <Textarea\n value={reportImmediateAction}\n onChange={(e) => setReportImmediateAction(e.target.value)}\n placeholder=\"Describe any immediate action taken to make the area safe...\"\n rows={2}\n />\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setReportDialogOpen(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleReportSubmit}\n disabled={submitting || !reportDescription.trim()}\n className=\"gap-2\"\n style={{\n backgroundColor: reportConfig?.color,\n color: \"white\",\n }}\n >\n <Send className=\"h-3.5 w-3.5\" />\n {submitting ? \"Submitting...\" : \"Submit Report\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Feedback Dialog */}\n <Dialog open={feedbackDialogOpen} onOpenChange={setFeedbackDialogOpen}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n {selectedFeedbackCategory === \"problem\" ? (\n <Bug className=\"h-5 w-5 text-[#EF4444]\" />\n ) : (\n <Lightbulb className=\"h-5 w-5 text-[#8C34E9]\" />\n )}\n {selectedFeedbackCategory === \"problem\"\n ? \"Report a Problem\"\n : \"Submit a Suggestion\"}\n </DialogTitle>\n <DialogDescription>\n {selectedFeedbackCategory === \"problem\"\n ? \"Help us fix issues — describe what went wrong.\"\n : \"We'd love to hear your ideas for improving Oplytics.\"}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Subject</Label>\n <Input\n value={feedbackSubject}\n onChange={(e) => setFeedbackSubject(e.target.value)}\n placeholder={\n selectedFeedbackCategory === \"problem\"\n ? \"Brief summary of the issue\"\n : \"Brief summary of your idea\"\n }\n className=\"h-9\"\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label className=\"text-xs font-medium\">Description *</Label>\n <Textarea\n value={feedbackDescription}\n onChange={(e) => setFeedbackDescription(e.target.value)}\n placeholder={\n selectedFeedbackCategory === \"problem\"\n ? \"What were you trying to do? What happened instead?\"\n : \"Describe your suggestion and how it would help...\"\n }\n rows={5}\n />\n </div>\n\n <div className=\"text-[10px] text-muted-foreground\">\n Module: {moduleName} — Feedback is reviewed by the Oplytics team\n </div>\n </div>\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setFeedbackDialogOpen(false)}>\n Cancel\n </Button>\n <Button\n onClick={handleFeedbackSubmit}\n disabled={submitting || !feedbackDescription.trim()}\n className=\"gap-2\"\n style={{\n backgroundColor:\n selectedFeedbackCategory === \"problem\" ? \"#EF4444\" : \"#8C34E9\",\n color: \"white\",\n }}\n >\n <Send className=\"h-3.5 w-3.5\" />\n {submitting ? \"Submitting...\" : \"Submit\"}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n","/**\n * @oplytics/shared-ui/reporting\n *\n * Reporting and feedback toolbar types and configuration for all Oplytics subdomains.\n * Provides the standard Safety/Environmental/Stop Work incident reporting buttons\n * and Problem/Suggestion feedback buttons.\n *\n * The actual ReportingToolbar React component depends on shadcn/ui primitives\n * (Dialog, Button, Textarea, Select) which vary across subdomains until\n * consolidation. This module provides the types, configuration, and submission\n * logic that are shared.\n */\n\n// ─── Report Types ────────────────────────────────────────────────────────────\n\nexport type ReportCategory = \"safety\" | \"environmental\" | \"stop-work\";\nexport type FeedbackCategory = \"problem\" | \"suggestion\";\n\nexport interface IncidentReport {\n category: ReportCategory;\n description: string;\n location?: string;\n severity?: \"low\" | \"medium\" | \"high\" | \"critical\";\n /** Optional — what was done at the scene to make the area safe. */\n immediateAction?: string;\n moduleName: string;\n /** ISO timestamp */\n timestamp: string;\n /** User who submitted */\n submittedBy?: string;\n /** Hierarchy context at time of submission */\n hierarchyContext?: {\n enterpriseId?: number;\n businessUnitId?: number;\n siteId?: number;\n areaId?: number;\n assetId?: number;\n };\n}\n\nexport interface FeedbackReport {\n category: FeedbackCategory;\n /** Optional — short summary entered in the dialog before the description. */\n subject?: string;\n description: string;\n moduleName: string;\n /** ISO timestamp */\n timestamp: string;\n /** User who submitted */\n submittedBy?: string;\n /** Page/route where feedback was submitted */\n pageContext?: string;\n}\n\n// ─── Toolbar Configuration ───────────────────────────────────────────────────\n\nexport interface ReportingToolbarConfig {\n /** Service/module name (e.g., \"SQDCP\", \"OEE Manager\") */\n moduleName: string;\n /** Whether to show incident reporting buttons (default: true) */\n showIncidentReporting?: boolean;\n /** Whether to show feedback buttons (default: true) */\n showFeedback?: boolean;\n /** Custom report categories to show (default: all three) */\n reportCategories?: ReportCategory[];\n /** Custom feedback categories to show (default: both) */\n feedbackCategories?: FeedbackCategory[];\n /** Handler called when an incident report is submitted */\n onReportSubmit: (report: IncidentReport) => Promise<void> | void;\n /** Handler called when feedback is submitted */\n onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;\n}\n\n// ─── Report Button Definitions ───────────────────────────────────────────────\n\nexport interface ReportButtonDef {\n category: ReportCategory;\n label: string;\n iconName: string;\n color: string;\n description: string;\n}\n\nexport interface FeedbackButtonDef {\n category: FeedbackCategory;\n label: string;\n iconName: string;\n color: string;\n description: string;\n}\n\n/** Standard incident report buttons — consistent across all subdomains */\nexport const REPORT_BUTTONS: ReportButtonDef[] = [\n {\n category: \"safety\",\n label: \"Safety\",\n iconName: \"ShieldAlert\",\n color: \"#ef4444\",\n description: \"Report a safety incident, near-miss, or hazard\",\n },\n {\n category: \"environmental\",\n label: \"Environmental\",\n iconName: \"Leaf\",\n color: \"#22c55e\",\n description: \"Report an environmental incident or concern\",\n },\n {\n category: \"stop-work\",\n label: \"Stop Work\",\n iconName: \"OctagonX\",\n color: \"#f59e0b\",\n description: \"Raise a stop work authority — immediate safety concern\",\n },\n];\n\n/** Standard feedback buttons — consistent across all subdomains */\nexport const FEEDBACK_BUTTONS: FeedbackButtonDef[] = [\n {\n category: \"problem\",\n label: \"Problem\",\n iconName: \"AlertTriangle\",\n color: \"#ef4444\",\n description: \"Report a problem with the platform\",\n },\n {\n category: \"suggestion\",\n label: \"Suggestion\",\n iconName: \"Lightbulb\",\n color: \"#8C34E9\",\n description: \"Suggest an improvement or new feature\",\n },\n];\n\n// ─── Helpers ─────────────────────────────────────────────────────────────────\n\n/** Create a default ReportingToolbarConfig with sensible defaults */\nexport function createReportingConfig(\n moduleName: string,\n handlers: {\n onReportSubmit: (report: IncidentReport) => Promise<void> | void;\n onFeedbackSubmit: (feedback: FeedbackReport) => Promise<void> | void;\n },\n): ReportingToolbarConfig {\n return {\n moduleName,\n showIncidentReporting: true,\n showFeedback: true,\n reportCategories: [\"safety\", \"environmental\", \"stop-work\"],\n feedbackCategories: [\"problem\", \"suggestion\"],\n ...handlers,\n };\n}\n\n// ─── ReportingToolbar Component ─────────────────────────────────────────────\n\nexport {\n ReportingToolbar,\n type ReportingToolbarProps,\n} from \"./ReportingToolbar\";\n"],"mappings":"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","names":[]}
|
package/dist/shell/index.js
CHANGED
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
CrossServiceNav,
|
|
6
6
|
DashboardLayout,
|
|
7
7
|
HealthFooter
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-7I4ADEJY.js";
|
|
9
9
|
import "../chunk-4QJMLQSH.js";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-CYIMXOQW.js";
|
|
11
11
|
import "../chunk-3E3GLIQV.js";
|
|
12
12
|
import "../chunk-3G43UG63.js";
|
|
13
13
|
import "../chunk-PS4K7FKB.js";
|
|
14
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-NTFR5ZIF.js";
|
|
15
15
|
import "../chunk-JT3XLKKD.js";
|
|
16
16
|
import "../chunk-R4NOLCSI.js";
|
|
17
17
|
|