@workos-inc/widgets 1.19.0 → 1.19.1-next.1790725314460

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 (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/lib/admin-portal-audit-log-streaming.cjs +5 -22
  3. package/dist/cjs/lib/admin-portal-audit-log-streaming.cjs.map +1 -1
  4. package/dist/cjs/lib/api-keys/relative-time.cjs +7 -12
  5. package/dist/cjs/lib/api-keys/relative-time.cjs.map +1 -1
  6. package/dist/cjs/lib/directory-sync.cjs +5 -30
  7. package/dist/cjs/lib/directory-sync.cjs.map +1 -1
  8. package/dist/cjs/lib/domain-item.cjs +5 -10
  9. package/dist/cjs/lib/domain-item.cjs.map +1 -1
  10. package/dist/cjs/lib/user-security.cjs +9 -17
  11. package/dist/cjs/lib/user-security.cjs.map +1 -1
  12. package/dist/cjs/lib/user-sessions.cjs +9 -13
  13. package/dist/cjs/lib/user-sessions.cjs.map +1 -1
  14. package/dist/cjs/lib/user-sessions.d.cts +2 -2
  15. package/dist/cjs/lib/users-management.cjs +14 -24
  16. package/dist/cjs/lib/users-management.cjs.map +1 -1
  17. package/dist/cjs/lib/utils.cjs +49 -13
  18. package/dist/cjs/lib/utils.cjs.map +1 -1
  19. package/dist/cjs/use-comparative-readable-date.cjs +128 -0
  20. package/dist/cjs/use-comparative-readable-date.cjs.map +1 -0
  21. package/dist/cjs/use-comparative-readable-date.d.cts +8 -0
  22. package/dist/esm/lib/admin-portal-audit-log-streaming.js +5 -22
  23. package/dist/esm/lib/admin-portal-audit-log-streaming.js.map +1 -1
  24. package/dist/esm/lib/api-keys/relative-time.js +7 -12
  25. package/dist/esm/lib/api-keys/relative-time.js.map +1 -1
  26. package/dist/esm/lib/directory-sync.js +5 -30
  27. package/dist/esm/lib/directory-sync.js.map +1 -1
  28. package/dist/esm/lib/domain-item.js +5 -10
  29. package/dist/esm/lib/domain-item.js.map +1 -1
  30. package/dist/esm/lib/identity-providers.d.ts +2 -2
  31. package/dist/esm/lib/user-security.js +9 -18
  32. package/dist/esm/lib/user-security.js.map +1 -1
  33. package/dist/esm/lib/user-sessions.d.ts +2 -2
  34. package/dist/esm/lib/user-sessions.js +9 -14
  35. package/dist/esm/lib/user-sessions.js.map +1 -1
  36. package/dist/esm/lib/users-management.js +14 -25
  37. package/dist/esm/lib/users-management.js.map +1 -1
  38. package/dist/esm/lib/utils.js +49 -13
  39. package/dist/esm/lib/utils.js.map +1 -1
  40. package/dist/esm/use-comparative-readable-date.d.ts +8 -0
  41. package/dist/esm/use-comparative-readable-date.js +94 -0
  42. package/dist/esm/use-comparative-readable-date.js.map +1 -0
  43. package/package.json +1 -1
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var use_comparative_readable_date_exports = {};
30
+ __export(use_comparative_readable_date_exports, {
31
+ useComparativeReadableDate: () => useComparativeReadableDate
32
+ });
33
+ module.exports = __toCommonJS(use_comparative_readable_date_exports);
34
+ var React = __toESM(require("react"), 1);
35
+ var import_use_locale = require("./lib/i18n/use-locale.js");
36
+ var import_utils = require("./lib/utils.js");
37
+ const DEFAULT_TIME_ZONE = "America/Los_Angeles";
38
+ const TICK_MS = 6e4;
39
+ let clock = null;
40
+ const listeners = /* @__PURE__ */ new Set();
41
+ let intervalId;
42
+ function getNow() {
43
+ if (clock === null) {
44
+ clock = /* @__PURE__ */ new Date();
45
+ }
46
+ return clock;
47
+ }
48
+ function getServerNow() {
49
+ return null;
50
+ }
51
+ function emit(next) {
52
+ clock = next;
53
+ for (const listener of listeners) {
54
+ listener();
55
+ }
56
+ }
57
+ function startInterval() {
58
+ if (intervalId !== void 0) {
59
+ return;
60
+ }
61
+ intervalId = window.setInterval(() => {
62
+ emit(/* @__PURE__ */ new Date());
63
+ }, TICK_MS);
64
+ }
65
+ function stopInterval() {
66
+ if (intervalId === void 0) {
67
+ return;
68
+ }
69
+ window.clearInterval(intervalId);
70
+ intervalId = void 0;
71
+ }
72
+ function handleVisibilityChange() {
73
+ if (document.hidden) {
74
+ stopInterval();
75
+ } else {
76
+ emit(/* @__PURE__ */ new Date());
77
+ startInterval();
78
+ }
79
+ }
80
+ function subscribe(listener) {
81
+ if (listeners.size === 0) {
82
+ document.addEventListener("visibilitychange", handleVisibilityChange);
83
+ if (!document.hidden) {
84
+ startInterval();
85
+ }
86
+ }
87
+ listeners.add(listener);
88
+ return () => {
89
+ listeners.delete(listener);
90
+ if (listeners.size === 0) {
91
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
92
+ stopInterval();
93
+ clock = null;
94
+ }
95
+ };
96
+ }
97
+ function useComparativeReadableDate({
98
+ date = null,
99
+ currentDate = null,
100
+ fallback,
101
+ timeZone
102
+ }) {
103
+ const locale = (0, import_use_locale.useLocale)();
104
+ const now = React.useSyncExternalStore(subscribe, getNow, getServerNow);
105
+ return React.useMemo(() => {
106
+ if (!date) {
107
+ return fallback || null;
108
+ }
109
+ const comparedDate = currentDate || now;
110
+ if (!comparedDate) {
111
+ return date.toLocaleDateString(locale, {
112
+ month: "short",
113
+ day: "numeric",
114
+ year: "numeric",
115
+ timeZone: timeZone ?? DEFAULT_TIME_ZONE
116
+ });
117
+ }
118
+ return (0, import_utils.getComparativeReadableDate)(comparedDate, date, {
119
+ locale,
120
+ timeZone: timeZone ?? void 0
121
+ });
122
+ }, [date, currentDate, now, fallback, locale, timeZone]);
123
+ }
124
+ // Annotate the CommonJS export names for ESM import in node:
125
+ 0 && (module.exports = {
126
+ useComparativeReadableDate
127
+ });
128
+ //# sourceMappingURL=use-comparative-readable-date.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/use-comparative-readable-date.ts"],"sourcesContent":["import * as React from \"react\";\nimport { useLocale } from \"./lib/i18n/use-locale.js\";\nimport { getComparativeReadableDate } from \"./lib/utils.js\";\n\nconst DEFAULT_TIME_ZONE = \"America/Los_Angeles\";\nconst TICK_MS = 60_000;\n\nlet clock: Date | null = null;\nconst listeners = new Set<() => void>();\nlet intervalId: number | undefined;\n\nfunction getNow(): Date {\n if (clock === null) {\n clock = new Date();\n }\n return clock;\n}\n\nfunction getServerNow(): null {\n return null;\n}\n\nfunction emit(next: Date) {\n clock = next;\n for (const listener of listeners) {\n listener();\n }\n}\n\nfunction startInterval() {\n if (intervalId !== undefined) {\n return;\n }\n intervalId = window.setInterval(() => {\n emit(new Date());\n }, TICK_MS);\n}\n\nfunction stopInterval() {\n if (intervalId === undefined) {\n return;\n }\n window.clearInterval(intervalId);\n intervalId = undefined;\n}\n\nfunction handleVisibilityChange() {\n if (document.hidden) {\n stopInterval();\n } else {\n emit(new Date());\n startInterval();\n }\n}\n\nfunction subscribe(listener: () => void) {\n if (listeners.size === 0) {\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n if (!document.hidden) {\n startInterval();\n }\n }\n listeners.add(listener);\n\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) {\n document.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n stopInterval();\n // Drop the cached snapshot so the next mount reads a fresh time\n // during render, before paint.\n clock = null;\n }\n };\n}\n\nexport function useComparativeReadableDate({\n date = null,\n currentDate = null,\n fallback,\n timeZone,\n}: {\n date?: Date | null;\n currentDate?: Date | null;\n fallback?: string;\n timeZone?: string | null;\n}) {\n const locale = useLocale();\n const now = React.useSyncExternalStore(subscribe, getNow, getServerNow);\n\n return React.useMemo(() => {\n if (!date) {\n return fallback || null;\n }\n\n const comparedDate = currentDate || now;\n if (!comparedDate) {\n return date.toLocaleDateString(locale, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n timeZone: timeZone ?? DEFAULT_TIME_ZONE,\n });\n }\n\n return getComparativeReadableDate(comparedDate, date, {\n locale,\n timeZone: timeZone ?? undefined,\n });\n }, [date, currentDate, now, fallback, locale, timeZone]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAAuB;AACvB,wBAA0B;AAC1B,mBAA2C;AAE3C,MAAM,oBAAoB;AAC1B,MAAM,UAAU;AAEhB,IAAI,QAAqB;AACzB,MAAM,YAAY,oBAAI,IAAgB;AACtC,IAAI;AAEJ,SAAS,SAAe;AACtB,MAAI,UAAU,MAAM;AAClB,YAAQ,oBAAI,KAAK;AAAA,EACnB;AACA,SAAO;AACT;AAEA,SAAS,eAAqB;AAC5B,SAAO;AACT;AAEA,SAAS,KAAK,MAAY;AACxB,UAAQ;AACR,aAAW,YAAY,WAAW;AAChC,aAAS;AAAA,EACX;AACF;AAEA,SAAS,gBAAgB;AACvB,MAAI,eAAe,QAAW;AAC5B;AAAA,EACF;AACA,eAAa,OAAO,YAAY,MAAM;AACpC,SAAK,oBAAI,KAAK,CAAC;AAAA,EACjB,GAAG,OAAO;AACZ;AAEA,SAAS,eAAe;AACtB,MAAI,eAAe,QAAW;AAC5B;AAAA,EACF;AACA,SAAO,cAAc,UAAU;AAC/B,eAAa;AACf;AAEA,SAAS,yBAAyB;AAChC,MAAI,SAAS,QAAQ;AACnB,iBAAa;AAAA,EACf,OAAO;AACL,SAAK,oBAAI,KAAK,CAAC;AACf,kBAAc;AAAA,EAChB;AACF;AAEA,SAAS,UAAU,UAAsB;AACvC,MAAI,UAAU,SAAS,GAAG;AACxB,aAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,QAAI,CAAC,SAAS,QAAQ;AACpB,oBAAc;AAAA,IAChB;AAAA,EACF;AACA,YAAU,IAAI,QAAQ;AAEtB,SAAO,MAAM;AACX,cAAU,OAAO,QAAQ;AACzB,QAAI,UAAU,SAAS,GAAG;AACxB,eAAS,oBAAoB,oBAAoB,sBAAsB;AACvE,mBAAa;AAGb,cAAQ;AAAA,IACV;AAAA,EACF;AACF;AAEO,SAAS,2BAA2B;AAAA,EACzC,OAAO;AAAA,EACP,cAAc;AAAA,EACd;AAAA,EACA;AACF,GAKG;AACD,QAAM,aAAS,6BAAU;AACzB,QAAM,MAAM,MAAM,qBAAqB,WAAW,QAAQ,YAAY;AAEtE,SAAO,MAAM,QAAQ,MAAM;AACzB,QAAI,CAAC,MAAM;AACT,aAAO,YAAY;AAAA,IACrB;AAEA,UAAM,eAAe,eAAe;AACpC,QAAI,CAAC,cAAc;AACjB,aAAO,KAAK,mBAAmB,QAAQ;AAAA,QACrC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,MAAM;AAAA,QACN,UAAU,YAAY;AAAA,MACxB,CAAC;AAAA,IACH;AAEA,eAAO,yCAA2B,cAAc,MAAM;AAAA,MACpD;AAAA,MACA,UAAU,YAAY;AAAA,IACxB,CAAC;AAAA,EACH,GAAG,CAAC,MAAM,aAAa,KAAK,UAAU,QAAQ,QAAQ,CAAC;AACzD;","names":[]}
@@ -0,0 +1,8 @@
1
+ declare function useComparativeReadableDate({ date, currentDate, fallback, timeZone, }: {
2
+ date?: Date | null;
3
+ currentDate?: Date | null;
4
+ fallback?: string;
5
+ timeZone?: string | null;
6
+ }): string | null;
7
+
8
+ export { useComparativeReadableDate };
@@ -19,6 +19,7 @@ import {
19
19
  import { Translation } from "./i18n/translation.js";
20
20
  import { useTranslation } from "./i18n/use-translation.js";
21
21
  import { getErrorMessage } from "./generic-error.js";
22
+ import { useComparativeReadableDate } from "../use-comparative-readable-date.js";
22
23
  const AdminPortalAuditLogStreamingContext = React.createContext(null);
23
24
  function useAdminPortalAuditLogStreamingContext() {
24
25
  const context = React.useContext(AdminPortalAuditLogStreamingContext);
@@ -82,22 +83,6 @@ function decodeUlidTimestamp(ulid) {
82
83
  }
83
84
  return new Date(timestamp);
84
85
  }
85
- function getRelativeTimeString(currentDate, pastDate) {
86
- const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
87
- const diff = pastDate.getTime() - currentDate.getTime();
88
- const diffSeconds = Math.round(diff / 1e3);
89
- const diffMinutes = Math.round(diffSeconds / 60);
90
- const diffHours = Math.round(diffMinutes / 60);
91
- const diffDays = Math.round(diffHours / 24);
92
- const diffMonths = Math.round(diffDays / 30);
93
- const diffYears = Math.round(diffMonths / 12);
94
- if (Math.abs(diffSeconds) < 60) return "now";
95
- if (Math.abs(diffMinutes) < 60) return rtf.format(diffMinutes, "minute");
96
- if (Math.abs(diffHours) < 24) return rtf.format(diffHours, "hour");
97
- if (Math.abs(diffDays) < 30) return rtf.format(diffDays, "day");
98
- if (Math.abs(diffMonths) < 12) return rtf.format(diffMonths, "month");
99
- return rtf.format(diffYears, "year");
100
- }
101
86
  function AdminPortalAuditLogStreamingButton({
102
87
  isPending,
103
88
  href,
@@ -164,6 +149,9 @@ const AdminPortalAuditLogStreaming = (props) => {
164
149
  const lastSyncedEventId = connectionStatus === "Active" || connectionStatus === "Error" ? props.lastSyncedEventId : void 0;
165
150
  const lastSyncedAt = lastSyncedEventId ? decodeUlidTimestamp(lastSyncedEventId) : null;
166
151
  const icon = destinationType ? getDestinationIcon(destinationType) : null;
152
+ const relativeTime = useComparativeReadableDate({
153
+ date: lastSyncedAt
154
+ });
167
155
  return /* @__PURE__ */ jsx(AdminPortalAuditLogStreamingContext.Provider, { value: { connectionStatus }, children: /* @__PURE__ */ jsxs(CardList.Root, { ...getWidgetRootDomProps("resolved", { className }), children: [
168
156
  /* @__PURE__ */ jsx(CardList.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "row", justify: "between", align: "center", gap: "2", children: [
169
157
  /* @__PURE__ */ jsx(Flex, { gap: "4", align: "center", children: connectionStatus === "NotConfigured" ? /* @__PURE__ */ jsx(Text, { size: "2", color: "gray", children: /* @__PURE__ */ jsx(
@@ -183,12 +171,7 @@ const AdminPortalAuditLogStreaming = (props) => {
183
171
  defaultMessage: "Last sync {relativeTime}",
184
172
  id: "fT9f0p",
185
173
  description: "Label showing when the last log stream sync occurred",
186
- values: {
187
- relativeTime: getRelativeTimeString(
188
- /* @__PURE__ */ new Date(),
189
- lastSyncedAt
190
- )
191
- }
174
+ values: { relativeTime }
192
175
  }
193
176
  ) })
194
177
  ] }) : /* @__PURE__ */ jsx(Text, { size: "2", weight: "bold", children: getDestinationName(destinationType) })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/admin-portal-audit-log-streaming.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Text } from \"@radix-ui/themes\";\nimport * as CardList from \"./card-list.js\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport {\n ExternalLinkIcon,\n Cross2Icon,\n InfoCircledIcon,\n} from \"@radix-ui/react-icons\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { GenericHttpsIcon } from \"./audit-log-stream-icons.js\";\nimport { Status } from \"./status.js\";\nimport {\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { getErrorMessage } from \"./generic-error.js\";\nimport type { AuditLogStreamType } from \"../api/client-graphql/generated.js\";\n\n// ============================================================================\n// TYPE DEFINITIONS\n// ============================================================================\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n destinationType: AuditLogStreamType;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n destinationType: AuditLogStreamType;\n lastSyncedEventId?: string | null;\n}\n\ninterface ErrorProps {\n connectionStatus: \"Error\";\n destinationType: AuditLogStreamType;\n lastSyncedEventId?: string | null;\n}\n\nconst AdminPortalAuditLogStreamingContext = React.createContext<{\n connectionStatus: AdminPortalAuditLogStreamingStatusProps[\"connectionStatus\"];\n} | null>(null);\n\nfunction useAdminPortalAuditLogStreamingContext() {\n const context = React.useContext(AdminPortalAuditLogStreamingContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalAuditLogStreamingContext must be used within a AdminPortalAuditLogStreamingContext provider\",\n );\n }\n return context;\n}\n\nexport type AdminPortalAuditLogStreamingStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | ErrorProps;\n\ntype AdminPortalAuditLogStreamingProps = WidgetRootDomProps &\n AdminPortalAuditLogStreamingStatusProps & {\n adminPortalOpenButton: React.ReactNode;\n };\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Maps AuditLogStreamType to display name\n */\nfunction getDestinationName(type: AuditLogStreamType): string {\n switch (type) {\n case \"Datadog\":\n return \"Datadog\";\n case \"Splunk\":\n return \"Splunk\";\n case \"S3\":\n return \"AWS S3\";\n case \"GoogleCloudStorage\":\n return \"Google Cloud Storage\";\n case \"AzureSentinel\":\n return \"Azure Sentinel\";\n case \"GenericHttps\":\n return \"Generic HTTPS\";\n default:\n return type;\n }\n}\n\n/**\n * Maps AuditLogStreamType to ProviderIcon provider name\n */\nfunction getDestinationIcon(\n type: AuditLogStreamType,\n): \"datadog\" | \"splunk\" | \"aws\" | \"google-cloud\" | \"azure\" | undefined {\n switch (type) {\n case \"Datadog\":\n return \"datadog\";\n case \"Splunk\":\n return \"splunk\";\n case \"S3\":\n return \"aws\";\n case \"GoogleCloudStorage\":\n return \"google-cloud\";\n case \"AzureSentinel\":\n return \"azure\";\n default:\n return undefined;\n }\n}\n\n/**\n * Helper to get the correct WidgetRootDomProps based on state\n */\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"admin-portal-audit-log-streaming\",\n widgetState: state,\n });\n}\n\nconst CROCKFORD_BASE32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction decodeUlidTimestamp(ulid: string): Date | null {\n if (!ulid || ulid.length < 10) return null;\n let timestamp = 0;\n for (let i = 0; i < 10; i++) {\n const charIndex = CROCKFORD_BASE32.indexOf(ulid.charAt(i).toUpperCase());\n if (charIndex === -1) return null;\n timestamp = timestamp * 32 + charIndex;\n }\n return new Date(timestamp);\n}\n\nfunction getRelativeTimeString(currentDate: Date, pastDate: Date): string {\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = pastDate.getTime() - currentDate.getTime();\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) return \"now\";\n if (Math.abs(diffMinutes) < 60) return rtf.format(diffMinutes, \"minute\");\n if (Math.abs(diffHours) < 24) return rtf.format(diffHours, \"hour\");\n if (Math.abs(diffDays) < 30) return rtf.format(diffDays, \"day\");\n if (Math.abs(diffMonths) < 12) return rtf.format(diffMonths, \"month\");\n return rtf.format(diffYears, \"year\");\n}\n\nfunction AdminPortalAuditLogStreamingButton({\n isPending,\n href,\n initConfig,\n}: {\n isPending: boolean;\n href: string | null;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalAuditLogStreamingContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return (\n <Translation\n defaultMessage=\"Set up Log Streams\"\n id=\"s3Wu7U\"\n description=\"Button label to start log stream setup\"\n />\n );\n case \"Inactive\":\n return (\n <Translation\n defaultMessage=\"Continue setup\"\n id=\"/oM/HY\"\n description=\"Button label to continue incomplete log stream setup\"\n />\n );\n case \"Active\":\n case \"Error\":\n return (\n <Translation\n defaultMessage=\"Manage\"\n id=\"+k5uUi\"\n description=\"Button label to manage log stream settings\"\n />\n );\n }\n })();\n\n if (href) {\n return (\n <Button variant=\"secondary\" asChild>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {label} <ExternalLinkIcon aria-hidden />\n </a>\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"secondary\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nconst AdminPortalAuditLogStreaming: React.FC<\n AdminPortalAuditLogStreamingProps\n> = (props) => {\n const { connectionStatus, adminPortalOpenButton, className } = props;\n\n const destinationType =\n connectionStatus !== \"NotConfigured\"\n ? (props as InactiveProps | ActiveProps | ErrorProps).destinationType\n : null;\n const lastSyncedEventId =\n connectionStatus === \"Active\" || connectionStatus === \"Error\"\n ? (props as ActiveProps | ErrorProps).lastSyncedEventId\n : undefined;\n const lastSyncedAt = lastSyncedEventId\n ? decodeUlidTimestamp(lastSyncedEventId)\n : null;\n\n const icon = destinationType ? getDestinationIcon(destinationType) : null;\n\n return (\n <AdminPortalAuditLogStreamingContext.Provider value={{ connectionStatus }}>\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", { className })}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n {connectionStatus === \"NotConfigured\" ? (\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up Log Streams yet.\"\n id=\"n4mruE\"\n description=\"Empty state message when log streaming is not configured\"\n />\n </Text>\n ) : (\n <>\n <IconPanel color=\"panel\">\n {icon ? (\n <ProviderIcon provider={icon} size=\"2\" />\n ) : (\n <GenericHttpsIcon />\n )}\n </IconPanel>\n {lastSyncedAt ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getDestinationName(destinationType!)}\n </Text>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"Last sync {relativeTime}\"\n id=\"fT9f0p\"\n description=\"Label showing when the last log stream sync occurred\"\n values={{\n relativeTime: getRelativeTimeString(\n new Date(),\n lastSyncedAt,\n ),\n }}\n />\n </Text>\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getDestinationName(destinationType!)}\n </Text>\n )}\n </>\n )}\n </Flex>\n\n <Flex gap=\"5\" align=\"center\">\n {connectionStatus === \"NotConfigured\" ? (\n adminPortalOpenButton\n ) : (\n <>\n {connectionStatus === \"Inactive\" && (\n <Status state=\"waiting\">\n <Translation\n defaultMessage=\"Setup in progress\"\n id=\"M6iKLG\"\n description=\"Status when log stream setup is incomplete\"\n />\n </Status>\n )}\n {connectionStatus === \"Active\" && (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Streaming\"\n id=\"25L0J+\"\n description=\"Status when log stream is active\"\n />\n </Status>\n )}\n {connectionStatus === \"Error\" && (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Not streaming\"\n id=\"7fAKZo\"\n description=\"Status when log stream has an error\"\n />\n </Status>\n )}\n {adminPortalOpenButton}\n </>\n )}\n </Flex>\n </Flex>\n </CardList.Item>\n\n {connectionStatus === \"Error\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"The credentials provided are incorrect or missing. Please review and update your log stream configuration.\"\n id=\"23tmgn\"\n description=\"Error message shown when audit log stream has a configuration or delivery error\"\n />\n </Text>\n </Flex>\n </CardList.Item>\n )}\n </CardList.Root>\n </AdminPortalAuditLogStreamingContext.Provider>\n );\n};\n\n// ============================================================================\n// LOADING COMPONENT\n// ============================================================================\n\ninterface AdminPortalAuditLogStreamingLoadingProps extends WidgetRootDomProps {}\n\nconst AdminPortalAuditLogStreamingLoading: React.FC<\n AdminPortalAuditLogStreamingLoadingProps\n> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"datadog\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Datadog</Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Last sync 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Status state=\"success\">Streaming</Status>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Manage <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\n// ============================================================================\n// ERROR COMPONENT\n// ============================================================================\n\ninterface AdminPortalAuditLogStreamingErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst AdminPortalAuditLogStreamingError: React.FC<\n AdminPortalAuditLogStreamingErrorProps\n> = ({ error, ...domProps }) => {\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const translate = useTranslation();\n const { heading, message } = getErrorMessage(error, translate);\n\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n {/* Error icon circle */}\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n {/* Error text */}\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport type {\n AdminPortalAuditLogStreamingProps,\n AdminPortalAuditLogStreamingLoadingProps,\n AdminPortalAuditLogStreamingErrorProps,\n};\n\nexport {\n AdminPortalAuditLogStreaming,\n AdminPortalAuditLogStreamingLoading,\n AdminPortalAuditLogStreamingError,\n /** @internal */\n AdminPortalAuditLogStreamingButton,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/admin-portal-audit-log-streaming.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Text } from \"@radix-ui/themes\";\nimport * as CardList from \"./card-list.js\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport {\n ExternalLinkIcon,\n Cross2Icon,\n InfoCircledIcon,\n} from \"@radix-ui/react-icons\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { GenericHttpsIcon } from \"./audit-log-stream-icons.js\";\nimport { Status } from \"./status.js\";\nimport {\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useTranslation } from \"./i18n/use-translation.js\";\nimport { getErrorMessage } from \"./generic-error.js\";\nimport type { AuditLogStreamType } from \"../api/client-graphql/generated.js\";\nimport { useComparativeReadableDate } from \"../use-comparative-readable-date.js\";\n\n// ============================================================================\n// TYPE DEFINITIONS\n// ============================================================================\n\ninterface NotConfiguredProps {\n connectionStatus: \"NotConfigured\";\n}\n\ninterface InactiveProps {\n connectionStatus: \"Inactive\";\n destinationType: AuditLogStreamType;\n}\n\ninterface ActiveProps {\n connectionStatus: \"Active\";\n destinationType: AuditLogStreamType;\n lastSyncedEventId?: string | null;\n}\n\ninterface ErrorProps {\n connectionStatus: \"Error\";\n destinationType: AuditLogStreamType;\n lastSyncedEventId?: string | null;\n}\n\nconst AdminPortalAuditLogStreamingContext = React.createContext<{\n connectionStatus: AdminPortalAuditLogStreamingStatusProps[\"connectionStatus\"];\n} | null>(null);\n\nfunction useAdminPortalAuditLogStreamingContext() {\n const context = React.useContext(AdminPortalAuditLogStreamingContext);\n if (!context) {\n throw new Error(\n \"useAdminPortalAuditLogStreamingContext must be used within a AdminPortalAuditLogStreamingContext provider\",\n );\n }\n return context;\n}\n\nexport type AdminPortalAuditLogStreamingStatusProps =\n | NotConfiguredProps\n | InactiveProps\n | ActiveProps\n | ErrorProps;\n\ntype AdminPortalAuditLogStreamingProps = WidgetRootDomProps &\n AdminPortalAuditLogStreamingStatusProps & {\n adminPortalOpenButton: React.ReactNode;\n };\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\n/**\n * Maps AuditLogStreamType to display name\n */\nfunction getDestinationName(type: AuditLogStreamType): string {\n switch (type) {\n case \"Datadog\":\n return \"Datadog\";\n case \"Splunk\":\n return \"Splunk\";\n case \"S3\":\n return \"AWS S3\";\n case \"GoogleCloudStorage\":\n return \"Google Cloud Storage\";\n case \"AzureSentinel\":\n return \"Azure Sentinel\";\n case \"GenericHttps\":\n return \"Generic HTTPS\";\n default:\n return type;\n }\n}\n\n/**\n * Maps AuditLogStreamType to ProviderIcon provider name\n */\nfunction getDestinationIcon(\n type: AuditLogStreamType,\n): \"datadog\" | \"splunk\" | \"aws\" | \"google-cloud\" | \"azure\" | undefined {\n switch (type) {\n case \"Datadog\":\n return \"datadog\";\n case \"Splunk\":\n return \"splunk\";\n case \"S3\":\n return \"aws\";\n case \"GoogleCloudStorage\":\n return \"google-cloud\";\n case \"AzureSentinel\":\n return \"azure\";\n default:\n return undefined;\n }\n}\n\n/**\n * Helper to get the correct WidgetRootDomProps based on state\n */\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"admin-portal-audit-log-streaming\",\n widgetState: state,\n });\n}\n\nconst CROCKFORD_BASE32 = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\n\nfunction decodeUlidTimestamp(ulid: string): Date | null {\n if (!ulid || ulid.length < 10) return null;\n let timestamp = 0;\n for (let i = 0; i < 10; i++) {\n const charIndex = CROCKFORD_BASE32.indexOf(ulid.charAt(i).toUpperCase());\n if (charIndex === -1) return null;\n timestamp = timestamp * 32 + charIndex;\n }\n return new Date(timestamp);\n}\n\nfunction AdminPortalAuditLogStreamingButton({\n isPending,\n href,\n initConfig,\n}: {\n isPending: boolean;\n href: string | null;\n initConfig: () => void;\n}) {\n const { connectionStatus } = useAdminPortalAuditLogStreamingContext();\n const label = (() => {\n switch (connectionStatus) {\n case \"NotConfigured\":\n return (\n <Translation\n defaultMessage=\"Set up Log Streams\"\n id=\"s3Wu7U\"\n description=\"Button label to start log stream setup\"\n />\n );\n case \"Inactive\":\n return (\n <Translation\n defaultMessage=\"Continue setup\"\n id=\"/oM/HY\"\n description=\"Button label to continue incomplete log stream setup\"\n />\n );\n case \"Active\":\n case \"Error\":\n return (\n <Translation\n defaultMessage=\"Manage\"\n id=\"+k5uUi\"\n description=\"Button label to manage log stream settings\"\n />\n );\n }\n })();\n\n if (href) {\n return (\n <Button variant=\"secondary\" asChild>\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\">\n {label} <ExternalLinkIcon aria-hidden />\n </a>\n </Button>\n );\n }\n\n return (\n <Button\n variant=\"secondary\"\n loading={isPending}\n disabled={isPending}\n onClick={initConfig}\n >\n {label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\n// ============================================================================\n// MAIN COMPONENT\n// ============================================================================\n\nconst AdminPortalAuditLogStreaming: React.FC<\n AdminPortalAuditLogStreamingProps\n> = (props) => {\n const { connectionStatus, adminPortalOpenButton, className } = props;\n\n const destinationType =\n connectionStatus !== \"NotConfigured\"\n ? (props as InactiveProps | ActiveProps | ErrorProps).destinationType\n : null;\n const lastSyncedEventId =\n connectionStatus === \"Active\" || connectionStatus === \"Error\"\n ? (props as ActiveProps | ErrorProps).lastSyncedEventId\n : undefined;\n const lastSyncedAt = lastSyncedEventId\n ? decodeUlidTimestamp(lastSyncedEventId)\n : null;\n\n const icon = destinationType ? getDestinationIcon(destinationType) : null;\n\n const relativeTime = useComparativeReadableDate({\n date: lastSyncedAt,\n });\n\n return (\n <AdminPortalAuditLogStreamingContext.Provider value={{ connectionStatus }}>\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", { className })}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n {connectionStatus === \"NotConfigured\" ? (\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up Log Streams yet.\"\n id=\"n4mruE\"\n description=\"Empty state message when log streaming is not configured\"\n />\n </Text>\n ) : (\n <>\n <IconPanel color=\"panel\">\n {icon ? (\n <ProviderIcon provider={icon} size=\"2\" />\n ) : (\n <GenericHttpsIcon />\n )}\n </IconPanel>\n {lastSyncedAt ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getDestinationName(destinationType!)}\n </Text>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"Last sync {relativeTime}\"\n id=\"fT9f0p\"\n description=\"Label showing when the last log stream sync occurred\"\n values={{ relativeTime }}\n />\n </Text>\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getDestinationName(destinationType!)}\n </Text>\n )}\n </>\n )}\n </Flex>\n\n <Flex gap=\"5\" align=\"center\">\n {connectionStatus === \"NotConfigured\" ? (\n adminPortalOpenButton\n ) : (\n <>\n {connectionStatus === \"Inactive\" && (\n <Status state=\"waiting\">\n <Translation\n defaultMessage=\"Setup in progress\"\n id=\"M6iKLG\"\n description=\"Status when log stream setup is incomplete\"\n />\n </Status>\n )}\n {connectionStatus === \"Active\" && (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Streaming\"\n id=\"25L0J+\"\n description=\"Status when log stream is active\"\n />\n </Status>\n )}\n {connectionStatus === \"Error\" && (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Not streaming\"\n id=\"7fAKZo\"\n description=\"Status when log stream has an error\"\n />\n </Status>\n )}\n {adminPortalOpenButton}\n </>\n )}\n </Flex>\n </Flex>\n </CardList.Item>\n\n {connectionStatus === \"Error\" && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"gray\" />\n </Box>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"The credentials provided are incorrect or missing. Please review and update your log stream configuration.\"\n id=\"23tmgn\"\n description=\"Error message shown when audit log stream has a configuration or delivery error\"\n />\n </Text>\n </Flex>\n </CardList.Item>\n )}\n </CardList.Root>\n </AdminPortalAuditLogStreamingContext.Provider>\n );\n};\n\n// ============================================================================\n// LOADING COMPONENT\n// ============================================================================\n\ninterface AdminPortalAuditLogStreamingLoadingProps extends WidgetRootDomProps {}\n\nconst AdminPortalAuditLogStreamingLoading: React.FC<\n AdminPortalAuditLogStreamingLoadingProps\n> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n <Skeleton>\n <IconPanel color=\"panel\">\n <ProviderIcon provider=\"datadog\" size=\"2\" />\n </IconPanel>\n </Skeleton>\n <Flex direction=\"column\" gap=\"1\" my=\"-4px\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Datadog</Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"1\">Last sync 10 minutes ago</Text>\n </Skeleton>\n </Flex>\n </Flex>\n\n <Flex gap=\"5\" align=\"center\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Status state=\"success\">Streaming</Status>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Manage <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\n// ============================================================================\n// ERROR COMPONENT\n// ============================================================================\n\ninterface AdminPortalAuditLogStreamingErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst AdminPortalAuditLogStreamingError: React.FC<\n AdminPortalAuditLogStreamingErrorProps\n> = ({ error, ...domProps }) => {\n React.useEffect(() => {\n console.error(error);\n }, [error]);\n\n const translate = useTranslation();\n const { heading, message } = getErrorMessage(error, translate);\n\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Flex gap=\"4\" align=\"center\">\n {/* Error icon circle */}\n <Flex\n align=\"center\"\n justify=\"center\"\n width=\"24px\"\n height=\"24px\"\n style={{\n borderRadius: \"9999px\",\n backgroundColor: \"var(--red-a4)\",\n color: \"var(--red-a11)\",\n flexShrink: 0,\n }}\n >\n <Cross2Icon width=\"18px\" height=\"18px\" />\n </Flex>\n {/* Error text */}\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {heading}\n </Text>\n <Text size=\"2\" color=\"gray\">\n {message}\n </Text>\n </Flex>\n </Flex>\n </Flex>\n </Card>\n );\n};\n\n// ============================================================================\n// EXPORTS\n// ============================================================================\n\nexport type {\n AdminPortalAuditLogStreamingProps,\n AdminPortalAuditLogStreamingLoadingProps,\n AdminPortalAuditLogStreamingErrorProps,\n};\n\nexport {\n AdminPortalAuditLogStreaming,\n AdminPortalAuditLogStreamingLoading,\n AdminPortalAuditLogStreamingError,\n /** @internal */\n AdminPortalAuditLogStreamingButton,\n};\n"],"mappings":"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","names":[]}
@@ -1,26 +1,21 @@
1
1
  import { Fragment, jsx } from "react/jsx-runtime";
2
- import { useIsHydrated } from "../use-is-hydrated.js";
3
- import { getComparativeReadableDate } from "../utils.js";
4
2
  import { Translation } from "../i18n/translation.js";
5
- import { useLocale } from "../i18n/use-locale.js";
3
+ import { useComparativeReadableDate } from "../../use-comparative-readable-date.js";
6
4
  function RelativeTime({ date }) {
7
- const isHydrated = useIsHydrated();
8
- const locale = useLocale();
9
5
  if (!date) {
10
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
6
+ return /* @__PURE__ */ jsx(
11
7
  Translation,
12
8
  {
13
9
  defaultMessage: "Never",
14
10
  id: "yXCbRa",
15
11
  description: "Text indicating API key was never used"
16
12
  }
17
- ) });
13
+ );
18
14
  }
19
- return /* @__PURE__ */ jsx(Fragment, { children: isHydrated ? getComparativeReadableDate(/* @__PURE__ */ new Date(), date, { locale }) : date.toLocaleDateString(locale, {
20
- month: "short",
21
- day: "numeric",
22
- year: "numeric"
23
- }) });
15
+ return /* @__PURE__ */ jsx(RelativeTimeImpl, { date });
16
+ }
17
+ function RelativeTimeImpl({ date }) {
18
+ return /* @__PURE__ */ jsx(Fragment, { children: useComparativeReadableDate({ date }) });
24
19
  }
25
20
  export {
26
21
  RelativeTime
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/lib/api-keys/relative-time.tsx"],"sourcesContent":["import { useIsHydrated } from \"../use-is-hydrated.js\";\nimport { getComparativeReadableDate } from \"../utils.js\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useLocale } from \"../i18n/use-locale.js\";\n\nexport function RelativeTime({ date }: { date?: Date }) {\n const isHydrated = useIsHydrated();\n const locale = useLocale();\n\n if (!date) {\n return (\n <>\n <Translation\n defaultMessage=\"Never\"\n id=\"yXCbRa\"\n description=\"Text indicating API key was never used\"\n />\n </>\n );\n }\n\n return (\n <>\n {isHydrated\n ? getComparativeReadableDate(new Date(), date, { locale })\n : date.toLocaleDateString(locale, {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n })}\n </>\n );\n}\n"],"mappings":"AAWM,mBACE,WADF;AAXN,SAAS,qBAAqB;AAC9B,SAAS,kCAAkC;AAC3C,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAEnB,SAAS,aAAa,EAAE,KAAK,GAAoB;AACtD,QAAM,aAAa,cAAc;AACjC,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,MAAM;AACT,WACE,gCACE;AAAA,MAAC;AAAA;AAAA,QACC,gBAAe;AAAA,QACf,IAAG;AAAA,QACH,aAAY;AAAA;AAAA,IACd,GACF;AAAA,EAEJ;AAEA,SACE,gCACG,uBACG,2BAA2B,oBAAI,KAAK,GAAG,MAAM,EAAE,OAAO,CAAC,IACvD,KAAK,mBAAmB,QAAQ;AAAA,IAC9B,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,EACR,CAAC,GACP;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/lib/api-keys/relative-time.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Translation } from \"../i18n/translation.js\";\nimport { useComparativeReadableDate } from \"../../use-comparative-readable-date.js\";\n\nexport function RelativeTime({ date }: { date?: Date }) {\n if (!date) {\n return (\n <Translation\n defaultMessage=\"Never\"\n id=\"yXCbRa\"\n description=\"Text indicating API key was never used\"\n />\n );\n }\n\n return <RelativeTimeImpl date={date} />;\n}\n\nfunction RelativeTimeImpl({ date }: { date: Date }): React.ReactNode {\n return <>{useComparativeReadableDate({ date })}</>;\n}\n"],"mappings":"AAOM,SAYG,UAZH;AANN,SAAS,mBAAmB;AAC5B,SAAS,kCAAkC;AAEpC,SAAS,aAAa,EAAE,KAAK,GAAoB;AACtD,MAAI,CAAC,MAAM;AACT,WACE;AAAA,MAAC;AAAA;AAAA,QACC,gBAAe;AAAA,QACf,IAAG;AAAA,QACH,aAAY;AAAA;AAAA,IACd;AAAA,EAEJ;AAEA,SAAO,oBAAC,oBAAiB,MAAY;AACvC;AAEA,SAAS,iBAAiB,EAAE,KAAK,GAAoC;AACnE,SAAO,gCAAG,qCAA2B,EAAE,KAAK,CAAC,GAAE;AACjD;","names":[]}
@@ -17,6 +17,7 @@ import { Translation } from "./i18n/translation.js";
17
17
  import {
18
18
  getDomProps
19
19
  } from "./utils.js";
20
+ import { useComparativeReadableDate } from "../use-comparative-readable-date.js";
20
21
  const DirectoryState = {
21
22
  requires_type: "requires_type",
22
23
  linked: "linked",
@@ -109,7 +110,10 @@ const DirectorySync = ({
109
110
  const groupCount = metadata?.groups ?? 0;
110
111
  const lastSyncAt = rest.lastSyncAt ? new Date(rest.lastSyncAt) : null;
111
112
  const currentDate = "currentDate" in rest && rest.currentDate instanceof Date ? rest.currentDate : void 0;
112
- const lastSyncString = lastSyncAt ? getRelativeTimeString(currentDate ?? /* @__PURE__ */ new Date(), lastSyncAt) : null;
113
+ const lastSyncString = useComparativeReadableDate({
114
+ date: lastSyncAt,
115
+ currentDate
116
+ });
113
117
  const showCounts = state === DirectoryState.linked || state === DirectoryState.invalid_credentials || state === DirectoryState.deleting;
114
118
  const statusBadge = getStatusBadge(state);
115
119
  const spinnerMessage = getSpinnerMessage(state, !!type);
@@ -252,35 +256,6 @@ function getWidgetRootDomProps(state, domProps) {
252
256
  widgetState: state
253
257
  });
254
258
  }
255
- function getRelativeTimeString(currentDate, lastSync) {
256
- if (!currentDate || !lastSync) {
257
- return null;
258
- }
259
- const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
260
- const diff = lastSync.getTime() - currentDate.getTime();
261
- const diffSeconds = Math.round(diff / 1e3);
262
- const diffMinutes = Math.round(diffSeconds / 60);
263
- const diffHours = Math.round(diffMinutes / 60);
264
- const diffDays = Math.round(diffHours / 24);
265
- const diffMonths = Math.round(diffDays / 30);
266
- const diffYears = Math.round(diffMonths / 12);
267
- if (Math.abs(diffSeconds) < 60) {
268
- return "now";
269
- }
270
- if (Math.abs(diffMinutes) < 60) {
271
- return rtf.format(diffMinutes, "minute");
272
- }
273
- if (Math.abs(diffHours) < 24) {
274
- return rtf.format(diffHours, "hour");
275
- }
276
- if (Math.abs(diffDays) < 30) {
277
- return rtf.format(diffDays, "day");
278
- }
279
- if (Math.abs(diffMonths) < 12) {
280
- return rtf.format(diffMonths, "month");
281
- }
282
- return rtf.format(diffYears, "year");
283
- }
284
259
  export {
285
260
  DirectoryState,
286
261
  DirectorySync,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/directory-sync.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Spinner, Text } from \"@radix-ui/themes\";\nimport { ExternalLinkIcon, InfoCircledIcon } from \"@radix-ui/react-icons\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport * as CardList from \"./card-list.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getDirectoryTypeIcon,\n getDirectoryTypeName,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport {\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\n\nconst DirectoryState = {\n requires_type: \"requires_type\",\n linked: \"linked\",\n validating: \"validating\",\n invalid_credentials: \"invalid_credentials\",\n unlinked: \"unlinked\",\n deleting: \"deleting\",\n} as const;\ntype DirectoryState = (typeof DirectoryState)[keyof typeof DirectoryState];\n\nfunction isDirectoryState(state: string): state is DirectoryState {\n return Object.values(DirectoryState).some((known) => known === state);\n}\n\ntype DirectoryType = string;\n\ninterface DirectoryMetadata {\n users: { active: number };\n groups: number;\n}\n\ninterface BaseDirectorySyncProps {\n type?: DirectoryType;\n metadata?: DirectoryMetadata;\n lastSyncAt?: string | null;\n onOpenAdminPortal?: () => void;\n isOpeningAdminPortal?: boolean;\n errorMessage?: never;\n userCount?: never;\n groupCount?: never;\n currentDate?: never;\n state: DirectoryState;\n}\n\ninterface NotConfiguredProps extends BaseDirectorySyncProps {\n state: (typeof DirectoryState)[\"unlinked\"];\n}\n\ninterface SetupInProgressProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"validating\"];\n type: DirectoryType;\n}\n\ninterface ErrorBeforeConfigProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"errorMessage\"\n> {\n state: DirectoryState;\n type: DirectoryType;\n errorMessage: React.ReactNode;\n}\n\ninterface ValidatingProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"validating\"];\n type: DirectoryType;\n}\n\ninterface ActiveProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"lastSyncAt\" | \"currentDate\" | \"errorMessage\"\n> {\n state: (typeof DirectoryState)[\"linked\"];\n type: DirectoryType;\n lastSyncAt: string | null;\n currentDate?: Date | null;\n errorMessage?: React.ReactNode;\n}\n\ninterface InvalidCredentialsProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"errorMessage\"\n> {\n state: (typeof DirectoryState)[\"invalid_credentials\"];\n type: DirectoryType;\n errorMessage: React.ReactNode;\n}\n\ninterface DeletingProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"deleting\"];\n type: DirectoryType;\n}\n\ntype DirectorySyncStatusProps =\n | NotConfiguredProps\n | SetupInProgressProps\n | ErrorBeforeConfigProps\n | ValidatingProps\n | ActiveProps\n | InvalidCredentialsProps\n | DeletingProps;\n\ntype DirectorySyncProps = WidgetRootDomProps & DirectorySyncStatusProps;\n\ninterface DirectorySyncContextValue {\n state: DirectorySyncStatusProps[\"state\"];\n type?: DirectoryType;\n}\n\nconst DirectorySyncContext =\n React.createContext<DirectorySyncContextValue | null>(null);\nDirectorySyncContext.displayName = \"DirectorySyncContext\";\n\nfunction useDirectorySyncContext() {\n const context = React.useContext(DirectorySyncContext);\n if (!context) {\n throw new Error(\n \"useDirectorySyncContext must be used within a DirectorySyncContext provider\",\n );\n }\n return context;\n}\n\nfunction DirectoryProviderInfo({\n type,\n subtitle,\n}: {\n type: DirectoryType;\n subtitle?: React.ReactNode;\n}) {\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon\n provider={getDirectoryTypeIcon(type) ?? \"workos\"}\n size=\"2\"\n />\n </IconPanel>\n {subtitle ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getDirectoryTypeName(type)}\n </Text>\n {subtitle}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getDirectoryTypeName(type)}\n </Text>\n )}\n </Flex>\n );\n}\n\nfunction SpinnerMessage({ children }: { children: React.ReactNode }) {\n return (\n <Flex gap=\"2\" align=\"center\">\n <Spinner />\n <Text size=\"2\" color=\"gray\">\n {children}\n </Text>\n </Flex>\n );\n}\n\nfunction getStatusBadge(state: DirectoryState) {\n switch (state) {\n case DirectoryState.requires_type:\n case DirectoryState.invalid_credentials:\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Requires action\"\n id=\"uuuXIF\"\n description=\"Status badge when directory requires user action\"\n />\n </Status>\n );\n case DirectoryState.linked:\n return (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Connected\"\n id=\"H/dAHq\"\n description=\"Status badge when directory is active\"\n />\n </Status>\n );\n default:\n return null;\n }\n}\n\nfunction getSpinnerMessage(\n state: DirectoryState,\n hasType: boolean,\n): string | null {\n if (state === DirectoryState.unlinked && hasType)\n return \"Setup in progress...\";\n if (state === DirectoryState.validating)\n return \"Waiting for users and groups...\";\n if (state === DirectoryState.deleting) return \"Deleting directory...\";\n return null;\n}\n\nconst DirectorySync: React.FC<DirectorySyncProps> = ({\n state,\n className,\n ...rest\n}) => {\n const type =\n \"type\" in rest ? (rest as { type: DirectoryType }).type : undefined;\n const errorMessage =\n \"errorMessage\" in rest\n ? (rest as { errorMessage: React.ReactNode }).errorMessage\n : undefined;\n const metadata =\n \"metadata\" in rest\n ? (rest as { metadata: DirectoryMetadata }).metadata\n : undefined;\n const { onOpenAdminPortal, isOpeningAdminPortal } = rest;\n const userCount = metadata?.users.active ?? 0;\n const groupCount = metadata?.groups ?? 0;\n const lastSyncAt = rest.lastSyncAt ? new Date(rest.lastSyncAt) : null;\n\n const currentDate =\n \"currentDate\" in rest && rest.currentDate instanceof Date\n ? rest.currentDate\n : undefined;\n\n const lastSyncString = lastSyncAt\n ? getRelativeTimeString(currentDate ?? new Date(), lastSyncAt)\n : null;\n\n const showCounts =\n state === DirectoryState.linked ||\n state === DirectoryState.invalid_credentials ||\n state === DirectoryState.deleting;\n const statusBadge = getStatusBadge(state);\n const spinnerMessage = getSpinnerMessage(state, !!type);\n const showButton = state !== DirectoryState.deleting;\n const domProps: WidgetRootDomProps = { className };\n\n const countsSubtitle = showCounts ? (\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"{userCount} {userLabel}\"\n id=\"aZxx55\"\n description=\"Directory sync user and group counts\"\n values={{\n userCount,\n userLabel: userCount !== 1 ? \"users\" : \"user\",\n }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden> ∙ </span>\n <Translation\n defaultMessage=\"{groupCount} {groupLabel}\"\n id=\"SgiDio\"\n description=\"Directory sync group count\"\n values={{\n groupCount,\n groupLabel: groupCount !== 1 ? \"groups\" : \"group\",\n }}\n />\n {lastSyncString && (\n <>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden> ∙ </span>\n <Translation\n defaultMessage=\"Last sync {lastSync}\"\n id=\"UUqjnE\"\n description=\"Last sync timestamp for directory\"\n values={{ lastSync: lastSyncString }}\n />\n </>\n )}\n </Text>\n ) : null;\n\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <DirectorySyncContext.Provider value={{ state, type }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {!type ? (\n <>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up a directory yet.\"\n id=\"+ywYVl\"\n description=\"Empty state message when no directory is configured\"\n />\n </Text>\n <AdminPortalOpenButton\n onOpen={onOpenAdminPortal}\n isPending={isOpeningAdminPortal ?? false}\n />\n </>\n ) : (\n <>\n <DirectoryProviderInfo type={type} subtitle={countsSubtitle} />\n <Flex gap=\"5\" align=\"center\">\n {statusBadge}\n {spinnerMessage && (\n <SpinnerMessage>{spinnerMessage}</SpinnerMessage>\n )}\n {showButton && (\n <AdminPortalOpenButton\n onOpen={onOpenAdminPortal}\n isPending={isOpeningAdminPortal ?? false}\n />\n )}\n </Flex>\n </>\n )}\n </Flex>\n </CardList.Item>\n\n {errorMessage && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"var(--gray-11)\" />\n </Box>\n <Text size=\"2\" color=\"gray\">\n {errorMessage}\n </Text>\n </Flex>\n </CardList.Item>\n )}\n </DirectorySyncContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction AdminPortalOpenButton({\n onOpen,\n isPending,\n children,\n}: {\n onOpen: (() => void) | undefined;\n isPending: boolean;\n children?: React.ReactNode;\n}) {\n const { state, type } = useDirectorySyncContext();\n\n const label = (() => {\n switch (state) {\n case DirectoryState.unlinked:\n return type ? \"Continue setup\" : \"Set up directory\";\n case DirectoryState.validating:\n return \"Manage\";\n default:\n return \"Manage\";\n }\n })();\n\n if (onOpen) {\n return (\n <Button\n variant=\"secondary\"\n onClick={() => onOpen()}\n loading={isPending}\n disabled={isPending}\n >\n {children ?? label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n }\n\n return (\n <Button variant=\"secondary\" disabled>\n {children ?? label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\ninterface DirectorySyncLoadingProps extends WidgetRootDomProps {}\n\nconst DirectorySyncLoading: React.FC<DirectorySyncLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"2\" color=\"gray\">\n You haven't set up a directory yet.\n </Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Set up directory <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Card>\n );\n};\n\ninterface DirectorySyncErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst DirectorySyncError: React.FC<DirectorySyncErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"directory-sync\",\n widgetState: state,\n });\n}\n\nfunction getRelativeTimeString(\n currentDate: Date | null,\n lastSync: Date | null,\n) {\n if (!currentDate || !lastSync) {\n return null;\n }\n\n const rtf = new Intl.RelativeTimeFormat(\"en\", { numeric: \"auto\" });\n const diff = lastSync.getTime() - currentDate.getTime();\n\n const diffSeconds = Math.round(diff / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffMonths / 12);\n\n if (Math.abs(diffSeconds) < 60) {\n return \"now\";\n }\n\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, \"minute\");\n }\n\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, \"hour\");\n }\n\n if (Math.abs(diffDays) < 30) {\n return rtf.format(diffDays, \"day\");\n }\n\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, \"month\");\n }\n\n return rtf.format(diffYears, \"year\");\n}\n\nexport type {\n DirectorySyncProps,\n DirectorySyncLoadingProps,\n DirectorySyncErrorProps,\n DirectorySyncStatusProps,\n DirectoryMetadata,\n};\nexport {\n DirectorySync,\n DirectorySyncLoading,\n DirectorySyncError,\n DirectoryState,\n isDirectoryState,\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/directory-sync.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { Box, Card, Flex, Spinner, Text } from \"@radix-ui/themes\";\nimport { ExternalLinkIcon, InfoCircledIcon } from \"@radix-ui/react-icons\";\nimport { Button, Skeleton } from \"./elements.js\";\nimport { GenericError } from \"./generic-error.js\";\nimport * as CardList from \"./card-list.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport {\n getDirectoryTypeIcon,\n getDirectoryTypeName,\n} from \"./identity-providers.js\";\nimport { Status } from \"./status.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport {\n getDomProps,\n type WidgetRootState,\n type WidgetRootDomProps,\n} from \"./utils.js\";\nimport { useComparativeReadableDate } from \"../use-comparative-readable-date.js\";\n\nconst DirectoryState = {\n requires_type: \"requires_type\",\n linked: \"linked\",\n validating: \"validating\",\n invalid_credentials: \"invalid_credentials\",\n unlinked: \"unlinked\",\n deleting: \"deleting\",\n} as const;\ntype DirectoryState = (typeof DirectoryState)[keyof typeof DirectoryState];\n\nfunction isDirectoryState(state: string): state is DirectoryState {\n return Object.values(DirectoryState).some((known) => known === state);\n}\n\ntype DirectoryType = string;\n\ninterface DirectoryMetadata {\n users: { active: number };\n groups: number;\n}\n\ninterface BaseDirectorySyncProps {\n type?: DirectoryType;\n metadata?: DirectoryMetadata;\n lastSyncAt?: string | null;\n onOpenAdminPortal?: () => void;\n isOpeningAdminPortal?: boolean;\n errorMessage?: never;\n userCount?: never;\n groupCount?: never;\n currentDate?: never;\n state: DirectoryState;\n}\n\ninterface NotConfiguredProps extends BaseDirectorySyncProps {\n state: (typeof DirectoryState)[\"unlinked\"];\n}\n\ninterface SetupInProgressProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"validating\"];\n type: DirectoryType;\n}\n\ninterface ErrorBeforeConfigProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"errorMessage\"\n> {\n state: DirectoryState;\n type: DirectoryType;\n errorMessage: React.ReactNode;\n}\n\ninterface ValidatingProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"validating\"];\n type: DirectoryType;\n}\n\ninterface ActiveProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"lastSyncAt\" | \"currentDate\" | \"errorMessage\"\n> {\n state: (typeof DirectoryState)[\"linked\"];\n type: DirectoryType;\n lastSyncAt: string | null;\n currentDate?: Date | null;\n errorMessage?: React.ReactNode;\n}\n\ninterface InvalidCredentialsProps extends Omit<\n BaseDirectorySyncProps,\n \"type\" | \"errorMessage\"\n> {\n state: (typeof DirectoryState)[\"invalid_credentials\"];\n type: DirectoryType;\n errorMessage: React.ReactNode;\n}\n\ninterface DeletingProps extends Omit<BaseDirectorySyncProps, \"type\"> {\n state: (typeof DirectoryState)[\"deleting\"];\n type: DirectoryType;\n}\n\ntype DirectorySyncStatusProps =\n | NotConfiguredProps\n | SetupInProgressProps\n | ErrorBeforeConfigProps\n | ValidatingProps\n | ActiveProps\n | InvalidCredentialsProps\n | DeletingProps;\n\ntype DirectorySyncProps = WidgetRootDomProps & DirectorySyncStatusProps;\n\ninterface DirectorySyncContextValue {\n state: DirectorySyncStatusProps[\"state\"];\n type?: DirectoryType;\n}\n\nconst DirectorySyncContext =\n React.createContext<DirectorySyncContextValue | null>(null);\nDirectorySyncContext.displayName = \"DirectorySyncContext\";\n\nfunction useDirectorySyncContext() {\n const context = React.useContext(DirectorySyncContext);\n if (!context) {\n throw new Error(\n \"useDirectorySyncContext must be used within a DirectorySyncContext provider\",\n );\n }\n return context;\n}\n\nfunction DirectoryProviderInfo({\n type,\n subtitle,\n}: {\n type: DirectoryType;\n subtitle?: React.ReactNode;\n}) {\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color=\"panel\">\n <ProviderIcon\n provider={getDirectoryTypeIcon(type) ?? \"workos\"}\n size=\"2\"\n />\n </IconPanel>\n {subtitle ? (\n <Flex direction=\"column\">\n <Text size=\"2\" weight=\"bold\">\n {getDirectoryTypeName(type)}\n </Text>\n {subtitle}\n </Flex>\n ) : (\n <Text size=\"2\" weight=\"bold\">\n {getDirectoryTypeName(type)}\n </Text>\n )}\n </Flex>\n );\n}\n\nfunction SpinnerMessage({ children }: { children: React.ReactNode }) {\n return (\n <Flex gap=\"2\" align=\"center\">\n <Spinner />\n <Text size=\"2\" color=\"gray\">\n {children}\n </Text>\n </Flex>\n );\n}\n\nfunction getStatusBadge(state: DirectoryState) {\n switch (state) {\n case DirectoryState.requires_type:\n case DirectoryState.invalid_credentials:\n return (\n <Status state=\"error\">\n <Translation\n defaultMessage=\"Requires action\"\n id=\"uuuXIF\"\n description=\"Status badge when directory requires user action\"\n />\n </Status>\n );\n case DirectoryState.linked:\n return (\n <Status state=\"success\">\n <Translation\n defaultMessage=\"Connected\"\n id=\"H/dAHq\"\n description=\"Status badge when directory is active\"\n />\n </Status>\n );\n default:\n return null;\n }\n}\n\nfunction getSpinnerMessage(\n state: DirectoryState,\n hasType: boolean,\n): string | null {\n if (state === DirectoryState.unlinked && hasType)\n return \"Setup in progress...\";\n if (state === DirectoryState.validating)\n return \"Waiting for users and groups...\";\n if (state === DirectoryState.deleting) return \"Deleting directory...\";\n return null;\n}\n\nconst DirectorySync: React.FC<DirectorySyncProps> = ({\n state,\n className,\n ...rest\n}) => {\n const type =\n \"type\" in rest ? (rest as { type: DirectoryType }).type : undefined;\n const errorMessage =\n \"errorMessage\" in rest\n ? (rest as { errorMessage: React.ReactNode }).errorMessage\n : undefined;\n const metadata =\n \"metadata\" in rest\n ? (rest as { metadata: DirectoryMetadata }).metadata\n : undefined;\n const { onOpenAdminPortal, isOpeningAdminPortal } = rest;\n const userCount = metadata?.users.active ?? 0;\n const groupCount = metadata?.groups ?? 0;\n const lastSyncAt = rest.lastSyncAt ? new Date(rest.lastSyncAt) : null;\n\n const currentDate =\n \"currentDate\" in rest && rest.currentDate instanceof Date\n ? rest.currentDate\n : undefined;\n\n const lastSyncString = useComparativeReadableDate({\n date: lastSyncAt,\n currentDate,\n });\n\n const showCounts =\n state === DirectoryState.linked ||\n state === DirectoryState.invalid_credentials ||\n state === DirectoryState.deleting;\n const statusBadge = getStatusBadge(state);\n const spinnerMessage = getSpinnerMessage(state, !!type);\n const showButton = state !== DirectoryState.deleting;\n const domProps: WidgetRootDomProps = { className };\n\n const countsSubtitle = showCounts ? (\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"{userCount} {userLabel}\"\n id=\"aZxx55\"\n description=\"Directory sync user and group counts\"\n values={{\n userCount,\n userLabel: userCount !== 1 ? \"users\" : \"user\",\n }}\n />\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden> ∙ </span>\n <Translation\n defaultMessage=\"{groupCount} {groupLabel}\"\n id=\"SgiDio\"\n description=\"Directory sync group count\"\n values={{\n groupCount,\n groupLabel: groupCount !== 1 ? \"groups\" : \"group\",\n }}\n />\n {lastSyncString && (\n <>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <span aria-hidden> ∙ </span>\n <Translation\n defaultMessage=\"Last sync {lastSync}\"\n id=\"UUqjnE\"\n description=\"Last sync timestamp for directory\"\n values={{ lastSync: lastSyncString }}\n />\n </>\n )}\n </Text>\n ) : null;\n\n return (\n <CardList.Root {...getWidgetRootDomProps(\"resolved\", domProps)}>\n <DirectorySyncContext.Provider value={{ state, type }}>\n <CardList.Item>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n {!type ? (\n <>\n <Text size=\"2\" color=\"gray\">\n <Translation\n defaultMessage=\"You haven't set up a directory yet.\"\n id=\"+ywYVl\"\n description=\"Empty state message when no directory is configured\"\n />\n </Text>\n <AdminPortalOpenButton\n onOpen={onOpenAdminPortal}\n isPending={isOpeningAdminPortal ?? false}\n />\n </>\n ) : (\n <>\n <DirectoryProviderInfo type={type} subtitle={countsSubtitle} />\n <Flex gap=\"5\" align=\"center\">\n {statusBadge}\n {spinnerMessage && (\n <SpinnerMessage>{spinnerMessage}</SpinnerMessage>\n )}\n {showButton && (\n <AdminPortalOpenButton\n onOpen={onOpenAdminPortal}\n isPending={isOpeningAdminPortal ?? false}\n />\n )}\n </Flex>\n </>\n )}\n </Flex>\n </CardList.Item>\n\n {errorMessage && (\n <CardList.Item>\n <Flex align=\"start\" gap=\"2\">\n <Box asChild mt=\"2px\" flexShrink=\"0\">\n <InfoCircledIcon color=\"var(--gray-11)\" />\n </Box>\n <Text size=\"2\" color=\"gray\">\n {errorMessage}\n </Text>\n </Flex>\n </CardList.Item>\n )}\n </DirectorySyncContext.Provider>\n </CardList.Root>\n );\n};\n\nfunction AdminPortalOpenButton({\n onOpen,\n isPending,\n children,\n}: {\n onOpen: (() => void) | undefined;\n isPending: boolean;\n children?: React.ReactNode;\n}) {\n const { state, type } = useDirectorySyncContext();\n\n const label = (() => {\n switch (state) {\n case DirectoryState.unlinked:\n return type ? \"Continue setup\" : \"Set up directory\";\n case DirectoryState.validating:\n return \"Manage\";\n default:\n return \"Manage\";\n }\n })();\n\n if (onOpen) {\n return (\n <Button\n variant=\"secondary\"\n onClick={() => onOpen()}\n loading={isPending}\n disabled={isPending}\n >\n {children ?? label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n }\n\n return (\n <Button variant=\"secondary\" disabled>\n {children ?? label} <ExternalLinkIcon aria-hidden />\n </Button>\n );\n}\n\ninterface DirectorySyncLoadingProps extends WidgetRootDomProps {}\n\nconst DirectorySyncLoading: React.FC<DirectorySyncLoadingProps> = (props) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"loading\", props)}>\n <Flex direction=\"row\" justify=\"between\" align=\"center\" gap=\"2\">\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Text size=\"2\" color=\"gray\">\n You haven't set up a directory yet.\n </Text>\n </Skeleton>\n <Skeleton>\n {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}\n <Button variant=\"secondary\">\n Set up directory <ExternalLinkIcon aria-hidden />\n </Button>\n </Skeleton>\n </Flex>\n </Card>\n );\n};\n\ninterface DirectorySyncErrorProps extends WidgetRootDomProps {\n error: unknown;\n}\n\nconst DirectorySyncError: React.FC<DirectorySyncErrorProps> = ({\n error,\n ...domProps\n}) => {\n return (\n <Card size=\"2\" {...getWidgetRootDomProps(\"error\", domProps)}>\n <GenericError error={error} />\n </Card>\n );\n};\n\nfunction getWidgetRootDomProps(\n state: WidgetRootState,\n domProps: WidgetRootDomProps,\n) {\n return getDomProps({\n ...domProps,\n isWidgetRoot: true,\n widgetId: \"directory-sync\",\n widgetState: state,\n });\n}\n\nexport type {\n DirectorySyncProps,\n DirectorySyncLoadingProps,\n DirectorySyncErrorProps,\n DirectorySyncStatusProps,\n DirectoryMetadata,\n};\nexport {\n DirectorySync,\n DirectorySyncLoading,\n DirectorySyncError,\n DirectoryState,\n isDirectoryState,\n};\n"],"mappings":"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","names":[]}
@@ -2,18 +2,19 @@
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Flex, Text } from "@radix-ui/themes";
4
4
  import { IconPanel } from "./icon-panel.js";
