@burdenoff/microfe-devportal 2026.830.1 → 2026.831.1
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/devportal/AdminDevportalRoot.d.ts.map +1 -1
- package/dist/devportal/AdminDevportalRoot.js +16 -19
- package/dist/devportal/AdminDevportalRoot.js.map +1 -1
- package/dist/devportal/DevportalRoot.d.ts.map +1 -1
- package/dist/devportal/DevportalRoot.js +36 -39
- package/dist/devportal/DevportalRoot.js.map +1 -1
- package/dist/devportal/components/AppCard.js +41 -41
- package/dist/devportal/components/ConfirmDialog.d.ts.map +1 -1
- package/dist/devportal/components/ConfirmDialog.js +19 -22
- package/dist/devportal/components/ConfirmDialog.js.map +1 -1
- package/dist/devportal/components/DataTable.d.ts.map +1 -1
- package/dist/devportal/components/DataTable.js +31 -34
- package/dist/devportal/components/DataTable.js.map +1 -1
- package/dist/devportal/components/FeatureFlaggedRoute.js +8 -8
- package/dist/devportal/components/FormField.d.ts.map +1 -1
- package/dist/devportal/components/FormField.js +26 -32
- package/dist/devportal/components/FormField.js.map +1 -1
- package/dist/devportal/components/GrantDelegationModal.js +64 -64
- package/dist/devportal/components/GrantDelegationModal.js.map +1 -1
- package/dist/devportal/components/LoadingState.d.ts.map +1 -1
- package/dist/devportal/components/LoadingState.js +5 -8
- package/dist/devportal/components/LoadingState.js.map +1 -1
- package/dist/devportal/components/PageLayout.d.ts.map +1 -1
- package/dist/devportal/components/PageLayout.js +10 -13
- package/dist/devportal/components/PageLayout.js.map +1 -1
- package/dist/devportal/components/PermissionGuard.d.ts.map +1 -1
- package/dist/devportal/components/PermissionGuard.js +11 -14
- package/dist/devportal/components/PermissionGuard.js.map +1 -1
- package/dist/devportal/components/SecretDisplay.d.ts.map +1 -1
- package/dist/devportal/components/SecretDisplay.js +24 -30
- package/dist/devportal/components/SecretDisplay.js.map +1 -1
- package/dist/devportal/components/SectionNav.d.ts.map +1 -1
- package/dist/devportal/components/SectionNav.js +24 -27
- package/dist/devportal/components/SectionNav.js.map +1 -1
- package/dist/devportal/components/StatusBadge.d.ts.map +1 -1
- package/dist/devportal/components/StatusBadge.js +24 -33
- package/dist/devportal/components/StatusBadge.js.map +1 -1
- package/dist/devportal/index.d.ts +1 -0
- package/dist/devportal/index.d.ts.map +1 -1
- package/dist/devportal/index.js +1 -0
- package/dist/devportal/pages/AdminReviewPage.js +172 -172
- package/dist/devportal/pages/AnalyticsDashboardPage.js +43 -43
- package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
- package/dist/devportal/pages/ApiKeysPage.js +119 -119
- package/dist/devportal/pages/ApiKeysPage.js.map +1 -1
- package/dist/devportal/pages/AppLogsPage.js +45 -45
- package/dist/devportal/pages/ApplicationDetailPage.js +607 -607
- package/dist/devportal/pages/ApplicationVersionsPage.js +13 -13
- package/dist/devportal/pages/ApplicationsPage.d.ts.map +1 -1
- package/dist/devportal/pages/ApplicationsPage.js +104 -101
- package/dist/devportal/pages/ApplicationsPage.js.map +1 -1
- package/dist/devportal/pages/CreateApiKeyPage.js +45 -45
- package/dist/devportal/pages/CreateApplicationPage.js +38 -38
- package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
- package/dist/devportal/pages/CreateOAuthClientPage.js +52 -52
- package/dist/devportal/pages/CreateOrganizationPage.js +26 -26
- package/dist/devportal/pages/CreateWebhookPage.d.ts.map +1 -1
- package/dist/devportal/pages/CreateWebhookPage.js +48 -48
- package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
- package/dist/devportal/pages/DashboardPage.d.ts.map +1 -1
- package/dist/devportal/pages/DashboardPage.js +66 -72
- package/dist/devportal/pages/DashboardPage.js.map +1 -1
- package/dist/devportal/pages/DelegationsPage.js +174 -174
- package/dist/devportal/pages/DocumentationPage.js +93 -93
- package/dist/devportal/pages/EditApplicationPage.js +14 -14
- package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
- package/dist/devportal/pages/ListingPreviewPage.js +76 -76
- package/dist/devportal/pages/OAuthClientDetailPage.js +75 -75
- package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
- package/dist/devportal/pages/OAuthClientsPage.js +64 -64
- package/dist/devportal/pages/OrganizationDetailPage.js +189 -189
- package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
- package/dist/devportal/pages/OrganizationMembersPage.js +10 -10
- package/dist/devportal/pages/OrganizationsPage.d.ts.map +1 -1
- package/dist/devportal/pages/OrganizationsPage.js +163 -154
- package/dist/devportal/pages/OrganizationsPage.js.map +1 -1
- package/dist/devportal/pages/PublishPage.js +104 -104
- package/dist/devportal/pages/PublishPage.js.map +1 -1
- package/dist/devportal/pages/PublisherProfilePage.js +55 -55
- package/dist/devportal/pages/ResourcesPage.js +60 -60
- package/dist/devportal/pages/RevenueDashboardPage.js +60 -60
- package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
- package/dist/devportal/pages/SellerDashboardPage.js +83 -83
- package/dist/devportal/pages/SellerItemsPage.js +163 -163
- package/dist/devportal/pages/SellerItemsPage.js.map +1 -1
- package/dist/devportal/pages/SellerOrdersPage.js +63 -63
- package/dist/devportal/pages/SettingsPage.js +21 -21
- package/dist/devportal/pages/SetupPage.js +183 -183
- package/dist/devportal/pages/SetupPage.js.map +1 -1
- package/dist/devportal/pages/StoreSubmissionPage.js +5 -5
- package/dist/devportal/pages/WebhookDetailPage.js +123 -123
- package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
- package/dist/devportal/pages/WebhooksPage.js +118 -118
- package/dist/devportal/pages/WebhooksPage.js.map +1 -1
- package/dist/devportal/utils/i18n.d.ts +9 -2
- package/dist/devportal/utils/i18n.d.ts.map +1 -1
- package/dist/devportal/utils/i18n.js +13 -10
- package/dist/devportal/utils/i18n.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/translations/en.d.ts +1251 -0
- package/dist/translations/en.d.ts.map +1 -0
- package/dist/translations/en.js +1235 -0
- package/dist/translations/en.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useTr as e } from "../utils/i18n.js";
|
|
2
|
+
import { cn as t } from "../utils/cn.js";
|
|
3
|
+
import { useEffect as n, useId as r, useRef as i } from "react";
|
|
4
4
|
import { AlertTriangle as a, CheckCircle as o, Info as s, XCircle as c } from "lucide-react";
|
|
5
5
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
6
6
|
//#region src/devportal/components/ConfirmDialog.tsx
|
|
7
7
|
var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, confirmLabel: g = "Confirm", cancelLabel: _ = "Cancel", variant: v = "default", loading: y = !1, children: b }) => {
|
|
8
|
-
let x =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
},
|
|
12
|
-
if (t(() => {
|
|
13
|
-
O.current = f;
|
|
14
|
-
}, [f]), t(() => {
|
|
8
|
+
let x = r(), S = r(), C = i(null), w = i(null), T = i(null), E = e(), D = i(f);
|
|
9
|
+
if (n(() => {
|
|
10
|
+
D.current = f;
|
|
11
|
+
}, [f]), n(() => {
|
|
15
12
|
if (!d) return;
|
|
16
13
|
T.current = document.activeElement;
|
|
17
14
|
let e = document.body.style.overflow;
|
|
@@ -21,13 +18,13 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
21
18
|
t?.focus();
|
|
22
19
|
});
|
|
23
20
|
let n = (e) => {
|
|
24
|
-
e.key === "Escape" && !y && (e.preventDefault(),
|
|
21
|
+
e.key === "Escape" && !y && (e.preventDefault(), D.current(!1));
|
|
25
22
|
};
|
|
26
23
|
return document.addEventListener("keydown", n), () => {
|
|
27
24
|
document.body.style.overflow = e, document.removeEventListener("keydown", n), T.current?.focus();
|
|
28
25
|
};
|
|
29
26
|
}, [y, d]), !d) return null;
|
|
30
|
-
let
|
|
27
|
+
let O = {
|
|
31
28
|
default: {
|
|
32
29
|
icon: /* @__PURE__ */ l(s, { className: "h-6 w-6 text-accent-blue" }),
|
|
33
30
|
iconBg: "bg-status-info-bg-subtle",
|
|
@@ -48,14 +45,14 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
48
45
|
iconBg: "bg-status-success-bg-subtle",
|
|
49
46
|
button: "bg-status-success-bg text-white hover:bg-status-success-bg/90"
|
|
50
47
|
}
|
|
51
|
-
}[v === "destructive" ? "danger" : v],
|
|
48
|
+
}[v === "destructive" ? "danger" : v], k = () => f(!1);
|
|
52
49
|
return /* @__PURE__ */ u("div", {
|
|
53
50
|
className: "fixed inset-0 z-50 flex items-center justify-center",
|
|
54
51
|
children: [/* @__PURE__ */ l("button", {
|
|
55
52
|
type: "button",
|
|
56
53
|
"aria-label": "Close dialog backdrop",
|
|
57
54
|
className: "absolute inset-0 bg-bg-overlay",
|
|
58
|
-
onClick:
|
|
55
|
+
onClick: k
|
|
59
56
|
}), /* @__PURE__ */ u("div", {
|
|
60
57
|
ref: C,
|
|
61
58
|
role: "dialog",
|
|
@@ -67,8 +64,8 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
67
64
|
children: [/* @__PURE__ */ u("div", {
|
|
68
65
|
className: "flex items-start gap-4",
|
|
69
66
|
children: [/* @__PURE__ */ l("div", {
|
|
70
|
-
className:
|
|
71
|
-
children:
|
|
67
|
+
className: t("rounded-full p-2", O.iconBg),
|
|
68
|
+
children: O.icon
|
|
72
69
|
}), /* @__PURE__ */ u("div", {
|
|
73
70
|
className: "flex-1",
|
|
74
71
|
children: [
|
|
@@ -93,7 +90,7 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
93
90
|
className: "mt-6 flex justify-end gap-3",
|
|
94
91
|
children: [/* @__PURE__ */ l("button", {
|
|
95
92
|
type: "button",
|
|
96
|
-
onClick:
|
|
93
|
+
onClick: k,
|
|
97
94
|
disabled: y,
|
|
98
95
|
className: "rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50",
|
|
99
96
|
children: _
|
|
@@ -102,13 +99,13 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
102
99
|
type: "button",
|
|
103
100
|
onClick: p,
|
|
104
101
|
disabled: y,
|
|
105
|
-
className:
|
|
106
|
-
children: y ?
|
|
102
|
+
className: t("rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:opacity-50", O.button),
|
|
103
|
+
children: y ? E("devportal.processing", "Processing...") : g
|
|
107
104
|
})]
|
|
108
105
|
})]
|
|
109
106
|
})]
|
|
110
107
|
});
|
|
111
|
-
}, f = ({ variant:
|
|
108
|
+
}, f = ({ variant: e = "info", title: n, children: r, onDismiss: i, className: d }) => {
|
|
112
109
|
let f = {
|
|
113
110
|
info: "bg-status-info-bg-subtle border-border-subtle text-status-info-text",
|
|
114
111
|
warning: "bg-status-warning-bg-subtle border-border-subtle text-status-warning-text",
|
|
@@ -121,11 +118,11 @@ var d = ({ open: d, onOpenChange: f, onConfirm: p, title: m, description: h, con
|
|
|
121
118
|
success: /* @__PURE__ */ l(o, { className: "h-5 w-5" })
|
|
122
119
|
};
|
|
123
120
|
return /* @__PURE__ */ l("div", {
|
|
124
|
-
className:
|
|
121
|
+
className: t("rounded-lg border p-4", f[e], d),
|
|
125
122
|
children: /* @__PURE__ */ u("div", {
|
|
126
123
|
className: "flex items-start gap-3",
|
|
127
124
|
children: [
|
|
128
|
-
p[
|
|
125
|
+
p[e],
|
|
129
126
|
/* @__PURE__ */ u("div", {
|
|
130
127
|
className: "flex-1",
|
|
131
128
|
children: [n && /* @__PURE__ */ l("h4", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/devportal/components/ConfirmDialog.tsx"],"sourcesContent":["import { useEffect, useId, useRef, type FC, type ReactNode } from \"react\";\nimport { AlertTriangle, Info, CheckCircle, XCircle } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { cn } from \"../utils/cn\";\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onConfirm: () => void | Promise<void>;\n title: string;\n description?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n variant?: \"default\" | \"danger\" | \"warning\" | \"success\" | \"destructive\";\n loading?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Confirmation dialog component\n */\nexport const ConfirmDialog: FC<ConfirmDialogProps> = ({\n open,\n onOpenChange,\n onConfirm,\n title,\n description,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n variant = \"default\",\n loading = false,\n children,\n}) => {\n const titleId = useId();\n const descriptionId = useId();\n const dialogRef = useRef<HTMLDivElement | null>(null);\n const confirmButtonRef = useRef<HTMLButtonElement | null>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n // Keep a stable ref to the latest onOpenChange. Parents commonly pass an\n // inline arrow (new reference every render), so depending on it directly\n // would re-run the focus effect on every keystroke and yank focus away from\n // form inputs. Storing it in a ref lets the effect depend only on open/loading.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n }, [onOpenChange]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n previousFocusRef.current = document.activeElement as HTMLElement | null;\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n // For form dialogs (with children), focus the container so Tab naturally\n // walks through the form fields first. Only auto-focus the confirm button\n // for simple confirmation dialogs that have no form fields.\n const focusTarget = children\n ? dialogRef.current\n : (confirmButtonRef.current ?? dialogRef.current);\n window.requestAnimationFrame(() => {\n focusTarget?.focus();\n });\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && !loading) {\n event.preventDefault();\n onOpenChangeRef.current(false);\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.removeEventListener(\"keydown\", onKeyDown);\n previousFocusRef.current?.focus();\n };\n // children is intentionally omitted: it re-creates every render and would\n // re-trigger focus-stealing on each keystroke. Only open/loading gate this.\n }, [loading, open]);\n\n if (!open) return null;\n\n // Map 'destructive' to 'danger' for internal use\n const normalizedVariant = variant === \"destructive\" ? \"danger\" : variant;\n\n const variantStyles = {\n default: {\n icon: <Info className=\"h-6 w-6 text-accent-blue\" />,\n iconBg: \"bg-status-info-bg-subtle\",\n button:\n \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n },\n danger: {\n icon: <XCircle className=\"h-6 w-6 text-status-error-text\" />,\n iconBg: \"bg-status-error-bg-subtle\",\n button: \"bg-status-error-bg text-white hover:bg-status-error-bg/90\",\n },\n warning: {\n icon: <AlertTriangle className=\"h-6 w-6 text-status-warning-text\" />,\n iconBg: \"bg-status-warning-bg-subtle\",\n button: \"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\",\n },\n success: {\n icon: <CheckCircle className=\"h-6 w-6 text-status-success-text\" />,\n iconBg: \"bg-status-success-bg-subtle\",\n button: \"bg-status-success-bg text-white hover:bg-status-success-bg/90\",\n },\n };\n\n const styles = variantStyles[normalizedVariant];\n\n const handleClose = () => onOpenChange(false);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label=\"Close dialog backdrop\"\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={handleClose}\n />\n\n {/* Dialog */}\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={description || children ? descriptionId : undefined}\n tabIndex={-1}\n className=\"relative z-10 w-full max-w-md rounded-lg bg-bg-surface p-6 shadow-xl\"\n >\n <div className=\"flex items-start gap-4\">\n <div className={cn(\"rounded-full p-2\", styles.iconBg)}>\n {styles.icon}\n </div>\n <div className=\"flex-1\">\n <h3 id={titleId} className=\"text-lg font-semibold\">\n {title}\n </h3>\n {description && (\n <p\n id={descriptionId}\n className=\"mt-2 text-sm text-text-secondary\"\n >\n {description}\n </p>\n )}\n {children && (\n <div\n className=\"mt-4\"\n id={description ? undefined : descriptionId}\n >\n {children}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"mt-6 flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={loading}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n {cancelLabel}\n </button>\n <button\n ref={confirmButtonRef}\n type=\"button\"\n onClick={onConfirm}\n disabled={loading}\n className={cn(\n \"rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:opacity-50\",\n styles.button,\n )}\n >\n {loading\n ? tr(\"devportal.processing\", \"Processing...\")\n : confirmLabel}\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * Alert banner component\n */\nexport const Alert: FC<{\n variant?: \"info\" | \"warning\" | \"error\" | \"success\";\n title?: string;\n children: ReactNode;\n onDismiss?: () => void;\n className?: string;\n}> = ({ variant = \"info\", title, children, onDismiss, className }) => {\n const variantStyles = {\n info: \"bg-status-info-bg-subtle border-border-subtle text-status-info-text\",\n warning:\n \"bg-status-warning-bg-subtle border-border-subtle text-status-warning-text\",\n error:\n \"bg-status-error-bg-subtle border-border-subtle text-status-error-text\",\n success:\n \"bg-status-success-bg-subtle border-border-subtle text-status-success-text\",\n };\n\n const icons = {\n info: <Info className=\"h-5 w-5\" />,\n warning: <AlertTriangle className=\"h-5 w-5\" />,\n error: <XCircle className=\"h-5 w-5\" />,\n success: <CheckCircle className=\"h-5 w-5\" />,\n };\n\n return (\n <div\n className={cn(\"rounded-lg border p-4\", variantStyles[variant], className)}\n >\n <div className=\"flex items-start gap-3\">\n {icons[variant]}\n <div className=\"flex-1\">\n {title && <h4 className=\"font-medium\">{title}</h4>}\n <div className=\"text-sm\">{children}</div>\n </div>\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"hover:opacity-70\"\n >\n <XCircle className=\"h-5 w-5\" />\n </button>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/devportal/components/ConfirmDialog.tsx"],"sourcesContent":["import { useEffect, useId, useRef, type FC, type ReactNode } from \"react\";\nimport { AlertTriangle, Info, CheckCircle, XCircle } from \"lucide-react\";\nimport { cn } from \"../utils/cn\";\nimport { useTr } from \"../utils/i18n\";\n\nexport interface ConfirmDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onConfirm: () => void | Promise<void>;\n title: string;\n description?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n variant?: \"default\" | \"danger\" | \"warning\" | \"success\" | \"destructive\";\n loading?: boolean;\n children?: ReactNode;\n}\n\n/**\n * Confirmation dialog component\n */\nexport const ConfirmDialog: FC<ConfirmDialogProps> = ({\n open,\n onOpenChange,\n onConfirm,\n title,\n description,\n confirmLabel = \"Confirm\",\n cancelLabel = \"Cancel\",\n variant = \"default\",\n loading = false,\n children,\n}) => {\n const titleId = useId();\n const descriptionId = useId();\n const dialogRef = useRef<HTMLDivElement | null>(null);\n const confirmButtonRef = useRef<HTMLButtonElement | null>(null);\n const previousFocusRef = useRef<HTMLElement | null>(null);\n const tr = useTr();\n\n // Keep a stable ref to the latest onOpenChange. Parents commonly pass an\n // inline arrow (new reference every render), so depending on it directly\n // would re-run the focus effect on every keystroke and yank focus away from\n // form inputs. Storing it in a ref lets the effect depend only on open/loading.\n const onOpenChangeRef = useRef(onOpenChange);\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n }, [onOpenChange]);\n\n useEffect(() => {\n if (!open) {\n return undefined;\n }\n\n previousFocusRef.current = document.activeElement as HTMLElement | null;\n const originalOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n\n // For form dialogs (with children), focus the container so Tab naturally\n // walks through the form fields first. Only auto-focus the confirm button\n // for simple confirmation dialogs that have no form fields.\n const focusTarget = children\n ? dialogRef.current\n : (confirmButtonRef.current ?? dialogRef.current);\n window.requestAnimationFrame(() => {\n focusTarget?.focus();\n });\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && !loading) {\n event.preventDefault();\n onOpenChangeRef.current(false);\n }\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n\n return () => {\n document.body.style.overflow = originalOverflow;\n document.removeEventListener(\"keydown\", onKeyDown);\n previousFocusRef.current?.focus();\n };\n // children is intentionally omitted: it re-creates every render and would\n // re-trigger focus-stealing on each keystroke. Only open/loading gate this.\n }, [loading, open]);\n\n if (!open) return null;\n\n // Map 'destructive' to 'danger' for internal use\n const normalizedVariant = variant === \"destructive\" ? \"danger\" : variant;\n\n const variantStyles = {\n default: {\n icon: <Info className=\"h-6 w-6 text-accent-blue\" />,\n iconBg: \"bg-status-info-bg-subtle\",\n button:\n \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\",\n },\n danger: {\n icon: <XCircle className=\"h-6 w-6 text-status-error-text\" />,\n iconBg: \"bg-status-error-bg-subtle\",\n button: \"bg-status-error-bg text-white hover:bg-status-error-bg/90\",\n },\n warning: {\n icon: <AlertTriangle className=\"h-6 w-6 text-status-warning-text\" />,\n iconBg: \"bg-status-warning-bg-subtle\",\n button: \"bg-status-warning-bg text-white hover:bg-status-warning-bg/90\",\n },\n success: {\n icon: <CheckCircle className=\"h-6 w-6 text-status-success-text\" />,\n iconBg: \"bg-status-success-bg-subtle\",\n button: \"bg-status-success-bg text-white hover:bg-status-success-bg/90\",\n },\n };\n\n const styles = variantStyles[normalizedVariant];\n\n const handleClose = () => onOpenChange(false);\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <button\n type=\"button\"\n aria-label=\"Close dialog backdrop\"\n className=\"absolute inset-0 bg-bg-overlay\"\n onClick={handleClose}\n />\n\n {/* Dialog */}\n <div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={description || children ? descriptionId : undefined}\n tabIndex={-1}\n className=\"relative z-10 w-full max-w-md rounded-lg bg-bg-surface p-6 shadow-xl\"\n >\n <div className=\"flex items-start gap-4\">\n <div className={cn(\"rounded-full p-2\", styles.iconBg)}>\n {styles.icon}\n </div>\n <div className=\"flex-1\">\n <h3 id={titleId} className=\"text-lg font-semibold\">\n {title}\n </h3>\n {description && (\n <p\n id={descriptionId}\n className=\"mt-2 text-sm text-text-secondary\"\n >\n {description}\n </p>\n )}\n {children && (\n <div\n className=\"mt-4\"\n id={description ? undefined : descriptionId}\n >\n {children}\n </div>\n )}\n </div>\n </div>\n\n <div className=\"mt-6 flex justify-end gap-3\">\n <button\n type=\"button\"\n onClick={handleClose}\n disabled={loading}\n className=\"rounded-md border px-4 py-2 text-sm font-medium hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n {cancelLabel}\n </button>\n <button\n ref={confirmButtonRef}\n type=\"button\"\n onClick={onConfirm}\n disabled={loading}\n className={cn(\n \"rounded-md px-4 py-2 text-sm font-medium transition-colors disabled:opacity-50\",\n styles.button,\n )}\n >\n {loading\n ? tr(\"devportal.processing\", \"Processing...\")\n : confirmLabel}\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * Alert banner component\n */\nexport const Alert: FC<{\n variant?: \"info\" | \"warning\" | \"error\" | \"success\";\n title?: string;\n children: ReactNode;\n onDismiss?: () => void;\n className?: string;\n}> = ({ variant = \"info\", title, children, onDismiss, className }) => {\n const variantStyles = {\n info: \"bg-status-info-bg-subtle border-border-subtle text-status-info-text\",\n warning:\n \"bg-status-warning-bg-subtle border-border-subtle text-status-warning-text\",\n error:\n \"bg-status-error-bg-subtle border-border-subtle text-status-error-text\",\n success:\n \"bg-status-success-bg-subtle border-border-subtle text-status-success-text\",\n };\n\n const icons = {\n info: <Info className=\"h-5 w-5\" />,\n warning: <AlertTriangle className=\"h-5 w-5\" />,\n error: <XCircle className=\"h-5 w-5\" />,\n success: <CheckCircle className=\"h-5 w-5\" />,\n };\n\n return (\n <div\n className={cn(\"rounded-lg border p-4\", variantStyles[variant], className)}\n >\n <div className=\"flex items-start gap-3\">\n {icons[variant]}\n <div className=\"flex-1\">\n {title && <h4 className=\"font-medium\">{title}</h4>}\n <div className=\"text-sm\">{children}</div>\n </div>\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"hover:opacity-70\"\n >\n <XCircle className=\"h-5 w-5\" />\n </button>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/devportal/components/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAU3C,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KACtC,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,EAAE,EAC5D,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,SAAS,EACT,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,cAAc,CAAC,CAAC,CAAC,+
|
|
1
|
+
{"version":3,"file":"DataTable.d.ts","sourceRoot":"","sources":["../../../src/devportal/components/DataTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAU3C,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC,CAAC;IAClB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KACtC,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,EAAE,EAC5D,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,SAAS,EACT,YAAY,EACZ,OAAO,EACP,UAAU,GACX,EAAE,cAAc,CAAC,CAAC,CAAC,+BAoJnB;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAmBA,CAAC"}
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useTr as e } from "../utils/i18n.js";
|
|
2
|
+
import { cn as t } from "../utils/cn.js";
|
|
3
3
|
import { ChevronLeft as n, ChevronRight as r, ChevronsLeft as i, ChevronsRight as a } from "lucide-react";
|
|
4
4
|
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
5
|
//#region src/devportal/components/DataTable.tsx
|
|
6
6
|
function c({ data: c, columns: l, keyField: u, onRowClick: d, className: f, emptyMessage: p, loading: m, pagination: h }) {
|
|
7
|
-
let
|
|
8
|
-
let n = g(e);
|
|
9
|
-
return n === e ? t : n;
|
|
10
|
-
}, v = p ?? _("devportal.noDataAvailable", "No data available"), y = h ? Math.ceil(h.totalCount / h.pageSize) : 1;
|
|
7
|
+
let g = e(), _ = p ?? g("devportal.noDataAvailable", "No data available"), v = h ? Math.ceil(h.totalCount / h.pageSize) : 1;
|
|
11
8
|
return /* @__PURE__ */ s("div", {
|
|
12
|
-
className:
|
|
9
|
+
className: t("rounded-lg border border-border-seam bg-bg-surface", f),
|
|
13
10
|
children: [/* @__PURE__ */ o("div", {
|
|
14
11
|
className: "overflow-x-auto",
|
|
15
12
|
children: /* @__PURE__ */ s("table", {
|
|
16
13
|
className: "w-full",
|
|
17
14
|
children: [/* @__PURE__ */ o("thead", { children: /* @__PURE__ */ o("tr", {
|
|
18
15
|
className: "border-b border-border-seam bg-bg-sunken/40",
|
|
19
|
-
children: l.map((
|
|
20
|
-
className:
|
|
21
|
-
children:
|
|
22
|
-
},
|
|
16
|
+
children: l.map((e) => /* @__PURE__ */ o("th", {
|
|
17
|
+
className: t("px-4 py-3 text-left text-sm font-medium text-text-secondary", e.className),
|
|
18
|
+
children: e.header
|
|
19
|
+
}, e.key))
|
|
23
20
|
}) }), /* @__PURE__ */ o("tbody", { children: m ? Array.from({ length: 5 }).map((e, t) => /* @__PURE__ */ o("tr", {
|
|
24
21
|
className: "animate-pulse border-b border-border-seam",
|
|
25
22
|
children: l.map((e) => /* @__PURE__ */ o("td", {
|
|
@@ -29,39 +26,39 @@ function c({ data: c, columns: l, keyField: u, onRowClick: d, className: f, empt
|
|
|
29
26
|
}, t)) : c.length === 0 ? /* @__PURE__ */ o("tr", { children: /* @__PURE__ */ o("td", {
|
|
30
27
|
colSpan: l.length,
|
|
31
28
|
className: "px-4 py-8 text-center text-text-secondary",
|
|
32
|
-
children:
|
|
33
|
-
}) }) : c.map((
|
|
29
|
+
children: _
|
|
30
|
+
}) }) : c.map((e) => /* @__PURE__ */ o("tr", {
|
|
34
31
|
role: d ? "button" : void 0,
|
|
35
32
|
tabIndex: d ? 0 : void 0,
|
|
36
|
-
className:
|
|
37
|
-
onClick: () => d?.(
|
|
38
|
-
onKeyDown: (
|
|
39
|
-
d && (
|
|
33
|
+
className: t("border-b border-border-seam transition-colors", d && "cursor-pointer hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:bg-bg-sunken/50"),
|
|
34
|
+
onClick: () => d?.(e),
|
|
35
|
+
onKeyDown: (t) => {
|
|
36
|
+
d && (t.key === "Enter" || t.key === " ") && (t.preventDefault(), d(e));
|
|
40
37
|
},
|
|
41
38
|
children: l.map((n) => /* @__PURE__ */ o("td", {
|
|
42
|
-
className:
|
|
43
|
-
children: n.render ? n.render(
|
|
39
|
+
className: t("px-4 py-3 text-sm", n.className),
|
|
40
|
+
children: n.render ? n.render(e) : String(e[n.key] ?? "")
|
|
44
41
|
}, String(n.key)))
|
|
45
|
-
}, String(
|
|
42
|
+
}, String(e[u]))) })]
|
|
46
43
|
})
|
|
47
|
-
}), h &&
|
|
44
|
+
}), h && v > 1 && /* @__PURE__ */ s("div", {
|
|
48
45
|
className: "flex items-center justify-between border-t border-border-seam px-4 py-3",
|
|
49
46
|
children: [/* @__PURE__ */ s("p", {
|
|
50
47
|
className: "text-sm text-text-secondary",
|
|
51
48
|
children: [
|
|
52
|
-
|
|
49
|
+
g("devportal.showingResults", "Showing"),
|
|
53
50
|
" ",
|
|
54
51
|
(h.page - 1) * h.pageSize + 1,
|
|
55
52
|
" ",
|
|
56
|
-
|
|
53
|
+
g("devportal.to", "to"),
|
|
57
54
|
" ",
|
|
58
55
|
Math.min(h.page * h.pageSize, h.totalCount),
|
|
59
56
|
" ",
|
|
60
|
-
|
|
57
|
+
g("devportal.of", "of"),
|
|
61
58
|
" ",
|
|
62
59
|
h.totalCount,
|
|
63
60
|
" ",
|
|
64
|
-
|
|
61
|
+
g("devportal.results", "results")
|
|
65
62
|
]
|
|
66
63
|
}), /* @__PURE__ */ s("div", {
|
|
67
64
|
className: "flex items-center gap-1",
|
|
@@ -81,24 +78,24 @@ function c({ data: c, columns: l, keyField: u, onRowClick: d, className: f, empt
|
|
|
81
78
|
/* @__PURE__ */ s("span", {
|
|
82
79
|
className: "px-3 text-sm",
|
|
83
80
|
children: [
|
|
84
|
-
|
|
81
|
+
g("devportal.page", "Page"),
|
|
85
82
|
" ",
|
|
86
83
|
h.page,
|
|
87
84
|
" ",
|
|
88
|
-
|
|
85
|
+
g("devportal.of", "of"),
|
|
89
86
|
" ",
|
|
90
|
-
|
|
87
|
+
v
|
|
91
88
|
]
|
|
92
89
|
}),
|
|
93
90
|
/* @__PURE__ */ o("button", {
|
|
94
91
|
onClick: () => h.onPageChange(h.page + 1),
|
|
95
|
-
disabled: h.page ===
|
|
92
|
+
disabled: h.page === v,
|
|
96
93
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
97
94
|
children: /* @__PURE__ */ o(r, { size: 20 })
|
|
98
95
|
}),
|
|
99
96
|
/* @__PURE__ */ o("button", {
|
|
100
|
-
onClick: () => h.onPageChange(
|
|
101
|
-
disabled: h.page ===
|
|
97
|
+
onClick: () => h.onPageChange(v),
|
|
98
|
+
disabled: h.page === v,
|
|
102
99
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
103
100
|
children: /* @__PURE__ */ o(a, { size: 20 })
|
|
104
101
|
})
|
|
@@ -107,9 +104,9 @@ function c({ data: c, columns: l, keyField: u, onRowClick: d, className: f, empt
|
|
|
107
104
|
})]
|
|
108
105
|
});
|
|
109
106
|
}
|
|
110
|
-
var l = ({ items:
|
|
111
|
-
className:
|
|
112
|
-
children:
|
|
107
|
+
var l = ({ items: e, className: n }) => /* @__PURE__ */ o("dl", {
|
|
108
|
+
className: t("divide-y divide-border-seam rounded-lg border border-border-seam", n),
|
|
109
|
+
children: e.map((e, t) => /* @__PURE__ */ s("div", {
|
|
113
110
|
className: "flex flex-col gap-1 px-4 py-3 sm:flex-row sm:gap-4",
|
|
114
111
|
children: [/* @__PURE__ */ o("dt", {
|
|
115
112
|
className: "text-sm font-medium text-text-secondary sm:w-1/3",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/devportal/components/DataTable.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport {\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { cn } from \"../utils/cn\";\n\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render?: (item: T) => ReactNode;\n className?: string;\n sortable?: boolean;\n}\n\nexport interface DataTableProps<T> {\n data: T[];\n columns: Column<T>[];\n keyField: keyof T;\n onRowClick?: (item: T) => void;\n className?: string;\n emptyMessage?: string;\n loading?: boolean;\n pagination?: {\n page: number;\n pageSize: number;\n totalCount: number;\n onPageChange: (page: number) => void;\n };\n}\n\n/**\n * Reusable data table component with pagination\n */\nexport function DataTable<T extends { [K in keyof T]: T[K] }>({\n data,\n columns,\n keyField,\n onRowClick,\n className,\n emptyMessage,\n loading,\n pagination,\n}: DataTableProps<T>) {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n const resolvedEmptyMessage =\n emptyMessage ?? tr(\"devportal.noDataAvailable\", \"No data available\");\n const totalPages = pagination\n ? Math.ceil(pagination.totalCount / pagination.pageSize)\n : 1;\n\n return (\n <div\n className={cn(\n \"rounded-lg border border-border-seam bg-bg-surface\",\n className,\n )}\n >\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken/40\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={cn(\n \"px-4 py-3 text-left text-sm font-medium text-text-secondary\",\n column.className,\n )}\n >\n {column.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n Array.from({ length: 5 }).map((_, i) => (\n <tr\n key={i}\n className=\"animate-pulse border-b border-border-seam\"\n >\n {columns.map((column) => (\n <td key={column.key} className=\"px-4 py-3\">\n <div className=\"h-4 rounded bg-bg-sunken\" />\n </td>\n ))}\n </tr>\n ))\n ) : data.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length}\n className=\"px-4 py-8 text-center text-text-secondary\"\n >\n {resolvedEmptyMessage}\n </td>\n </tr>\n ) : (\n data.map((item) => (\n <tr\n key={String(item[keyField])}\n role={onRowClick ? \"button\" : undefined}\n tabIndex={onRowClick ? 0 : undefined}\n className={cn(\n \"border-b border-border-seam transition-colors\",\n onRowClick &&\n \"cursor-pointer hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:bg-bg-sunken/50\",\n )}\n onClick={() => onRowClick?.(item)}\n onKeyDown={(event) => {\n if (!onRowClick) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onRowClick(item);\n }\n }}\n >\n {columns.map((column) => (\n <td\n key={String(column.key)}\n className={cn(\"px-4 py-3 text-sm\", column.className)}\n >\n {column.render\n ? column.render(item)\n : String(\n (item as Record<string, unknown>)[\n column.key as string\n ] ?? \"\",\n )}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {pagination && totalPages > 1 && (\n <div className=\"flex items-center justify-between border-t border-border-seam px-4 py-3\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.showingResults\", \"Showing\")}{\" \"}\n {(pagination.page - 1) * pagination.pageSize + 1}{\" \"}\n {tr(\"devportal.to\", \"to\")}{\" \"}\n {Math.min(\n pagination.page * pagination.pageSize,\n pagination.totalCount,\n )}{\" \"}\n {tr(\"devportal.of\", \"of\")} {pagination.totalCount}{\" \"}\n {tr(\"devportal.results\", \"results\")}\n </p>\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => pagination.onPageChange(1)}\n disabled={pagination.page === 1}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronsLeft size={20} />\n </button>\n <button\n onClick={() => pagination.onPageChange(pagination.page - 1)}\n disabled={pagination.page === 1}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronLeft size={20} />\n </button>\n <span className=\"px-3 text-sm\">\n {tr(\"devportal.page\", \"Page\")} {pagination.page}{\" \"}\n {tr(\"devportal.of\", \"of\")} {totalPages}\n </span>\n <button\n onClick={() => pagination.onPageChange(pagination.page + 1)}\n disabled={pagination.page === totalPages}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronRight size={20} />\n </button>\n <button\n onClick={() => pagination.onPageChange(totalPages)}\n disabled={pagination.page === totalPages}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronsRight size={20} />\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Simple key-value detail list\n */\nexport const DetailList: FC<{\n items: Array<{ label: string; value: ReactNode }>;\n className?: string;\n}> = ({ items, className }) => (\n <dl\n className={cn(\n \"divide-y divide-border-seam rounded-lg border border-border-seam\",\n className,\n )}\n >\n {items.map((item, index) => (\n <div\n key={index}\n className=\"flex flex-col gap-1 px-4 py-3 sm:flex-row sm:gap-4\"\n >\n <dt className=\"text-sm font-medium text-text-secondary sm:w-1/3\">\n {item.label}\n </dt>\n <dd className=\"text-sm sm:w-2/3\">{item.value}</dd>\n </div>\n ))}\n </dl>\n);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/devportal/components/DataTable.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport {\n ChevronLeft,\n ChevronRight,\n ChevronsLeft,\n ChevronsRight,\n} from \"lucide-react\";\nimport { cn } from \"../utils/cn\";\nimport { useTr } from \"../utils/i18n\";\n\nexport interface Column<T> {\n key: string;\n header: ReactNode;\n render?: (item: T) => ReactNode;\n className?: string;\n sortable?: boolean;\n}\n\nexport interface DataTableProps<T> {\n data: T[];\n columns: Column<T>[];\n keyField: keyof T;\n onRowClick?: (item: T) => void;\n className?: string;\n emptyMessage?: string;\n loading?: boolean;\n pagination?: {\n page: number;\n pageSize: number;\n totalCount: number;\n onPageChange: (page: number) => void;\n };\n}\n\n/**\n * Reusable data table component with pagination\n */\nexport function DataTable<T extends { [K in keyof T]: T[K] }>({\n data,\n columns,\n keyField,\n onRowClick,\n className,\n emptyMessage,\n loading,\n pagination,\n}: DataTableProps<T>) {\n const tr = useTr();\n const resolvedEmptyMessage =\n emptyMessage ?? tr(\"devportal.noDataAvailable\", \"No data available\");\n const totalPages = pagination\n ? Math.ceil(pagination.totalCount / pagination.pageSize)\n : 1;\n\n return (\n <div\n className={cn(\n \"rounded-lg border border-border-seam bg-bg-surface\",\n className,\n )}\n >\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken/40\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={cn(\n \"px-4 py-3 text-left text-sm font-medium text-text-secondary\",\n column.className,\n )}\n >\n {column.header}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n Array.from({ length: 5 }).map((_, i) => (\n <tr\n key={i}\n className=\"animate-pulse border-b border-border-seam\"\n >\n {columns.map((column) => (\n <td key={column.key} className=\"px-4 py-3\">\n <div className=\"h-4 rounded bg-bg-sunken\" />\n </td>\n ))}\n </tr>\n ))\n ) : data.length === 0 ? (\n <tr>\n <td\n colSpan={columns.length}\n className=\"px-4 py-8 text-center text-text-secondary\"\n >\n {resolvedEmptyMessage}\n </td>\n </tr>\n ) : (\n data.map((item) => (\n <tr\n key={String(item[keyField])}\n role={onRowClick ? \"button\" : undefined}\n tabIndex={onRowClick ? 0 : undefined}\n className={cn(\n \"border-b border-border-seam transition-colors\",\n onRowClick &&\n \"cursor-pointer hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:bg-bg-sunken/50\",\n )}\n onClick={() => onRowClick?.(item)}\n onKeyDown={(event) => {\n if (!onRowClick) return;\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onRowClick(item);\n }\n }}\n >\n {columns.map((column) => (\n <td\n key={String(column.key)}\n className={cn(\"px-4 py-3 text-sm\", column.className)}\n >\n {column.render\n ? column.render(item)\n : String(\n (item as Record<string, unknown>)[\n column.key as string\n ] ?? \"\",\n )}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n\n {/* Pagination */}\n {pagination && totalPages > 1 && (\n <div className=\"flex items-center justify-between border-t border-border-seam px-4 py-3\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.showingResults\", \"Showing\")}{\" \"}\n {(pagination.page - 1) * pagination.pageSize + 1}{\" \"}\n {tr(\"devportal.to\", \"to\")}{\" \"}\n {Math.min(\n pagination.page * pagination.pageSize,\n pagination.totalCount,\n )}{\" \"}\n {tr(\"devportal.of\", \"of\")} {pagination.totalCount}{\" \"}\n {tr(\"devportal.results\", \"results\")}\n </p>\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => pagination.onPageChange(1)}\n disabled={pagination.page === 1}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronsLeft size={20} />\n </button>\n <button\n onClick={() => pagination.onPageChange(pagination.page - 1)}\n disabled={pagination.page === 1}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronLeft size={20} />\n </button>\n <span className=\"px-3 text-sm\">\n {tr(\"devportal.page\", \"Page\")} {pagination.page}{\" \"}\n {tr(\"devportal.of\", \"of\")} {totalPages}\n </span>\n <button\n onClick={() => pagination.onPageChange(pagination.page + 1)}\n disabled={pagination.page === totalPages}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronRight size={20} />\n </button>\n <button\n onClick={() => pagination.onPageChange(totalPages)}\n disabled={pagination.page === totalPages}\n className=\"inline-flex h-9 w-9 items-center justify-center rounded-md hover:bg-bg-sunken disabled:opacity-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n <ChevronsRight size={20} />\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Simple key-value detail list\n */\nexport const DetailList: FC<{\n items: Array<{ label: string; value: ReactNode }>;\n className?: string;\n}> = ({ items, className }) => (\n <dl\n className={cn(\n \"divide-y divide-border-seam rounded-lg border border-border-seam\",\n className,\n )}\n >\n {items.map((item, index) => (\n <div\n key={index}\n className=\"flex flex-col gap-1 px-4 py-3 sm:flex-row sm:gap-4\"\n >\n <dt className=\"text-sm font-medium text-text-secondary sm:w-1/3\">\n {item.label}\n </dt>\n <dd className=\"text-sm sm:w-2/3\">{item.value}</dd>\n </div>\n ))}\n </dl>\n);\n"],"mappings":"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"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { EmptyState as e } from "./EmptyState.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { Fragment as t, jsx as n } from "react/jsx-runtime";
|
|
3
|
+
import { useFeatureFlag as r } from "@burdenoff/fe-libs/shared/feature-flags";
|
|
4
|
+
import { useI18n as i } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
5
5
|
//#region src/devportal/components/FeatureFlaggedRoute.tsx
|
|
6
6
|
var a = (e) => {
|
|
7
7
|
try {
|
|
8
|
-
return
|
|
8
|
+
return r(e);
|
|
9
9
|
} catch {
|
|
10
10
|
return !0;
|
|
11
11
|
}
|
|
12
12
|
}, o = () => {
|
|
13
13
|
try {
|
|
14
|
-
let e =
|
|
14
|
+
let e = i();
|
|
15
15
|
return { t: (t, n) => e.t(t, n) };
|
|
16
16
|
} catch {
|
|
17
17
|
return { t: (e, t) => t ?? e };
|
|
18
18
|
}
|
|
19
|
-
}, s = ({ flag:
|
|
20
|
-
let c = a(
|
|
21
|
-
return c ? /* @__PURE__ */
|
|
19
|
+
}, s = ({ flag: r, children: i, fallback: s }) => {
|
|
20
|
+
let c = a(r), { t: l } = o();
|
|
21
|
+
return c ? /* @__PURE__ */ n(t, { children: i }) : s ? /* @__PURE__ */ n(t, { children: s }) : /* @__PURE__ */ n(e, {
|
|
22
22
|
title: l("devportal.featureDisabled.title", "This feature is currently unavailable"),
|
|
23
23
|
description: l("devportal.featureDisabled.description", "Your administrator has disabled this section. Please check back later.")
|
|
24
24
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../../src/devportal/components/FormField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../../src/devportal/components/FormField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,EAAE,EACF,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACrB,MAAM,OAAO,CAAC;AAIf,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,eACR,SACE,cAAc,EACd,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,WAAW,CAAC;IAC1D,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;CACjE;AAED,UAAU,kBACR,SACE,cAAc,EACd,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,WAAW,CAAC;CAAG;AAErE,UAAU,gBACR,SACE,cAAc,EACd,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAC5D,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,kBACR,SACE,cAAc,EACd,IAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAiC1C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAiChD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA0C5C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAgChD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CA2BA,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAoDA,CAAC"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useTr as e } from "../utils/i18n.js";
|
|
2
|
+
import { cn as t } from "../utils/cn.js";
|
|
3
3
|
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
4
4
|
//#region src/devportal/components/FormField.tsx
|
|
5
|
-
var i = ({ label:
|
|
6
|
-
let d = l ||
|
|
5
|
+
var i = ({ label: e, error: i, hint: a, required: o, className: s, type: c = "text", id: l, ...u }) => {
|
|
6
|
+
let d = l || e.toLowerCase().replace(/\s+/g, "-");
|
|
7
7
|
return /* @__PURE__ */ r("div", {
|
|
8
|
-
className:
|
|
8
|
+
className: t("space-y-1", s),
|
|
9
9
|
children: [
|
|
10
10
|
/* @__PURE__ */ r("label", {
|
|
11
11
|
htmlFor: d,
|
|
12
12
|
className: "block text-sm font-medium",
|
|
13
|
-
children: [
|
|
13
|
+
children: [e, o && /* @__PURE__ */ n("span", {
|
|
14
14
|
className: "text-status-error-text ml-1",
|
|
15
15
|
children: "*"
|
|
16
16
|
})]
|
|
@@ -18,7 +18,7 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
18
18
|
/* @__PURE__ */ n("input", {
|
|
19
19
|
id: d,
|
|
20
20
|
type: c,
|
|
21
|
-
className:
|
|
21
|
+
className: t("w-full rounded-md border bg-bg-surface px-3 py-2 text-sm", "focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent", "placeholder:text-text-secondary", i && "border-status-error-bg focus:ring-status-error-bg"),
|
|
22
22
|
...u
|
|
23
23
|
}),
|
|
24
24
|
a && !i && /* @__PURE__ */ n("p", {
|
|
@@ -31,15 +31,15 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
31
31
|
})
|
|
32
32
|
]
|
|
33
33
|
});
|
|
34
|
-
}, a = ({ label:
|
|
35
|
-
let d = c ||
|
|
34
|
+
}, a = ({ label: e, error: i, hint: a, required: o, className: s, id: c, rows: l = 4, ...u }) => {
|
|
35
|
+
let d = c || e.toLowerCase().replace(/\s+/g, "-");
|
|
36
36
|
return /* @__PURE__ */ r("div", {
|
|
37
|
-
className:
|
|
37
|
+
className: t("space-y-1", s),
|
|
38
38
|
children: [
|
|
39
39
|
/* @__PURE__ */ r("label", {
|
|
40
40
|
htmlFor: d,
|
|
41
41
|
className: "block text-sm font-medium",
|
|
42
|
-
children: [
|
|
42
|
+
children: [e, o && /* @__PURE__ */ n("span", {
|
|
43
43
|
className: "text-status-error-text ml-1",
|
|
44
44
|
children: "*"
|
|
45
45
|
})]
|
|
@@ -47,7 +47,7 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
47
47
|
/* @__PURE__ */ n("textarea", {
|
|
48
48
|
id: d,
|
|
49
49
|
rows: l,
|
|
50
|
-
className:
|
|
50
|
+
className: t("w-full rounded-md border bg-bg-surface px-3 py-2 text-sm", "focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent", "placeholder:text-text-secondary resize-none", i && "border-status-error-bg focus:ring-status-error-bg"),
|
|
51
51
|
...u
|
|
52
52
|
}),
|
|
53
53
|
a && !i && /* @__PURE__ */ n("p", {
|
|
@@ -61,12 +61,9 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
61
61
|
]
|
|
62
62
|
});
|
|
63
63
|
}, o = ({ label: i, error: a, hint: o, required: s, className: c, options: l, placeholder: u, id: d, ...f }) => {
|
|
64
|
-
let
|
|
65
|
-
let n = p(e);
|
|
66
|
-
return n === e ? t : n;
|
|
67
|
-
})("devportal.selectAnOption", "Select an option"), h = d || i.toLowerCase().replace(/\s+/g, "-");
|
|
64
|
+
let p = e(), m = u ?? p("devportal.selectAnOption", "Select an option"), h = d || i.toLowerCase().replace(/\s+/g, "-");
|
|
68
65
|
return /* @__PURE__ */ r("div", {
|
|
69
|
-
className:
|
|
66
|
+
className: t("space-y-1", c),
|
|
70
67
|
children: [
|
|
71
68
|
/* @__PURE__ */ r("label", {
|
|
72
69
|
htmlFor: h,
|
|
@@ -78,7 +75,7 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
78
75
|
}),
|
|
79
76
|
/* @__PURE__ */ r("select", {
|
|
80
77
|
id: h,
|
|
81
|
-
className:
|
|
78
|
+
className: t("w-full rounded-md border bg-bg-surface px-3 py-2 text-sm", "focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent", a && "border-status-error-bg focus:ring-status-error-bg"),
|
|
82
79
|
...f,
|
|
83
80
|
children: [/* @__PURE__ */ n("option", {
|
|
84
81
|
value: "",
|
|
@@ -98,20 +95,20 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
98
95
|
})
|
|
99
96
|
]
|
|
100
97
|
});
|
|
101
|
-
}, s = ({ label:
|
|
102
|
-
let l = s ||
|
|
98
|
+
}, s = ({ label: e, description: i, error: a, className: o, id: s, ...c }) => {
|
|
99
|
+
let l = s || e.toLowerCase().replace(/\s+/g, "-");
|
|
103
100
|
return /* @__PURE__ */ r("div", {
|
|
104
|
-
className:
|
|
101
|
+
className: t("flex items-start gap-3", o),
|
|
105
102
|
children: [/* @__PURE__ */ n("input", {
|
|
106
103
|
id: l,
|
|
107
104
|
type: "checkbox",
|
|
108
|
-
className:
|
|
105
|
+
className: t("mt-1 h-4 w-4 rounded border-border-default text-primary", "focus:ring-primary"),
|
|
109
106
|
...c
|
|
110
107
|
}), /* @__PURE__ */ r("div", { children: [
|
|
111
108
|
/* @__PURE__ */ n("label", {
|
|
112
109
|
htmlFor: l,
|
|
113
110
|
className: "text-sm font-medium cursor-pointer",
|
|
114
|
-
children:
|
|
111
|
+
children: e
|
|
115
112
|
}),
|
|
116
113
|
i && /* @__PURE__ */ n("p", {
|
|
117
114
|
className: "text-xs text-text-secondary",
|
|
@@ -124,20 +121,17 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
124
121
|
] })]
|
|
125
122
|
});
|
|
126
123
|
}, c = ({ label: i, value: a, onChange: o, placeholder: s, error: c, hint: l, className: u }) => {
|
|
127
|
-
let
|
|
128
|
-
let n = d(e);
|
|
129
|
-
return n === e ? t : n;
|
|
130
|
-
}, p = (e) => {
|
|
124
|
+
let d = e(), f = (e) => {
|
|
131
125
|
if (e.key === "Enter" || e.key === ",") {
|
|
132
126
|
e.preventDefault();
|
|
133
127
|
let t = e.currentTarget, n = t.value.trim();
|
|
134
128
|
n && !a.includes(n) && (o([...a, n]), t.value = "");
|
|
135
129
|
}
|
|
136
|
-
},
|
|
130
|
+
}, p = (e) => {
|
|
137
131
|
o(a.filter((t) => t !== e));
|
|
138
132
|
};
|
|
139
133
|
return /* @__PURE__ */ r("div", {
|
|
140
|
-
className:
|
|
134
|
+
className: t("space-y-1", u),
|
|
141
135
|
children: [
|
|
142
136
|
/* @__PURE__ */ n("label", {
|
|
143
137
|
className: "block text-sm font-medium",
|
|
@@ -149,14 +143,14 @@ var i = ({ label: t, error: i, hint: a, required: o, className: s, type: c = "te
|
|
|
149
143
|
className: "inline-flex items-center gap-1 rounded-full bg-action-primary-bg/10 px-2 py-1 text-xs",
|
|
150
144
|
children: [e, /* @__PURE__ */ n("button", {
|
|
151
145
|
type: "button",
|
|
152
|
-
onClick: () =>
|
|
146
|
+
onClick: () => p(e),
|
|
153
147
|
className: "hover:text-status-error-text",
|
|
154
148
|
children: "×"
|
|
155
149
|
})]
|
|
156
150
|
}, e)), /* @__PURE__ */ n("input", {
|
|
157
151
|
type: "text",
|
|
158
|
-
placeholder: a.length === 0 ? s :
|
|
159
|
-
onKeyDown:
|
|
152
|
+
placeholder: a.length === 0 ? s : d("devportal.addMore", "Add more..."),
|
|
153
|
+
onKeyDown: f,
|
|
160
154
|
className: "flex-1 min-w-[100px] bg-transparent text-sm outline-none"
|
|
161
155
|
})]
|
|
162
156
|
}),
|