@plumile/backoffice-react 0.1.65 → 0.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +101 -0
  2. package/lib/esm/hooks/useConditionalSubscription.js +57 -0
  3. package/lib/esm/hooks/useConditionalSubscription.js.map +1 -0
  4. package/lib/esm/hooks/useCopyToClipboard.js +31 -0
  5. package/lib/esm/hooks/useCopyToClipboard.js.map +1 -0
  6. package/lib/esm/hooks/useRefetchNeededReload.js +23 -0
  7. package/lib/esm/hooks/useRefetchNeededReload.js.map +1 -0
  8. package/lib/esm/i18n/useReviewStatusLabel.js +19 -0
  9. package/lib/esm/i18n/useReviewStatusLabel.js.map +1 -0
  10. package/lib/esm/i18n/useSharedEnumLabels.js +22 -0
  11. package/lib/esm/i18n/useSharedEnumLabels.js.map +1 -0
  12. package/lib/esm/index.js +23 -7
  13. package/lib/esm/modules/access/viewerPermissionsPolicy.js +17 -0
  14. package/lib/esm/modules/access/viewerPermissionsPolicy.js.map +1 -0
  15. package/lib/esm/modules/base64.js +23 -0
  16. package/lib/esm/modules/base64.js.map +1 -0
  17. package/lib/esm/modules/billing/usageChartMappers.js +49 -0
  18. package/lib/esm/modules/billing/usageChartMappers.js.map +1 -0
  19. package/lib/esm/modules/formatFileSize.js +28 -0
  20. package/lib/esm/modules/formatFileSize.js.map +1 -0
  21. package/lib/esm/modules/merge/taskMergeRun.js +67 -0
  22. package/lib/esm/modules/merge/taskMergeRun.js.map +1 -0
  23. package/lib/esm/modules/projectIngestionStatus.js +25 -0
  24. package/lib/esm/modules/projectIngestionStatus.js.map +1 -0
  25. package/lib/esm/provider/BackofficeProvider.js +30 -20
  26. package/lib/esm/provider/BackofficeProvider.js.map +1 -1
  27. package/lib/esm/subscriptions/conversationStream.js +38 -0
  28. package/lib/esm/subscriptions/conversationStream.js.map +1 -0
  29. package/lib/types/hooks/useConditionalSubscription.d.ts +13 -0
  30. package/lib/types/hooks/useConditionalSubscription.d.ts.map +1 -0
  31. package/lib/types/hooks/useCopyToClipboard.d.ts +6 -0
  32. package/lib/types/hooks/useCopyToClipboard.d.ts.map +1 -0
  33. package/lib/types/hooks/useRefetchNeededReload.d.ts +10 -0
  34. package/lib/types/hooks/useRefetchNeededReload.d.ts.map +1 -0
  35. package/lib/types/i18n/useReviewStatusLabel.d.ts +6 -0
  36. package/lib/types/i18n/useReviewStatusLabel.d.ts.map +1 -0
  37. package/lib/types/i18n/useSharedEnumLabels.d.ts +6 -0
  38. package/lib/types/i18n/useSharedEnumLabels.d.ts.map +1 -0
  39. package/lib/types/index.d.ts +16 -0
  40. package/lib/types/index.d.ts.map +1 -1
  41. package/lib/types/modules/access/viewerPermissionsPolicy.d.ts +38 -0
  42. package/lib/types/modules/access/viewerPermissionsPolicy.d.ts.map +1 -0
  43. package/lib/types/modules/base64.d.ts +3 -0
  44. package/lib/types/modules/base64.d.ts.map +1 -0
  45. package/lib/types/modules/billing/usageChartMappers.d.ts +26 -0
  46. package/lib/types/modules/billing/usageChartMappers.d.ts.map +1 -0
  47. package/lib/types/modules/formatFileSize.d.ts +8 -0
  48. package/lib/types/modules/formatFileSize.d.ts.map +1 -0
  49. package/lib/types/modules/merge/taskMergeRun.d.ts +48 -0
  50. package/lib/types/modules/merge/taskMergeRun.d.ts.map +1 -0
  51. package/lib/types/modules/projectIngestionStatus.d.ts +9 -0
  52. package/lib/types/modules/projectIngestionStatus.d.ts.map +1 -0
  53. package/lib/types/provider/BackofficeProvider.d.ts.map +1 -1
  54. package/lib/types/provider/types.d.ts +2 -0
  55. package/lib/types/provider/types.d.ts.map +1 -1
  56. package/lib/types/subscriptions/conversationStream.d.ts +12 -0
  57. package/lib/types/subscriptions/conversationStream.d.ts.map +1 -0
  58. package/package.json +15 -5
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @plumile/backoffice-react
2
+
3
+ React provider and pages for Plumile backoffice.
4
+
5
+ ## Instrumentation
6
+
7
+ `BackofficeProvider` forwards router instrumentations to the internal
8
+ `createRouter(...)` call.
9
+
10
+ Use this when you want to expose:
11
+
12
+ - the Plumile Router DevTools bridge
13
+ - Performance Timeline marks and measures in Chrome DevTools
14
+
15
+ Example:
16
+
17
+ ```ts
18
+ import {
19
+ createDevtoolsBridgeInstrumentation,
20
+ createPerformanceTimelineInstrumentation,
21
+ } from '@plumile/router';
22
+ import { BackofficeProvider } from '@plumile/backoffice-react';
23
+
24
+ const instrumentations = [
25
+ createDevtoolsBridgeInstrumentation(),
26
+ createPerformanceTimelineInstrumentation(),
27
+ ];
28
+
29
+ <BackofficeProvider
30
+ entityManifest={entityManifest}
31
+ auth={auth}
32
+ graphql={graphql}
33
+ instrumentations={instrumentations}
34
+ />;
35
+ ```
36
+
37
+ This remains optional. If `instrumentations` is omitted, backoffice routing
38
+ behaves exactly as before.
39
+
40
+ ## Examples
41
+
42
+ ### Performance Timeline only
43
+
44
+ ```ts
45
+ import { createPerformanceTimelineInstrumentation } from '@plumile/router';
46
+ import { BackofficeProvider } from '@plumile/backoffice-react';
47
+
48
+ <BackofficeProvider
49
+ entityManifest={entityManifest}
50
+ auth={auth}
51
+ graphql={graphql}
52
+ instrumentations={[createPerformanceTimelineInstrumentation()]}
53
+ />;
54
+ ```
55
+
56
+ ### DevTools bridge + Performance Timeline in development
57
+
58
+ ```ts
59
+ import {
60
+ createDevtoolsBridgeInstrumentation,
61
+ createPerformanceTimelineInstrumentation,
62
+ } from '@plumile/router';
63
+ import { BackofficeProvider } from '@plumile/backoffice-react';
64
+
65
+ const instrumentations = [];
66
+
67
+ if (import.meta.env.DEV) {
68
+ instrumentations.push(createDevtoolsBridgeInstrumentation());
69
+ instrumentations.push(createPerformanceTimelineInstrumentation());
70
+ }
71
+
72
+ <BackofficeProvider
73
+ entityManifest={entityManifest}
74
+ auth={auth}
75
+ graphql={graphql}
76
+ instrumentations={instrumentations}
77
+ />;
78
+ ```
79
+
80
+ ### With additional custom instrumentation
81
+
82
+ ```ts
83
+ import {
84
+ createConsoleLoggerInstrumentation,
85
+ createDevtoolsBridgeInstrumentation,
86
+ createPerformanceTimelineInstrumentation,
87
+ } from '@plumile/router';
88
+
89
+ const instrumentations = [
90
+ createDevtoolsBridgeInstrumentation(),
91
+ createPerformanceTimelineInstrumentation(),
92
+ createConsoleLoggerInstrumentation({ label: 'backoffice-router' }),
93
+ ];
94
+ ```
95
+
96
+ In practice, this is useful to inspect:
97
+
98
+ - route navigations
99
+ - route preloads
100
+ - route `prepare` durations
101
+ - backoffice page transitions driven by the internal router
@@ -0,0 +1,57 @@
1
+ import { useEffect as e, useMemo as t, useRef as n, useState as r } from "react";
2
+ import * as i from "react-relay";
3
+ //#region src/hooks/useConditionalSubscription.ts
4
+ function a() {
5
+ return Reflect.get(i, "default") ?? i;
6
+ }
7
+ var o = a();
8
+ function s(i, a) {
9
+ let s = o.useRelayEnvironment(), [c, l] = r(null), { enabled: u = !0, deps: d = [], getVariables: f } = a, p = t(() => {
10
+ try {
11
+ return f == null ? i.variables : f();
12
+ } catch {
13
+ return null;
14
+ }
15
+ }, [i.variables, f]), m = t(() => {
16
+ if (p == null) return null;
17
+ try {
18
+ return JSON.stringify(p);
19
+ } catch {
20
+ return null;
21
+ }
22
+ }, [p]), h = !!u, g = p, _ = h && g != null, v = n(null);
23
+ return e(() => {
24
+ let e = null;
25
+ return h && g != null && (l(null), e = o.requestSubscription(s, {
26
+ subscription: i.subscription,
27
+ variables: g,
28
+ cacheConfig: i.cacheConfig,
29
+ configs: i.configs,
30
+ onCompleted: i.onCompleted,
31
+ onError: (e) => {
32
+ l(e), i.onError?.(e);
33
+ },
34
+ onNext: i.onNext,
35
+ updater: i.updater
36
+ }), v.current = e), () => {
37
+ if (e != null) try {
38
+ e.dispose();
39
+ } catch {}
40
+ v.current === e && (v.current = null);
41
+ };
42
+ }, [
43
+ i,
44
+ d,
45
+ s,
46
+ h,
47
+ m,
48
+ g
49
+ ]), {
50
+ active: _,
51
+ error: c
52
+ };
53
+ }
54
+ //#endregion
55
+ export { s as useConditionalSubscription };
56
+
57
+ //# sourceMappingURL=useConditionalSubscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConditionalSubscription.js","names":[],"sources":["../../../src/hooks/useConditionalSubscription.ts"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react';\nimport * as ReactRelay from 'react-relay';\nimport type { GraphQLSubscriptionConfig, OperationType } from 'relay-runtime';\n\ntype ConditionalOptions<T extends OperationType> = {\n enabled: boolean;\n deps?: readonly unknown[];\n getVariables?: () => T['variables'];\n};\n\ntype UseConditionalSubscriptionReturn = {\n active: boolean;\n error: Error | null;\n};\n\ntype Hop = { dispose: () => void } | null;\n\n/** Resolve the Relay module regardless of whether the package exposes a default export shim. */\nfunction resolveRelayApi(): typeof ReactRelay {\n const relayDefault: unknown = Reflect.get(ReactRelay, 'default');\n if (relayDefault != null) {\n return relayDefault as typeof ReactRelay;\n }\n return ReactRelay;\n}\n\nconst relayApi = resolveRelayApi();\n\n/** Subscribe only when the caller enables the subscription and variables exist. */\nexport function useConditionalSubscription<T extends OperationType>(\n config: GraphQLSubscriptionConfig<T>,\n options: ConditionalOptions<T>,\n): UseConditionalSubscriptionReturn {\n const environment = relayApi.useRelayEnvironment();\n const [error, setError] = useState<Error | null>(null);\n\n const { enabled = true, deps = [], getVariables } = options;\n\n const resolvedVariables = useMemo<T['variables'] | null>(() => {\n try {\n if (getVariables != null) {\n return getVariables();\n }\n return config.variables;\n } catch {\n return null;\n }\n }, [config.variables, getVariables]);\n\n const stableVarsString = useMemo(() => {\n if (resolvedVariables == null) {\n return null;\n }\n try {\n return JSON.stringify(resolvedVariables);\n } catch {\n return null;\n }\n }, [resolvedVariables]);\n\n const isEnabled = Boolean(enabled);\n const variables = resolvedVariables;\n const active = isEnabled && variables != null;\n\n const disposableRef = useRef<Hop>(null);\n\n useEffect(() => {\n let disposable: Hop = null;\n\n if (isEnabled && variables != null) {\n setError(null);\n\n disposable = relayApi.requestSubscription<T>(environment, {\n subscription: config.subscription,\n variables,\n cacheConfig: config.cacheConfig,\n configs: config.configs,\n onCompleted: config.onCompleted,\n onError: (nextError) => {\n setError(nextError);\n config.onError?.(nextError);\n },\n onNext: config.onNext,\n updater: config.updater,\n });\n\n disposableRef.current = disposable;\n }\n\n return () => {\n if (disposable != null) {\n try {\n disposable.dispose();\n } catch {\n // ignore cleanup failures\n }\n }\n if (disposableRef.current === disposable) {\n disposableRef.current = null;\n }\n };\n }, [config, deps, environment, isEnabled, stableVarsString, variables]);\n\n return { active, error };\n}\n"],"mappings":";;;AAkBA,SAAS,IAAqC;AAK5C,QAJ8B,QAAQ,IAAI,GAAY,UAAU,IAIzD;;AAGT,IAAM,IAAW,GAAiB;AAGlC,SAAgB,EACd,GACA,GACkC;CAClC,IAAM,IAAc,EAAS,qBAAqB,EAC5C,CAAC,GAAO,KAAY,EAAuB,KAAK,EAEhD,EAAE,aAAU,IAAM,UAAO,EAAE,EAAE,oBAAiB,GAE9C,IAAoB,QAAqC;AAC7D,MAAI;AAIF,UAHI,KAAgB,OAGb,EAAO,YAFL,GAAc;UAGjB;AACN,UAAO;;IAER,CAAC,EAAO,WAAW,EAAa,CAAC,EAE9B,IAAmB,QAAc;AACrC,MAAI,KAAqB,KACvB,QAAO;AAET,MAAI;AACF,UAAO,KAAK,UAAU,EAAkB;UAClC;AACN,UAAO;;IAER,CAAC,EAAkB,CAAC,EAEjB,IAAY,EAAQ,GACpB,IAAY,GACZ,IAAS,KAAa,KAAa,MAEnC,IAAgB,EAAY,KAAK;AAuCvC,QArCA,QAAgB;EACd,IAAI,IAAkB;AAsBtB,SApBI,KAAa,KAAa,SAC5B,EAAS,KAAK,EAEd,IAAa,EAAS,oBAAuB,GAAa;GACxD,cAAc,EAAO;GACrB;GACA,aAAa,EAAO;GACpB,SAAS,EAAO;GAChB,aAAa,EAAO;GACpB,UAAU,MAAc;AAEtB,IADA,EAAS,EAAU,EACnB,EAAO,UAAU,EAAU;;GAE7B,QAAQ,EAAO;GACf,SAAS,EAAO;GACjB,CAAC,EAEF,EAAc,UAAU,UAGb;AACX,OAAI,KAAc,KAChB,KAAI;AACF,MAAW,SAAS;WACd;AAIV,GAAI,EAAc,YAAY,MAC5B,EAAc,UAAU;;IAG3B;EAAC;EAAQ;EAAM;EAAa;EAAW;EAAkB;EAAU,CAAC,EAEhE;EAAE;EAAQ;EAAO"}
@@ -0,0 +1,31 @@
1
+ import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
2
+ //#region src/hooks/useCopyToClipboard.ts
3
+ var i = "copy-to-clipboard-fallback";
4
+ function a(e) {
5
+ if (typeof document > "u") return;
6
+ let t = document.getElementById(i);
7
+ t ?? (t = document.createElement("textarea"), t.id = i, t.setAttribute("readonly", ""), t.style.position = "absolute", t.style.left = "-9999px", t.style.top = "0", t.style.opacity = "0", document.body.appendChild(t)), t.value = e, t.select(), document.execCommand("copy");
8
+ }
9
+ function o(i = 2e3) {
10
+ let [o, s] = r(null), c = n(null);
11
+ return t(() => () => {
12
+ c.current != null && window.clearTimeout(c.current);
13
+ }, []), {
14
+ copiedKey: o,
15
+ copy: e(async (e, t) => {
16
+ let n = !1, r;
17
+ if (typeof navigator < "u" && (r = navigator.clipboard), r != null) try {
18
+ await r.writeText(e), n = !0;
19
+ } catch {
20
+ n = !1;
21
+ }
22
+ return n ||= (a(e), !0), t != null && (s(t), c.current != null && window.clearTimeout(c.current), c.current = window.setTimeout(() => {
23
+ s(null), c.current = null;
24
+ }, i)), n;
25
+ }, [i])
26
+ };
27
+ }
28
+ //#endregion
29
+ export { o as default, o as useCopyToClipboard };
30
+
31
+ //# sourceMappingURL=useCopyToClipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCopyToClipboard.js","names":[],"sources":["../../../src/hooks/useCopyToClipboard.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nconst FALLBACK_TEXTAREA_ID = 'copy-to-clipboard-fallback';\n\n/** Write to the clipboard via a hidden textarea when the Clipboard API is unavailable. */\nfunction writeWithFallback(value: string): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n let textarea = document.getElementById(\n FALLBACK_TEXTAREA_ID,\n ) as HTMLTextAreaElement | null;\n\n if (textarea == null) {\n textarea = document.createElement('textarea');\n textarea.id = FALLBACK_TEXTAREA_ID;\n textarea.setAttribute('readonly', '');\n textarea.style.position = 'absolute';\n textarea.style.left = '-9999px';\n textarea.style.top = '0';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n }\n\n textarea.value = value;\n textarea.select();\n document.execCommand('copy');\n}\n\n/** Copy text with best-effort browser fallback and short-lived copied state. */\nexport function useCopyToClipboard(timeoutMs = 2000): {\n copiedKey: string | null;\n copy: (value: string, key?: string) => Promise<boolean>;\n} {\n const [copiedKey, setCopiedKey] = useState<string | null>(null);\n const timeoutRef = useRef<number | null>(null);\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n }\n };\n }, []);\n\n const copy = useCallback(\n async (value: string, key?: string): Promise<boolean> => {\n let succeeded = false;\n\n let clipboard: Clipboard | undefined;\n if (typeof navigator !== 'undefined') {\n clipboard = navigator.clipboard;\n }\n\n if (clipboard != null) {\n try {\n await clipboard.writeText(value);\n succeeded = true;\n } catch {\n succeeded = false;\n }\n }\n\n if (!succeeded) {\n writeWithFallback(value);\n succeeded = true;\n }\n\n if (key != null) {\n setCopiedKey(key);\n if (timeoutRef.current != null) {\n window.clearTimeout(timeoutRef.current);\n }\n timeoutRef.current = window.setTimeout(() => {\n setCopiedKey(null);\n timeoutRef.current = null;\n }, timeoutMs);\n }\n\n return succeeded;\n },\n [timeoutMs],\n );\n\n return { copiedKey, copy };\n}\n\nexport default useCopyToClipboard;\n"],"mappings":";;AAEA,IAAM,IAAuB;AAG7B,SAAS,EAAkB,GAAqB;AAC9C,KAAI,OAAO,WAAa,IACtB;CAGF,IAAI,IAAW,SAAS,eACtB,EACD;AAeD,CAbI,MACF,IAAW,SAAS,cAAc,WAAW,EAC7C,EAAS,KAAK,GACd,EAAS,aAAa,YAAY,GAAG,EACrC,EAAS,MAAM,WAAW,YAC1B,EAAS,MAAM,OAAO,WACtB,EAAS,MAAM,MAAM,KACrB,EAAS,MAAM,UAAU,KACzB,SAAS,KAAK,YAAY,EAAS,GAGrC,EAAS,QAAQ,GACjB,EAAS,QAAQ,EACjB,SAAS,YAAY,OAAO;;AAI9B,SAAgB,EAAmB,IAAY,KAG7C;CACA,IAAM,CAAC,GAAW,KAAgB,EAAwB,KAAK,EACzD,IAAa,EAAsB,KAAK;AAiD9C,QA/CA,cACe;AACX,EAAI,EAAW,WAAW,QACxB,OAAO,aAAa,EAAW,QAAQ;IAG1C,EAAE,CAAC,EAyCC;EAAE;EAAW,MAvCP,EACX,OAAO,GAAe,MAAmC;GACvD,IAAI,IAAY,IAEZ;AAKJ,OAJI,OAAO,YAAc,QACvB,IAAY,UAAU,YAGpB,KAAa,KACf,KAAI;AAEF,IADA,MAAM,EAAU,UAAU,EAAM,EAChC,IAAY;WACN;AACN,QAAY;;AAoBhB,UAhBA,AAEE,OADA,EAAkB,EAAM,EACZ,KAGV,KAAO,SACT,EAAa,EAAI,EACb,EAAW,WAAW,QACxB,OAAO,aAAa,EAAW,QAAQ,EAEzC,EAAW,UAAU,OAAO,iBAAiB;AAE3C,IADA,EAAa,KAAK,EAClB,EAAW,UAAU;MACpB,EAAU,GAGR;KAET,CAAC,EAAU,CACZ;EAEyB"}
@@ -0,0 +1,23 @@
1
+ import { useCallback as e, useEffect as t, useState as n } from "react";
2
+ //#region src/hooks/useRefetchNeededReload.ts
3
+ function r(r) {
4
+ let [i, a] = n(null);
5
+ return t(() => {
6
+ a(null);
7
+ }, [r]), {
8
+ reason: i,
9
+ onRefetchNeeded: e((e) => {
10
+ a(e ?? "UNKNOWN");
11
+ }, []),
12
+ reload: e(() => {
13
+ window.location.reload();
14
+ }, []),
15
+ clear: e(() => {
16
+ a(null);
17
+ }, [])
18
+ };
19
+ }
20
+ //#endregion
21
+ export { r as useRefetchNeededReload };
22
+
23
+ //# sourceMappingURL=useRefetchNeededReload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRefetchNeededReload.js","names":[],"sources":["../../../src/hooks/useRefetchNeededReload.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\n\ntype RefetchReason = string;\n\ntype UseRefetchNeededReloadReturn = {\n reason: RefetchReason | null;\n onRefetchNeeded: (reason: RefetchReason | null | undefined) => void;\n reload: () => void;\n clear: () => void;\n};\n\n/** Track refetch-needed interruptions and expose a reload helper. */\nexport function useRefetchNeededReload(\n resetKey: string | null | undefined,\n): UseRefetchNeededReloadReturn {\n const [reason, setReason] = useState<RefetchReason | null>(null);\n\n useEffect(() => {\n setReason(null);\n }, [resetKey]);\n\n const onRefetchNeeded = useCallback(\n (nextReason: RefetchReason | null | undefined) => {\n setReason(nextReason ?? 'UNKNOWN');\n },\n [],\n );\n\n const reload = useCallback(() => {\n window.location.reload();\n }, []);\n\n const clear = useCallback(() => {\n setReason(null);\n }, []);\n\n return { reason, onRefetchNeeded, reload, clear };\n}\n"],"mappings":";;AAYA,SAAgB,EACd,GAC8B;CAC9B,IAAM,CAAC,GAAQ,KAAa,EAA+B,KAAK;AAqBhE,QAnBA,QAAgB;AACd,IAAU,KAAK;IACd,CAAC,EAAS,CAAC,EAiBP;EAAE;EAAQ,iBAfO,GACrB,MAAiD;AAChD,KAAU,KAAc,UAAU;KAEpC,EAAE,CACH;EAUiC,QARnB,QAAkB;AAC/B,UAAO,SAAS,QAAQ;KACvB,EAAE,CAAC;EAMoC,OAJ5B,QAAkB;AAC9B,KAAU,KAAK;KACd,EAAE,CAAC;EAE2C"}
@@ -0,0 +1,19 @@
1
+ import { useSharedTranslation as e } from "./useSharedTranslation.js";
2
+ //#region src/i18n/useReviewStatusLabel.ts
3
+ function t() {
4
+ let { t } = e();
5
+ function n(e) {
6
+ if (e == null) return t("review.status.unknown");
7
+ switch (e) {
8
+ case "APPROVED": return t("review.status.approved");
9
+ case "CHANGES_REQUESTED": return t("review.status.changesRequested");
10
+ case "PENDING": return t("review.status.pending");
11
+ default: return t("review.status.unknown");
12
+ }
13
+ }
14
+ return { getReviewStatusLabel: n };
15
+ }
16
+ //#endregion
17
+ export { t as useReviewStatusLabel };
18
+
19
+ //# sourceMappingURL=useReviewStatusLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useReviewStatusLabel.js","names":[],"sources":["../../../src/i18n/useReviewStatusLabel.ts"],"sourcesContent":["import type { ReviewStatus } from '../modules/sharedSchemaTypes.js';\nimport { useSharedTranslation } from './useSharedTranslation.js';\n\nexport type ReviewStatusLabeler = {\n getReviewStatusLabel: (status: ReviewStatus | null | undefined) => string;\n};\n\n/** Provide shared i18n labels for review status values. */\nexport function useReviewStatusLabel(): ReviewStatusLabeler {\n const { t } = useSharedTranslation();\n\n /** Resolve a translated label for a review status value. */\n function getReviewStatusLabel(\n status: ReviewStatus | null | undefined,\n ): string {\n if (status == null) {\n return t('review.status.unknown');\n }\n switch (status) {\n case 'APPROVED':\n return t('review.status.approved');\n case 'CHANGES_REQUESTED':\n return t('review.status.changesRequested');\n case 'PENDING':\n return t('review.status.pending');\n default:\n return t('review.status.unknown');\n }\n }\n\n return { getReviewStatusLabel };\n}\n"],"mappings":";;AAQA,SAAgB,IAA4C;CAC1D,IAAM,EAAE,MAAM,GAAsB;CAGpC,SAAS,EACP,GACQ;AACR,MAAI,KAAU,KACZ,QAAO,EAAE,wBAAwB;AAEnC,UAAQ,GAAR;GACE,KAAK,WACH,QAAO,EAAE,yBAAyB;GACpC,KAAK,oBACH,QAAO,EAAE,iCAAiC;GAC5C,KAAK,UACH,QAAO,EAAE,wBAAwB;GACnC,QACE,QAAO,EAAE,wBAAwB;;;AAIvC,QAAO,EAAE,yBAAsB"}
@@ -0,0 +1,22 @@
1
+ import { useSharedTranslation as e } from "./useSharedTranslation.js";
2
+ //#region src/i18n/useSharedEnumLabels.ts
3
+ function t() {
4
+ let { t } = e();
5
+ function n() {
6
+ return t("projectIngestionStatus.unknown");
7
+ }
8
+ function r(e) {
9
+ if (e == null) return n();
10
+ switch (e) {
11
+ case "IDLE": return t("projectIngestionStatus.idle");
12
+ case "RUNNING": return t("projectIngestionStatus.running");
13
+ case "FAILED": return t("projectIngestionStatus.failed");
14
+ default: return n();
15
+ }
16
+ }
17
+ return { projectIngestionStatus: r };
18
+ }
19
+ //#endregion
20
+ export { t as useSharedEnumLabels };
21
+
22
+ //# sourceMappingURL=useSharedEnumLabels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSharedEnumLabels.js","names":[],"sources":["../../../src/i18n/useSharedEnumLabels.ts"],"sourcesContent":["import type { ProjectIngestionStatusKind } from '../modules/sharedSchemaTypes.js';\nimport { useSharedTranslation } from './useSharedTranslation.js';\n\nexport type SharedEnumLabels = {\n projectIngestionStatus: (\n kind: ProjectIngestionStatusKind | null | undefined,\n ) => string;\n};\n\n/** Provide shared i18n labels for common enum values. */\nexport function useSharedEnumLabels(): SharedEnumLabels {\n const { t } = useSharedTranslation();\n\n /** Resolve the fallback label for unknown ingestion states. */\n function projectIngestionUnknownLabel(): string {\n return t('projectIngestionStatus.unknown');\n }\n\n /** Resolve a translated label for a project ingestion status value. */\n function projectIngestionStatus(\n kind: ProjectIngestionStatusKind | null | undefined,\n ): string {\n if (kind == null) {\n return projectIngestionUnknownLabel();\n }\n switch (kind) {\n case 'IDLE':\n return t('projectIngestionStatus.idle');\n case 'RUNNING':\n return t('projectIngestionStatus.running');\n case 'FAILED':\n return t('projectIngestionStatus.failed');\n default:\n return projectIngestionUnknownLabel();\n }\n }\n\n return { projectIngestionStatus };\n}\n"],"mappings":";;AAUA,SAAgB,IAAwC;CACtD,IAAM,EAAE,MAAM,GAAsB;CAGpC,SAAS,IAAuC;AAC9C,SAAO,EAAE,iCAAiC;;CAI5C,SAAS,EACP,GACQ;AACR,MAAI,KAAQ,KACV,QAAO,GAA8B;AAEvC,UAAQ,GAAR;GACE,KAAK,OACH,QAAO,EAAE,8BAA8B;GACzC,KAAK,UACH,QAAO,EAAE,iCAAiC;GAC5C,KAAK,SACH,QAAO,EAAE,gCAAgC;GAC3C,QACE,QAAO,GAA8B;;;AAI3C,QAAO,EAAE,2BAAwB"}
package/lib/esm/index.js CHANGED
@@ -9,10 +9,26 @@ import { BackofficeOverviewLayout as s } from "./components/backoffice/overview/
9
9
  import { BackofficeInlineFilterRow as c } from "./components/backoffice/shared/BackofficeInlineFilterRow.js";
