@xenide-io/the-old-ui-theme 0.9.10 → 0.9.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/suite.d.mts +119 -2
- package/dist/suite.d.ts +119 -2
- package/dist/suite.js +856 -418
- package/dist/suite.mjs +821 -382
- package/package.json +1 -1
- package/src/suite/components/suite-clients-projects-directory.test.tsx +5 -13
- package/src/suite/components/suite-clients-projects-directory.tsx +163 -200
- package/src/suite/components/suite-entity-icon.tsx +80 -0
- package/src/suite/components/suite-palette-library.tsx +434 -0
- package/src/suite/index.ts +17 -0
- package/src/suite/lib/palette-api.ts +143 -0
package/dist/suite.js
CHANGED
|
@@ -168,6 +168,7 @@ __export(suite_exports, {
|
|
|
168
168
|
SuiteBreadcrumbs: () => SuiteBreadcrumbs,
|
|
169
169
|
SuiteClientsProjectsDirectory: () => SuiteClientsProjectsDirectory,
|
|
170
170
|
SuiteEmptyState: () => SuiteEmptyState,
|
|
171
|
+
SuiteEntityIcon: () => SuiteEntityIcon,
|
|
171
172
|
SuiteIcon: () => SuiteIcon,
|
|
172
173
|
SuiteIntegrationPicker: () => SuiteIntegrationPicker,
|
|
173
174
|
SuiteIntegrationRules: () => SuiteIntegrationRules,
|
|
@@ -177,6 +178,7 @@ __export(suite_exports, {
|
|
|
177
178
|
SuiteNotificationBell: () => SuiteNotificationBell,
|
|
178
179
|
SuitePage: () => SuitePage,
|
|
179
180
|
SuitePageHeader: () => SuitePageHeader,
|
|
181
|
+
SuitePaletteLibrary: () => SuitePaletteLibrary,
|
|
180
182
|
SuiteSectionHeader: () => SuiteSectionHeader,
|
|
181
183
|
SuiteSettingsLayout: () => SuiteSettingsLayout,
|
|
182
184
|
SuiteSettingsMobileNav: () => SuiteSettingsMobileNav,
|
|
@@ -209,6 +211,9 @@ __export(suite_exports, {
|
|
|
209
211
|
cn: () => cn,
|
|
210
212
|
consumePendingAskAiPrompt: () => consumePendingAskAiPrompt,
|
|
211
213
|
consumeSuiteAskAiOpenFromLocation: () => consumeSuiteAskAiOpenFromLocation,
|
|
214
|
+
fetchPaletteCollection: () => fetchPaletteCollection,
|
|
215
|
+
fetchPaletteLibrary: () => fetchPaletteLibrary,
|
|
216
|
+
findPaletteIcons: () => findPaletteIcons,
|
|
212
217
|
getTodayGreeting: () => getTodayGreeting,
|
|
213
218
|
m: () => import_react15.m,
|
|
214
219
|
openSuiteAskAi: () => openSuiteAskAi,
|
|
@@ -672,13 +677,13 @@ function SuiteAppStrip({
|
|
|
672
677
|
),
|
|
673
678
|
"aria-label": "ShellStack suite apps",
|
|
674
679
|
children: SUITE_APPS.map((app) => {
|
|
675
|
-
var
|
|
680
|
+
var _a2;
|
|
676
681
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
677
682
|
"div",
|
|
678
683
|
{
|
|
679
684
|
className: "flex items-center gap-2 rounded-full border border-ph-border bg-ph-surface px-2.5 py-1.5 shadow-sm",
|
|
680
685
|
children: [
|
|
681
|
-
(
|
|
686
|
+
(_a2 = icons == null ? void 0 : icons[app]) != null ? _a2 : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SuiteAppIcon, { app, size: "sm" }),
|
|
682
687
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-xs font-medium text-ph-subtle", children: APP_META[app].name })
|
|
683
688
|
]
|
|
684
689
|
},
|
|
@@ -797,13 +802,13 @@ function TodayTopBar({
|
|
|
797
802
|
] });
|
|
798
803
|
}
|
|
799
804
|
function getTodayGreeting(user, stats) {
|
|
800
|
-
var
|
|
805
|
+
var _a2, _b, _c, _d, _e;
|
|
801
806
|
const hour = (/* @__PURE__ */ new Date()).getHours();
|
|
802
807
|
let period = "morning";
|
|
803
808
|
if (hour >= 12 && hour < 17) period = "afternoon";
|
|
804
809
|
else if (hour >= 17 && hour < 21) period = "evening";
|
|
805
810
|
else if (hour >= 21 || hour < 5) period = "night";
|
|
806
|
-
const name = (user == null ? void 0 : user.first_name) || ((
|
|
811
|
+
const name = (user == null ? void 0 : user.first_name) || ((_a2 = user == null ? void 0 : user.name) == null ? void 0 : _a2.split(" ")[0]) || ((_b = user == null ? void 0 : user.email) == null ? void 0 : _b.split("@")[0]) || null;
|
|
807
812
|
let greeting = `Good ${period}`;
|
|
808
813
|
if (name) greeting += `, ${name}`;
|
|
809
814
|
const taskCount = (_c = stats == null ? void 0 : stats.taskCount) != null ? _c : 0;
|
|
@@ -1302,8 +1307,8 @@ var SOURCE_APP_SLUG = {
|
|
|
1302
1307
|
shellstack: "shellstack"
|
|
1303
1308
|
};
|
|
1304
1309
|
function suiteAppSlugForNotificationSource(sourceApp) {
|
|
1305
|
-
var
|
|
1306
|
-
return (
|
|
1310
|
+
var _a2;
|
|
1311
|
+
return (_a2 = SOURCE_APP_SLUG[(sourceApp || "").toLowerCase()]) != null ? _a2 : null;
|
|
1307
1312
|
}
|
|
1308
1313
|
function resolveSuiteNotificationHref(href, sourceApp) {
|
|
1309
1314
|
const value = (href || "").trim();
|
|
@@ -1391,14 +1396,14 @@ function SuiteNotificationBell({
|
|
|
1391
1396
|
(0, import_react2.useEffect)(() => {
|
|
1392
1397
|
if (cacheKey) {
|
|
1393
1398
|
queueMicrotask(() => {
|
|
1394
|
-
var
|
|
1399
|
+
var _a2;
|
|
1395
1400
|
try {
|
|
1396
1401
|
const raw = sessionStorage.getItem(cacheKey);
|
|
1397
1402
|
if (raw) {
|
|
1398
1403
|
const cached = JSON.parse(raw);
|
|
1399
1404
|
if (Array.isArray(cached.notifications)) {
|
|
1400
1405
|
setItems(cached.notifications);
|
|
1401
|
-
setUnread((
|
|
1406
|
+
setUnread((_a2 = cached.unread_count) != null ? _a2 : 0);
|
|
1402
1407
|
}
|
|
1403
1408
|
}
|
|
1404
1409
|
} catch (e) {
|
|
@@ -1469,9 +1474,9 @@ function SuiteNotificationBell({
|
|
|
1469
1474
|
const markAll = (0, import_react2.useCallback)(async () => {
|
|
1470
1475
|
setItems(
|
|
1471
1476
|
(prev) => prev.map((i) => {
|
|
1472
|
-
var
|
|
1477
|
+
var _a2;
|
|
1473
1478
|
return __spreadProps(__spreadValues({}, i), {
|
|
1474
|
-
read_at: (
|
|
1479
|
+
read_at: (_a2 = i.read_at) != null ? _a2 : (/* @__PURE__ */ new Date()).toISOString()
|
|
1475
1480
|
});
|
|
1476
1481
|
})
|
|
1477
1482
|
);
|
|
@@ -2087,8 +2092,8 @@ function cn2(...parts) {
|
|
|
2087
2092
|
|
|
2088
2093
|
// src/components/icons/IconBase.tsx
|
|
2089
2094
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2090
|
-
var IconBase = (0, import_react7.forwardRef)(function IconBase2(
|
|
2091
|
-
var _b =
|
|
2095
|
+
var IconBase = (0, import_react7.forwardRef)(function IconBase2(_a2, ref) {
|
|
2096
|
+
var _b = _a2, {
|
|
2092
2097
|
className,
|
|
2093
2098
|
size,
|
|
2094
2099
|
children,
|
|
@@ -2503,8 +2508,8 @@ var IconActivity = createIconBasePath(
|
|
|
2503
2508
|
var IconFlask = createIconBasePath(
|
|
2504
2509
|
"M19.8 18.4L14 10.67V6.5l1.35-1.35c.39-.39.39-1.02 0-1.41L14.65 2.7a.9959.9959 0 0 0-1.41 0L9.35 6.54c-.39.39-.39 1.02 0 1.41L10.7 9.3v4.17L4.2 18.4C3.53 19.07 4.04 20.25 5 20.25h14c.96 0 1.47-1.18.8-1.85zM6.91 18.25l5.09-5.09 5.09 5.09H6.91z"
|
|
2505
2510
|
);
|
|
2506
|
-
var IconSpinner = (0, import_react9.forwardRef)(function IconSpinner2(
|
|
2507
|
-
var _b =
|
|
2511
|
+
var IconSpinner = (0, import_react9.forwardRef)(function IconSpinner2(_a2, ref) {
|
|
2512
|
+
var _b = _a2, { className } = _b, props = __objRest(_b, ["className"]);
|
|
2508
2513
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconSync, __spreadValues({ ref, className: cn2("ph-icon-spin", className) }, props));
|
|
2509
2514
|
});
|
|
2510
2515
|
IconSpinner.displayName = "IconSpinner";
|
|
@@ -2603,8 +2608,8 @@ for (const [name, Icon] of Object.entries(CANONICAL_ICONS)) {
|
|
|
2603
2608
|
namedIcon.displayName = `Icon${name[0].toUpperCase()}${name.slice(1)}`;
|
|
2604
2609
|
}
|
|
2605
2610
|
}
|
|
2606
|
-
var IconByName = (0, import_react9.forwardRef)(function IconByName2(
|
|
2607
|
-
var _b =
|
|
2611
|
+
var IconByName = (0, import_react9.forwardRef)(function IconByName2(_a2, ref) {
|
|
2612
|
+
var _b = _a2, { name } = _b, props = __objRest(_b, ["name"]);
|
|
2608
2613
|
const Icon = PH_ICONS[name];
|
|
2609
2614
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Icon, __spreadValues({ ref }, props));
|
|
2610
2615
|
});
|
|
@@ -2658,8 +2663,8 @@ function DropdownContent({
|
|
|
2658
2663
|
}
|
|
2659
2664
|
) });
|
|
2660
2665
|
}
|
|
2661
|
-
function DropdownMenu(
|
|
2662
|
-
var _b =
|
|
2666
|
+
function DropdownMenu(_a2) {
|
|
2667
|
+
var _b = _a2, {
|
|
2663
2668
|
trigger,
|
|
2664
2669
|
triggerId,
|
|
2665
2670
|
triggerDataTest,
|
|
@@ -2734,8 +2739,8 @@ function DropdownMenu(_a) {
|
|
|
2734
2739
|
}
|
|
2735
2740
|
) }));
|
|
2736
2741
|
}
|
|
2737
|
-
function DropdownItem(
|
|
2738
|
-
var _b =
|
|
2742
|
+
function DropdownItem(_a2) {
|
|
2743
|
+
var _b = _a2, {
|
|
2739
2744
|
className,
|
|
2740
2745
|
children,
|
|
2741
2746
|
disabled
|
|
@@ -2934,7 +2939,7 @@ function SuiteBottomNav({
|
|
|
2934
2939
|
children: [
|
|
2935
2940
|
activeIndex >= 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": true, className: "suite-bottom-nav__indicator" }) : null,
|
|
2936
2941
|
items.map((item) => {
|
|
2937
|
-
var
|
|
2942
|
+
var _a2;
|
|
2938
2943
|
const Icon = item.icon;
|
|
2939
2944
|
const active = Boolean(item.active);
|
|
2940
2945
|
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
@@ -2942,7 +2947,7 @@ function SuiteBottomNav({
|
|
|
2942
2947
|
{
|
|
2943
2948
|
href: item.href,
|
|
2944
2949
|
id: item.id,
|
|
2945
|
-
"data-test": (
|
|
2950
|
+
"data-test": (_a2 = item.dataTest) != null ? _a2 : `suite-nav-${item.label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
2946
2951
|
"aria-current": active ? "page" : void 0,
|
|
2947
2952
|
className: cn(
|
|
2948
2953
|
"suite-bottom-nav__item relative flex min-h-[60px] min-w-0 flex-col items-center justify-center gap-1 px-1 pb-1.5 pt-2 text-[10px] font-medium leading-none text-ph-mutedtext transition-colors duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ph-brand motion-reduce:transition-none",
|
|
@@ -3033,7 +3038,7 @@ var import_react10 = require("react");
|
|
|
3033
3038
|
|
|
3034
3039
|
// src/suite/lib/cookies.ts
|
|
3035
3040
|
function suiteCookieDomainAttr() {
|
|
3036
|
-
var
|
|
3041
|
+
var _a2;
|
|
3037
3042
|
const host = window.location.hostname;
|
|
3038
3043
|
if (host === "localhost" || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(host)) {
|
|
3039
3044
|
return "";
|
|
@@ -3052,7 +3057,7 @@ function suiteCookieDomainAttr() {
|
|
|
3052
3057
|
"portal"
|
|
3053
3058
|
]);
|
|
3054
3059
|
const parts = host.split(".");
|
|
3055
|
-
if (parts.length >= 3 && known.has((
|
|
3060
|
+
if (parts.length >= 3 && known.has((_a2 = parts[0]) != null ? _a2 : "")) {
|
|
3056
3061
|
return `; Domain=.${parts.slice(1).join(".")}`;
|
|
3057
3062
|
}
|
|
3058
3063
|
if (parts.length >= 2) return `; Domain=.${parts.slice(1).join(".")}`;
|
|
@@ -3261,10 +3266,10 @@ function useSuiteTheme() {
|
|
|
3261
3266
|
|
|
3262
3267
|
// src/suite/lib/theme-boot.ts
|
|
3263
3268
|
function suiteThemeBootScript(options) {
|
|
3264
|
-
var
|
|
3269
|
+
var _a2, _b, _c, _d;
|
|
3265
3270
|
const light = JSON.stringify(options.lightThemeId);
|
|
3266
3271
|
const dark = JSON.stringify(options.darkThemeId);
|
|
3267
|
-
const storageKey = JSON.stringify((
|
|
3272
|
+
const storageKey = JSON.stringify((_a2 = options.storageKey) != null ? _a2 : null);
|
|
3268
3273
|
const metaLight = JSON.stringify((_b = options.themeColorLight) != null ? _b : null);
|
|
3269
3274
|
const metaDark = JSON.stringify((_c = options.themeColorDark) != null ? _c : null);
|
|
3270
3275
|
const fallback = JSON.stringify((_d = options.fallback) != null ? _d : "light");
|
|
@@ -3461,8 +3466,8 @@ function consumeSuiteAskAiOpenFromLocation() {
|
|
|
3461
3466
|
}
|
|
3462
3467
|
var pendingAskAiPrompt = null;
|
|
3463
3468
|
function openSuiteAskAi(detail) {
|
|
3464
|
-
var
|
|
3465
|
-
pendingAskAiPrompt = ((
|
|
3469
|
+
var _a2;
|
|
3470
|
+
pendingAskAiPrompt = ((_a2 = detail == null ? void 0 : detail.prompt) == null ? void 0 : _a2.trim()) || null;
|
|
3466
3471
|
if (typeof window === "undefined") return;
|
|
3467
3472
|
window.dispatchEvent(
|
|
3468
3473
|
new CustomEvent(SUITE_OPEN_ASK_AI_EVENT, {
|
|
@@ -3534,9 +3539,9 @@ function SuiteAiPanel({
|
|
|
3534
3539
|
const waiting = loading || isWaitingForReply;
|
|
3535
3540
|
(0, import_react12.useEffect)(() => {
|
|
3536
3541
|
function onOpen(event) {
|
|
3537
|
-
var
|
|
3542
|
+
var _a2;
|
|
3538
3543
|
const detail = event.detail;
|
|
3539
|
-
const queued = ((
|
|
3544
|
+
const queued = ((_a2 = detail == null ? void 0 : detail.prompt) == null ? void 0 : _a2.trim()) || consumePendingAskAiPrompt();
|
|
3540
3545
|
setOpen(true);
|
|
3541
3546
|
if (queued) {
|
|
3542
3547
|
pendingPromptRef.current = queued;
|
|
@@ -3559,12 +3564,12 @@ function SuiteAiPanel({
|
|
|
3559
3564
|
setAtBottom(distance < 64);
|
|
3560
3565
|
}, []);
|
|
3561
3566
|
const hydrate = (0, import_react12.useCallback)(async () => {
|
|
3562
|
-
var
|
|
3567
|
+
var _a2, _b, _c;
|
|
3563
3568
|
setHydrating(true);
|
|
3564
3569
|
setError("");
|
|
3565
3570
|
try {
|
|
3566
3571
|
const data = await fetchChat();
|
|
3567
|
-
setMessages((
|
|
3572
|
+
setMessages((_a2 = data.messages) != null ? _a2 : []);
|
|
3568
3573
|
if (!data.configured) {
|
|
3569
3574
|
setError("ShellStack AI is not configured for this workspace yet.");
|
|
3570
3575
|
} else {
|
|
@@ -3582,9 +3587,9 @@ function SuiteAiPanel({
|
|
|
3582
3587
|
}
|
|
3583
3588
|
}, [fetchChat]);
|
|
3584
3589
|
(0, import_react12.useEffect)(() => {
|
|
3585
|
-
var
|
|
3590
|
+
var _a2;
|
|
3586
3591
|
if (!open) return;
|
|
3587
|
-
const queued = (
|
|
3592
|
+
const queued = (_a2 = pendingPromptRef.current) != null ? _a2 : consumePendingAskAiPrompt();
|
|
3588
3593
|
pendingPromptRef.current = queued;
|
|
3589
3594
|
void hydrate().then(() => {
|
|
3590
3595
|
const pending = pendingPromptRef.current;
|
|
@@ -3596,8 +3601,8 @@ function SuiteAiPanel({
|
|
|
3596
3601
|
if (open && atBottom) scrollToBottom();
|
|
3597
3602
|
}, [messages, waiting, open, atBottom, scrollToBottom]);
|
|
3598
3603
|
(0, import_react12.useEffect)(() => {
|
|
3599
|
-
var
|
|
3600
|
-
if (open && !hydrating) (
|
|
3604
|
+
var _a2;
|
|
3605
|
+
if (open && !hydrating) (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
3601
3606
|
}, [open, hydrating]);
|
|
3602
3607
|
(0, import_react12.useEffect)(() => {
|
|
3603
3608
|
if (!open) return;
|
|
@@ -3611,7 +3616,7 @@ function SuiteAiPanel({
|
|
|
3611
3616
|
el.style.height = `${Math.min(el.scrollHeight, 176)}px`;
|
|
3612
3617
|
}, [prompt, open]);
|
|
3613
3618
|
async function ask(text) {
|
|
3614
|
-
var
|
|
3619
|
+
var _a2;
|
|
3615
3620
|
const trimmed = text.trim();
|
|
3616
3621
|
if (!trimmed || waiting) return;
|
|
3617
3622
|
const controller = new AbortController();
|
|
@@ -3627,20 +3632,20 @@ function SuiteAiPanel({
|
|
|
3627
3632
|
signal: controller.signal
|
|
3628
3633
|
});
|
|
3629
3634
|
if (controller.signal.aborted) return;
|
|
3630
|
-
const nextMessages = (
|
|
3635
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
3631
3636
|
setMessages(nextMessages);
|
|
3632
3637
|
notifySuiteMutated(
|
|
3633
3638
|
nextMessages.flatMap((message) => {
|
|
3634
|
-
var
|
|
3635
|
-
return (
|
|
3639
|
+
var _a3;
|
|
3640
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
3636
3641
|
})
|
|
3637
3642
|
);
|
|
3638
3643
|
} catch (err) {
|
|
3639
3644
|
if (controller.signal.aborted) return;
|
|
3640
3645
|
setMessages(
|
|
3641
3646
|
(prev) => {
|
|
3642
|
-
var
|
|
3643
|
-
return ((
|
|
3647
|
+
var _a3, _b;
|
|
3648
|
+
return ((_a3 = prev[prev.length - 1]) == null ? void 0 : _a3.role) === "user" && ((_b = prev[prev.length - 1]) == null ? void 0 : _b.content) === trimmed ? prev.slice(0, -1) : prev;
|
|
3644
3649
|
}
|
|
3645
3650
|
);
|
|
3646
3651
|
setPrompt(trimmed);
|
|
@@ -3653,8 +3658,8 @@ function SuiteAiPanel({
|
|
|
3653
3658
|
}
|
|
3654
3659
|
}
|
|
3655
3660
|
function stop() {
|
|
3656
|
-
var
|
|
3657
|
-
(
|
|
3661
|
+
var _a2;
|
|
3662
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
3658
3663
|
abortRef.current = null;
|
|
3659
3664
|
setLoading(false);
|
|
3660
3665
|
if (!cancelMessage) return;
|
|
@@ -3664,14 +3669,14 @@ function SuiteAiPanel({
|
|
|
3664
3669
|
});
|
|
3665
3670
|
}
|
|
3666
3671
|
function retry() {
|
|
3667
|
-
var
|
|
3668
|
-
const lastUser = (
|
|
3672
|
+
var _a2;
|
|
3673
|
+
const lastUser = (_a2 = [...messages].reverse().find((message) => message.role === "user")) == null ? void 0 : _a2.content;
|
|
3669
3674
|
setError("");
|
|
3670
3675
|
if (lastUser) void ask(lastUser);
|
|
3671
3676
|
else void hydrate();
|
|
3672
3677
|
}
|
|
3673
3678
|
async function saveEdit(index) {
|
|
3674
|
-
var
|
|
3679
|
+
var _a2;
|
|
3675
3680
|
const trimmed = editDraft.trim();
|
|
3676
3681
|
if (!trimmed || waiting) return;
|
|
3677
3682
|
setEditingIndex(null);
|
|
@@ -3689,12 +3694,12 @@ function SuiteAiPanel({
|
|
|
3689
3694
|
signal: controller.signal
|
|
3690
3695
|
}) : await sendMessage({ prompt: trimmed, signal: controller.signal });
|
|
3691
3696
|
if (controller.signal.aborted) return;
|
|
3692
|
-
const nextMessages = (
|
|
3697
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
3693
3698
|
setMessages(nextMessages);
|
|
3694
3699
|
notifySuiteMutated(
|
|
3695
3700
|
nextMessages.flatMap((message) => {
|
|
3696
|
-
var
|
|
3697
|
-
return (
|
|
3701
|
+
var _a3;
|
|
3702
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
3698
3703
|
})
|
|
3699
3704
|
);
|
|
3700
3705
|
} catch (err) {
|
|
@@ -3732,18 +3737,18 @@ function SuiteAiPanel({
|
|
|
3732
3737
|
}
|
|
3733
3738
|
}
|
|
3734
3739
|
async function handleResolve(actionId, decision) {
|
|
3735
|
-
var
|
|
3740
|
+
var _a2;
|
|
3736
3741
|
if (!resolveAction || resolvingId) return;
|
|
3737
3742
|
setResolvingId(actionId);
|
|
3738
3743
|
setError("");
|
|
3739
3744
|
try {
|
|
3740
3745
|
const result = await resolveAction(actionId, decision);
|
|
3741
|
-
const nextMessages = (
|
|
3746
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
3742
3747
|
setMessages(nextMessages);
|
|
3743
3748
|
notifySuiteMutated(
|
|
3744
3749
|
nextMessages.flatMap((message) => {
|
|
3745
|
-
var
|
|
3746
|
-
return (
|
|
3750
|
+
var _a3;
|
|
3751
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
3747
3752
|
})
|
|
3748
3753
|
);
|
|
3749
3754
|
} catch (err) {
|
|
@@ -3755,12 +3760,12 @@ function SuiteAiPanel({
|
|
|
3755
3760
|
}
|
|
3756
3761
|
}
|
|
3757
3762
|
function onConversationClick(event) {
|
|
3758
|
-
var
|
|
3763
|
+
var _a2;
|
|
3759
3764
|
if (event.defaultPrevented) return;
|
|
3760
3765
|
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
3761
3766
|
return;
|
|
3762
3767
|
}
|
|
3763
|
-
const anchor = (
|
|
3768
|
+
const anchor = (_a2 = event.target) == null ? void 0 : _a2.closest("a");
|
|
3764
3769
|
if (!anchor || !suiteAppBases) return;
|
|
3765
3770
|
const href = anchor.href;
|
|
3766
3771
|
if (!href) return;
|
|
@@ -3848,7 +3853,7 @@ function SuiteAiPanel({
|
|
|
3848
3853
|
)) }) : null
|
|
3849
3854
|
] }) : null,
|
|
3850
3855
|
messages.map((message, index) => {
|
|
3851
|
-
var
|
|
3856
|
+
var _a2;
|
|
3852
3857
|
const isUser = message.role === "user";
|
|
3853
3858
|
if (isUser) {
|
|
3854
3859
|
if (editingIndex === index) {
|
|
@@ -3981,7 +3986,7 @@ function SuiteAiPanel({
|
|
|
3981
3986
|
)
|
|
3982
3987
|
}
|
|
3983
3988
|
) }),
|
|
3984
|
-
((
|
|
3989
|
+
((_a2 = message.actions) != null ? _a2 : []).map((action) => /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
3985
3990
|
"div",
|
|
3986
3991
|
{
|
|
3987
3992
|
"data-test": "ask-ai-action",
|
|
@@ -4153,9 +4158,9 @@ function SuiteWorkspaceSwitcher({
|
|
|
4153
4158
|
triggerDataTest,
|
|
4154
4159
|
footer
|
|
4155
4160
|
}) {
|
|
4156
|
-
var
|
|
4161
|
+
var _a2;
|
|
4157
4162
|
const [open, setOpen] = (0, import_react13.useState)(false);
|
|
4158
|
-
const sections = (
|
|
4163
|
+
const sections = (_a2 = groups == null ? void 0 : groups.filter((group) => group.workspaces.length > 0)) != null ? _a2 : workspaces.length > 0 ? [{ id: "workspaces", label: "Switch workspace", workspaces }] : [];
|
|
4159
4164
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4160
4165
|
DropdownMenu2,
|
|
4161
4166
|
{
|
|
@@ -4857,7 +4862,7 @@ function SuiteSidebar({
|
|
|
4857
4862
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "min-h-0 flex-1", children: askAi })
|
|
4858
4863
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
4859
4864
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("nav", { "aria-label": "Pages", className: "shrink-0 space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "space-y-1", children: navItems.map((item) => {
|
|
4860
|
-
var
|
|
4865
|
+
var _a2;
|
|
4861
4866
|
const Icon = item.icon;
|
|
4862
4867
|
const active = Boolean(item.active);
|
|
4863
4868
|
const link = /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
@@ -4865,7 +4870,7 @@ function SuiteSidebar({
|
|
|
4865
4870
|
{
|
|
4866
4871
|
href: item.href,
|
|
4867
4872
|
id: item.id,
|
|
4868
|
-
"data-test": (
|
|
4873
|
+
"data-test": (_a2 = item.dataTest) != null ? _a2 : "nav-link",
|
|
4869
4874
|
"aria-current": active ? "page" : void 0,
|
|
4870
4875
|
onClick: item.onClick,
|
|
4871
4876
|
className: cn(
|
|
@@ -5071,8 +5076,8 @@ var shapeClass = {
|
|
|
5071
5076
|
square: "ph-btn-square",
|
|
5072
5077
|
wide: "ph-btn-wide"
|
|
5073
5078
|
};
|
|
5074
|
-
var Button = (0, import_react18.forwardRef)(function Button2(
|
|
5075
|
-
var _b =
|
|
5079
|
+
var Button = (0, import_react18.forwardRef)(function Button2(_a2, ref) {
|
|
5080
|
+
var _b = _a2, {
|
|
5076
5081
|
variant = "secondary",
|
|
5077
5082
|
size = "md",
|
|
5078
5083
|
shape = "default",
|
|
@@ -5149,8 +5154,8 @@ var statusClassMap = {
|
|
|
5149
5154
|
warning: "ph-alert-warning",
|
|
5150
5155
|
danger: "ph-alert-danger"
|
|
5151
5156
|
};
|
|
5152
|
-
var Alert = (0, import_react19.forwardRef)(function Alert2(
|
|
5153
|
-
var _b =
|
|
5157
|
+
var Alert = (0, import_react19.forwardRef)(function Alert2(_a2, ref) {
|
|
5158
|
+
var _b = _a2, {
|
|
5154
5159
|
status = "info",
|
|
5155
5160
|
title,
|
|
5156
5161
|
description,
|
|
@@ -5222,8 +5227,8 @@ var sizeMap = {
|
|
|
5222
5227
|
sm: "text-[10px] px-1.5 py-0.5",
|
|
5223
5228
|
md: ""
|
|
5224
5229
|
};
|
|
5225
|
-
var Badge = (0, import_react20.forwardRef)(function Badge2(
|
|
5226
|
-
var _b =
|
|
5230
|
+
var Badge = (0, import_react20.forwardRef)(function Badge2(_a2, ref) {
|
|
5231
|
+
var _b = _a2, {
|
|
5227
5232
|
variant = "neutral",
|
|
5228
5233
|
size = "md",
|
|
5229
5234
|
children,
|
|
@@ -5260,8 +5265,8 @@ var variantMap2 = {
|
|
|
5260
5265
|
elevated: "ph-card-elevated",
|
|
5261
5266
|
highlighted: "ph-card-highlighted"
|
|
5262
5267
|
};
|
|
5263
|
-
var Card = (0, import_react21.forwardRef)(function Card2(
|
|
5264
|
-
var _b =
|
|
5268
|
+
var Card = (0, import_react21.forwardRef)(function Card2(_a2, ref) {
|
|
5269
|
+
var _b = _a2, {
|
|
5265
5270
|
children,
|
|
5266
5271
|
title,
|
|
5267
5272
|
description,
|
|
@@ -5353,8 +5358,8 @@ var import_iconoir_react11 = require("iconoir-react");
|
|
|
5353
5358
|
// src/components/ui/FormField.tsx
|
|
5354
5359
|
var import_react22 = require("react");
|
|
5355
5360
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
5356
|
-
function FormField(
|
|
5357
|
-
var _b =
|
|
5361
|
+
function FormField(_a2) {
|
|
5362
|
+
var _b = _a2, {
|
|
5358
5363
|
controlId,
|
|
5359
5364
|
label,
|
|
5360
5365
|
hideLabel = false,
|
|
@@ -5414,8 +5419,8 @@ function joinIds(...ids) {
|
|
|
5414
5419
|
const value = ids.filter(Boolean).join(" ");
|
|
5415
5420
|
return value || void 0;
|
|
5416
5421
|
}
|
|
5417
|
-
var Input = (0, import_react23.forwardRef)(function Input2(
|
|
5418
|
-
var _b =
|
|
5422
|
+
var Input = (0, import_react23.forwardRef)(function Input2(_a2, ref) {
|
|
5423
|
+
var _b = _a2, {
|
|
5419
5424
|
id: idProp,
|
|
5420
5425
|
label,
|
|
5421
5426
|
hideLabel = false,
|
|
@@ -5497,8 +5502,8 @@ var Input = (0, import_react23.forwardRef)(function Input2(_a, ref) {
|
|
|
5497
5502
|
);
|
|
5498
5503
|
});
|
|
5499
5504
|
Input.displayName = "Input";
|
|
5500
|
-
var Select = (0, import_react23.forwardRef)(function Select2(
|
|
5501
|
-
var _b =
|
|
5505
|
+
var Select = (0, import_react23.forwardRef)(function Select2(_a2, ref) {
|
|
5506
|
+
var _b = _a2, {
|
|
5502
5507
|
id: idProp,
|
|
5503
5508
|
label,
|
|
5504
5509
|
hideLabel = false,
|
|
@@ -5548,8 +5553,8 @@ var Select = (0, import_react23.forwardRef)(function Select2(_a, ref) {
|
|
|
5548
5553
|
) });
|
|
5549
5554
|
});
|
|
5550
5555
|
Select.displayName = "Select";
|
|
5551
|
-
var Textarea = (0, import_react23.forwardRef)(function Textarea2(
|
|
5552
|
-
var _b =
|
|
5556
|
+
var Textarea = (0, import_react23.forwardRef)(function Textarea2(_a2, ref) {
|
|
5557
|
+
var _b = _a2, {
|
|
5553
5558
|
id: idProp,
|
|
5554
5559
|
label,
|
|
5555
5560
|
hideLabel = false,
|
|
@@ -5595,8 +5600,8 @@ var Textarea = (0, import_react23.forwardRef)(function Textarea2(_a, ref) {
|
|
|
5595
5600
|
) });
|
|
5596
5601
|
});
|
|
5597
5602
|
Textarea.displayName = "Textarea";
|
|
5598
|
-
var Checkbox = (0, import_react23.forwardRef)(function Checkbox2(
|
|
5599
|
-
var _b =
|
|
5603
|
+
var Checkbox = (0, import_react23.forwardRef)(function Checkbox2(_a2, ref) {
|
|
5604
|
+
var _b = _a2, {
|
|
5600
5605
|
id: idProp,
|
|
5601
5606
|
label,
|
|
5602
5607
|
error,
|
|
@@ -5650,8 +5655,8 @@ var Checkbox = (0, import_react23.forwardRef)(function Checkbox2(_a, ref) {
|
|
|
5650
5655
|
] });
|
|
5651
5656
|
});
|
|
5652
5657
|
Checkbox.displayName = "Checkbox";
|
|
5653
|
-
var Radio = (0, import_react23.forwardRef)(function Radio2(
|
|
5654
|
-
var _b =
|
|
5658
|
+
var Radio = (0, import_react23.forwardRef)(function Radio2(_a2, ref) {
|
|
5659
|
+
var _b = _a2, {
|
|
5655
5660
|
id: idProp,
|
|
5656
5661
|
label,
|
|
5657
5662
|
className,
|
|
@@ -5681,8 +5686,8 @@ var Radio = (0, import_react23.forwardRef)(function Radio2(_a, ref) {
|
|
|
5681
5686
|
] });
|
|
5682
5687
|
});
|
|
5683
5688
|
Radio.displayName = "Radio";
|
|
5684
|
-
var Toggle = (0, import_react23.forwardRef)(function Toggle2(
|
|
5685
|
-
var _b =
|
|
5689
|
+
var Toggle = (0, import_react23.forwardRef)(function Toggle2(_a2, ref) {
|
|
5690
|
+
var _b = _a2, {
|
|
5686
5691
|
id: idProp,
|
|
5687
5692
|
label,
|
|
5688
5693
|
className,
|
|
@@ -5713,8 +5718,8 @@ var Toggle = (0, import_react23.forwardRef)(function Toggle2(_a, ref) {
|
|
|
5713
5718
|
] });
|
|
5714
5719
|
});
|
|
5715
5720
|
Toggle.displayName = "Toggle";
|
|
5716
|
-
var Range = (0, import_react23.forwardRef)(function Range2(
|
|
5717
|
-
var _b =
|
|
5721
|
+
var Range = (0, import_react23.forwardRef)(function Range2(_a2, ref) {
|
|
5722
|
+
var _b = _a2, {
|
|
5718
5723
|
id: idProp,
|
|
5719
5724
|
label,
|
|
5720
5725
|
minLabel,
|
|
@@ -5744,8 +5749,8 @@ var Range = (0, import_react23.forwardRef)(function Range2(_a, ref) {
|
|
|
5744
5749
|
] });
|
|
5745
5750
|
});
|
|
5746
5751
|
Range.displayName = "Range";
|
|
5747
|
-
var FileUpload = (0, import_react23.forwardRef)(function FileUpload2(
|
|
5748
|
-
var _b =
|
|
5752
|
+
var FileUpload = (0, import_react23.forwardRef)(function FileUpload2(_a2, ref) {
|
|
5753
|
+
var _b = _a2, {
|
|
5749
5754
|
id: idProp,
|
|
5750
5755
|
label,
|
|
5751
5756
|
prompt = "Drop file or browse",
|
|
@@ -5833,9 +5838,9 @@ function Modal({
|
|
|
5833
5838
|
restoreFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
5834
5839
|
},
|
|
5835
5840
|
onCloseAutoFocus: (event) => {
|
|
5836
|
-
var
|
|
5841
|
+
var _a2;
|
|
5837
5842
|
event.preventDefault();
|
|
5838
|
-
(
|
|
5843
|
+
(_a2 = restoreFocusRef.current) == null ? void 0 : _a2.focus();
|
|
5839
5844
|
},
|
|
5840
5845
|
onEscapeKeyDown: (event) => {
|
|
5841
5846
|
if (!canDismiss || !closeOnEscape) event.preventDefault();
|
|
@@ -5904,15 +5909,15 @@ var AUTH_SCHEME_LABELS = {
|
|
|
5904
5909
|
OAUTH2: "OAuth 2.0"
|
|
5905
5910
|
};
|
|
5906
5911
|
function authSchemeLabel(scheme) {
|
|
5907
|
-
var
|
|
5912
|
+
var _a2;
|
|
5908
5913
|
const normalised = scheme.trim().toUpperCase();
|
|
5909
|
-
return (
|
|
5914
|
+
return (_a2 = AUTH_SCHEME_LABELS[normalised]) != null ? _a2 : normalised.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
5910
5915
|
}
|
|
5911
5916
|
function authSchemesFor(item) {
|
|
5912
|
-
var
|
|
5917
|
+
var _a2;
|
|
5913
5918
|
return Array.from(
|
|
5914
5919
|
new Set(
|
|
5915
|
-
((
|
|
5920
|
+
((_a2 = item.authSchemes) != null ? _a2 : []).map((scheme) => scheme.trim().toUpperCase()).filter(Boolean)
|
|
5916
5921
|
)
|
|
5917
5922
|
);
|
|
5918
5923
|
}
|
|
@@ -5935,10 +5940,10 @@ var CATEGORY_APP_AFFINITY = {
|
|
|
5935
5940
|
};
|
|
5936
5941
|
var DEFAULT_APP_AFFINITY = ["tides", "kraken"];
|
|
5937
5942
|
function suiteAppsForIntegration(categories) {
|
|
5938
|
-
var
|
|
5943
|
+
var _a2;
|
|
5939
5944
|
const apps = /* @__PURE__ */ new Set();
|
|
5940
5945
|
for (const category of categories != null ? categories : []) {
|
|
5941
|
-
for (const app of (
|
|
5946
|
+
for (const app of (_a2 = CATEGORY_APP_AFFINITY[category.trim().toLowerCase()]) != null ? _a2 : []) {
|
|
5942
5947
|
apps.add(app);
|
|
5943
5948
|
}
|
|
5944
5949
|
}
|
|
@@ -5995,8 +6000,8 @@ function SuiteIntegrationPicker({
|
|
|
5995
6000
|
const itemCategories = (0, import_react25.useMemo)(
|
|
5996
6001
|
() => Array.from(
|
|
5997
6002
|
new Set(items.flatMap((item) => {
|
|
5998
|
-
var
|
|
5999
|
-
return (
|
|
6003
|
+
var _a2;
|
|
6004
|
+
return (_a2 = item.categories) != null ? _a2 : [];
|
|
6000
6005
|
}))
|
|
6001
6006
|
).sort(),
|
|
6002
6007
|
[items]
|
|
@@ -6006,8 +6011,8 @@ function SuiteIntegrationPicker({
|
|
|
6006
6011
|
const activeCategory = controlledCategory != null ? controlledCategory : category;
|
|
6007
6012
|
const categoryLabel = (value) => value.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
6008
6013
|
const filtered = onSearchChange || onCategoryChange ? items : items.filter((item) => {
|
|
6009
|
-
var
|
|
6010
|
-
return item.label.toLowerCase().includes(activeSearch.trim().toLowerCase()) && (activeCategory === "all" || ((
|
|
6014
|
+
var _a2;
|
|
6015
|
+
return item.label.toLowerCase().includes(activeSearch.trim().toLowerCase()) && (activeCategory === "all" || ((_a2 = item.categories) != null ? _a2 : []).includes(activeCategory));
|
|
6011
6016
|
});
|
|
6012
6017
|
const visibleCategories = categories.filter(
|
|
6013
6018
|
(value) => categoryLabel(value).toLowerCase().includes(categoryQuery.trim().toLowerCase())
|
|
@@ -6032,7 +6037,7 @@ function SuiteIntegrationPicker({
|
|
|
6032
6037
|
closeCategoryMenu(true);
|
|
6033
6038
|
}
|
|
6034
6039
|
function moveCategoryFocus(event, value) {
|
|
6035
|
-
var
|
|
6040
|
+
var _a2;
|
|
6036
6041
|
const index = categoryValues.indexOf(value);
|
|
6037
6042
|
let nextIndex = null;
|
|
6038
6043
|
if (event.key === "ArrowDown") nextIndex = (index + 1) % categoryValues.length;
|
|
@@ -6042,16 +6047,16 @@ function SuiteIntegrationPicker({
|
|
|
6042
6047
|
else if (event.key === "End") nextIndex = categoryValues.length - 1;
|
|
6043
6048
|
if (nextIndex === null) return;
|
|
6044
6049
|
event.preventDefault();
|
|
6045
|
-
(
|
|
6050
|
+
(_a2 = categoryOptionRefs.current[categoryValues[nextIndex]]) == null ? void 0 : _a2.focus();
|
|
6046
6051
|
}
|
|
6047
6052
|
function handleCategoryTriggerKeyDown(event) {
|
|
6048
|
-
var
|
|
6053
|
+
var _a2;
|
|
6049
6054
|
if (event.key === "ArrowDown") {
|
|
6050
6055
|
event.preventDefault();
|
|
6051
6056
|
openCategoryMenu(activeCategory === "all" ? "all" : activeCategory);
|
|
6052
6057
|
} else if (event.key === "ArrowUp") {
|
|
6053
6058
|
event.preventDefault();
|
|
6054
|
-
openCategoryMenu((
|
|
6059
|
+
openCategoryMenu((_a2 = categoryValues.at(-1)) != null ? _a2 : "all");
|
|
6055
6060
|
} else if (event.key === "Enter" || event.key === " ") {
|
|
6056
6061
|
event.preventDefault();
|
|
6057
6062
|
openCategoryMenu("search");
|
|
@@ -6069,7 +6074,7 @@ function SuiteIntegrationPicker({
|
|
|
6069
6074
|
resetAuthForm();
|
|
6070
6075
|
}
|
|
6071
6076
|
async function prepareConnection(item, scheme) {
|
|
6072
|
-
var
|
|
6077
|
+
var _a2;
|
|
6073
6078
|
setMethodItem(null);
|
|
6074
6079
|
setAuthError(null);
|
|
6075
6080
|
setConnectionError(null);
|
|
@@ -6091,7 +6096,7 @@ function SuiteIntegrationPicker({
|
|
|
6091
6096
|
try {
|
|
6092
6097
|
const details = await onFetchAuthFields(item, scheme);
|
|
6093
6098
|
if (requestId !== authRequestRef.current) return;
|
|
6094
|
-
const resolvedScheme = (
|
|
6099
|
+
const resolvedScheme = (_a2 = details.auth_scheme) != null ? _a2 : scheme;
|
|
6095
6100
|
if (details.managed) {
|
|
6096
6101
|
setAuthItem(null);
|
|
6097
6102
|
await onConnect(item, { auth_scheme: resolvedScheme });
|
|
@@ -6176,8 +6181,8 @@ function SuiteIntegrationPicker({
|
|
|
6176
6181
|
(0, import_react25.useEffect)(() => {
|
|
6177
6182
|
if (!categoryMenuOpen) return;
|
|
6178
6183
|
const handlePointerDown = (event) => {
|
|
6179
|
-
var
|
|
6180
|
-
if (!((
|
|
6184
|
+
var _a2;
|
|
6185
|
+
if (!((_a2 = categoryMenuRef.current) == null ? void 0 : _a2.contains(event.target))) {
|
|
6181
6186
|
closeCategoryMenu();
|
|
6182
6187
|
}
|
|
6183
6188
|
};
|
|
@@ -6192,11 +6197,11 @@ function SuiteIntegrationPicker({
|
|
|
6192
6197
|
};
|
|
6193
6198
|
}, [categoryMenuOpen]);
|
|
6194
6199
|
(0, import_react25.useEffect)(() => {
|
|
6195
|
-
var
|
|
6200
|
+
var _a2, _b, _c;
|
|
6196
6201
|
const target = pendingCategoryFocus.current;
|
|
6197
6202
|
if (!target) return;
|
|
6198
6203
|
pendingCategoryFocus.current = null;
|
|
6199
|
-
if (target === "trigger") (
|
|
6204
|
+
if (target === "trigger") (_a2 = categoryTriggerRef.current) == null ? void 0 : _a2.focus();
|
|
6200
6205
|
else if (target === "search") (_b = categorySearchRef.current) == null ? void 0 : _b.focus();
|
|
6201
6206
|
else (_c = categoryOptionRefs.current[target]) == null ? void 0 : _c.focus();
|
|
6202
6207
|
}, [activeCategory, categoryMenuOpen, categoryQuery, visibleCategories]);
|
|
@@ -6309,10 +6314,10 @@ function SuiteIntegrationPicker({
|
|
|
6309
6314
|
placeholder: "Search categories...",
|
|
6310
6315
|
"aria-label": "Search categories",
|
|
6311
6316
|
onKeyDown: (event) => {
|
|
6312
|
-
var
|
|
6317
|
+
var _a2;
|
|
6313
6318
|
if (event.key === "ArrowDown") {
|
|
6314
6319
|
event.preventDefault();
|
|
6315
|
-
(
|
|
6320
|
+
(_a2 = categoryOptionRefs.current[categoryValues[0]]) == null ? void 0 : _a2.focus();
|
|
6316
6321
|
} else if (event.key === "Escape") {
|
|
6317
6322
|
event.preventDefault();
|
|
6318
6323
|
closeCategoryMenu(true);
|
|
@@ -6375,7 +6380,7 @@ function SuiteIntegrationPicker({
|
|
|
6375
6380
|
}
|
|
6376
6381
|
) : /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-3", children: [
|
|
6377
6382
|
filtered.map((item) => {
|
|
6378
|
-
var
|
|
6383
|
+
var _a2, _b;
|
|
6379
6384
|
const isExpanded = expanded === item.id;
|
|
6380
6385
|
const longDescription = item.description.length > DESCRIPTION_LIMIT;
|
|
6381
6386
|
const text = isExpanded || !longDescription ? item.description : `${item.description.slice(0, DESCRIPTION_LIMIT).trimEnd()}...`;
|
|
@@ -6392,7 +6397,7 @@ function SuiteIntegrationPicker({
|
|
|
6392
6397
|
onClick: () => longDescription && setExpanded(isExpanded ? null : item.id),
|
|
6393
6398
|
"aria-expanded": isExpanded,
|
|
6394
6399
|
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "flex items-start gap-3", children: [
|
|
6395
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-ph-muted text-ph-ink", children: (
|
|
6400
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-ph-muted text-ph-ink", children: (_a2 = item.icon) != null ? _a2 : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_iconoir_react12.EvPlug, { className: "h-5 w-5", "aria-hidden": true }) }),
|
|
6396
6401
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "min-w-0", children: [
|
|
6397
6402
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "block truncate font-medium text-ph-ink", children: item.label }),
|
|
6398
6403
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("span", { className: "mt-1 block text-xs text-ph-subtle", children: text }),
|
|
@@ -6600,12 +6605,12 @@ function SuiteIntegrationPicker({
|
|
|
6600
6605
|
}
|
|
6601
6606
|
) : null,
|
|
6602
6607
|
authItem.fields.map((field) => {
|
|
6603
|
-
var
|
|
6608
|
+
var _a2, _b;
|
|
6604
6609
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
6605
6610
|
Input,
|
|
6606
6611
|
{
|
|
6607
6612
|
label: field.label,
|
|
6608
|
-
type: (
|
|
6613
|
+
type: (_a2 = field.type) != null ? _a2 : "password",
|
|
6609
6614
|
required: true,
|
|
6610
6615
|
value: (_b = authValues[field.name]) != null ? _b : "",
|
|
6611
6616
|
onChange: (event) => setAuthValues((current) => __spreadProps(__spreadValues({}, current), {
|
|
@@ -6648,8 +6653,8 @@ var ACTION_LABELS = {
|
|
|
6648
6653
|
create_suite_notification: "Send a suite notification"
|
|
6649
6654
|
};
|
|
6650
6655
|
function actionLabel(actionType) {
|
|
6651
|
-
var
|
|
6652
|
-
return (
|
|
6656
|
+
var _a2;
|
|
6657
|
+
return (_a2 = ACTION_LABELS[actionType]) != null ? _a2 : actionType;
|
|
6653
6658
|
}
|
|
6654
6659
|
function formatDateTime(value) {
|
|
6655
6660
|
if (!value) return "\u2014";
|
|
@@ -7037,214 +7042,566 @@ function SuiteIntegrationRules({
|
|
|
7037
7042
|
}
|
|
7038
7043
|
|
|
7039
7044
|
// src/suite/components/suite-clients-projects-directory.tsx
|
|
7045
|
+
var import_react28 = require("react");
|
|
7046
|
+
var import_iconoir_react15 = require("iconoir-react");
|
|
7047
|
+
|
|
7048
|
+
// src/suite/lib/palette-api.ts
|
|
7049
|
+
var _a;
|
|
7050
|
+
var PALETTE_URL = ((_a = process.env.NEXT_PUBLIC_PALETTE_URL) != null ? _a : "http://localhost:8010").replace(/\/$/, "");
|
|
7051
|
+
function toQuery(params) {
|
|
7052
|
+
const query = new URLSearchParams();
|
|
7053
|
+
for (const [key, value] of Object.entries(params != null ? params : {})) {
|
|
7054
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
7055
|
+
query.set(key, String(value));
|
|
7056
|
+
}
|
|
7057
|
+
}
|
|
7058
|
+
return query.toString();
|
|
7059
|
+
}
|
|
7060
|
+
async function paletteGet(path, params) {
|
|
7061
|
+
const suffix = toQuery(params);
|
|
7062
|
+
const response = await fetch(
|
|
7063
|
+
`${PALETTE_URL}${path}${suffix ? `?${suffix}` : ""}`,
|
|
7064
|
+
{ headers: { Accept: "application/json" } }
|
|
7065
|
+
);
|
|
7066
|
+
if (!response.ok) {
|
|
7067
|
+
throw new Error(`Palette request failed (${response.status}).`);
|
|
7068
|
+
}
|
|
7069
|
+
return await response.json();
|
|
7070
|
+
}
|
|
7071
|
+
var cache = /* @__PURE__ */ new Map();
|
|
7072
|
+
async function paletteGetCached(path, params, ttlMs) {
|
|
7073
|
+
const key = `${path}?${toQuery(params)}`;
|
|
7074
|
+
const now = Date.now();
|
|
7075
|
+
const hit = cache.get(key);
|
|
7076
|
+
if (hit && hit.expires > now) return hit.value;
|
|
7077
|
+
const value = await paletteGet(path, params);
|
|
7078
|
+
cache.set(key, { expires: now + ttlMs, value });
|
|
7079
|
+
return value;
|
|
7080
|
+
}
|
|
7081
|
+
function fetchPaletteLibrary(options) {
|
|
7082
|
+
return paletteGetCached("/library", options, 5 * 6e4);
|
|
7083
|
+
}
|
|
7084
|
+
function fetchPaletteCollection(slug, options) {
|
|
7085
|
+
return paletteGetCached(
|
|
7086
|
+
`/collections/${slug}`,
|
|
7087
|
+
options,
|
|
7088
|
+
2 * 6e4
|
|
7089
|
+
);
|
|
7090
|
+
}
|
|
7091
|
+
function findPaletteIcons(options) {
|
|
7092
|
+
return paletteGet("/find", options);
|
|
7093
|
+
}
|
|
7094
|
+
function paletteIconSrc(imageUrl, color) {
|
|
7095
|
+
if (!imageUrl || !color) return imageUrl;
|
|
7096
|
+
if (!imageUrl.includes("/svgrepo/")) return imageUrl;
|
|
7097
|
+
return `${PALETTE_URL}/render?src=${encodeURIComponent(imageUrl)}&color=${encodeURIComponent(color)}`;
|
|
7098
|
+
}
|
|
7099
|
+
|
|
7100
|
+
// src/suite/components/suite-entity-icon.tsx
|
|
7101
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
7102
|
+
function SuiteEntityIcon({
|
|
7103
|
+
imageUrl,
|
|
7104
|
+
label,
|
|
7105
|
+
color,
|
|
7106
|
+
className,
|
|
7107
|
+
roundedClass = "rounded-md",
|
|
7108
|
+
style,
|
|
7109
|
+
tinted = false
|
|
7110
|
+
}) {
|
|
7111
|
+
const hasColor = typeof color === "string" && /^#[0-9a-fA-F]{3,8}$/.test(color);
|
|
7112
|
+
const tint = hasColor ? color : null;
|
|
7113
|
+
const neutralBackground = "var(--ph-muted, rgba(127,127,127,0.08))";
|
|
7114
|
+
if (imageUrl) {
|
|
7115
|
+
const src = tinted && tint ? paletteIconSrc(imageUrl, tint) : imageUrl;
|
|
7116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7117
|
+
"span",
|
|
7118
|
+
{
|
|
7119
|
+
className: cn2(
|
|
7120
|
+
"inline-flex shrink-0 items-center justify-center overflow-hidden leading-none",
|
|
7121
|
+
roundedClass,
|
|
7122
|
+
className
|
|
7123
|
+
),
|
|
7124
|
+
style: __spreadValues({
|
|
7125
|
+
backgroundColor: tint ? `${tint}18` : neutralBackground
|
|
7126
|
+
}, style),
|
|
7127
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("img", { src: src != null ? src : void 0, alt: "", className: "h-full w-full object-cover" })
|
|
7128
|
+
}
|
|
7129
|
+
);
|
|
7130
|
+
}
|
|
7131
|
+
const initial = label == null ? void 0 : label.trim().charAt(0).toUpperCase();
|
|
7132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7133
|
+
"span",
|
|
7134
|
+
{
|
|
7135
|
+
className: cn2(
|
|
7136
|
+
"inline-flex shrink-0 items-center justify-center font-semibold leading-none",
|
|
7137
|
+
roundedClass,
|
|
7138
|
+
className
|
|
7139
|
+
),
|
|
7140
|
+
style: __spreadValues({
|
|
7141
|
+
color: tint != null ? tint : "var(--ph-mutedtext)",
|
|
7142
|
+
backgroundColor: tint ? `${tint}18` : neutralBackground
|
|
7143
|
+
}, style),
|
|
7144
|
+
"aria-hidden": "true",
|
|
7145
|
+
children: initial ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "text-[0.7em]", children: initial }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "block h-1.5 w-1.5 rounded-full bg-current opacity-40" })
|
|
7146
|
+
}
|
|
7147
|
+
);
|
|
7148
|
+
}
|
|
7149
|
+
|
|
7150
|
+
// src/suite/components/suite-palette-library.tsx
|
|
7040
7151
|
var import_react27 = require("react");
|
|
7041
7152
|
var import_iconoir_react14 = require("iconoir-react");
|
|
7042
|
-
var
|
|
7043
|
-
var
|
|
7044
|
-
var
|
|
7045
|
-
var
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
["tower", "Tower"],
|
|
7053
|
-
["wooden-sign", "Sign"],
|
|
7054
|
-
["anvil", "Anvil"],
|
|
7055
|
-
["book", "Book"],
|
|
7056
|
-
["chessboard", "Chessboard"],
|
|
7057
|
-
["cog", "Settings"],
|
|
7058
|
-
["hammer", "Build"],
|
|
7059
|
-
["light-bulb", "Idea"],
|
|
7060
|
-
["microphone", "Communication"],
|
|
7061
|
-
["quill-ink", "Writing"],
|
|
7062
|
-
["scroll-unfurled", "Notes"],
|
|
7063
|
-
["hourglass", "Planning"],
|
|
7064
|
-
["wrench", "Tools"],
|
|
7065
|
-
["archer", "Archer"],
|
|
7066
|
-
["archery-target", "Target"],
|
|
7067
|
-
["axe", "Axe"],
|
|
7068
|
-
["campfire", "Campfire"],
|
|
7069
|
-
["compass", "Compass"],
|
|
7070
|
-
["crossed-swords", "Battle"],
|
|
7071
|
-
["knight-helmet", "Knight"],
|
|
7072
|
-
["mountains", "Mountains"],
|
|
7073
|
-
["shield", "Shield"],
|
|
7074
|
-
["ship-emblem", "Voyage"],
|
|
7075
|
-
["sword", "Sword"],
|
|
7076
|
-
["trophy", "Trophy"],
|
|
7077
|
-
["apple", "Apple"],
|
|
7078
|
-
["butterfly", "Butterfly"],
|
|
7079
|
-
["clover", "Clover"],
|
|
7080
|
-
["dragon", "Dragon"],
|
|
7081
|
-
["fire", "Fire"],
|
|
7082
|
-
["flower", "Flower"],
|
|
7083
|
-
["flowers", "Flowers"],
|
|
7084
|
-
["grass", "Grass"],
|
|
7085
|
-
["leaf", "Leaf"],
|
|
7086
|
-
["pine-tree", "Pine tree"],
|
|
7087
|
-
["sun", "Sun"],
|
|
7088
|
-
["water-drop", "Water"],
|
|
7089
|
-
["aura", "Aura"],
|
|
7090
|
-
["crystal-ball", "Crystal ball"],
|
|
7091
|
-
["diamond", "Diamond"],
|
|
7092
|
-
["explosion", "Explosion"],
|
|
7093
|
-
["fire-symbol", "Fire symbol"],
|
|
7094
|
-
["gem", "Gem"],
|
|
7095
|
-
["lightning-trio", "Lightning"],
|
|
7096
|
-
["potion", "Potion"],
|
|
7097
|
-
["rune-stone", "Rune stone"],
|
|
7098
|
-
["skull", "Skull"],
|
|
7099
|
-
["tentacle", "Tentacle"],
|
|
7100
|
-
["wolf-head", "Wolf"],
|
|
7101
|
-
["anchor", "Anchor"],
|
|
7102
|
-
["beer", "Beer"],
|
|
7103
|
-
["carrot", "Carrot"],
|
|
7104
|
-
["cat", "Cat"],
|
|
7105
|
-
["crown", "Crown"],
|
|
7106
|
-
["gold-bar", "Gold bar"],
|
|
7107
|
-
["helmet", "Helmet"],
|
|
7108
|
-
["key", "Key"],
|
|
7109
|
-
["three-keys", "Keys"]
|
|
7153
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
7154
|
+
var PAGE_SIZE = 60;
|
|
7155
|
+
var DISCOVER_LIMIT = 120;
|
|
7156
|
+
var ICON_TYPES = [
|
|
7157
|
+
{ value: "all", label: "All types" },
|
|
7158
|
+
{ value: "line", label: "Line" },
|
|
7159
|
+
{ value: "solid", label: "Solid" },
|
|
7160
|
+
{ value: "duotone", label: "Duotone" },
|
|
7161
|
+
{ value: "color", label: "Colour" },
|
|
7162
|
+
{ value: "mixed", label: "Mixed" }
|
|
7110
7163
|
];
|
|
7111
|
-
function
|
|
7112
|
-
|
|
7113
|
-
|
|
7114
|
-
function DirectoryIconPicker({
|
|
7164
|
+
function FilterSelect({
|
|
7165
|
+
icon: Icon,
|
|
7166
|
+
label,
|
|
7115
7167
|
value,
|
|
7116
|
-
|
|
7117
|
-
|
|
7118
|
-
onClear,
|
|
7119
|
-
onChange
|
|
7168
|
+
onChange,
|
|
7169
|
+
children
|
|
7120
7170
|
}) {
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
let nextIndex = null;
|
|
7125
|
-
if (event.key === "ArrowRight" || event.key === "ArrowDown") {
|
|
7126
|
-
nextIndex = (index + 1) % DIRECTORY_ICON_OPTIONS.length;
|
|
7127
|
-
} else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
|
|
7128
|
-
nextIndex = (index - 1 + DIRECTORY_ICON_OPTIONS.length) % DIRECTORY_ICON_OPTIONS.length;
|
|
7129
|
-
} else if (event.key === "Home") {
|
|
7130
|
-
nextIndex = 0;
|
|
7131
|
-
} else if (event.key === "End") {
|
|
7132
|
-
nextIndex = DIRECTORY_ICON_OPTIONS.length - 1;
|
|
7133
|
-
}
|
|
7134
|
-
if (nextIndex === null) return;
|
|
7135
|
-
event.preventDefault();
|
|
7136
|
-
const [nextIcon] = DIRECTORY_ICON_OPTIONS[nextIndex];
|
|
7137
|
-
onChange(nextIcon);
|
|
7138
|
-
(_a = iconRefs.current[nextIcon]) == null ? void 0 : _a.focus();
|
|
7139
|
-
}
|
|
7140
|
-
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "space-y-2", children: [
|
|
7141
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "mb-1.5 block text-sm font-medium text-ph-ink", children: "Icon" }),
|
|
7142
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7143
|
-
"div",
|
|
7171
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative", children: [
|
|
7172
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7173
|
+
Icon,
|
|
7144
7174
|
{
|
|
7145
|
-
|
|
7146
|
-
"aria-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7175
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
7176
|
+
"aria-hidden": true
|
|
7177
|
+
}
|
|
7178
|
+
),
|
|
7179
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7180
|
+
"select",
|
|
7181
|
+
{
|
|
7182
|
+
"aria-label": label,
|
|
7183
|
+
value,
|
|
7184
|
+
onChange: (event) => onChange(event.target.value),
|
|
7185
|
+
className: "h-full w-full appearance-none rounded-lg border border-ph-border bg-ph-surface py-2 pl-8 pr-7 text-sm text-ph-ink focus:border-ph-brand focus:outline-none",
|
|
7186
|
+
children
|
|
7187
|
+
}
|
|
7188
|
+
),
|
|
7189
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7190
|
+
import_iconoir_react14.NavArrowDown,
|
|
7191
|
+
{
|
|
7192
|
+
className: "pointer-events-none absolute right-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-ph-mutedtext",
|
|
7193
|
+
"aria-hidden": true
|
|
7194
|
+
}
|
|
7195
|
+
)
|
|
7196
|
+
] });
|
|
7197
|
+
}
|
|
7198
|
+
function SuitePaletteLibrary({
|
|
7199
|
+
onPick
|
|
7200
|
+
}) {
|
|
7201
|
+
var _a2, _b;
|
|
7202
|
+
const [collections, setCollections] = (0, import_react27.useState)([]);
|
|
7203
|
+
const [typeFilter, setTypeFilter] = (0, import_react27.useState)("all");
|
|
7204
|
+
const [collectionFilter, setCollectionFilter] = (0, import_react27.useState)("");
|
|
7205
|
+
const [libraryOpen, setLibraryOpen] = (0, import_react27.useState)(false);
|
|
7206
|
+
const [libraryQuery, setLibraryQuery] = (0, import_react27.useState)("");
|
|
7207
|
+
const libraryRef = (0, import_react27.useRef)(null);
|
|
7208
|
+
const [icons, setIcons] = (0, import_react27.useState)([]);
|
|
7209
|
+
const [total, setTotal] = (0, import_react27.useState)(0);
|
|
7210
|
+
const [page, setPage] = (0, import_react27.useState)(1);
|
|
7211
|
+
const [query, setQuery] = (0, import_react27.useState)("");
|
|
7212
|
+
const [loading, setLoading] = (0, import_react27.useState)(true);
|
|
7213
|
+
const [loadingMore, setLoadingMore] = (0, import_react27.useState)(false);
|
|
7214
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
7215
|
+
const requestId = (0, import_react27.useRef)(0);
|
|
7216
|
+
const libraryOptions = (0, import_react27.useMemo)(() => {
|
|
7217
|
+
const list = collections.filter(
|
|
7218
|
+
(item) => typeFilter === "all" || item.style === typeFilter
|
|
7219
|
+
);
|
|
7220
|
+
return [...list].sort(
|
|
7221
|
+
(a, b) => Number(b.featured) - Number(a.featured) || a.name.localeCompare(b.name)
|
|
7222
|
+
);
|
|
7223
|
+
}, [collections, typeFilter]);
|
|
7224
|
+
const discoverIcons = (0, import_react27.useMemo)(() => {
|
|
7225
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7226
|
+
const out = [];
|
|
7227
|
+
for (const collection of libraryOptions) {
|
|
7228
|
+
for (const url of collection.preview) {
|
|
7229
|
+
if (seen.has(url)) continue;
|
|
7230
|
+
seen.add(url);
|
|
7231
|
+
out.push({ id: url, name: collection.name, tags: [], url });
|
|
7232
|
+
if (out.length >= DISCOVER_LIMIT) return out;
|
|
7233
|
+
}
|
|
7234
|
+
}
|
|
7235
|
+
return out;
|
|
7236
|
+
}, [libraryOptions]);
|
|
7237
|
+
const loadCollection = (0, import_react27.useCallback)(async (slug, nextPage = 1) => {
|
|
7238
|
+
const id = ++requestId.current;
|
|
7239
|
+
if (nextPage === 1) {
|
|
7240
|
+
setLoading(true);
|
|
7241
|
+
setIcons([]);
|
|
7242
|
+
} else {
|
|
7243
|
+
setLoadingMore(true);
|
|
7244
|
+
}
|
|
7245
|
+
setError(null);
|
|
7246
|
+
try {
|
|
7247
|
+
const detail = await fetchPaletteCollection(slug, {
|
|
7248
|
+
page: nextPage,
|
|
7249
|
+
size: PAGE_SIZE
|
|
7250
|
+
});
|
|
7251
|
+
if (id !== requestId.current) return;
|
|
7252
|
+
setTotal(detail.count);
|
|
7253
|
+
setPage(nextPage);
|
|
7254
|
+
setIcons(
|
|
7255
|
+
(current) => nextPage === 1 ? detail.icons : [...current, ...detail.icons]
|
|
7256
|
+
);
|
|
7257
|
+
} catch (err) {
|
|
7258
|
+
if (id === requestId.current) {
|
|
7259
|
+
setError(err instanceof Error ? err.message : "Could not load icons.");
|
|
7260
|
+
}
|
|
7261
|
+
} finally {
|
|
7262
|
+
if (id === requestId.current) {
|
|
7263
|
+
setLoading(false);
|
|
7264
|
+
setLoadingMore(false);
|
|
7265
|
+
}
|
|
7266
|
+
}
|
|
7267
|
+
}, []);
|
|
7268
|
+
(0, import_react27.useEffect)(() => {
|
|
7269
|
+
let cancelled = false;
|
|
7270
|
+
fetchPaletteLibrary().then((library) => {
|
|
7271
|
+
if (cancelled) return;
|
|
7272
|
+
setCollections(library.collections);
|
|
7273
|
+
}).catch((err) => {
|
|
7274
|
+
if (cancelled) return;
|
|
7275
|
+
setError(err instanceof Error ? err.message : "Could not load the library.");
|
|
7276
|
+
setLoading(false);
|
|
7277
|
+
});
|
|
7278
|
+
return () => {
|
|
7279
|
+
cancelled = true;
|
|
7280
|
+
};
|
|
7281
|
+
}, []);
|
|
7282
|
+
(0, import_react27.useEffect)(() => {
|
|
7283
|
+
if (!collections.length) return;
|
|
7284
|
+
if (collectionFilter && !libraryOptions.some((c) => c.slug === collectionFilter)) {
|
|
7285
|
+
setCollectionFilter("");
|
|
7286
|
+
}
|
|
7287
|
+
}, [libraryOptions, collectionFilter, collections.length]);
|
|
7288
|
+
(0, import_react27.useEffect)(() => {
|
|
7289
|
+
if (query.trim()) return;
|
|
7290
|
+
if (collectionFilter) {
|
|
7291
|
+
void loadCollection(collectionFilter, 1);
|
|
7292
|
+
return;
|
|
7293
|
+
}
|
|
7294
|
+
requestId.current += 1;
|
|
7295
|
+
setLoading(false);
|
|
7296
|
+
setPage(1);
|
|
7297
|
+
setIcons(discoverIcons);
|
|
7298
|
+
setTotal(discoverIcons.length);
|
|
7299
|
+
}, [collectionFilter, query, loadCollection, discoverIcons]);
|
|
7300
|
+
(0, import_react27.useEffect)(() => {
|
|
7301
|
+
const term = query.trim();
|
|
7302
|
+
if (!term) return;
|
|
7303
|
+
const id = ++requestId.current;
|
|
7304
|
+
setLoading(true);
|
|
7305
|
+
setError(null);
|
|
7306
|
+
const handle = setTimeout(async () => {
|
|
7307
|
+
try {
|
|
7308
|
+
const results = await findPaletteIcons({
|
|
7309
|
+
q: term,
|
|
7310
|
+
collection: collectionFilter || void 0,
|
|
7311
|
+
style: typeFilter === "all" ? void 0 : typeFilter,
|
|
7312
|
+
limit: 120
|
|
7313
|
+
});
|
|
7314
|
+
if (id !== requestId.current) return;
|
|
7315
|
+
setTotal(results.total);
|
|
7316
|
+
setPage(1);
|
|
7317
|
+
setIcons(
|
|
7318
|
+
results.results.map((hit) => ({
|
|
7319
|
+
id: `${hit.collection}/${hit.id}`,
|
|
7320
|
+
name: hit.name,
|
|
7321
|
+
tags: hit.tags,
|
|
7322
|
+
url: hit.url
|
|
7323
|
+
}))
|
|
7324
|
+
);
|
|
7325
|
+
} catch (err) {
|
|
7326
|
+
if (id === requestId.current) {
|
|
7327
|
+
setError(err instanceof Error ? err.message : "Search failed.");
|
|
7328
|
+
}
|
|
7329
|
+
} finally {
|
|
7330
|
+
if (id === requestId.current) setLoading(false);
|
|
7331
|
+
}
|
|
7332
|
+
}, 250);
|
|
7333
|
+
return () => clearTimeout(handle);
|
|
7334
|
+
}, [query, collectionFilter, typeFilter]);
|
|
7335
|
+
const searching = Boolean(query.trim());
|
|
7336
|
+
const activeLibrary = (_a2 = collections.find((c) => c.slug === collectionFilter)) != null ? _a2 : null;
|
|
7337
|
+
const filteredLibraries = (0, import_react27.useMemo)(() => {
|
|
7338
|
+
const term = libraryQuery.trim().toLowerCase();
|
|
7339
|
+
if (!term) return libraryOptions;
|
|
7340
|
+
return libraryOptions.filter((c) => c.name.toLowerCase().includes(term));
|
|
7341
|
+
}, [libraryOptions, libraryQuery]);
|
|
7342
|
+
(0, import_react27.useEffect)(() => {
|
|
7343
|
+
if (!libraryOpen) return;
|
|
7344
|
+
const onPointerDown = (event) => {
|
|
7345
|
+
var _a3;
|
|
7346
|
+
if (!((_a3 = libraryRef.current) == null ? void 0 : _a3.contains(event.target))) setLibraryOpen(false);
|
|
7347
|
+
};
|
|
7348
|
+
document.addEventListener("pointerdown", onPointerDown);
|
|
7349
|
+
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
7350
|
+
}, [libraryOpen]);
|
|
7351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-3", "data-test": "palette-icon-library", children: [
|
|
7352
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { ref: libraryRef, className: "space-y-2", children: [
|
|
7353
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex flex-col gap-2 sm:flex-row", children: [
|
|
7354
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative flex-1", children: [
|
|
7355
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7356
|
+
import_iconoir_react14.Search,
|
|
7152
7357
|
{
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7358
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
7359
|
+
"aria-hidden": true
|
|
7360
|
+
}
|
|
7361
|
+
),
|
|
7362
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7363
|
+
"input",
|
|
7364
|
+
{
|
|
7365
|
+
type: "search",
|
|
7366
|
+
value: query,
|
|
7367
|
+
onChange: (event) => setQuery(event.target.value),
|
|
7368
|
+
placeholder: "Search icons \u2014 handshake, rocket, briefcase\u2026",
|
|
7369
|
+
"aria-label": "Search icons",
|
|
7370
|
+
className: "w-full rounded-lg border border-ph-border bg-ph-surface py-2 pl-8 pr-3 text-sm text-ph-ink placeholder:text-ph-mutedtext focus:border-ph-brand focus:outline-none"
|
|
7371
|
+
}
|
|
7372
|
+
)
|
|
7373
|
+
] }),
|
|
7374
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
7375
|
+
"button",
|
|
7376
|
+
{
|
|
7377
|
+
type: "button",
|
|
7378
|
+
"aria-haspopup": "listbox",
|
|
7379
|
+
"aria-expanded": libraryOpen,
|
|
7380
|
+
onClick: () => setLibraryOpen((open) => !open),
|
|
7381
|
+
className: "flex items-center gap-2 rounded-lg border border-ph-border bg-ph-surface px-2.5 py-2 text-sm text-ph-ink hover:border-ph-brand focus:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
|
|
7382
|
+
children: [
|
|
7383
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_iconoir_react14.FilterList, { className: "h-4 w-4 shrink-0 text-ph-mutedtext", "aria-hidden": true }),
|
|
7384
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "max-w-[10rem] truncate", children: (_b = activeLibrary == null ? void 0 : activeLibrary.name) != null ? _b : "All libraries" }),
|
|
7385
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7386
|
+
import_iconoir_react14.NavArrowDown,
|
|
7170
7387
|
{
|
|
7171
|
-
className: cn2(
|
|
7388
|
+
className: cn2(
|
|
7389
|
+
"h-3.5 w-3.5 shrink-0 text-ph-mutedtext transition-transform",
|
|
7390
|
+
libraryOpen && "rotate-180"
|
|
7391
|
+
),
|
|
7172
7392
|
"aria-hidden": true
|
|
7173
7393
|
}
|
|
7174
7394
|
)
|
|
7175
|
-
|
|
7176
|
-
name
|
|
7177
|
-
);
|
|
7178
|
-
})
|
|
7179
|
-
}
|
|
7180
|
-
),
|
|
7181
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "rounded-lg border border-ph-border bg-ph-muted p-2", children: [
|
|
7182
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center gap-2 text-sm font-medium text-ph-ink", children: [
|
|
7183
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_iconoir_react14.MediaImagePlus, { className: "h-4 w-4", "aria-hidden": true }),
|
|
7184
|
-
" Custom image"
|
|
7185
|
-
] }),
|
|
7186
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "mt-1 text-xs text-ph-mutedtext", children: "PNG, JPG, GIF, WebP, or SVG \u2014 max 512 KB." }),
|
|
7187
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7188
|
-
FileUpload,
|
|
7189
|
-
{
|
|
7190
|
-
accept: "image/png,image/jpeg,image/gif,image/webp,image/svg+xml,.svg",
|
|
7191
|
-
onChange: (event) => {
|
|
7192
|
-
var _a, _b;
|
|
7193
|
-
return onFileChange((_b = (_a = event.target.files) == null ? void 0 : _a[0]) != null ? _b : null);
|
|
7395
|
+
]
|
|
7194
7396
|
}
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
|
|
7198
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7199
|
-
"img",
|
|
7397
|
+
),
|
|
7398
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7399
|
+
FilterSelect,
|
|
7200
7400
|
{
|
|
7201
|
-
|
|
7202
|
-
|
|
7203
|
-
|
|
7401
|
+
icon: import_iconoir_react14.Filter,
|
|
7402
|
+
label: "Filter by icon type",
|
|
7403
|
+
value: typeFilter,
|
|
7404
|
+
onChange: setTypeFilter,
|
|
7405
|
+
children: ICON_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("option", { value: type.value, children: type.label }, type.value))
|
|
7204
7406
|
}
|
|
7205
|
-
)
|
|
7206
|
-
|
|
7207
|
-
|
|
7407
|
+
)
|
|
7408
|
+
] }),
|
|
7409
|
+
libraryOpen ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "rounded-lg border border-ph-border bg-ph-surface p-2", children: [
|
|
7410
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative mb-2", children: [
|
|
7411
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7412
|
+
import_iconoir_react14.Search,
|
|
7413
|
+
{
|
|
7414
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
7415
|
+
"aria-hidden": true
|
|
7416
|
+
}
|
|
7417
|
+
),
|
|
7418
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7419
|
+
"input",
|
|
7420
|
+
{
|
|
7421
|
+
type: "search",
|
|
7422
|
+
autoFocus: true,
|
|
7423
|
+
value: libraryQuery,
|
|
7424
|
+
onChange: (event) => setLibraryQuery(event.target.value),
|
|
7425
|
+
placeholder: "Search libraries\u2026",
|
|
7426
|
+
"aria-label": "Search libraries",
|
|
7427
|
+
className: "w-full rounded-md border border-ph-border bg-ph-muted py-1.5 pl-8 pr-3 text-sm text-ph-ink placeholder:text-ph-mutedtext focus:border-ph-brand focus:outline-none"
|
|
7428
|
+
}
|
|
7429
|
+
)
|
|
7430
|
+
] }),
|
|
7431
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
7432
|
+
"ul",
|
|
7208
7433
|
{
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7434
|
+
role: "listbox",
|
|
7435
|
+
"aria-label": "Libraries",
|
|
7436
|
+
className: "max-h-56 overflow-y-auto",
|
|
7212
7437
|
children: [
|
|
7213
|
-
/* @__PURE__ */ (0,
|
|
7214
|
-
|
|
7438
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7439
|
+
"button",
|
|
7440
|
+
{
|
|
7441
|
+
type: "button",
|
|
7442
|
+
role: "option",
|
|
7443
|
+
"aria-selected": !collectionFilter,
|
|
7444
|
+
onClick: () => {
|
|
7445
|
+
setCollectionFilter("");
|
|
7446
|
+
setLibraryOpen(false);
|
|
7447
|
+
},
|
|
7448
|
+
className: cn2(
|
|
7449
|
+
"flex w-full items-center rounded-md px-2 py-1.5 text-left text-sm",
|
|
7450
|
+
!collectionFilter ? "bg-ph-muted text-ph-ink" : "text-ph-ink hover:bg-ph-muted"
|
|
7451
|
+
),
|
|
7452
|
+
children: "All libraries"
|
|
7453
|
+
}
|
|
7454
|
+
) }),
|
|
7455
|
+
filteredLibraries.map((collection) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
7456
|
+
"button",
|
|
7457
|
+
{
|
|
7458
|
+
type: "button",
|
|
7459
|
+
role: "option",
|
|
7460
|
+
"aria-selected": collectionFilter === collection.slug,
|
|
7461
|
+
onClick: () => {
|
|
7462
|
+
setCollectionFilter(collection.slug);
|
|
7463
|
+
setLibraryOpen(false);
|
|
7464
|
+
},
|
|
7465
|
+
className: cn2(
|
|
7466
|
+
"flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left text-sm",
|
|
7467
|
+
collectionFilter === collection.slug ? "bg-ph-muted text-ph-ink" : "text-ph-ink hover:bg-ph-muted"
|
|
7468
|
+
),
|
|
7469
|
+
children: [
|
|
7470
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "truncate", children: collection.name }),
|
|
7471
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "shrink-0 text-xs text-ph-mutedtext", children: collection.count })
|
|
7472
|
+
]
|
|
7473
|
+
}
|
|
7474
|
+
) }, collection.slug)),
|
|
7475
|
+
filteredLibraries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { className: "px-2 py-4 text-center text-sm text-ph-mutedtext", children: "No libraries match." }) : null
|
|
7215
7476
|
]
|
|
7216
7477
|
}
|
|
7217
7478
|
)
|
|
7218
7479
|
] }) : null
|
|
7480
|
+
] }),
|
|
7481
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "text-sm text-ph-danger", children: error }) : loading ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "py-8 text-center text-sm text-ph-mutedtext", children: "Loading icons\u2026" }) : icons.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "py-8 text-center text-sm text-ph-mutedtext", children: "No icons matched. Try another word or filter." }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
|
|
7482
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "max-h-[320px] overflow-y-auto rounded-lg border border-ph-border p-2", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "grid grid-cols-6 gap-1.5 sm:grid-cols-8", children: icons.map((icon) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7483
|
+
"button",
|
|
7484
|
+
{
|
|
7485
|
+
type: "button",
|
|
7486
|
+
onClick: () => onPick({ url: icon.url, name: icon.name }),
|
|
7487
|
+
title: icon.name,
|
|
7488
|
+
"aria-label": `Use ${icon.name}`,
|
|
7489
|
+
className: "flex h-10 items-center justify-center rounded-md border border-transparent p-1.5 hover:border-ph-brand hover:bg-ph-muted",
|
|
7490
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7491
|
+
"img",
|
|
7492
|
+
{
|
|
7493
|
+
src: icon.url,
|
|
7494
|
+
alt: "",
|
|
7495
|
+
loading: "lazy",
|
|
7496
|
+
decoding: "async",
|
|
7497
|
+
className: "h-6 w-6"
|
|
7498
|
+
}
|
|
7499
|
+
)
|
|
7500
|
+
},
|
|
7501
|
+
icon.id
|
|
7502
|
+
)) }) }),
|
|
7503
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex items-center justify-between text-xs text-ph-mutedtext", children: [
|
|
7504
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { children: [
|
|
7505
|
+
icons.length,
|
|
7506
|
+
" of ",
|
|
7507
|
+
total,
|
|
7508
|
+
searching ? " matching" : activeLibrary ? ` in ${activeLibrary.name}` : " across all libraries"
|
|
7509
|
+
] }),
|
|
7510
|
+
!searching && activeLibrary && icons.length < total ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
7511
|
+
"button",
|
|
7512
|
+
{
|
|
7513
|
+
type: "button",
|
|
7514
|
+
disabled: loadingMore,
|
|
7515
|
+
onClick: () => void loadCollection(activeLibrary.slug, page + 1),
|
|
7516
|
+
className: cn2(
|
|
7517
|
+
"font-medium text-ph-brand hover:underline",
|
|
7518
|
+
loadingMore && "opacity-50"
|
|
7519
|
+
),
|
|
7520
|
+
children: loadingMore ? "Loading\u2026" : "Load more"
|
|
7521
|
+
}
|
|
7522
|
+
) : null
|
|
7523
|
+
] })
|
|
7219
7524
|
] })
|
|
7220
7525
|
] });
|
|
7221
7526
|
}
|
|
7222
|
-
|
|
7223
|
-
|
|
7527
|
+
|
|
7528
|
+
// src/suite/components/suite-clients-projects-directory.tsx
|
|
7529
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
7530
|
+
var DEFAULT_ICON = "";
|
|
7531
|
+
var DEFAULT_COLOR = "";
|
|
7532
|
+
function DirectoryIconPicker({
|
|
7533
|
+
preview,
|
|
7534
|
+
label,
|
|
7535
|
+
color,
|
|
7536
|
+
onFileChange,
|
|
7537
|
+
onClear,
|
|
7538
|
+
onBrowse
|
|
7224
7539
|
}) {
|
|
7225
|
-
|
|
7226
|
-
|
|
7227
|
-
"
|
|
7228
|
-
|
|
7229
|
-
|
|
7230
|
-
|
|
7231
|
-
children: item.icon_image ? (
|
|
7232
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
7233
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
7234
|
-
"img",
|
|
7540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "space-y-2", children: [
|
|
7541
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "mb-1.5 block text-sm font-medium text-ph-ink", children: "Icon" }),
|
|
7542
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "rounded-lg border border-ph-border bg-ph-muted p-3", children: [
|
|
7543
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
7544
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7545
|
+
SuiteEntityIcon,
|
|
7235
7546
|
{
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7547
|
+
imageUrl: preview,
|
|
7548
|
+
label,
|
|
7549
|
+
color,
|
|
7550
|
+
tinted: true,
|
|
7551
|
+
className: "h-9 w-9 text-base"
|
|
7239
7552
|
}
|
|
7240
|
-
)
|
|
7241
|
-
|
|
7242
|
-
|
|
7553
|
+
),
|
|
7554
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
7555
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-sm font-medium text-ph-ink", children: preview ? "Custom image" : "No icon yet" }),
|
|
7556
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-xs text-ph-mutedtext", children: preview ? "Shown on cards and lists." : "Browse the library or upload your own." })
|
|
7557
|
+
] }),
|
|
7558
|
+
onBrowse ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7559
|
+
"button",
|
|
7560
|
+
{
|
|
7561
|
+
type: "button",
|
|
7562
|
+
onClick: onBrowse,
|
|
7563
|
+
className: "rounded-md border border-ph-border px-3 py-1.5 text-xs font-medium text-ph-ink hover:border-ph-brand hover:bg-ph-surface",
|
|
7564
|
+
children: "Browse library"
|
|
7565
|
+
}
|
|
7566
|
+
) : null
|
|
7567
|
+
] }),
|
|
7568
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "mt-3", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7569
|
+
FileUpload,
|
|
7243
7570
|
{
|
|
7244
|
-
|
|
7245
|
-
|
|
7571
|
+
accept: "image/png,image/jpeg,image/gif,image/webp,image/svg+xml,.svg",
|
|
7572
|
+
onChange: (event) => {
|
|
7573
|
+
var _a2, _b;
|
|
7574
|
+
return onFileChange((_b = (_a2 = event.target.files) == null ? void 0 : _a2[0]) != null ? _b : null);
|
|
7575
|
+
}
|
|
7246
7576
|
}
|
|
7247
|
-
)
|
|
7577
|
+
) }),
|
|
7578
|
+
preview ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7579
|
+
"button",
|
|
7580
|
+
{
|
|
7581
|
+
type: "button",
|
|
7582
|
+
className: "mt-2 inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-xs text-ph-mutedtext hover:bg-ph-surface hover:text-ph-ink",
|
|
7583
|
+
onClick: onClear,
|
|
7584
|
+
children: [
|
|
7585
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.Trash, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
7586
|
+
" Remove image"
|
|
7587
|
+
]
|
|
7588
|
+
}
|
|
7589
|
+
) : null
|
|
7590
|
+
] })
|
|
7591
|
+
] });
|
|
7592
|
+
}
|
|
7593
|
+
function DirectoryIcon({
|
|
7594
|
+
item
|
|
7595
|
+
}) {
|
|
7596
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7597
|
+
SuiteEntityIcon,
|
|
7598
|
+
{
|
|
7599
|
+
imageUrl: item.icon_image,
|
|
7600
|
+
label: item.name,
|
|
7601
|
+
color: item.color,
|
|
7602
|
+
tinted: true,
|
|
7603
|
+
className: "h-8 w-8 text-sm",
|
|
7604
|
+
roundedClass: "rounded-lg"
|
|
7248
7605
|
}
|
|
7249
7606
|
);
|
|
7250
7607
|
}
|
|
@@ -7260,51 +7617,53 @@ function SuiteClientsProjectsDirectory({
|
|
|
7260
7617
|
onCreateProject,
|
|
7261
7618
|
onUpdateProject,
|
|
7262
7619
|
onDeleteProject,
|
|
7620
|
+
renderIconLibrary,
|
|
7263
7621
|
dataTest = "suite-clients-projects-directory"
|
|
7264
7622
|
}) {
|
|
7265
|
-
var
|
|
7266
|
-
const [query, setQuery] = (0,
|
|
7267
|
-
const [selectedClientId, setSelectedClientId] = (0,
|
|
7268
|
-
const [mobileDetail, setMobileDetail] = (0,
|
|
7269
|
-
const [editing, setEditing] = (0,
|
|
7270
|
-
const [draft, setDraft] = (0,
|
|
7623
|
+
var _a2;
|
|
7624
|
+
const [query, setQuery] = (0, import_react28.useState)("");
|
|
7625
|
+
const [selectedClientId, setSelectedClientId] = (0, import_react28.useState)(null);
|
|
7626
|
+
const [mobileDetail, setMobileDetail] = (0, import_react28.useState)(false);
|
|
7627
|
+
const [editing, setEditing] = (0, import_react28.useState)(null);
|
|
7628
|
+
const [draft, setDraft] = (0, import_react28.useState)({
|
|
7271
7629
|
name: "",
|
|
7272
7630
|
icon: DEFAULT_ICON,
|
|
7273
7631
|
color: DEFAULT_COLOR
|
|
7274
7632
|
});
|
|
7275
|
-
const [draftClientId, setDraftClientId] = (0,
|
|
7276
|
-
const [preview, setPreview] = (0,
|
|
7277
|
-
const [
|
|
7278
|
-
const [
|
|
7279
|
-
const [
|
|
7280
|
-
const [
|
|
7281
|
-
const
|
|
7282
|
-
const
|
|
7283
|
-
const
|
|
7284
|
-
(0,
|
|
7285
|
-
|
|
7633
|
+
const [draftClientId, setDraftClientId] = (0, import_react28.useState)(null);
|
|
7634
|
+
const [preview, setPreview] = (0, import_react28.useState)(null);
|
|
7635
|
+
const [libraryOpen, setLibraryOpen] = (0, import_react28.useState)(false);
|
|
7636
|
+
const [draftArchived, setDraftArchived] = (0, import_react28.useState)(false);
|
|
7637
|
+
const [confirming, setConfirming] = (0, import_react28.useState)(null);
|
|
7638
|
+
const [saving, setSaving] = (0, import_react28.useState)(false);
|
|
7639
|
+
const [mutationError, setMutationError] = (0, import_react28.useState)(null);
|
|
7640
|
+
const clientButtonRefs = (0, import_react28.useRef)({});
|
|
7641
|
+
const backToClientsRef = (0, import_react28.useRef)(null);
|
|
7642
|
+
const mobileFocusTarget = (0, import_react28.useRef)(null);
|
|
7643
|
+
(0, import_react28.useEffect)(() => {
|
|
7644
|
+
var _a3, _b;
|
|
7286
7645
|
if (selectedClientId && clients.some((client) => client.id === selectedClientId))
|
|
7287
7646
|
return;
|
|
7288
|
-
setSelectedClientId((_b = (
|
|
7647
|
+
setSelectedClientId((_b = (_a3 = clients[0]) == null ? void 0 : _a3.id) != null ? _b : null);
|
|
7289
7648
|
}, [clients, selectedClientId]);
|
|
7290
|
-
(0,
|
|
7291
|
-
var
|
|
7649
|
+
(0, import_react28.useEffect)(() => {
|
|
7650
|
+
var _a3, _b;
|
|
7292
7651
|
const target = mobileFocusTarget.current;
|
|
7293
7652
|
if (!target) return;
|
|
7294
7653
|
mobileFocusTarget.current = null;
|
|
7295
|
-
if (target === "detail") (
|
|
7654
|
+
if (target === "detail") (_a3 = backToClientsRef.current) == null ? void 0 : _a3.focus();
|
|
7296
7655
|
else if (selectedClientId)
|
|
7297
7656
|
(_b = clientButtonRefs.current[selectedClientId]) == null ? void 0 : _b.focus();
|
|
7298
7657
|
}, [mobileDetail, selectedClientId]);
|
|
7299
|
-
const filteredClients = (0,
|
|
7658
|
+
const filteredClients = (0, import_react28.useMemo)(() => {
|
|
7300
7659
|
const value = query.trim().toLowerCase();
|
|
7301
7660
|
return [...clients].sort((a, b) => a.name.localeCompare(b.name)).filter((client) => !value || client.name.toLowerCase().includes(value));
|
|
7302
7661
|
}, [clients, query]);
|
|
7303
|
-
const selectedClient = (
|
|
7662
|
+
const selectedClient = (_a2 = clients.find((client) => client.id === selectedClientId)) != null ? _a2 : null;
|
|
7304
7663
|
const selectedProjects = projects.filter((project) => project.clientId === selectedClientId).sort((a, b) => a.name.localeCompare(b.name));
|
|
7305
7664
|
function isMobileDirectoryView() {
|
|
7306
|
-
var
|
|
7307
|
-
return (_b = (
|
|
7665
|
+
var _a3, _b;
|
|
7666
|
+
return (_b = (_a3 = window.matchMedia) == null ? void 0 : _a3.call(window, "(max-width: 1023px)").matches) != null ? _b : false;
|
|
7308
7667
|
}
|
|
7309
7668
|
function selectClient(client) {
|
|
7310
7669
|
setSelectedClientId(client.id);
|
|
@@ -7312,7 +7671,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7312
7671
|
if (isMobileDirectoryView()) mobileFocusTarget.current = "detail";
|
|
7313
7672
|
}
|
|
7314
7673
|
function moveClientSelection(event, index) {
|
|
7315
|
-
var
|
|
7674
|
+
var _a3;
|
|
7316
7675
|
let nextIndex = null;
|
|
7317
7676
|
if (event.key === "ArrowDown") {
|
|
7318
7677
|
nextIndex = (index + 1) % filteredClients.length;
|
|
@@ -7327,7 +7686,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7327
7686
|
event.preventDefault();
|
|
7328
7687
|
const client = filteredClients[nextIndex];
|
|
7329
7688
|
selectClient(client);
|
|
7330
|
-
if (!isMobileDirectoryView()) (
|
|
7689
|
+
if (!isMobileDirectoryView()) (_a3 = clientButtonRefs.current[client.id]) == null ? void 0 : _a3.focus();
|
|
7331
7690
|
}
|
|
7332
7691
|
function openNew(kind) {
|
|
7333
7692
|
setMutationError(null);
|
|
@@ -7336,6 +7695,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7336
7695
|
icon: DEFAULT_ICON,
|
|
7337
7696
|
color: DEFAULT_COLOR,
|
|
7338
7697
|
iconImageFile: null,
|
|
7698
|
+
iconImageUrl: null,
|
|
7339
7699
|
clearIconImage: false
|
|
7340
7700
|
});
|
|
7341
7701
|
setPreview(null);
|
|
@@ -7344,13 +7704,14 @@ function SuiteClientsProjectsDirectory({
|
|
|
7344
7704
|
setEditing({ kind: kind === "client" ? "new-client" : "new-project" });
|
|
7345
7705
|
}
|
|
7346
7706
|
function openEdit(item, kind) {
|
|
7347
|
-
var
|
|
7707
|
+
var _a3, _b;
|
|
7348
7708
|
setMutationError(null);
|
|
7349
7709
|
setDraft({
|
|
7350
7710
|
name: item.name,
|
|
7351
|
-
icon:
|
|
7711
|
+
icon: (_a3 = item.icon) != null ? _a3 : DEFAULT_ICON,
|
|
7352
7712
|
color: item.color || DEFAULT_COLOR,
|
|
7353
7713
|
iconImageFile: null,
|
|
7714
|
+
iconImageUrl: null,
|
|
7354
7715
|
clearIconImage: false
|
|
7355
7716
|
});
|
|
7356
7717
|
setPreview(item.icon_image || null);
|
|
@@ -7358,7 +7719,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7358
7719
|
kind === "project" && Boolean(item.isArchived)
|
|
7359
7720
|
);
|
|
7360
7721
|
setDraftClientId(
|
|
7361
|
-
kind === "project" ? (
|
|
7722
|
+
kind === "project" ? (_b = item.clientId) != null ? _b : null : null
|
|
7362
7723
|
);
|
|
7363
7724
|
setEditing({ kind, item });
|
|
7364
7725
|
}
|
|
@@ -7372,6 +7733,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7372
7733
|
if (preview == null ? void 0 : preview.startsWith("blob:")) URL.revokeObjectURL(preview);
|
|
7373
7734
|
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
7374
7735
|
iconImageFile: file,
|
|
7736
|
+
iconImageUrl: null,
|
|
7375
7737
|
clearIconImage: false
|
|
7376
7738
|
}));
|
|
7377
7739
|
setPreview(URL.createObjectURL(file));
|
|
@@ -7381,9 +7743,21 @@ function SuiteClientsProjectsDirectory({
|
|
|
7381
7743
|
setPreview(null);
|
|
7382
7744
|
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
7383
7745
|
iconImageFile: null,
|
|
7746
|
+
iconImageUrl: null,
|
|
7384
7747
|
clearIconImage: true
|
|
7385
7748
|
}));
|
|
7386
7749
|
}
|
|
7750
|
+
function pickFromLibrary(icon) {
|
|
7751
|
+
if (preview == null ? void 0 : preview.startsWith("blob:")) URL.revokeObjectURL(preview);
|
|
7752
|
+
setMutationError(null);
|
|
7753
|
+
setPreview(icon.url);
|
|
7754
|
+
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
7755
|
+
iconImageFile: null,
|
|
7756
|
+
iconImageUrl: icon.url,
|
|
7757
|
+
clearIconImage: false
|
|
7758
|
+
}));
|
|
7759
|
+
setLibraryOpen(false);
|
|
7760
|
+
}
|
|
7387
7761
|
function closeEditor() {
|
|
7388
7762
|
if (!saving) setEditing(null);
|
|
7389
7763
|
}
|
|
@@ -7419,14 +7793,14 @@ function SuiteClientsProjectsDirectory({
|
|
|
7419
7793
|
setConfirming({ item, kind });
|
|
7420
7794
|
}
|
|
7421
7795
|
async function toggleArchive(project) {
|
|
7422
|
-
var
|
|
7796
|
+
var _a3, _b;
|
|
7423
7797
|
if (!onUpdateProject) return;
|
|
7424
7798
|
try {
|
|
7425
7799
|
await onUpdateProject(project, {
|
|
7426
7800
|
name: project.name,
|
|
7427
|
-
icon:
|
|
7801
|
+
icon: (_a3 = project.icon) != null ? _a3 : DEFAULT_ICON,
|
|
7428
7802
|
color: project.color || DEFAULT_COLOR,
|
|
7429
|
-
clientId: (
|
|
7803
|
+
clientId: (_b = project.clientId) != null ? _b : null,
|
|
7430
7804
|
isArchived: !project.isArchived
|
|
7431
7805
|
});
|
|
7432
7806
|
} catch (err) {
|
|
@@ -7449,10 +7823,10 @@ function SuiteClientsProjectsDirectory({
|
|
|
7449
7823
|
);
|
|
7450
7824
|
}
|
|
7451
7825
|
}
|
|
7452
|
-
return /* @__PURE__ */ (0,
|
|
7453
|
-
error || mutationError ? /* @__PURE__ */ (0,
|
|
7454
|
-
loading ? /* @__PURE__ */ (0,
|
|
7455
|
-
/* @__PURE__ */ (0,
|
|
7826
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { "data-test": dataTest, className: "space-y-3", children: [
|
|
7827
|
+
error || mutationError ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Alert, { status: "danger", live: "assertive", children: error || mutationError }) : null,
|
|
7828
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-sm text-ph-mutedtext", children: "Loading directory..." }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "overflow-hidden rounded-xl border border-ph-border bg-ph-surface lg:grid lg:min-h-[22rem] lg:grid-cols-[minmax(14rem,18rem)_1fr]", children: [
|
|
7829
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7456
7830
|
"section",
|
|
7457
7831
|
{
|
|
7458
7832
|
className: cn2(
|
|
@@ -7460,16 +7834,16 @@ function SuiteClientsProjectsDirectory({
|
|
|
7460
7834
|
mobileDetail ? "hidden lg:block" : "block"
|
|
7461
7835
|
),
|
|
7462
7836
|
children: [
|
|
7463
|
-
/* @__PURE__ */ (0,
|
|
7464
|
-
/* @__PURE__ */ (0,
|
|
7465
|
-
/* @__PURE__ */ (0,
|
|
7466
|
-
|
|
7837
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex h-14 items-center gap-2 border-b border-ph-border px-3", children: [
|
|
7838
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "relative min-w-0 flex-1", children: [
|
|
7839
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7840
|
+
import_iconoir_react15.Search,
|
|
7467
7841
|
{
|
|
7468
7842
|
className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
7469
7843
|
"aria-hidden": true
|
|
7470
7844
|
}
|
|
7471
7845
|
),
|
|
7472
|
-
/* @__PURE__ */ (0,
|
|
7846
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7473
7847
|
Input,
|
|
7474
7848
|
{
|
|
7475
7849
|
hideLabel: true,
|
|
@@ -7481,18 +7855,18 @@ function SuiteClientsProjectsDirectory({
|
|
|
7481
7855
|
}
|
|
7482
7856
|
)
|
|
7483
7857
|
] }),
|
|
7484
|
-
canEdit && onCreateClient ? /* @__PURE__ */ (0,
|
|
7858
|
+
canEdit && onCreateClient ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7485
7859
|
Button,
|
|
7486
7860
|
{
|
|
7487
7861
|
size: "sm",
|
|
7488
7862
|
variant: "primary",
|
|
7489
|
-
icon: /* @__PURE__ */ (0,
|
|
7863
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.Plus, { className: "h-4 w-4" }),
|
|
7490
7864
|
onClick: () => openNew("client"),
|
|
7491
7865
|
children: "New client"
|
|
7492
7866
|
}
|
|
7493
7867
|
) : null
|
|
7494
7868
|
] }),
|
|
7495
|
-
/* @__PURE__ */ (0,
|
|
7869
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7496
7870
|
"ul",
|
|
7497
7871
|
{
|
|
7498
7872
|
role: "listbox",
|
|
@@ -7503,7 +7877,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7503
7877
|
const count = projects.filter(
|
|
7504
7878
|
(project) => project.clientId === client.id
|
|
7505
7879
|
).length;
|
|
7506
|
-
return /* @__PURE__ */ (0,
|
|
7880
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { role: "none", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7507
7881
|
"button",
|
|
7508
7882
|
{
|
|
7509
7883
|
type: "button",
|
|
@@ -7520,10 +7894,10 @@ function SuiteClientsProjectsDirectory({
|
|
|
7520
7894
|
selected ? "bg-ph-muted" : "hover:bg-ph-canvas"
|
|
7521
7895
|
),
|
|
7522
7896
|
children: [
|
|
7523
|
-
/* @__PURE__ */ (0,
|
|
7524
|
-
/* @__PURE__ */ (0,
|
|
7525
|
-
/* @__PURE__ */ (0,
|
|
7526
|
-
/* @__PURE__ */ (0,
|
|
7897
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(DirectoryIcon, { item: client }),
|
|
7898
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
7899
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "block truncate text-sm font-medium text-ph-ink", children: client.name }),
|
|
7900
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "text-xs text-ph-mutedtext", children: [
|
|
7527
7901
|
count,
|
|
7528
7902
|
" project",
|
|
7529
7903
|
count === 1 ? "" : "s"
|
|
@@ -7532,13 +7906,13 @@ function SuiteClientsProjectsDirectory({
|
|
|
7532
7906
|
]
|
|
7533
7907
|
}
|
|
7534
7908
|
) }, client.id);
|
|
7535
|
-
}) : /* @__PURE__ */ (0,
|
|
7909
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { className: "px-3 py-8 text-center text-sm text-ph-mutedtext", children: clients.length ? "No matches." : "Add a client to get started." })
|
|
7536
7910
|
}
|
|
7537
7911
|
)
|
|
7538
7912
|
]
|
|
7539
7913
|
}
|
|
7540
7914
|
),
|
|
7541
|
-
/* @__PURE__ */ (0,
|
|
7915
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7542
7916
|
"section",
|
|
7543
7917
|
{
|
|
7544
7918
|
className: cn2(
|
|
@@ -7546,8 +7920,8 @@ function SuiteClientsProjectsDirectory({
|
|
|
7546
7920
|
mobileDetail ? "flex" : "hidden lg:flex"
|
|
7547
7921
|
),
|
|
7548
7922
|
children: [
|
|
7549
|
-
/* @__PURE__ */ (0,
|
|
7550
|
-
/* @__PURE__ */ (0,
|
|
7923
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex min-h-14 items-center gap-2 border-b border-ph-border px-3 py-2", children: selectedClient ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
7924
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7551
7925
|
"button",
|
|
7552
7926
|
{
|
|
7553
7927
|
type: "button",
|
|
@@ -7558,36 +7932,36 @@ function SuiteClientsProjectsDirectory({
|
|
|
7558
7932
|
setMobileDetail(false);
|
|
7559
7933
|
},
|
|
7560
7934
|
"aria-label": "Back to clients",
|
|
7561
|
-
children: /* @__PURE__ */ (0,
|
|
7935
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.ArrowLeft, { className: "h-4 w-4" })
|
|
7562
7936
|
}
|
|
7563
7937
|
),
|
|
7564
|
-
/* @__PURE__ */ (0,
|
|
7565
|
-
/* @__PURE__ */ (0,
|
|
7566
|
-
/* @__PURE__ */ (0,
|
|
7567
|
-
/* @__PURE__ */ (0,
|
|
7938
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(DirectoryIcon, { item: selectedClient }),
|
|
7939
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
7940
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h3", { className: "truncate text-sm font-semibold text-ph-ink", children: selectedClient.name }),
|
|
7941
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "text-xs text-ph-mutedtext", children: [
|
|
7568
7942
|
selectedProjects.length,
|
|
7569
7943
|
" project",
|
|
7570
7944
|
selectedProjects.length === 1 ? "" : "s"
|
|
7571
7945
|
] })
|
|
7572
7946
|
] }),
|
|
7573
|
-
canEdit && (onUpdateClient || onDeleteClient) ? /* @__PURE__ */ (0,
|
|
7947
|
+
canEdit && (onUpdateClient || onDeleteClient) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7574
7948
|
DropdownMenu,
|
|
7575
7949
|
{
|
|
7576
7950
|
"aria-label": `Actions for ${selectedClient.name}`,
|
|
7577
7951
|
align: "end",
|
|
7578
|
-
trigger: /* @__PURE__ */ (0,
|
|
7579
|
-
/* @__PURE__ */ (0,
|
|
7580
|
-
/* @__PURE__ */ (0,
|
|
7952
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "inline-flex h-8 w-8 items-center justify-center rounded-md text-ph-mutedtext hover:bg-ph-muted hover:text-ph-ink", children: [
|
|
7953
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.MoreHoriz, { className: "h-4 w-4", "aria-hidden": true }),
|
|
7954
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sr-only", children: "Client actions" })
|
|
7581
7955
|
] }),
|
|
7582
|
-
children: /* @__PURE__ */ (0,
|
|
7583
|
-
onUpdateClient ? /* @__PURE__ */ (0,
|
|
7956
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "p-1", children: [
|
|
7957
|
+
onUpdateClient ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7584
7958
|
DropdownItem,
|
|
7585
7959
|
{
|
|
7586
7960
|
onClick: () => openEdit(selectedClient, "client"),
|
|
7587
7961
|
children: "Edit client"
|
|
7588
7962
|
}
|
|
7589
7963
|
) : null,
|
|
7590
|
-
onDeleteClient ? /* @__PURE__ */ (0,
|
|
7964
|
+
onDeleteClient ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7591
7965
|
DropdownItem,
|
|
7592
7966
|
{
|
|
7593
7967
|
className: "text-red-600",
|
|
@@ -7598,32 +7972,32 @@ function SuiteClientsProjectsDirectory({
|
|
|
7598
7972
|
] })
|
|
7599
7973
|
}
|
|
7600
7974
|
) }) : null
|
|
7601
|
-
] }) : /* @__PURE__ */ (0,
|
|
7602
|
-
canEdit && onCreateProject ? /* @__PURE__ */ (0,
|
|
7975
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "text-sm text-ph-mutedtext", children: "Select a client" }) }),
|
|
7976
|
+
canEdit && onCreateProject ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "border-b border-ph-border p-3", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7603
7977
|
Button,
|
|
7604
7978
|
{
|
|
7605
7979
|
variant: "primary",
|
|
7606
|
-
icon: /* @__PURE__ */ (0,
|
|
7980
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.Plus, { className: "h-4 w-4" }),
|
|
7607
7981
|
onClick: () => openNew("project"),
|
|
7608
7982
|
children: "Add project"
|
|
7609
7983
|
}
|
|
7610
7984
|
) }) : null,
|
|
7611
|
-
/* @__PURE__ */ (0,
|
|
7985
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("ul", { className: "flex-1 p-2", children: selectedClient && selectedProjects.length ? selectedProjects.map((project) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7612
7986
|
"div",
|
|
7613
7987
|
{
|
|
7614
7988
|
className: "flex items-center gap-3 rounded-lg px-2 py-1 hover:bg-ph-canvas",
|
|
7615
7989
|
onClick: () => openEdit(project, "project"),
|
|
7616
7990
|
children: [
|
|
7617
|
-
/* @__PURE__ */ (0,
|
|
7991
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7618
7992
|
"button",
|
|
7619
7993
|
{
|
|
7620
7994
|
type: "button",
|
|
7621
7995
|
className: "flex min-w-0 flex-1 items-center gap-3 rounded-lg py-1 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ph-brand",
|
|
7622
7996
|
onClick: () => openEdit(project, "project"),
|
|
7623
7997
|
children: [
|
|
7624
|
-
/* @__PURE__ */ (0,
|
|
7625
|
-
/* @__PURE__ */ (0,
|
|
7626
|
-
/* @__PURE__ */ (0,
|
|
7998
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(DirectoryIcon, { item: project }),
|
|
7999
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "min-w-0 flex-1", children: [
|
|
8000
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7627
8001
|
"span",
|
|
7628
8002
|
{
|
|
7629
8003
|
className: cn2(
|
|
@@ -7633,36 +8007,36 @@ function SuiteClientsProjectsDirectory({
|
|
|
7633
8007
|
children: project.name
|
|
7634
8008
|
}
|
|
7635
8009
|
),
|
|
7636
|
-
/* @__PURE__ */ (0,
|
|
8010
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-xs text-ph-mutedtext", children: project.isArchived ? "Archived" : "Active" })
|
|
7637
8011
|
] })
|
|
7638
8012
|
]
|
|
7639
8013
|
}
|
|
7640
8014
|
),
|
|
7641
|
-
canEdit && (onUpdateProject || onDeleteProject) ? /* @__PURE__ */ (0,
|
|
8015
|
+
canEdit && (onUpdateProject || onDeleteProject) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7642
8016
|
DropdownMenu,
|
|
7643
8017
|
{
|
|
7644
8018
|
"aria-label": `Actions for ${project.name}`,
|
|
7645
8019
|
align: "end",
|
|
7646
|
-
trigger: /* @__PURE__ */ (0,
|
|
7647
|
-
/* @__PURE__ */ (0,
|
|
7648
|
-
|
|
8020
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-ph-mutedtext hover:bg-ph-muted hover:text-ph-ink", children: [
|
|
8021
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8022
|
+
import_iconoir_react15.MoreHoriz,
|
|
7649
8023
|
{
|
|
7650
8024
|
className: "h-4 w-4",
|
|
7651
8025
|
"aria-hidden": true
|
|
7652
8026
|
}
|
|
7653
8027
|
),
|
|
7654
|
-
/* @__PURE__ */ (0,
|
|
8028
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "sr-only", children: "Project actions" })
|
|
7655
8029
|
] }),
|
|
7656
|
-
children: /* @__PURE__ */ (0,
|
|
7657
|
-
onUpdateProject ? /* @__PURE__ */ (0,
|
|
7658
|
-
/* @__PURE__ */ (0,
|
|
8030
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "p-1", children: [
|
|
8031
|
+
onUpdateProject ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_jsx_runtime43.Fragment, { children: [
|
|
8032
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7659
8033
|
DropdownItem,
|
|
7660
8034
|
{
|
|
7661
8035
|
onClick: () => openEdit(project, "project"),
|
|
7662
8036
|
children: "Edit project"
|
|
7663
8037
|
}
|
|
7664
8038
|
),
|
|
7665
|
-
/* @__PURE__ */ (0,
|
|
8039
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7666
8040
|
DropdownItem,
|
|
7667
8041
|
{
|
|
7668
8042
|
onClick: () => void toggleArchive(project),
|
|
@@ -7670,7 +8044,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7670
8044
|
}
|
|
7671
8045
|
)
|
|
7672
8046
|
] }) : null,
|
|
7673
|
-
onDeleteProject ? /* @__PURE__ */ (0,
|
|
8047
|
+
onDeleteProject ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7674
8048
|
DropdownItem,
|
|
7675
8049
|
{
|
|
7676
8050
|
className: "text-red-600",
|
|
@@ -7683,20 +8057,20 @@ function SuiteClientsProjectsDirectory({
|
|
|
7683
8057
|
) }) : null
|
|
7684
8058
|
]
|
|
7685
8059
|
}
|
|
7686
|
-
) }, project.id)) : /* @__PURE__ */ (0,
|
|
8060
|
+
) }, project.id)) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("li", { className: "px-3 py-8 text-center text-sm text-ph-mutedtext", children: selectedClient ? "No projects yet." : "Select a client to see its projects." }) })
|
|
7687
8061
|
]
|
|
7688
8062
|
}
|
|
7689
8063
|
)
|
|
7690
8064
|
] }),
|
|
7691
|
-
/* @__PURE__ */ (0,
|
|
8065
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7692
8066
|
Modal,
|
|
7693
8067
|
{
|
|
7694
8068
|
open: editing !== null,
|
|
7695
8069
|
onClose: closeEditor,
|
|
7696
8070
|
title: (editing == null ? void 0 : editing.kind.includes("project")) ? editing.kind === "new-project" ? "New project" : "Edit project" : (editing == null ? void 0 : editing.kind) === "new-client" ? "New client" : "Edit client",
|
|
7697
|
-
footer: /* @__PURE__ */ (0,
|
|
7698
|
-
/* @__PURE__ */ (0,
|
|
7699
|
-
/* @__PURE__ */ (0,
|
|
8071
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex justify-end gap-2", children: [
|
|
8072
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { variant: "tertiary", onClick: closeEditor, disabled: saving, children: "Cancel" }),
|
|
8073
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7700
8074
|
Button,
|
|
7701
8075
|
{
|
|
7702
8076
|
variant: "primary",
|
|
@@ -7706,8 +8080,8 @@ function SuiteClientsProjectsDirectory({
|
|
|
7706
8080
|
}
|
|
7707
8081
|
)
|
|
7708
8082
|
] }),
|
|
7709
|
-
children: /* @__PURE__ */ (0,
|
|
7710
|
-
/* @__PURE__ */ (0,
|
|
8083
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "space-y-3", children: [
|
|
8084
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7711
8085
|
Input,
|
|
7712
8086
|
{
|
|
7713
8087
|
label: "Name",
|
|
@@ -7716,22 +8090,35 @@ function SuiteClientsProjectsDirectory({
|
|
|
7716
8090
|
onChange: (event) => setDraft(__spreadProps(__spreadValues({}, draft), { name: event.target.value }))
|
|
7717
8091
|
}
|
|
7718
8092
|
),
|
|
7719
|
-
/* @__PURE__ */ (0,
|
|
8093
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7720
8094
|
DirectoryIconPicker,
|
|
7721
8095
|
{
|
|
7722
|
-
value: isDirectoryIcon(draft.icon) ? draft.icon : DEFAULT_ICON,
|
|
7723
8096
|
preview,
|
|
8097
|
+
label: draft.name,
|
|
8098
|
+
color: draft.color,
|
|
7724
8099
|
onFileChange: chooseImage,
|
|
7725
8100
|
onClear: clearImage,
|
|
7726
|
-
|
|
7727
|
-
if (preview) clearImage();
|
|
7728
|
-
setDraft((current) => __spreadProps(__spreadValues({}, current), { icon }));
|
|
7729
|
-
}
|
|
8101
|
+
onBrowse: () => setLibraryOpen(true)
|
|
7730
8102
|
}
|
|
7731
8103
|
),
|
|
7732
|
-
/* @__PURE__ */ (0,
|
|
7733
|
-
/* @__PURE__ */ (0,
|
|
7734
|
-
/* @__PURE__ */ (0,
|
|
8104
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { children: [
|
|
8105
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "mb-1.5 block text-sm font-medium text-ph-ink", children: "Colour" }),
|
|
8106
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
8107
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8108
|
+
"button",
|
|
8109
|
+
{
|
|
8110
|
+
type: "button",
|
|
8111
|
+
"aria-label": "No colour",
|
|
8112
|
+
"aria-pressed": !draft.color,
|
|
8113
|
+
title: "No colour",
|
|
8114
|
+
onClick: () => setDraft(__spreadProps(__spreadValues({}, draft), { color: "" })),
|
|
8115
|
+
className: cn2(
|
|
8116
|
+
"flex h-8 w-8 items-center justify-center rounded-full border border-ph-border bg-ph-surface text-ph-mutedtext ring-offset-2",
|
|
8117
|
+
!draft.color && "ring-2 ring-ph-brand"
|
|
8118
|
+
),
|
|
8119
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.Prohibition, { className: "h-4 w-4", "aria-hidden": true })
|
|
8120
|
+
}
|
|
8121
|
+
),
|
|
7735
8122
|
[
|
|
7736
8123
|
"#6366f1",
|
|
7737
8124
|
"#0ea5e9",
|
|
@@ -7740,7 +8127,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7740
8127
|
"#ef4444",
|
|
7741
8128
|
"#a855f7",
|
|
7742
8129
|
"#64748b"
|
|
7743
|
-
].map((color) => /* @__PURE__ */ (0,
|
|
8130
|
+
].map((color) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7744
8131
|
"button",
|
|
7745
8132
|
{
|
|
7746
8133
|
type: "button",
|
|
@@ -7755,33 +8142,70 @@ function SuiteClientsProjectsDirectory({
|
|
|
7755
8142
|
},
|
|
7756
8143
|
color
|
|
7757
8144
|
)),
|
|
7758
|
-
/* @__PURE__ */ (0,
|
|
7759
|
-
|
|
8145
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8146
|
+
"label",
|
|
7760
8147
|
{
|
|
7761
|
-
|
|
7762
|
-
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
8148
|
+
className: cn2(
|
|
8149
|
+
"relative inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-full ring-1 ring-ph-border ring-offset-2",
|
|
8150
|
+
![
|
|
8151
|
+
"#6366f1",
|
|
8152
|
+
"#0ea5e9",
|
|
8153
|
+
"#10b981",
|
|
8154
|
+
"#f59e0b",
|
|
8155
|
+
"#ef4444",
|
|
8156
|
+
"#a855f7",
|
|
8157
|
+
"#64748b"
|
|
8158
|
+
].includes(draft.color) && "ring-2 ring-ph-brand"
|
|
8159
|
+
),
|
|
8160
|
+
style: {
|
|
8161
|
+
background: "conic-gradient(from 0deg, #ef4444, #f59e0b, #eab308, #22c55e, #06b6d4, #3b82f6, #8b5cf6, #ec4899, #ef4444)"
|
|
8162
|
+
},
|
|
8163
|
+
title: "Custom colour",
|
|
8164
|
+
children: [
|
|
8165
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "flex h-4 w-4 items-center justify-center rounded-full bg-ph-surface", children: [
|
|
8166
|
+
"#6366f1",
|
|
8167
|
+
"#0ea5e9",
|
|
8168
|
+
"#10b981",
|
|
8169
|
+
"#f59e0b",
|
|
8170
|
+
"#ef4444",
|
|
8171
|
+
"#a855f7",
|
|
8172
|
+
"#64748b"
|
|
8173
|
+
].includes(draft.color) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_iconoir_react15.Plus, { className: "h-3 w-3 text-ph-ink", "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8174
|
+
"span",
|
|
8175
|
+
{
|
|
8176
|
+
className: "h-2.5 w-2.5 rounded-full",
|
|
8177
|
+
style: { backgroundColor: draft.color }
|
|
8178
|
+
}
|
|
8179
|
+
) }),
|
|
8180
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8181
|
+
"input",
|
|
8182
|
+
{
|
|
8183
|
+
type: "color",
|
|
8184
|
+
"aria-label": "Custom colour",
|
|
8185
|
+
value: draft.color,
|
|
8186
|
+
onChange: (event) => setDraft(__spreadProps(__spreadValues({}, draft), { color: event.target.value })),
|
|
8187
|
+
className: "sr-only"
|
|
8188
|
+
}
|
|
8189
|
+
)
|
|
8190
|
+
]
|
|
7767
8191
|
}
|
|
7768
8192
|
)
|
|
7769
8193
|
] })
|
|
7770
8194
|
] }),
|
|
7771
|
-
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ (0,
|
|
8195
|
+
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
7772
8196
|
Select,
|
|
7773
8197
|
{
|
|
7774
8198
|
label: "Client",
|
|
7775
8199
|
value: draftClientId != null ? draftClientId : "",
|
|
7776
8200
|
onChange: (event) => setDraftClientId(event.target.value || null),
|
|
7777
8201
|
children: [
|
|
7778
|
-
/* @__PURE__ */ (0,
|
|
7779
|
-
clients.map((client) => /* @__PURE__ */ (0,
|
|
8202
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: "", children: "No client" }),
|
|
8203
|
+
clients.map((client) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("option", { value: client.id, children: client.name }, client.id))
|
|
7780
8204
|
]
|
|
7781
8205
|
}
|
|
7782
8206
|
) : null,
|
|
7783
|
-
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ (0,
|
|
7784
|
-
/* @__PURE__ */ (0,
|
|
8207
|
+
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("label", { className: "flex items-center gap-2 text-sm text-ph-ink", children: [
|
|
8208
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7785
8209
|
"input",
|
|
7786
8210
|
{
|
|
7787
8211
|
type: "checkbox",
|
|
@@ -7794,17 +8218,26 @@ function SuiteClientsProjectsDirectory({
|
|
|
7794
8218
|
] })
|
|
7795
8219
|
}
|
|
7796
8220
|
),
|
|
7797
|
-
/* @__PURE__ */ (0,
|
|
8221
|
+
libraryOpen ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8222
|
+
Modal,
|
|
8223
|
+
{
|
|
8224
|
+
open: true,
|
|
8225
|
+
onClose: () => setLibraryOpen(false),
|
|
8226
|
+
title: "Icon library",
|
|
8227
|
+
children: renderIconLibrary ? renderIconLibrary({ onPick: pickFromLibrary }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(SuitePaletteLibrary, { onPick: pickFromLibrary })
|
|
8228
|
+
}
|
|
8229
|
+
) : null,
|
|
8230
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
7798
8231
|
Modal,
|
|
7799
8232
|
{
|
|
7800
8233
|
open: confirming !== null,
|
|
7801
8234
|
onClose: () => setConfirming(null),
|
|
7802
8235
|
title: "Confirm deletion",
|
|
7803
|
-
footer: /* @__PURE__ */ (0,
|
|
7804
|
-
/* @__PURE__ */ (0,
|
|
7805
|
-
/* @__PURE__ */ (0,
|
|
8236
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex justify-end gap-2", children: [
|
|
8237
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { variant: "tertiary", onClick: () => setConfirming(null), children: "Cancel" }),
|
|
8238
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Button, { variant: "primary", onClick: () => void confirmRemove(), children: "Delete" })
|
|
7806
8239
|
] }),
|
|
7807
|
-
children: /* @__PURE__ */ (0,
|
|
8240
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("p", { className: "text-sm text-ph-ink", children: [
|
|
7808
8241
|
"Delete ",
|
|
7809
8242
|
confirming == null ? void 0 : confirming.item.name,
|
|
7810
8243
|
"? This cannot be undone."
|
|
@@ -7850,6 +8283,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7850
8283
|
SuiteBreadcrumbs,
|
|
7851
8284
|
SuiteClientsProjectsDirectory,
|
|
7852
8285
|
SuiteEmptyState,
|
|
8286
|
+
SuiteEntityIcon,
|
|
7853
8287
|
SuiteIcon,
|
|
7854
8288
|
SuiteIntegrationPicker,
|
|
7855
8289
|
SuiteIntegrationRules,
|
|
@@ -7859,6 +8293,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
7859
8293
|
SuiteNotificationBell,
|
|
7860
8294
|
SuitePage,
|
|
7861
8295
|
SuitePageHeader,
|
|
8296
|
+
SuitePaletteLibrary,
|
|
7862
8297
|
SuiteSectionHeader,
|
|
7863
8298
|
SuiteSettingsLayout,
|
|
7864
8299
|
SuiteSettingsMobileNav,
|
|
@@ -7891,6 +8326,9 @@ function SuiteClientsProjectsDirectory({
|
|
|
7891
8326
|
cn,
|
|
7892
8327
|
consumePendingAskAiPrompt,
|
|
7893
8328
|
consumeSuiteAskAiOpenFromLocation,
|
|
8329
|
+
fetchPaletteCollection,
|
|
8330
|
+
fetchPaletteLibrary,
|
|
8331
|
+
findPaletteIcons,
|
|
7894
8332
|
getTodayGreeting,
|
|
7895
8333
|
m,
|
|
7896
8334
|
openSuiteAskAi,
|