5
- import { getComparativeReadableDate } from "./utils.js";
6
5
  import { Status } from "./status.js";
7
6
  import { NameServerIcon } from "./name-server-icon.js";
8
7
  import { DomainActions } from "./domain-actions.js";
9
8
  import { Translation } from "./i18n/translation.js";
10
- import { useLocale } from "./i18n/use-locale.js";
9
+ import { useComparativeReadableDate } from "../use-comparative-readable-date.js";
11
10
  const DomainItem = ({
12
11
  domain,
13
12
  onDeleteDomain,
14
13
  onReverifyDomain
15
14
  }) => {
16
- const locale = useLocale();
15
+ const timeAgo = useComparativeReadableDate({
16
+ date: new Date(domain.createdAt)
17
+ });
17
18
  return /* @__PURE__ */ jsxs(Flex, { gap: "4", align: "center", children: [
18
19
  /* @__PURE__ */ jsx(IconPanel, { color: domain.nameServer === "Other" ? "gray" : "panel", children: /* @__PURE__ */ jsx(NameServerIcon, { provider: domain.nameServer }) }),
19
20
  /* @__PURE__ */ jsxs(Flex, { direction: "column", children: [
@@ -24,13 +25,7 @@ const DomainItem = ({
24
25
  defaultMessage: "Added {timeAgo}",
25
26
  id: "DtZ2fb",
26
27
  description: "Label showing when the domain was added",
27
- values: {
28
- timeAgo: getComparativeReadableDate(
29
- /* @__PURE__ */ new Date(),
30
- new Date(domain.createdAt),
31
- { locale }
32
- )
33
- }
28
+ values: { timeAgo }
34
29
  }
35
30
  ) })
36
31
  ] }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/domain-item.tsx"],"sourcesContent":["\"use client\";\n\nimport { Flex, Text } from \"@radix-ui/themes\";\nimport type { OrganizationDomainFieldsFragment } from \"../api/client-graphql/generated.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { getComparativeReadableDate } from \"./utils.js\";\nimport { Status } from \"./status.js\";\nimport { NameServerIcon } from \"./name-server-icon.js\";\nimport { DomainActions } from \"./domain-actions.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useLocale } from \"./i18n/use-locale.js\";\n\ninterface DomainItemProps {\n domain: OrganizationDomainFieldsFragment;\n onDeleteDomain: (domainId: string) => void;\n onReverifyDomain: (domainId: string) => void;\n}\n\nexport const DomainItem = ({\n domain,\n onDeleteDomain,\n onReverifyDomain,\n}: DomainItemProps) => {\n const locale = useLocale();\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color={domain.nameServer === \"Other\" ? \"gray\" : \"panel\"}>\n <NameServerIcon provider={domain.nameServer} />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\">\n {domain.domain}\n </Text>\n\n <Text size=\"2\" color=\"gray\" as=\"p\">\n <Translation\n defaultMessage=\"Added {timeAgo}\"\n id=\"DtZ2fb\"\n description=\"Label showing when the domain was added\"\n values={{\n timeAgo: getComparativeReadableDate(\n new Date(),\n new Date(domain.createdAt),\n { locale },\n ),\n }}\n />\n </Text>\n </Flex>\n\n <Flex ml=\"auto\" mr=\"2\" gap=\"4\" align=\"center\">\n <Flex gap=\"1\" align=\"center\">\n <Status state={getDomainStatus(domain)}>\n {domainStateToLabel(domain)}\n </Status>\n </Flex>\n\n <DomainActions\n domain={domain}\n onDeleteDomain={onDeleteDomain}\n onReverifyDomain={onReverifyDomain}\n />\n </Flex>\n </Flex>\n );\n};\n\nconst domainStateToLabel = (domain: OrganizationDomainFieldsFragment) => {\n switch (domain.state) {\n case \"Verified\":\n case \"LegacyVerified\":\n return (\n <Translation\n defaultMessage=\"Verified\"\n id=\"T7rpHw\"\n description=\"Domain verification status indicating the domain is verified\"\n />\n );\n case \"Pending\":\n return (\n <Translation\n defaultMessage=\"Verification pending\"\n id=\"gc1yge\"\n description=\"Domain verification status indicating verification is in progress\"\n />\n );\n case \"Failed\":\n return (\n <Translation\n defaultMessage=\"Verification failed\"\n id=\"cbbwqK\"\n description=\"Domain verification status indicating verification has failed\"\n />\n );\n }\n};\n\nconst getDomainStatus = (domain: OrganizationDomainFieldsFragment) => {\n switch (domain.state) {\n case \"Verified\":\n case \"LegacyVerified\":\n return \"success\";\n case \"Pending\":\n return \"waiting\";\n case \"Failed\":\n return \"error\";\n }\n};\n"],"mappings":";AA4BQ,cAGF,YAHE;AA1BR,SAAS,MAAM,YAAY;AAE3B,SAAS,iBAAiB;AAC1B,SAAS,kCAAkC;AAC3C,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAQnB,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,QAAM,SAAS,UAAU;AAEzB,SACE,qBAAC,QAAK,KAAI,KAAI,OAAM,UAClB;AAAA,wBAAC,aAAU,OAAO,OAAO,eAAe,UAAU,SAAS,SACzD,8BAAC,kBAAe,UAAU,OAAO,YAAY,GAC/C;AAAA,IAEA,qBAAC,QAAK,WAAU,UACd;AAAA,0BAAC,QAAK,MAAK,KAAI,cAAY,MAAC,QAAO,QAAO,IAAG,KAC1C,iBAAO,QACV;AAAA,MAEA,oBAAC,QAAK,MAAK,KAAI,OAAM,QAAO,IAAG,KAC7B;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA,UACZ,QAAQ;AAAA,YACN,SAAS;AAAA,cACP,oBAAI,KAAK;AAAA,cACT,IAAI,KAAK,OAAO,SAAS;AAAA,cACzB,EAAE,OAAO;AAAA,YACX;AAAA,UACF;AAAA;AAAA,MACF,GACF;AAAA,OACF;AAAA,IAEA,qBAAC,QAAK,IAAG,QAAO,IAAG,KAAI,KAAI,KAAI,OAAM,UACnC;AAAA,0BAAC,QAAK,KAAI,KAAI,OAAM,UAClB,8BAAC,UAAO,OAAO,gBAAgB,MAAM,GAClC,6BAAmB,MAAM,GAC5B,GACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,MAAM,qBAAqB,CAAC,WAA6C;AACvE,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,EAEN;AACF;AAEA,MAAM,kBAAkB,CAAC,WAA6C;AACpE,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/domain-item.tsx"],"sourcesContent":["\"use client\";\n\nimport { Flex, Text } from \"@radix-ui/themes\";\nimport type { OrganizationDomainFieldsFragment } from \"../api/client-graphql/generated.js\";\nimport { IconPanel } from \"./icon-panel.js\";\nimport { Status } from \"./status.js\";\nimport { NameServerIcon } from \"./name-server-icon.js\";\nimport { DomainActions } from \"./domain-actions.js\";\nimport { Translation } from \"./i18n/translation.js\";\nimport { useComparativeReadableDate } from \"../use-comparative-readable-date.js\";\n\ninterface DomainItemProps {\n domain: OrganizationDomainFieldsFragment;\n onDeleteDomain: (domainId: string) => void;\n onReverifyDomain: (domainId: string) => void;\n}\n\nexport const DomainItem = ({\n domain,\n onDeleteDomain,\n onReverifyDomain,\n}: DomainItemProps) => {\n const timeAgo = useComparativeReadableDate({\n date: new Date(domain.createdAt),\n });\n\n return (\n <Flex gap=\"4\" align=\"center\">\n <IconPanel color={domain.nameServer === \"Other\" ? \"gray\" : \"panel\"}>\n <NameServerIcon provider={domain.nameServer} />\n </IconPanel>\n\n <Flex direction=\"column\">\n <Text size=\"2\" highContrast weight=\"bold\" as=\"p\">\n {domain.domain}\n </Text>\n\n <Text size=\"2\" color=\"gray\" as=\"p\">\n <Translation\n defaultMessage=\"Added {timeAgo}\"\n id=\"DtZ2fb\"\n description=\"Label showing when the domain was added\"\n values={{ timeAgo }}\n />\n </Text>\n </Flex>\n\n <Flex ml=\"auto\" mr=\"2\" gap=\"4\" align=\"center\">\n <Flex gap=\"1\" align=\"center\">\n <Status state={getDomainStatus(domain)}>\n {domainStateToLabel(domain)}\n </Status>\n </Flex>\n\n <DomainActions\n domain={domain}\n onDeleteDomain={onDeleteDomain}\n onReverifyDomain={onReverifyDomain}\n />\n </Flex>\n </Flex>\n );\n};\n\nconst domainStateToLabel = (domain: OrganizationDomainFieldsFragment) => {\n switch (domain.state) {\n case \"Verified\":\n case \"LegacyVerified\":\n return (\n <Translation\n defaultMessage=\"Verified\"\n id=\"T7rpHw\"\n description=\"Domain verification status indicating the domain is verified\"\n />\n );\n case \"Pending\":\n return (\n <Translation\n defaultMessage=\"Verification pending\"\n id=\"gc1yge\"\n description=\"Domain verification status indicating verification is in progress\"\n />\n );\n case \"Failed\":\n return (\n <Translation\n defaultMessage=\"Verification failed\"\n id=\"cbbwqK\"\n description=\"Domain verification status indicating verification has failed\"\n />\n );\n }\n};\n\nconst getDomainStatus = (domain: OrganizationDomainFieldsFragment) => {\n switch (domain.state) {\n case \"Verified\":\n case \"LegacyVerified\":\n return \"success\";\n case \"Pending\":\n return \"waiting\";\n case \"Failed\":\n return \"error\";\n }\n};\n"],"mappings":";AA6BQ,cAGF,YAHE;AA3BR,SAAS,MAAM,YAAY;AAE3B,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,kCAAkC;AAQpC,MAAM,aAAa,CAAC;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AACF,MAAuB;AACrB,QAAM,UAAU,2BAA2B;AAAA,IACzC,MAAM,IAAI,KAAK,OAAO,SAAS;AAAA,EACjC,CAAC;AAED,SACE,qBAAC,QAAK,KAAI,KAAI,OAAM,UAClB;AAAA,wBAAC,aAAU,OAAO,OAAO,eAAe,UAAU,SAAS,SACzD,8BAAC,kBAAe,UAAU,OAAO,YAAY,GAC/C;AAAA,IAEA,qBAAC,QAAK,WAAU,UACd;AAAA,0BAAC,QAAK,MAAK,KAAI,cAAY,MAAC,QAAO,QAAO,IAAG,KAC1C,iBAAO,QACV;AAAA,MAEA,oBAAC,QAAK,MAAK,KAAI,OAAM,QAAO,IAAG,KAC7B;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA,UACZ,QAAQ,EAAE,QAAQ;AAAA;AAAA,MACpB,GACF;AAAA,OACF;AAAA,IAEA,qBAAC,QAAK,IAAG,QAAO,IAAG,KAAI,KAAI,KAAI,OAAM,UACnC;AAAA,0BAAC,QAAK,KAAI,KAAI,OAAM,UAClB,8BAAC,UAAO,OAAO,gBAAgB,MAAM,GAClC,6BAAmB,MAAM,GAC5B,GACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,MAAM,qBAAqB,CAAC,WAA6C;AACvE,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,IAEJ,KAAK;AACH,aACE;AAAA,QAAC;AAAA;AAAA,UACC,gBAAe;AAAA,UACf,IAAG;AAAA,UACH,aAAY;AAAA;AAAA,MACd;AAAA,EAEN;AACF;AAEA,MAAM,kBAAkB,CAAC,WAA6C;AACpE,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,EACX;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
- declare const IDENTITY_PROVIDER_DICT: Map<"asana" | "box" | "datadog" | "dropbox" | "github" | "gitlab" | "google" | "google-calendar" | "google-drive" | "hubspot" | "intercom" | "linear" | "microsoft" | "notion" | "salesforce" | "slack" | "stripe" | "xero" | "zendesk" | "azure" | "access-people-hr" | "adp" | "apple" | "auth0" | "aws" | "bamboohr" | "bamboo-hr" | "bitbucket" | "breathe-hr" | "bubble" | "cas" | "cezanne-hr" | "classlink" | "clerk" | "cloudflare" | "cyberark" | "duo" | "firebase" | "fourth" | "generic-saml" | "generic-oidc" | "godaddy" | "google-analytics" | "google-mail" | "google-cloud" | "hibob" | "intuit" | "jumpcloud" | "keycloak" | "lastpass" | "linkedin" | "login-gov" | "miniorange" | "net-iq" | "next-auth" | "okta" | "onelogin" | "oracle" | "personio" | "ping-identity" | "react-native-expo" | "rippling" | "segment" | "shibboleth" | "simple-saml-php" | "splunk" | "supabase" | "vercel" | "vmware" | "workday" | "workos" | "test-idp" | "discord" | "clever", "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "GoDaddy" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "HiBob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever">;
1
+ declare const IDENTITY_PROVIDER_DICT: Map<"asana" | "box" | "datadog" | "dropbox" | "github" | "gitlab" | "google" | "google-calendar" | "google-drive" | "hubspot" | "intercom" | "linear" | "microsoft" | "notion" | "salesforce" | "slack" | "stripe" | "xero" | "zendesk" | "azure" | "access-people-hr" | "adp" | "apple" | "auth0" | "aws" | "bamboohr" | "bamboo-hr" | "bitbucket" | "breathe-hr" | "bubble" | "cas" | "cezanne-hr" | "classlink" | "clerk" | "cloudflare" | "cyberark" | "duo" | "firebase" | "fourth" | "generic-saml" | "generic-oidc" | "godaddy" | "google-analytics" | "google-mail" | "google-cloud" | "hibob" | "intuit" | "jumpcloud" | "keycloak" | "lastpass" | "linkedin" | "login-gov" | "miniorange" | "net-iq" | "next-auth" | "okta" | "onelogin" | "oracle" | "personio" | "ping-identity" | "react-native-expo" | "rippling" | "segment" | "shibboleth" | "simple-saml-php" | "splunk" | "supabase" | "vercel" | "vmware" | "workday" | "workos" | "test-idp" | "discord" | "clever", "Datadog" | "Splunk" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "GoDaddy" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "HiBob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever">;
2
2
  type MapKey<T extends Map<unknown, unknown>> = T extends Map<infer K, unknown> ? K : never;
3
3
  type IdentityProvider = MapKey<typeof IDENTITY_PROVIDER_DICT>;
4
- declare function getIdentityProviderName(provider: IdentityProvider): "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Datadog" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "GoDaddy" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "HiBob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Splunk" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever" | undefined;
4
+ declare function getIdentityProviderName(provider: IdentityProvider): "Datadog" | "Splunk" | "Access People HR" | "ADP" | "Apple" | "Asana" | "Auth0" | "Azure" | "AWS" | "BambooHR" | "Bitbucket" | "Box" | "BreatheHR" | "Bubble" | "CAS" | "Cezanne HR" | "Classlink" | "Clerk" | "Cloudflare" | "CyberArk" | "Dropbox" | "Duo" | "Firebase" | "Fourth" | "Generic SAML" | "Generic OIDC" | "GitHub" | "GitLab" | "GoDaddy" | "Google" | "Google Analytics" | "Google Calendar" | "Google Drive" | "Google Mail" | "Google Cloud" | "HiBob" | "Hubspot" | "Intercom" | "Intuit" | "JumpCloud" | "Keycloak" | "LastPass" | "Linear" | "LinkedIn" | "Login.gov" | "Microsoft" | "Miniorange" | "NetIQ" | "NextAuth" | "Notion" | "Okta" | "OneLogin" | "Oracle" | "Personio" | "Ping Identity" | "React Native Expo" | "Rippling" | "Salesforce" | "Segment" | "Shibboleth" | "Simple SAML PHP" | "Slack" | "Stripe" | "Supabase" | "Vercel" | "VMware" | "Workday" | "WorkOS" | "Xero" | "Zendesk" | "Test IDP" | "Discord" | "Clever" | undefined;
5
5
  declare function getDirectoryTypeIcon(directoryType: string): IdentityProvider | null;
6
6
  declare function getDirectoryTypeName(directoryType: string): string;
7
7
  declare function isIdentityProvider(provider: unknown): boolean;