10
10
  import { BackofficeRelatedCountLink as l } from "./components/backoffice/refs/BackofficeRelatedCountLink.js";
11
11
  import { BackofficeTabbedDetailShell as u } from "./components/backoffice/scaffolds/BackofficeTabbedDetailShell.js";
12
- import { useBackofficeListUrlState as d } from "./hooks/useBackofficeListUrlState.js";
13
- import { BackofficeProvider as f } from "./provider/BackofficeProvider.js";
14
- import { createBackofficeLazyValue as p } from "./provider/lazyValue.js";
15
- import { resolveVisibleDetailPages as m } from "./pages/detail/pageResolution.js";
16
- import { createInlineDataReader as h } from "./relay/createInlineReader.js";
17
- import { identityView as g } from "./relay/identityView.js";
18
- export { r as BackofficeDetailBadgeRow, a as BackofficeDetailPayload, i as BackofficeDetailSection, n as BackofficeErrorBoundary, o as BackofficeFilterAction, c as BackofficeInlineFilterRow, s as BackofficeOverviewLayout, f as BackofficeProvider, l as BackofficeRelatedCountLink, u as BackofficeTabbedDetailShell, t as EntityIdFilterField, p as createBackofficeLazyValue, h as createInlineDataReader, g as identityView, m as resolveVisibleDetailPages, e as useBackofficeConfig, d as useBackofficeListUrlState };
12
+ import { base64UrlToBuffer as d, bufferToBase64Url as f, mapWebAuthnRegistrationError as p, parseSignCount as m } from "./modules/webauthn.js";
13
+ import { createUseAuth as h } from "./hooks/useAuth.js";
14
+ import { useBackofficeListUrlState as g } from "./hooks/useBackofficeListUrlState.js";
15
+ import { useConditionalSubscription as _ } from "./hooks/useConditionalSubscription.js";
16
+ import v from "./hooks/useCopyToClipboard.js";
17
+ import { useRefetchNeededReload as y } from "./hooks/useRefetchNeededReload.js";
18
+ import { createI18nInstance as b } from "./i18n/createI18nInstance.js";
19
+ import { backofficeReactI18nResources as x } from "./i18n/resources.js";
20
+ import { useReviewStatusLabel as S } from "./i18n/useReviewStatusLabel.js";
21
+ import { useSharedEnumLabels as C } from "./i18n/useSharedEnumLabels.js";
22
+ import { BackofficeProvider as w } from "./provider/BackofficeProvider.js";
23
+ import { createBackofficeLazyValue as T } from "./provider/lazyValue.js";
24
+ import { AccessReason as E, canAssignGroupRoles as D, canAssignOrganizationRoles as O, canCreateProject as k, canEditTaskByPermission as A, canLaunchInitiativeTechAgent as j, canLaunchProjectTechAgent as M, canManageBilling as N, canManageGroupInitiatives as P, canManageGroups as F, canManageProject as I, canRunGroupTechAgents as L, canRunOrganizationTechAgents as R, canStartProjectDigestAgent as z, canViewBilling as B, decideConnectorAccess as V } from "./modules/access/viewerPermissionsPolicy.js";
25
+ import { DEFAULT_BILLING_USAGE_CHART_CATEGORIES as H, DEFAULT_BILLING_USAGE_CHART_CATEGORY_COLORS as U, toBillingUsageChartSeries as W } from "./modules/billing/usageChartMappers.js";
26
+ import { decodeBase64ToUtf8 as G, encodeUtf8ToBase64 as K } from "./modules/base64.js";
27
+ import { formatFileSize as q } from "./modules/formatFileSize.js";
28
+ import { createMergeRunViewModel as J, formatMergeBlockReasonCode as Y, getMergeRunStatusTone as X, getMergeRunTone as Z } from "./modules/merge/taskMergeRun.js";
29
+ import { getProjectIngestionStatusMeta as Q } from "./modules/projectIngestionStatus.js";
30
+ import { resolveVisibleDetailPages as $ } from "./pages/detail/pageResolution.js";
31
+ import { createInlineDataReader as ee } from "./relay/createInlineReader.js";
32
+ import { identityView as te } from "./relay/identityView.js";
33
+ import { createConversationStreamUpdater as ne } from "./subscriptions/conversationStream.js";
34
+ export { E as AccessReason, r as BackofficeDetailBadgeRow, a as BackofficeDetailPayload, i as BackofficeDetailSection, n as BackofficeErrorBoundary, o as BackofficeFilterAction, c as BackofficeInlineFilterRow, s as BackofficeOverviewLayout, w as BackofficeProvider, l as BackofficeRelatedCountLink, u as BackofficeTabbedDetailShell, H as DEFAULT_BILLING_USAGE_CHART_CATEGORIES, U as DEFAULT_BILLING_USAGE_CHART_CATEGORY_COLORS, t as EntityIdFilterField, x as backofficeReactI18nResources, d as base64UrlToBuffer, f as bufferToBase64Url, D as canAssignGroupRoles, O as canAssignOrganizationRoles, k as canCreateProject, A as canEditTaskByPermission, j as canLaunchInitiativeTechAgent, M as canLaunchProjectTechAgent, N as canManageBilling, P as canManageGroupInitiatives, F as canManageGroups, I as canManageProject, L as canRunGroupTechAgents, R as canRunOrganizationTechAgents, z as canStartProjectDigestAgent, B as canViewBilling, T as createBackofficeLazyValue, ne as createConversationStreamUpdater, b as createI18nInstance, ee as createInlineDataReader, J as createMergeRunViewModel, h as createUseAuth, V as decideConnectorAccess, G as decodeBase64ToUtf8, K as encodeUtf8ToBase64, q as formatFileSize, Y as formatMergeBlockReasonCode, X as getMergeRunStatusTone, Z as getMergeRunTone, Q as getProjectIngestionStatusMeta, te as identityView, p as mapWebAuthnRegistrationError, m as parseSignCount, $ as resolveVisibleDetailPages, W as toBillingUsageChartSeries, e as useBackofficeConfig, g as useBackofficeListUrlState, _ as useConditionalSubscription, v as useCopyToClipboard, y as useRefetchNeededReload, S as useReviewStatusLabel, C as useSharedEnumLabels };
@@ -0,0 +1,17 @@
1
+ //#region src/modules/access/viewerPermissionsPolicy.ts
2
+ var e = /* @__PURE__ */ function(e) {
3
+ return e.MissingPermission = "MISSING_PERMISSION", e.FeatureDisabled = "FEATURE_DISABLED", e;
4
+ }({}), t = (e) => e === !0, n = (e) => t(e), r = (e) => t(e), i = (e) => t(e), a = (e) => t(e), o = (e) => t(e), s = (e) => t(e), c = (e) => t(e), l = (e) => t(e), u = (e) => t(e), d = (e) => t(e), f = (e) => t(e), p = (e) => t(e), m = (e) => t(e), h = (e) => t(e), g = (e) => t(e), _ = (e) => t(e), v = (e) => c(e.canManageGroup) && s(e.canManageProjects), y = (t) => t.isConnectorsEnabled ? a(t.canAssignRoles) ? {
5
+ allowed: !0,
6
+ reason: null
7
+ } : {
8
+ allowed: !1,
9
+ reason: e.MissingPermission
10
+ } : {
11
+ allowed: !1,
12
+ reason: e.FeatureDisabled
13
+ }, b = (e) => e.isGitRepositoryReady && f(e.canLaunchTechAgent);
14
+ //#endregion
15
+ export { e as AccessReason, u as canAssignGroupRoles, a as canAssignOrganizationRoles, v as canCreateProject, m as canEditTaskByPermission, _ as canLaunchInitiativeTechAgent, f as canLaunchProjectTechAgent, h as canLaunchTaskDevAgent, g as canLaunchTaskReviewAgent, n as canManageBilling, c as canManageGroup, l as canManageGroupInitiatives, o as canManageGroups, p as canManageProject, s as canManageProjects, d as canRunGroupTechAgents, i as canRunOrganizationTechAgents, b as canStartProjectDigestAgent, r as canViewBilling, y as decideConnectorAccess, t as hasCapability };
16
+
17
+ //# sourceMappingURL=viewerPermissionsPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewerPermissionsPolicy.js","names":[],"sources":["../../../../src/modules/access/viewerPermissionsPolicy.ts"],"sourcesContent":["export enum AccessReason {\n MissingPermission = 'MISSING_PERMISSION',\n FeatureDisabled = 'FEATURE_DISABLED',\n}\n\nexport type AccessDecision = {\n readonly allowed: boolean;\n readonly reason: AccessReason | null;\n};\n\nexport const hasCapability = (value: boolean | null | undefined): boolean => {\n return value === true;\n};\n\nexport const canManageBilling = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canViewBilling = (value: boolean | null | undefined): boolean => {\n return hasCapability(value);\n};\n\nexport const canRunOrganizationTechAgents = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canAssignOrganizationRoles = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canManageGroups = (value: boolean | null | undefined): boolean => {\n return hasCapability(value);\n};\n\nexport const canManageProjects = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canManageGroup = (value: boolean | null | undefined): boolean => {\n return hasCapability(value);\n};\n\nexport const canManageGroupInitiatives = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canAssignGroupRoles = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canRunGroupTechAgents = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canLaunchProjectTechAgent = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canManageProject = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canEditTaskByPermission = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canLaunchTaskDevAgent = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canLaunchTaskReviewAgent = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canLaunchInitiativeTechAgent = (\n value: boolean | null | undefined,\n): boolean => {\n return hasCapability(value);\n};\n\nexport const canCreateProject = (params: {\n readonly canManageGroup: boolean | null | undefined;\n readonly canManageProjects: boolean | null | undefined;\n}): boolean => {\n return (\n canManageGroup(params.canManageGroup) &&\n canManageProjects(params.canManageProjects)\n );\n};\n\nexport const decideConnectorAccess = (params: {\n readonly canAssignRoles: boolean | null | undefined;\n readonly isConnectorsEnabled: boolean;\n}): AccessDecision => {\n if (!params.isConnectorsEnabled) {\n return { allowed: false, reason: AccessReason.FeatureDisabled };\n }\n if (!canAssignOrganizationRoles(params.canAssignRoles)) {\n return { allowed: false, reason: AccessReason.MissingPermission };\n }\n return { allowed: true, reason: null };\n};\n\nexport const canStartProjectDigestAgent = (params: {\n readonly isGitRepositoryReady: boolean;\n readonly canLaunchTechAgent: boolean | null | undefined;\n}): boolean => {\n return (\n params.isGitRepositoryReady &&\n canLaunchProjectTechAgent(params.canLaunchTechAgent)\n );\n};\n"],"mappings":";AAAA,IAAY,IAAL,yBAAA,GAAA;QACL,EAAA,oBAAA,sBACA,EAAA,kBAAA;KACD,EAOY,KAAiB,MACrB,MAAU,IAGN,KACX,MAEO,EAAc,EAAM,EAGhB,KAAkB,MACtB,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KAAmB,MACvB,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KAAkB,MACtB,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KACX,MAEO,EAAc,EAAM,EAGhB,KAAoB,MAK7B,EAAe,EAAO,eAAe,IACrC,EAAkB,EAAO,kBAAkB,EAIlC,KAAyB,MAI/B,EAAO,sBAGP,EAA2B,EAAO,eAAe,GAG/C;CAAE,SAAS;CAAM,QAAQ;CAAM,GAF7B;CAAE,SAAS;CAAO,QAAQ,EAAa;CAAmB,GAH1D;CAAE,SAAS;CAAO,QAAQ,EAAa;CAAiB,EAQtD,KAA8B,MAKvC,EAAO,wBACP,EAA0B,EAAO,mBAAmB"}
@@ -0,0 +1,23 @@
1
+ //#region src/modules/base64.ts
2
+ function e(e) {
3
+ if (typeof e != "string") throw TypeError("encodeUtf8ToBase64 expects a string input.");
4
+ if (typeof Buffer < "u") return Buffer.from(e, "utf-8").toString("base64");
5
+ if (typeof globalThis.btoa == "function") {
6
+ let t = encodeURIComponent(e).replace(/%([0-9A-F]{2})/g, (e, t) => String.fromCharCode(Number.parseInt(t, 16)));
7
+ return globalThis.btoa(t);
8
+ }
9
+ throw Error("No base64 encoder is available in this environment.");
10
+ }
11
+ function t(e) {
12
+ if (typeof e != "string") throw TypeError("decodeBase64ToUtf8 expects a string input.");
13
+ if (typeof Buffer < "u") return Buffer.from(e, "base64").toString("utf-8");
14
+ if (typeof globalThis.atob == "function") {
15
+ let t = globalThis.atob(e), n = Array.from(t, (e) => `%${e.charCodeAt(0).toString(16).padStart(2, "0")}`).join("");
16
+ return decodeURIComponent(n);
17
+ }
18
+ throw Error("No base64 decoder is available in this environment.");
19
+ }
20
+ //#endregion
21
+ export { t as decodeBase64ToUtf8, e as encodeUtf8ToBase64 };
22
+
23
+ //# sourceMappingURL=base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64.js","names":[],"sources":["../../../src/modules/base64.ts"],"sourcesContent":["/** Encode a UTF-8 string into base64 using native helpers when available. */\nexport function encodeUtf8ToBase64(value: string): string {\n if (typeof value !== 'string') {\n throw new TypeError('encodeUtf8ToBase64 expects a string input.');\n }\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(value, 'utf-8').toString('base64');\n }\n\n if (typeof globalThis.btoa === 'function') {\n const utf8 = encodeURIComponent(value).replace(\n /%([0-9A-F]{2})/g,\n (_, code) => {\n return String.fromCharCode(Number.parseInt(code, 16));\n },\n );\n return globalThis.btoa(utf8);\n }\n\n throw new Error('No base64 encoder is available in this environment.');\n}\n\n/** Decode a base64 string into UTF-8 using native helpers when available. */\nexport function decodeBase64ToUtf8(value: string): string {\n if (typeof value !== 'string') {\n throw new TypeError('decodeBase64ToUtf8 expects a string input.');\n }\n\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(value, 'base64').toString('utf-8');\n }\n\n if (typeof globalThis.atob === 'function') {\n const binary = globalThis.atob(value);\n const percentEncoded = Array.from(binary, (char) => {\n const code = char.charCodeAt(0).toString(16).padStart(2, '0');\n return `%${code}`;\n }).join('');\n return decodeURIComponent(percentEncoded);\n }\n\n throw new Error('No base64 decoder is available in this environment.');\n}\n"],"mappings":";AACA,SAAgB,EAAmB,GAAuB;AACxD,KAAI,OAAO,KAAU,SACnB,OAAU,UAAU,6CAA6C;AAGnE,KAAI,OAAO,SAAW,IACpB,QAAO,OAAO,KAAK,GAAO,QAAQ,CAAC,SAAS,SAAS;AAGvD,KAAI,OAAO,WAAW,QAAS,YAAY;EACzC,IAAM,IAAO,mBAAmB,EAAM,CAAC,QACrC,oBACC,GAAG,MACK,OAAO,aAAa,OAAO,SAAS,GAAM,GAAG,CAAC,CAExD;AACD,SAAO,WAAW,KAAK,EAAK;;AAG9B,OAAU,MAAM,sDAAsD;;AAIxE,SAAgB,EAAmB,GAAuB;AACxD,KAAI,OAAO,KAAU,SACnB,OAAU,UAAU,6CAA6C;AAGnE,KAAI,OAAO,SAAW,IACpB,QAAO,OAAO,KAAK,GAAO,SAAS,CAAC,SAAS,QAAQ;AAGvD,KAAI,OAAO,WAAW,QAAS,YAAY;EACzC,IAAM,IAAS,WAAW,KAAK,EAAM,EAC/B,IAAiB,MAAM,KAAK,IAAS,MAElC,IADM,EAAK,WAAW,EAAE,CAAC,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,GAE7D,CAAC,KAAK,GAAG;AACX,SAAO,mBAAmB,EAAe;;AAG3C,OAAU,MAAM,sDAAsD"}
@@ -0,0 +1,49 @@
1
+ //#region src/modules/billing/usageChartMappers.ts
2
+ var e = [
3
+ "INGESTION",
4
+ "CHAT",
5
+ "DEVELOPMENT"
6
+ ], t = {
7
+ INGESTION: "#0B84A5",
8
+ CHAT: "#F6C85F",
9
+ DEVELOPMENT: "#6F4E7C"
10
+ }, n = 1440 * 60 * 1e3;
11
+ function r(e) {
12
+ return new Date(Date.UTC(e.getUTCFullYear(), e.getUTCMonth(), e.getUTCDate()));
13
+ }
14
+ function i(e) {
15
+ let t = new Date(e);
16
+ if (Number.isNaN(t.getTime())) throw Error(`Invalid ISO datetime: ${e}`);
17
+ return r(t).toISOString().slice(0, 10);
18
+ }
19
+ function a(e, t) {
20
+ let i = r(new Date(e)), a = r(new Date(t));
21
+ if (Number.isNaN(i.getTime())) throw Error(`Invalid "from" datetime: ${e}`);
22
+ if (Number.isNaN(a.getTime())) throw Error(`Invalid "to" datetime: ${t}`);
23
+ if (i.getTime() > a.getTime()) throw Error(`"from" must be before or equal to "to": ${e} > ${t}`);
24
+ let o = [];
25
+ for (let e = i.getTime(); e <= a.getTime(); e += n) o.push(new Date(e).toISOString().slice(0, 10));
26
+ return o;
27
+ }
28
+ function o(e, t) {
29
+ let n = /* @__PURE__ */ new Map();
30
+ for (let r of e) if (t.includes(r.category)) {
31
+ let e = `${i(r.day)}|${r.category}`, t = n.get(e) ?? 0;
32
+ n.set(e, t + r.credits);
33
+ }
34
+ return n;
35
+ }
36
+ function s(e) {
37
+ let t = a(e.fromIsoDateTime, e.toIsoDateTime), n = o(e.buckets, e.categories);
38
+ return e.categories.map((e) => ({
39
+ id: e,
40
+ data: t.map((t) => ({
41
+ x: t,
42
+ y: n.get(`${t}|${e}`) ?? 0
43
+ }))
44
+ }));
45
+ }
46
+ //#endregion
47
+ export { e as DEFAULT_BILLING_USAGE_CHART_CATEGORIES, t as DEFAULT_BILLING_USAGE_CHART_CATEGORY_COLORS, o as aggregateCreditsByDayAndCategory, a as buildUtcDayRange, s as toBillingUsageChartSeries, i as toUtcDayKey };
48
+
49
+ //# sourceMappingURL=usageChartMappers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usageChartMappers.js","names":[],"sources":["../../../../src/modules/billing/usageChartMappers.ts"],"sourcesContent":["export type BillingChartPoint = {\n x: string;\n y: number;\n};\n\nexport type BillingChartSerie<Category extends string> = {\n id: Category;\n data: readonly BillingChartPoint[];\n};\n\nexport type BillingChartBucketInput<Category extends string> = {\n day: string;\n category: Category;\n credits: number;\n};\n\nexport const DEFAULT_BILLING_USAGE_CHART_CATEGORIES = [\n 'INGESTION',\n 'CHAT',\n 'DEVELOPMENT',\n] as const;\n\nexport type DefaultBillingUsageChartCategory =\n (typeof DEFAULT_BILLING_USAGE_CHART_CATEGORIES)[number];\n\nexport const DEFAULT_BILLING_USAGE_CHART_CATEGORY_COLORS: Readonly<\n Record<DefaultBillingUsageChartCategory, string>\n> = {\n INGESTION: '#0B84A5',\n CHAT: '#F6C85F',\n DEVELOPMENT: '#6F4E7C',\n};\n\nconst UTC_DAY_MS = 24 * 60 * 60 * 1000;\n\n/** Truncate a date to UTC midnight for stable day-based aggregation. */\nfunction toUtcMidnightDate(value: Date): Date {\n return new Date(\n Date.UTC(value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate()),\n );\n}\n\n/** Normalize an ISO datetime string to a UTC day key. */\nexport function toUtcDayKey(isoDateTime: string): string {\n const parsed = new Date(isoDateTime);\n if (Number.isNaN(parsed.getTime())) {\n throw new Error(`Invalid ISO datetime: ${isoDateTime}`);\n }\n return toUtcMidnightDate(parsed).toISOString().slice(0, 10);\n}\n\n/** Build an inclusive list of UTC day keys between two ISO datetimes. */\nexport function buildUtcDayRange(\n fromIsoDateTime: string,\n toIsoDateTime: string,\n): readonly string[] {\n const from = toUtcMidnightDate(new Date(fromIsoDateTime));\n const to = toUtcMidnightDate(new Date(toIsoDateTime));\n\n if (Number.isNaN(from.getTime())) {\n throw new Error(`Invalid \"from\" datetime: ${fromIsoDateTime}`);\n }\n if (Number.isNaN(to.getTime())) {\n throw new Error(`Invalid \"to\" datetime: ${toIsoDateTime}`);\n }\n if (from.getTime() > to.getTime()) {\n throw new Error(\n `\"from\" must be before or equal to \"to\": ${fromIsoDateTime} > ${toIsoDateTime}`,\n );\n }\n\n const dayKeys: string[] = [];\n for (\n let cursor = from.getTime();\n cursor <= to.getTime();\n cursor += UTC_DAY_MS\n ) {\n dayKeys.push(new Date(cursor).toISOString().slice(0, 10));\n }\n\n return dayKeys;\n}\n\n/** Aggregate credit usage by UTC day and category for the requested categories. */\nexport function aggregateCreditsByDayAndCategory<Category extends string>(\n buckets: readonly BillingChartBucketInput<Category>[],\n allowedCategories: readonly Category[],\n): ReadonlyMap<string, number> {\n const totals = new Map<string, number>();\n\n for (const bucket of buckets) {\n if (allowedCategories.includes(bucket.category)) {\n const dayKey = toUtcDayKey(bucket.day);\n const key = `${dayKey}|${bucket.category}`;\n const previous = totals.get(key) ?? 0;\n totals.set(key, previous + bucket.credits);\n }\n }\n\n return totals;\n}\n\n/** Convert bucketed usage data into zero-filled chart series for each category. */\nexport function toBillingUsageChartSeries<Category extends string>(params: {\n fromIsoDateTime: string;\n toIsoDateTime: string;\n buckets: readonly BillingChartBucketInput<Category>[];\n categories: readonly Category[];\n}): readonly BillingChartSerie<Category>[] {\n const dayKeys = buildUtcDayRange(\n params.fromIsoDateTime,\n params.toIsoDateTime,\n );\n const totals = aggregateCreditsByDayAndCategory(\n params.buckets,\n params.categories,\n );\n\n return params.categories.map((category) => {\n const points = dayKeys.map((dayKey) => {\n return {\n x: dayKey,\n y: totals.get(`${dayKey}|${category}`) ?? 0,\n };\n });\n\n return {\n id: category,\n data: points,\n };\n });\n}\n"],"mappings":";AAgBA,IAAa,IAAyC;CACpD;CACA;CACA;CACD,EAKY,IAET;CACF,WAAW;CACX,MAAM;CACN,aAAa;CACd,EAEK,IAAa,OAAU,KAAK;AAGlC,SAAS,EAAkB,GAAmB;AAC5C,QAAO,IAAI,KACT,KAAK,IAAI,EAAM,gBAAgB,EAAE,EAAM,aAAa,EAAE,EAAM,YAAY,CAAC,CAC1E;;AAIH,SAAgB,EAAY,GAA6B;CACvD,IAAM,IAAS,IAAI,KAAK,EAAY;AACpC,KAAI,OAAO,MAAM,EAAO,SAAS,CAAC,CAChC,OAAU,MAAM,yBAAyB,IAAc;AAEzD,QAAO,EAAkB,EAAO,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG;;AAI7D,SAAgB,EACd,GACA,GACmB;CACnB,IAAM,IAAO,EAAkB,IAAI,KAAK,EAAgB,CAAC,EACnD,IAAK,EAAkB,IAAI,KAAK,EAAc,CAAC;AAErD,KAAI,OAAO,MAAM,EAAK,SAAS,CAAC,CAC9B,OAAU,MAAM,4BAA4B,IAAkB;AAEhE,KAAI,OAAO,MAAM,EAAG,SAAS,CAAC,CAC5B,OAAU,MAAM,0BAA0B,IAAgB;AAE5D,KAAI,EAAK,SAAS,GAAG,EAAG,SAAS,CAC/B,OAAU,MACR,2CAA2C,EAAgB,KAAK,IACjE;CAGH,IAAM,IAAoB,EAAE;AAC5B,MACE,IAAI,IAAS,EAAK,SAAS,EAC3B,KAAU,EAAG,SAAS,EACtB,KAAU,EAEV,GAAQ,KAAK,IAAI,KAAK,EAAO,CAAC,aAAa,CAAC,MAAM,GAAG,GAAG,CAAC;AAG3D,QAAO;;AAIT,SAAgB,EACd,GACA,GAC6B;CAC7B,IAAM,oBAAS,IAAI,KAAqB;AAExC,MAAK,IAAM,KAAU,EACnB,KAAI,EAAkB,SAAS,EAAO,SAAS,EAAE;EAE/C,IAAM,IAAM,GADG,EAAY,EAAO,IAAI,CAChB,GAAG,EAAO,YAC1B,IAAW,EAAO,IAAI,EAAI,IAAI;AACpC,IAAO,IAAI,GAAK,IAAW,EAAO,QAAQ;;AAI9C,QAAO;;AAIT,SAAgB,EAAmD,GAKxB;CACzC,IAAM,IAAU,EACd,EAAO,iBACP,EAAO,cACR,EACK,IAAS,EACb,EAAO,SACP,EAAO,WACR;AAED,QAAO,EAAO,WAAW,KAAK,OAQrB;EACL,IAAI;EACJ,MATa,EAAQ,KAAK,OACnB;GACL,GAAG;GACH,GAAG,EAAO,IAAI,GAAG,EAAO,GAAG,IAAW,IAAI;GAC3C,EACD;EAKD,EACD"}
@@ -0,0 +1,28 @@
1
+ //#region src/modules/formatFileSize.ts
2
+ var e = [
3
+ "B",
4
+ "KB",
5
+ "MB",
6
+ "GB",
7
+ "TB"
8
+ ], t = 1024, n = (e, t) => {
9
+ if (t === "B") return Math.round(e).toString();
10
+ let n = 1;
11
+ return e >= 10 && (n = 0), e.toFixed(n);
12
+ };
13
+ function r(r) {
14
+ let i = r;
15
+ Number.isFinite(r) || (i = 0);
16
+ let a = i < 0, o = Math.abs(i), s = 0;
17
+ for (; o >= t && s < e.length - 1;) o /= t, s += 1;
18
+ let c = e[s] ?? "B", l = o;
19
+ return a && (l = -o), {
20
+ value: l,
21
+ unit: c,
22
+ displayValue: n(l, c)
23
+ };
24
+ }
25
+ //#endregion
26
+ export { r as formatFileSize };
27
+
28
+ //# sourceMappingURL=formatFileSize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatFileSize.js","names":[],"sources":["../../../src/modules/formatFileSize.ts"],"sourcesContent":["export type FileSizeUnit = 'B' | 'KB' | 'MB' | 'GB' | 'TB';\n\nexport type FileSizeResult = {\n value: number;\n unit: FileSizeUnit;\n displayValue: string;\n};\n\nconst SIZE_UNITS: readonly FileSizeUnit[] = ['B', 'KB', 'MB', 'GB', 'TB'];\nconst BASE = 1024;\n\nconst roundValue = (value: number, unit: FileSizeUnit): string => {\n if (unit === 'B') {\n return Math.round(value).toString();\n }\n let decimals = 1;\n if (value >= 10) {\n decimals = 0;\n }\n return value.toFixed(decimals);\n};\n\n/** Format a byte count into a human-readable value and unit. */\nexport function formatFileSize(bytes: number): FileSizeResult {\n let normalized = bytes;\n if (!Number.isFinite(bytes)) {\n normalized = 0;\n }\n const isNegative = normalized < 0;\n let value = Math.abs(normalized);\n let unitIndex = 0;\n\n while (value >= BASE && unitIndex < SIZE_UNITS.length - 1) {\n value /= BASE;\n unitIndex += 1;\n }\n\n const unit = SIZE_UNITS[unitIndex] ?? 'B';\n let signedValue = value;\n if (isNegative) {\n signedValue = -value;\n }\n\n return {\n value: signedValue,\n unit,\n displayValue: roundValue(signedValue, unit),\n };\n}\n"],"mappings":";AAQA,IAAM,IAAsC;CAAC;CAAK;CAAM;CAAM;CAAM;CAAK,EACnE,IAAO,MAEP,KAAc,GAAe,MAA+B;AAChE,KAAI,MAAS,IACX,QAAO,KAAK,MAAM,EAAM,CAAC,UAAU;CAErC,IAAI,IAAW;AAIf,QAHI,KAAS,OACX,IAAW,IAEN,EAAM,QAAQ,EAAS;;AAIhC,SAAgB,EAAe,GAA+B;CAC5D,IAAI,IAAa;AACjB,CAAK,OAAO,SAAS,EAAM,KACzB,IAAa;CAEf,IAAM,IAAa,IAAa,GAC5B,IAAQ,KAAK,IAAI,EAAW,EAC5B,IAAY;AAEhB,QAAO,KAAS,KAAQ,IAAY,EAAW,SAAS,GAEtD,CADA,KAAS,GACT,KAAa;CAGf,IAAM,IAAO,EAAW,MAAc,KAClC,IAAc;AAKlB,QAJI,MACF,IAAc,CAAC,IAGV;EACL,OAAO;EACP;EACA,cAAc,EAAW,GAAa,EAAK;EAC5C"}
@@ -0,0 +1,67 @@
1
+ //#region src/modules/merge/taskMergeRun.ts
2
+ function e(e) {
3
+ return e == null ? [] : e.filter((e) => e.trim() !== "");
4
+ }
5
+ function t(t) {
6
+ return t == null ? [] : t.filter((e) => e.path != null && e.path.trim() !== "").map((t) => {
7
+ let n = t.kind, r = "SQUASH";
8
+ return n === "REBASE" && (r = "REBASE"), {
9
+ path: t.path ?? "",
10
+ kind: r,
11
+ relatedTaskIds: e(t.relatedTaskIds)
12
+ };
13
+ });
14
+ }
15
+ function n(n) {
16
+ return {
17
+ runKind: n.runKind ?? "NOT_STARTED",
18
+ runStatus: n.runStatus ?? null,
19
+ startedAt: n.startedAt ?? null,
20
+ completedAt: n.completedAt ?? null,
21
+ requestedAt: n.mergeStateRequestedAt ?? null,
22
+ mergedAt: n.mergeStateMergedAt ?? null,
23
+ sourceBranch: n.sourceBranch ?? null,
24
+ targetBranch: n.targetBranch ?? null,
25
+ reasonCode: n.reasonCode ?? null,
26
+ conflictFiles: e(n.conflictFiles),
27
+ conflictDetails: t(n.conflictDetails),
28
+ attemptedCommands: e(n.attemptedCommands)
29
+ };
30
+ }
31
+ function r(e) {
32
+ switch (e) {
33
+ case "RUNNING": return "info";
34
+ case "COMPLETED": return "success";
35
+ case "FAILED": return "danger";
36
+ default: return "neutral";
37
+ }
38
+ }
39
+ function i(e) {
40
+ if (e == null) return "neutral";
41
+ switch (e) {
42
+ case "SUCCEEDED": return "success";
43
+ case "BLOCKED": return "warning";
44
+ default: return "neutral";
45
+ }
46
+ }
47
+ function a(e) {
48
+ return e.runStatus === "BLOCKED";
49
+ }
50
+ function o(e) {
51
+ if (e == null) return "Unknown";
52
+ switch (e) {
53
+ case "CONFLICT_NEEDS_HUMAN_DECISION": return "Conflict needs human decision";
54
+ case "CONFLICT_UNRESOLVED": return "Conflict unresolved";
55
+ case "BRANCH_NOT_FOUND": return "Branch not found";
56
+ case "PERMISSION_DENIED": return "Permission denied";
57
+ case "TARGET_MOVED": return "Target moved";
58
+ case "REMOTE_POLICY_REJECTED": return "Remote policy rejected";
59
+ case "CI_POLICY_BLOCKED": return "CI policy blocked";
60
+ case "RETRY_BUDGET_EXCEEDED": return "Retry budget exceeded";
61
+ default: return "Unknown";
62
+ }
63
+ }
64
+ //#endregion
65
+ export { n as createMergeRunViewModel, o as formatMergeBlockReasonCode, i as getMergeRunStatusTone, r as getMergeRunTone, a as isMergeRunBlocked };
66
+
67
+ //# sourceMappingURL=taskMergeRun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taskMergeRun.js","names":[],"sources":["../../../../src/modules/merge/taskMergeRun.ts"],"sourcesContent":["export type MergeBlockReasonCode =\n | 'CONFLICT_NEEDS_HUMAN_DECISION'\n | 'CONFLICT_UNRESOLVED'\n | 'BRANCH_NOT_FOUND'\n | 'PERMISSION_DENIED'\n | 'TARGET_MOVED'\n | 'REMOTE_POLICY_REJECTED'\n | 'CI_POLICY_BLOCKED'\n | 'RETRY_BUDGET_EXCEEDED'\n | 'UNKNOWN';\n\nexport type ToolMergeBlockReasonCode = MergeBlockReasonCode;\n\nexport type TaskMergeConflictKind = 'SQUASH' | 'REBASE';\n\nexport type TaskMergeRunStateKind =\n | 'NOT_STARTED'\n | 'RUNNING'\n | 'COMPLETED'\n | 'FAILED';\n\nexport type TaskMergeRunStatus = 'SUCCEEDED' | 'BLOCKED';\n\nexport type MergeConflictDetailViewModel = {\n path: string;\n kind: TaskMergeConflictKind;\n relatedTaskIds: readonly string[];\n};\n\nexport type MergeRunViewModel = {\n runKind: TaskMergeRunStateKind;\n runStatus: TaskMergeRunStatus | null;\n startedAt: string | null;\n completedAt: string | null;\n requestedAt: string | null;\n mergedAt: string | null;\n sourceBranch: string | null;\n targetBranch: string | null;\n reasonCode: MergeBlockReasonCode | null;\n conflictFiles: readonly string[];\n conflictDetails: readonly MergeConflictDetailViewModel[];\n attemptedCommands: readonly string[];\n};\n\nexport type MergeRunInput = {\n mergeStateRequestedAt?: string | null;\n mergeStateMergedAt?: string | null;\n runKind?: TaskMergeRunStateKind | null;\n runStatus?: TaskMergeRunStatus | null;\n startedAt?: string | null;\n completedAt?: string | null;\n sourceBranch?: string | null;\n targetBranch?: string | null;\n reasonCode?: MergeBlockReasonCode | null;\n conflictFiles?: readonly string[] | null;\n conflictDetails?:\n | readonly {\n path?: string | null;\n kind?: TaskMergeConflictKind | null;\n relatedTaskIds?: readonly string[] | null;\n }[]\n | null;\n attemptedCommands?: readonly string[] | null;\n};\n\n/** Normalize an optional string list by removing blank values. */\nfunction normalizeStringList(\n value: readonly string[] | null | undefined,\n): string[] {\n if (value == null) {\n return [];\n }\n return value.filter((entry) => {\n return entry.trim() !== '';\n });\n}\n\n/** Normalize raw conflict details into the view-model shape consumed by the UI. */\nfunction normalizeConflictDetails(\n value: MergeRunInput['conflictDetails'],\n): MergeConflictDetailViewModel[] {\n if (value == null) {\n return [];\n }\n\n return value\n .filter((entry) => {\n return entry.path != null && entry.path.trim() !== '';\n })\n .map((entry) => {\n const rawKind = entry.kind;\n let kind: TaskMergeConflictKind = 'SQUASH';\n if (rawKind === 'REBASE') {\n kind = 'REBASE';\n }\n\n return {\n path: entry.path ?? '',\n kind,\n relatedTaskIds: normalizeStringList(entry.relatedTaskIds),\n };\n });\n}\n\n/** Build a merge-run view model from partially populated API input. */\nexport function createMergeRunViewModel(\n input: MergeRunInput,\n): MergeRunViewModel {\n const runKind = input.runKind ?? 'NOT_STARTED';\n\n return {\n runKind,\n runStatus: input.runStatus ?? null,\n startedAt: input.startedAt ?? null,\n completedAt: input.completedAt ?? null,\n requestedAt: input.mergeStateRequestedAt ?? null,\n mergedAt: input.mergeStateMergedAt ?? null,\n sourceBranch: input.sourceBranch ?? null,\n targetBranch: input.targetBranch ?? null,\n reasonCode: input.reasonCode ?? null,\n conflictFiles: normalizeStringList(input.conflictFiles),\n conflictDetails: normalizeConflictDetails(input.conflictDetails),\n attemptedCommands: normalizeStringList(input.attemptedCommands),\n };\n}\n\n/** Map a merge run state to its UI tone. */\nexport function getMergeRunTone(\n kind: TaskMergeRunStateKind,\n): 'neutral' | 'info' | 'success' | 'warning' | 'danger' {\n switch (kind) {\n case 'RUNNING':\n return 'info';\n case 'COMPLETED':\n return 'success';\n case 'FAILED':\n return 'danger';\n case 'NOT_STARTED':\n default:\n return 'neutral';\n }\n}\n\n/** Map a merge run status to its UI tone. */\nexport function getMergeRunStatusTone(\n status: TaskMergeRunStatus | null,\n): 'neutral' | 'success' | 'warning' {\n if (status == null) {\n return 'neutral';\n }\n\n switch (status) {\n case 'SUCCEEDED':\n return 'success';\n case 'BLOCKED':\n return 'warning';\n default:\n return 'neutral';\n }\n}\n\n/** Indicate whether a merge run is currently blocked. */\nexport function isMergeRunBlocked(model: MergeRunViewModel): boolean {\n return model.runStatus === 'BLOCKED';\n}\n\n/** Format a machine merge-block reason into a human-readable label. */\nexport function formatMergeBlockReasonCode(\n reasonCode:\n | MergeBlockReasonCode\n | ToolMergeBlockReasonCode\n | null\n | undefined,\n): string {\n if (reasonCode == null) {\n return 'Unknown';\n }\n\n switch (reasonCode) {\n case 'CONFLICT_NEEDS_HUMAN_DECISION':\n return 'Conflict needs human decision';\n case 'CONFLICT_UNRESOLVED':\n return 'Conflict unresolved';\n case 'BRANCH_NOT_FOUND':\n return 'Branch not found';\n case 'PERMISSION_DENIED':\n return 'Permission denied';\n case 'TARGET_MOVED':\n return 'Target moved';\n case 'REMOTE_POLICY_REJECTED':\n return 'Remote policy rejected';\n case 'CI_POLICY_BLOCKED':\n return 'CI policy blocked';\n case 'RETRY_BUDGET_EXCEEDED':\n return 'Retry budget exceeded';\n case 'UNKNOWN':\n default:\n return 'Unknown';\n }\n}\n"],"mappings":";AAkEA,SAAS,EACP,GACU;AAIV,QAHI,KAAS,OACJ,EAAE,GAEJ,EAAM,QAAQ,MACZ,EAAM,MAAM,KAAK,GACxB;;AAIJ,SAAS,EACP,GACgC;AAKhC,QAJI,KAAS,OACJ,EAAE,GAGJ,EACJ,QAAQ,MACA,EAAM,QAAQ,QAAQ,EAAM,KAAK,MAAM,KAAK,GACnD,CACD,KAAK,MAAU;EACd,IAAM,IAAU,EAAM,MAClB,IAA8B;AAKlC,SAJI,MAAY,aACd,IAAO,WAGF;GACL,MAAM,EAAM,QAAQ;GACpB;GACA,gBAAgB,EAAoB,EAAM,eAAe;GAC1D;GACD;;AAIN,SAAgB,EACd,GACmB;AAGnB,QAAO;EACL,SAHc,EAAM,WAAW;EAI/B,WAAW,EAAM,aAAa;EAC9B,WAAW,EAAM,aAAa;EAC9B,aAAa,EAAM,eAAe;EAClC,aAAa,EAAM,yBAAyB;EAC5C,UAAU,EAAM,sBAAsB;EACtC,cAAc,EAAM,gBAAgB;EACpC,cAAc,EAAM,gBAAgB;EACpC,YAAY,EAAM,cAAc;EAChC,eAAe,EAAoB,EAAM,cAAc;EACvD,iBAAiB,EAAyB,EAAM,gBAAgB;EAChE,mBAAmB,EAAoB,EAAM,kBAAkB;EAChE;;AAIH,SAAgB,EACd,GACuD;AACvD,SAAQ,GAAR;EACE,KAAK,UACH,QAAO;EACT,KAAK,YACH,QAAO;EACT,KAAK,SACH,QAAO;EAET,QACE,QAAO;;;AAKb,SAAgB,EACd,GACmC;AACnC,KAAI,KAAU,KACZ,QAAO;AAGT,SAAQ,GAAR;EACE,KAAK,YACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,QACE,QAAO;;;AAKb,SAAgB,EAAkB,GAAmC;AACnE,QAAO,EAAM,cAAc;;AAI7B,SAAgB,EACd,GAKQ;AACR,KAAI,KAAc,KAChB,QAAO;AAGT,SAAQ,GAAR;EACE,KAAK,gCACH,QAAO;EACT,KAAK,sBACH,QAAO;EACT,KAAK,mBACH,QAAO;EACT,KAAK,oBACH,QAAO;EACT,KAAK,eACH,QAAO;EACT,KAAK,yBACH,QAAO;EACT,KAAK,oBACH,QAAO;EACT,KAAK,wBACH,QAAO;EAET,QACE,QAAO"}
@@ -0,0 +1,25 @@
1
+ //#region src/modules/projectIngestionStatus.ts
2
+ var e = {
3
+ IDLE: {
4
+ label: "projectIngestionStatus.idle",
5
+ tone: "neutral"
6
+ },
7
+ RUNNING: {
8
+ label: "projectIngestionStatus.running",
9
+ tone: "info"
10
+ },
11
+ FAILED: {
12
+ label: "projectIngestionStatus.failed",
13
+ tone: "danger"
14
+ }
15
+ }, t = {
16
+ label: "projectIngestionStatus.unknown",
17
+ tone: "neutral"
18
+ };
19
+ function n(n) {
20
+ return n == null ? t : e[n];
21
+ }
22
+ //#endregion
23
+ export { n as getProjectIngestionStatusMeta };
24
+
25
+ //# sourceMappingURL=projectIngestionStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectIngestionStatus.js","names":[],"sources":["../../../src/modules/projectIngestionStatus.ts"],"sourcesContent":["import type { ProjectIngestionStatusKind } from './sharedSchemaTypes.js';\n\nexport type ProjectIngestionStatusTone =\n | 'neutral'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger';\n\ntype ProjectIngestionStatusMeta = {\n label: string;\n tone: ProjectIngestionStatusTone;\n};\n\nconst PROJECT_INGESTION_STATUS_META: Record<\n ProjectIngestionStatusKind,\n ProjectIngestionStatusMeta\n> = {\n IDLE: { label: 'projectIngestionStatus.idle', tone: 'neutral' },\n RUNNING: { label: 'projectIngestionStatus.running', tone: 'info' },\n FAILED: { label: 'projectIngestionStatus.failed', tone: 'danger' },\n};\n\nconst UNKNOWN_META: ProjectIngestionStatusMeta = {\n label: 'projectIngestionStatus.unknown',\n tone: 'neutral',\n};\n\n/** Return label and tone metadata for a project ingestion status kind. */\nexport function getProjectIngestionStatusMeta(\n kind: ProjectIngestionStatusKind | null | undefined,\n): ProjectIngestionStatusMeta {\n if (kind == null) {\n return UNKNOWN_META;\n }\n\n return PROJECT_INGESTION_STATUS_META[kind];\n}\n"],"mappings":";AAcA,IAAM,IAGF;CACF,MAAM;EAAE,OAAO;EAA+B,MAAM;EAAW;CAC/D,SAAS;EAAE,OAAO;EAAkC,MAAM;EAAQ;CAClE,QAAQ;EAAE,OAAO;EAAiC,MAAM;EAAU;CACnE,EAEK,IAA2C;CAC/C,OAAO;CACP,MAAM;CACP;AAGD,SAAgB,EACd,GAC4B;AAK5B,QAJI,KAAQ,OACH,IAGF,EAA8B"}