@xenide-io/the-old-ui-theme 0.9.10 → 0.9.11
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 +162 -199
- 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.mjs
CHANGED
|
@@ -465,13 +465,13 @@ function SuiteAppStrip({
|
|
|
465
465
|
),
|
|
466
466
|
"aria-label": "ShellStack suite apps",
|
|
467
467
|
children: SUITE_APPS.map((app) => {
|
|
468
|
-
var
|
|
468
|
+
var _a2;
|
|
469
469
|
return /* @__PURE__ */ jsxs4(
|
|
470
470
|
"div",
|
|
471
471
|
{
|
|
472
472
|
className: "flex items-center gap-2 rounded-full border border-ph-border bg-ph-surface px-2.5 py-1.5 shadow-sm",
|
|
473
473
|
children: [
|
|
474
|
-
(
|
|
474
|
+
(_a2 = icons == null ? void 0 : icons[app]) != null ? _a2 : /* @__PURE__ */ jsx4(SuiteAppIcon, { app, size: "sm" }),
|
|
475
475
|
/* @__PURE__ */ jsx4("span", { className: "text-xs font-medium text-ph-subtle", children: APP_META[app].name })
|
|
476
476
|
]
|
|
477
477
|
},
|
|
@@ -590,13 +590,13 @@ function TodayTopBar({
|
|
|
590
590
|
] });
|
|
591
591
|
}
|
|
592
592
|
function getTodayGreeting(user, stats) {
|
|
593
|
-
var
|
|
593
|
+
var _a2, _b, _c, _d, _e;
|
|
594
594
|
const hour = (/* @__PURE__ */ new Date()).getHours();
|
|
595
595
|
let period = "morning";
|
|
596
596
|
if (hour >= 12 && hour < 17) period = "afternoon";
|
|
597
597
|
else if (hour >= 17 && hour < 21) period = "evening";
|
|
598
598
|
else if (hour >= 21 || hour < 5) period = "night";
|
|
599
|
-
const name = (user == null ? void 0 : user.first_name) || ((
|
|
599
|
+
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;
|
|
600
600
|
let greeting = `Good ${period}`;
|
|
601
601
|
if (name) greeting += `, ${name}`;
|
|
602
602
|
const taskCount = (_c = stats == null ? void 0 : stats.taskCount) != null ? _c : 0;
|
|
@@ -1095,8 +1095,8 @@ var SOURCE_APP_SLUG = {
|
|
|
1095
1095
|
shellstack: "shellstack"
|
|
1096
1096
|
};
|
|
1097
1097
|
function suiteAppSlugForNotificationSource(sourceApp) {
|
|
1098
|
-
var
|
|
1099
|
-
return (
|
|
1098
|
+
var _a2;
|
|
1099
|
+
return (_a2 = SOURCE_APP_SLUG[(sourceApp || "").toLowerCase()]) != null ? _a2 : null;
|
|
1100
1100
|
}
|
|
1101
1101
|
function resolveSuiteNotificationHref(href, sourceApp) {
|
|
1102
1102
|
const value = (href || "").trim();
|
|
@@ -1184,14 +1184,14 @@ function SuiteNotificationBell({
|
|
|
1184
1184
|
useEffect(() => {
|
|
1185
1185
|
if (cacheKey) {
|
|
1186
1186
|
queueMicrotask(() => {
|
|
1187
|
-
var
|
|
1187
|
+
var _a2;
|
|
1188
1188
|
try {
|
|
1189
1189
|
const raw = sessionStorage.getItem(cacheKey);
|
|
1190
1190
|
if (raw) {
|
|
1191
1191
|
const cached = JSON.parse(raw);
|
|
1192
1192
|
if (Array.isArray(cached.notifications)) {
|
|
1193
1193
|
setItems(cached.notifications);
|
|
1194
|
-
setUnread((
|
|
1194
|
+
setUnread((_a2 = cached.unread_count) != null ? _a2 : 0);
|
|
1195
1195
|
}
|
|
1196
1196
|
}
|
|
1197
1197
|
} catch (e) {
|
|
@@ -1262,9 +1262,9 @@ function SuiteNotificationBell({
|
|
|
1262
1262
|
const markAll = useCallback(async () => {
|
|
1263
1263
|
setItems(
|
|
1264
1264
|
(prev) => prev.map((i) => {
|
|
1265
|
-
var
|
|
1265
|
+
var _a2;
|
|
1266
1266
|
return __spreadProps(__spreadValues({}, i), {
|
|
1267
|
-
read_at: (
|
|
1267
|
+
read_at: (_a2 = i.read_at) != null ? _a2 : (/* @__PURE__ */ new Date()).toISOString()
|
|
1268
1268
|
});
|
|
1269
1269
|
})
|
|
1270
1270
|
);
|
|
@@ -2047,7 +2047,7 @@ function SuiteBottomNav({
|
|
|
2047
2047
|
children: [
|
|
2048
2048
|
activeIndex >= 0 ? /* @__PURE__ */ jsx14("span", { "aria-hidden": true, className: "suite-bottom-nav__indicator" }) : null,
|
|
2049
2049
|
items.map((item) => {
|
|
2050
|
-
var
|
|
2050
|
+
var _a2;
|
|
2051
2051
|
const Icon = item.icon;
|
|
2052
2052
|
const active = Boolean(item.active);
|
|
2053
2053
|
return /* @__PURE__ */ jsxs12(
|
|
@@ -2055,7 +2055,7 @@ function SuiteBottomNav({
|
|
|
2055
2055
|
{
|
|
2056
2056
|
href: item.href,
|
|
2057
2057
|
id: item.id,
|
|
2058
|
-
"data-test": (
|
|
2058
|
+
"data-test": (_a2 = item.dataTest) != null ? _a2 : `suite-nav-${item.label.toLowerCase().replace(/\s+/g, "-")}`,
|
|
2059
2059
|
"aria-current": active ? "page" : void 0,
|
|
2060
2060
|
className: cn2(
|
|
2061
2061
|
"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",
|
|
@@ -2154,7 +2154,7 @@ import {
|
|
|
2154
2154
|
|
|
2155
2155
|
// src/suite/lib/cookies.ts
|
|
2156
2156
|
function suiteCookieDomainAttr() {
|
|
2157
|
-
var
|
|
2157
|
+
var _a2;
|
|
2158
2158
|
const host = window.location.hostname;
|
|
2159
2159
|
if (host === "localhost" || /^\d{1,3}(?:\.\d{1,3}){3}$/.test(host)) {
|
|
2160
2160
|
return "";
|
|
@@ -2173,7 +2173,7 @@ function suiteCookieDomainAttr() {
|
|
|
2173
2173
|
"portal"
|
|
2174
2174
|
]);
|
|
2175
2175
|
const parts = host.split(".");
|
|
2176
|
-
if (parts.length >= 3 && known.has((
|
|
2176
|
+
if (parts.length >= 3 && known.has((_a2 = parts[0]) != null ? _a2 : "")) {
|
|
2177
2177
|
return `; Domain=.${parts.slice(1).join(".")}`;
|
|
2178
2178
|
}
|
|
2179
2179
|
if (parts.length >= 2) return `; Domain=.${parts.slice(1).join(".")}`;
|
|
@@ -2441,8 +2441,8 @@ function consumeSuiteAskAiOpenFromLocation() {
|
|
|
2441
2441
|
}
|
|
2442
2442
|
var pendingAskAiPrompt = null;
|
|
2443
2443
|
function openSuiteAskAi(detail) {
|
|
2444
|
-
var
|
|
2445
|
-
pendingAskAiPrompt = ((
|
|
2444
|
+
var _a2;
|
|
2445
|
+
pendingAskAiPrompt = ((_a2 = detail == null ? void 0 : detail.prompt) == null ? void 0 : _a2.trim()) || null;
|
|
2446
2446
|
if (typeof window === "undefined") return;
|
|
2447
2447
|
window.dispatchEvent(
|
|
2448
2448
|
new CustomEvent(SUITE_OPEN_ASK_AI_EVENT, {
|
|
@@ -2514,9 +2514,9 @@ function SuiteAiPanel({
|
|
|
2514
2514
|
const waiting = loading || isWaitingForReply;
|
|
2515
2515
|
useEffect7(() => {
|
|
2516
2516
|
function onOpen(event) {
|
|
2517
|
-
var
|
|
2517
|
+
var _a2;
|
|
2518
2518
|
const detail = event.detail;
|
|
2519
|
-
const queued = ((
|
|
2519
|
+
const queued = ((_a2 = detail == null ? void 0 : detail.prompt) == null ? void 0 : _a2.trim()) || consumePendingAskAiPrompt();
|
|
2520
2520
|
setOpen(true);
|
|
2521
2521
|
if (queued) {
|
|
2522
2522
|
pendingPromptRef.current = queued;
|
|
@@ -2539,12 +2539,12 @@ function SuiteAiPanel({
|
|
|
2539
2539
|
setAtBottom(distance < 64);
|
|
2540
2540
|
}, []);
|
|
2541
2541
|
const hydrate = useCallback3(async () => {
|
|
2542
|
-
var
|
|
2542
|
+
var _a2, _b, _c;
|
|
2543
2543
|
setHydrating(true);
|
|
2544
2544
|
setError("");
|
|
2545
2545
|
try {
|
|
2546
2546
|
const data = await fetchChat();
|
|
2547
|
-
setMessages((
|
|
2547
|
+
setMessages((_a2 = data.messages) != null ? _a2 : []);
|
|
2548
2548
|
if (!data.configured) {
|
|
2549
2549
|
setError("ShellStack AI is not configured for this workspace yet.");
|
|
2550
2550
|
} else {
|
|
@@ -2562,9 +2562,9 @@ function SuiteAiPanel({
|
|
|
2562
2562
|
}
|
|
2563
2563
|
}, [fetchChat]);
|
|
2564
2564
|
useEffect7(() => {
|
|
2565
|
-
var
|
|
2565
|
+
var _a2;
|
|
2566
2566
|
if (!open) return;
|
|
2567
|
-
const queued = (
|
|
2567
|
+
const queued = (_a2 = pendingPromptRef.current) != null ? _a2 : consumePendingAskAiPrompt();
|
|
2568
2568
|
pendingPromptRef.current = queued;
|
|
2569
2569
|
void hydrate().then(() => {
|
|
2570
2570
|
const pending = pendingPromptRef.current;
|
|
@@ -2576,8 +2576,8 @@ function SuiteAiPanel({
|
|
|
2576
2576
|
if (open && atBottom) scrollToBottom();
|
|
2577
2577
|
}, [messages, waiting, open, atBottom, scrollToBottom]);
|
|
2578
2578
|
useEffect7(() => {
|
|
2579
|
-
var
|
|
2580
|
-
if (open && !hydrating) (
|
|
2579
|
+
var _a2;
|
|
2580
|
+
if (open && !hydrating) (_a2 = textareaRef.current) == null ? void 0 : _a2.focus();
|
|
2581
2581
|
}, [open, hydrating]);
|
|
2582
2582
|
useEffect7(() => {
|
|
2583
2583
|
if (!open) return;
|
|
@@ -2591,7 +2591,7 @@ function SuiteAiPanel({
|
|
|
2591
2591
|
el.style.height = `${Math.min(el.scrollHeight, 176)}px`;
|
|
2592
2592
|
}, [prompt, open]);
|
|
2593
2593
|
async function ask(text) {
|
|
2594
|
-
var
|
|
2594
|
+
var _a2;
|
|
2595
2595
|
const trimmed = text.trim();
|
|
2596
2596
|
if (!trimmed || waiting) return;
|
|
2597
2597
|
const controller = new AbortController();
|
|
@@ -2607,20 +2607,20 @@ function SuiteAiPanel({
|
|
|
2607
2607
|
signal: controller.signal
|
|
2608
2608
|
});
|
|
2609
2609
|
if (controller.signal.aborted) return;
|
|
2610
|
-
const nextMessages = (
|
|
2610
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
2611
2611
|
setMessages(nextMessages);
|
|
2612
2612
|
notifySuiteMutated(
|
|
2613
2613
|
nextMessages.flatMap((message) => {
|
|
2614
|
-
var
|
|
2615
|
-
return (
|
|
2614
|
+
var _a3;
|
|
2615
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
2616
2616
|
})
|
|
2617
2617
|
);
|
|
2618
2618
|
} catch (err) {
|
|
2619
2619
|
if (controller.signal.aborted) return;
|
|
2620
2620
|
setMessages(
|
|
2621
2621
|
(prev) => {
|
|
2622
|
-
var
|
|
2623
|
-
return ((
|
|
2622
|
+
var _a3, _b;
|
|
2623
|
+
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;
|
|
2624
2624
|
}
|
|
2625
2625
|
);
|
|
2626
2626
|
setPrompt(trimmed);
|
|
@@ -2633,8 +2633,8 @@ function SuiteAiPanel({
|
|
|
2633
2633
|
}
|
|
2634
2634
|
}
|
|
2635
2635
|
function stop() {
|
|
2636
|
-
var
|
|
2637
|
-
(
|
|
2636
|
+
var _a2;
|
|
2637
|
+
(_a2 = abortRef.current) == null ? void 0 : _a2.abort();
|
|
2638
2638
|
abortRef.current = null;
|
|
2639
2639
|
setLoading(false);
|
|
2640
2640
|
if (!cancelMessage) return;
|
|
@@ -2644,14 +2644,14 @@ function SuiteAiPanel({
|
|
|
2644
2644
|
});
|
|
2645
2645
|
}
|
|
2646
2646
|
function retry() {
|
|
2647
|
-
var
|
|
2648
|
-
const lastUser = (
|
|
2647
|
+
var _a2;
|
|
2648
|
+
const lastUser = (_a2 = [...messages].reverse().find((message) => message.role === "user")) == null ? void 0 : _a2.content;
|
|
2649
2649
|
setError("");
|
|
2650
2650
|
if (lastUser) void ask(lastUser);
|
|
2651
2651
|
else void hydrate();
|
|
2652
2652
|
}
|
|
2653
2653
|
async function saveEdit(index) {
|
|
2654
|
-
var
|
|
2654
|
+
var _a2;
|
|
2655
2655
|
const trimmed = editDraft.trim();
|
|
2656
2656
|
if (!trimmed || waiting) return;
|
|
2657
2657
|
setEditingIndex(null);
|
|
@@ -2669,12 +2669,12 @@ function SuiteAiPanel({
|
|
|
2669
2669
|
signal: controller.signal
|
|
2670
2670
|
}) : await sendMessage({ prompt: trimmed, signal: controller.signal });
|
|
2671
2671
|
if (controller.signal.aborted) return;
|
|
2672
|
-
const nextMessages = (
|
|
2672
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
2673
2673
|
setMessages(nextMessages);
|
|
2674
2674
|
notifySuiteMutated(
|
|
2675
2675
|
nextMessages.flatMap((message) => {
|
|
2676
|
-
var
|
|
2677
|
-
return (
|
|
2676
|
+
var _a3;
|
|
2677
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
2678
2678
|
})
|
|
2679
2679
|
);
|
|
2680
2680
|
} catch (err) {
|
|
@@ -2712,18 +2712,18 @@ function SuiteAiPanel({
|
|
|
2712
2712
|
}
|
|
2713
2713
|
}
|
|
2714
2714
|
async function handleResolve(actionId, decision) {
|
|
2715
|
-
var
|
|
2715
|
+
var _a2;
|
|
2716
2716
|
if (!resolveAction || resolvingId) return;
|
|
2717
2717
|
setResolvingId(actionId);
|
|
2718
2718
|
setError("");
|
|
2719
2719
|
try {
|
|
2720
2720
|
const result = await resolveAction(actionId, decision);
|
|
2721
|
-
const nextMessages = (
|
|
2721
|
+
const nextMessages = (_a2 = result.messages) != null ? _a2 : [];
|
|
2722
2722
|
setMessages(nextMessages);
|
|
2723
2723
|
notifySuiteMutated(
|
|
2724
2724
|
nextMessages.flatMap((message) => {
|
|
2725
|
-
var
|
|
2726
|
-
return (
|
|
2725
|
+
var _a3;
|
|
2726
|
+
return (_a3 = message.actions) != null ? _a3 : [];
|
|
2727
2727
|
})
|
|
2728
2728
|
);
|
|
2729
2729
|
} catch (err) {
|
|
@@ -2735,12 +2735,12 @@ function SuiteAiPanel({
|
|
|
2735
2735
|
}
|
|
2736
2736
|
}
|
|
2737
2737
|
function onConversationClick(event) {
|
|
2738
|
-
var
|
|
2738
|
+
var _a2;
|
|
2739
2739
|
if (event.defaultPrevented) return;
|
|
2740
2740
|
if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) {
|
|
2741
2741
|
return;
|
|
2742
2742
|
}
|
|
2743
|
-
const anchor = (
|
|
2743
|
+
const anchor = (_a2 = event.target) == null ? void 0 : _a2.closest("a");
|
|
2744
2744
|
if (!anchor || !suiteAppBases) return;
|
|
2745
2745
|
const href = anchor.href;
|
|
2746
2746
|
if (!href) return;
|
|
@@ -2828,7 +2828,7 @@ function SuiteAiPanel({
|
|
|
2828
2828
|
)) }) : null
|
|
2829
2829
|
] }) : null,
|
|
2830
2830
|
messages.map((message, index) => {
|
|
2831
|
-
var
|
|
2831
|
+
var _a2;
|
|
2832
2832
|
const isUser = message.role === "user";
|
|
2833
2833
|
if (isUser) {
|
|
2834
2834
|
if (editingIndex === index) {
|
|
@@ -2961,7 +2961,7 @@ function SuiteAiPanel({
|
|
|
2961
2961
|
)
|
|
2962
2962
|
}
|
|
2963
2963
|
) }),
|
|
2964
|
-
((
|
|
2964
|
+
((_a2 = message.actions) != null ? _a2 : []).map((action) => /* @__PURE__ */ jsxs14(
|
|
2965
2965
|
"div",
|
|
2966
2966
|
{
|
|
2967
2967
|
"data-test": "ask-ai-action",
|
|
@@ -3133,9 +3133,9 @@ function SuiteWorkspaceSwitcher({
|
|
|
3133
3133
|
triggerDataTest,
|
|
3134
3134
|
footer
|
|
3135
3135
|
}) {
|
|
3136
|
-
var
|
|
3136
|
+
var _a2;
|
|
3137
3137
|
const [open, setOpen] = useState9(false);
|
|
3138
|
-
const sections = (
|
|
3138
|
+
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 }] : [];
|
|
3139
3139
|
return /* @__PURE__ */ jsx18(
|
|
3140
3140
|
DropdownMenu2,
|
|
3141
3141
|
{
|
|
@@ -3841,7 +3841,7 @@ function SuiteSidebar({
|
|
|
3841
3841
|
/* @__PURE__ */ jsx23("div", { className: "min-h-0 flex-1", children: askAi })
|
|
3842
3842
|
] }) : /* @__PURE__ */ jsxs19(Fragment7, { children: [
|
|
3843
3843
|
/* @__PURE__ */ jsx23("nav", { "aria-label": "Pages", className: "shrink-0 space-y-1", children: /* @__PURE__ */ jsx23("div", { className: "space-y-1", children: navItems.map((item) => {
|
|
3844
|
-
var
|
|
3844
|
+
var _a2;
|
|
3845
3845
|
const Icon = item.icon;
|
|
3846
3846
|
const active = Boolean(item.active);
|
|
3847
3847
|
const link = /* @__PURE__ */ jsxs19(
|
|
@@ -3849,7 +3849,7 @@ function SuiteSidebar({
|
|
|
3849
3849
|
{
|
|
3850
3850
|
href: item.href,
|
|
3851
3851
|
id: item.id,
|
|
3852
|
-
"data-test": (
|
|
3852
|
+
"data-test": (_a2 = item.dataTest) != null ? _a2 : "nav-link",
|
|
3853
3853
|
"aria-current": active ? "page" : void 0,
|
|
3854
3854
|
onClick: item.onClick,
|
|
3855
3855
|
className: cn2(
|
|
@@ -4067,15 +4067,15 @@ var AUTH_SCHEME_LABELS = {
|
|
|
4067
4067
|
OAUTH2: "OAuth 2.0"
|
|
4068
4068
|
};
|
|
4069
4069
|
function authSchemeLabel(scheme) {
|
|
4070
|
-
var
|
|
4070
|
+
var _a2;
|
|
4071
4071
|
const normalised = scheme.trim().toUpperCase();
|
|
4072
|
-
return (
|
|
4072
|
+
return (_a2 = AUTH_SCHEME_LABELS[normalised]) != null ? _a2 : normalised.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
4073
4073
|
}
|
|
4074
4074
|
function authSchemesFor(item) {
|
|
4075
|
-
var
|
|
4075
|
+
var _a2;
|
|
4076
4076
|
return Array.from(
|
|
4077
4077
|
new Set(
|
|
4078
|
-
((
|
|
4078
|
+
((_a2 = item.authSchemes) != null ? _a2 : []).map((scheme) => scheme.trim().toUpperCase()).filter(Boolean)
|
|
4079
4079
|
)
|
|
4080
4080
|
);
|
|
4081
4081
|
}
|
|
@@ -4098,10 +4098,10 @@ var CATEGORY_APP_AFFINITY = {
|
|
|
4098
4098
|
};
|
|
4099
4099
|
var DEFAULT_APP_AFFINITY = ["tides", "kraken"];
|
|
4100
4100
|
function suiteAppsForIntegration(categories) {
|
|
4101
|
-
var
|
|
4101
|
+
var _a2;
|
|
4102
4102
|
const apps = /* @__PURE__ */ new Set();
|
|
4103
4103
|
for (const category of categories != null ? categories : []) {
|
|
4104
|
-
for (const app of (
|
|
4104
|
+
for (const app of (_a2 = CATEGORY_APP_AFFINITY[category.trim().toLowerCase()]) != null ? _a2 : []) {
|
|
4105
4105
|
apps.add(app);
|
|
4106
4106
|
}
|
|
4107
4107
|
}
|
|
@@ -4158,8 +4158,8 @@ function SuiteIntegrationPicker({
|
|
|
4158
4158
|
const itemCategories = useMemo2(
|
|
4159
4159
|
() => Array.from(
|
|
4160
4160
|
new Set(items.flatMap((item) => {
|
|
4161
|
-
var
|
|
4162
|
-
return (
|
|
4161
|
+
var _a2;
|
|
4162
|
+
return (_a2 = item.categories) != null ? _a2 : [];
|
|
4163
4163
|
}))
|
|
4164
4164
|
).sort(),
|
|
4165
4165
|
[items]
|
|
@@ -4169,8 +4169,8 @@ function SuiteIntegrationPicker({
|
|
|
4169
4169
|
const activeCategory = controlledCategory != null ? controlledCategory : category;
|
|
4170
4170
|
const categoryLabel = (value) => value.replace(/[-_]/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
4171
4171
|
const filtered = onSearchChange || onCategoryChange ? items : items.filter((item) => {
|
|
4172
|
-
var
|
|
4173
|
-
return item.label.toLowerCase().includes(activeSearch.trim().toLowerCase()) && (activeCategory === "all" || ((
|
|
4172
|
+
var _a2;
|
|
4173
|
+
return item.label.toLowerCase().includes(activeSearch.trim().toLowerCase()) && (activeCategory === "all" || ((_a2 = item.categories) != null ? _a2 : []).includes(activeCategory));
|
|
4174
4174
|
});
|
|
4175
4175
|
const visibleCategories = categories.filter(
|
|
4176
4176
|
(value) => categoryLabel(value).toLowerCase().includes(categoryQuery.trim().toLowerCase())
|
|
@@ -4195,7 +4195,7 @@ function SuiteIntegrationPicker({
|
|
|
4195
4195
|
closeCategoryMenu(true);
|
|
4196
4196
|
}
|
|
4197
4197
|
function moveCategoryFocus(event, value) {
|
|
4198
|
-
var
|
|
4198
|
+
var _a2;
|
|
4199
4199
|
const index = categoryValues.indexOf(value);
|
|
4200
4200
|
let nextIndex = null;
|
|
4201
4201
|
if (event.key === "ArrowDown") nextIndex = (index + 1) % categoryValues.length;
|
|
@@ -4205,16 +4205,16 @@ function SuiteIntegrationPicker({
|
|
|
4205
4205
|
else if (event.key === "End") nextIndex = categoryValues.length - 1;
|
|
4206
4206
|
if (nextIndex === null) return;
|
|
4207
4207
|
event.preventDefault();
|
|
4208
|
-
(
|
|
4208
|
+
(_a2 = categoryOptionRefs.current[categoryValues[nextIndex]]) == null ? void 0 : _a2.focus();
|
|
4209
4209
|
}
|
|
4210
4210
|
function handleCategoryTriggerKeyDown(event) {
|
|
4211
|
-
var
|
|
4211
|
+
var _a2;
|
|
4212
4212
|
if (event.key === "ArrowDown") {
|
|
4213
4213
|
event.preventDefault();
|
|
4214
4214
|
openCategoryMenu(activeCategory === "all" ? "all" : activeCategory);
|
|
4215
4215
|
} else if (event.key === "ArrowUp") {
|
|
4216
4216
|
event.preventDefault();
|
|
4217
|
-
openCategoryMenu((
|
|
4217
|
+
openCategoryMenu((_a2 = categoryValues.at(-1)) != null ? _a2 : "all");
|
|
4218
4218
|
} else if (event.key === "Enter" || event.key === " ") {
|
|
4219
4219
|
event.preventDefault();
|
|
4220
4220
|
openCategoryMenu("search");
|
|
@@ -4232,7 +4232,7 @@ function SuiteIntegrationPicker({
|
|
|
4232
4232
|
resetAuthForm();
|
|
4233
4233
|
}
|
|
4234
4234
|
async function prepareConnection(item, scheme) {
|
|
4235
|
-
var
|
|
4235
|
+
var _a2;
|
|
4236
4236
|
setMethodItem(null);
|
|
4237
4237
|
setAuthError(null);
|
|
4238
4238
|
setConnectionError(null);
|
|
@@ -4254,7 +4254,7 @@ function SuiteIntegrationPicker({
|
|
|
4254
4254
|
try {
|
|
4255
4255
|
const details = await onFetchAuthFields(item, scheme);
|
|
4256
4256
|
if (requestId !== authRequestRef.current) return;
|
|
4257
|
-
const resolvedScheme = (
|
|
4257
|
+
const resolvedScheme = (_a2 = details.auth_scheme) != null ? _a2 : scheme;
|
|
4258
4258
|
if (details.managed) {
|
|
4259
4259
|
setAuthItem(null);
|
|
4260
4260
|
await onConnect(item, { auth_scheme: resolvedScheme });
|
|
@@ -4339,8 +4339,8 @@ function SuiteIntegrationPicker({
|
|
|
4339
4339
|
useEffect9(() => {
|
|
4340
4340
|
if (!categoryMenuOpen) return;
|
|
4341
4341
|
const handlePointerDown = (event) => {
|
|
4342
|
-
var
|
|
4343
|
-
if (!((
|
|
4342
|
+
var _a2;
|
|
4343
|
+
if (!((_a2 = categoryMenuRef.current) == null ? void 0 : _a2.contains(event.target))) {
|
|
4344
4344
|
closeCategoryMenu();
|
|
4345
4345
|
}
|
|
4346
4346
|
};
|
|
@@ -4355,11 +4355,11 @@ function SuiteIntegrationPicker({
|
|
|
4355
4355
|
};
|
|
4356
4356
|
}, [categoryMenuOpen]);
|
|
4357
4357
|
useEffect9(() => {
|
|
4358
|
-
var
|
|
4358
|
+
var _a2, _b, _c;
|
|
4359
4359
|
const target = pendingCategoryFocus.current;
|
|
4360
4360
|
if (!target) return;
|
|
4361
4361
|
pendingCategoryFocus.current = null;
|
|
4362
|
-
if (target === "trigger") (
|
|
4362
|
+
if (target === "trigger") (_a2 = categoryTriggerRef.current) == null ? void 0 : _a2.focus();
|
|
4363
4363
|
else if (target === "search") (_b = categorySearchRef.current) == null ? void 0 : _b.focus();
|
|
4364
4364
|
else (_c = categoryOptionRefs.current[target]) == null ? void 0 : _c.focus();
|
|
4365
4365
|
}, [activeCategory, categoryMenuOpen, categoryQuery, visibleCategories]);
|
|
@@ -4472,10 +4472,10 @@ function SuiteIntegrationPicker({
|
|
|
4472
4472
|
placeholder: "Search categories...",
|
|
4473
4473
|
"aria-label": "Search categories",
|
|
4474
4474
|
onKeyDown: (event) => {
|
|
4475
|
-
var
|
|
4475
|
+
var _a2;
|
|
4476
4476
|
if (event.key === "ArrowDown") {
|
|
4477
4477
|
event.preventDefault();
|
|
4478
|
-
(
|
|
4478
|
+
(_a2 = categoryOptionRefs.current[categoryValues[0]]) == null ? void 0 : _a2.focus();
|
|
4479
4479
|
} else if (event.key === "Escape") {
|
|
4480
4480
|
event.preventDefault();
|
|
4481
4481
|
closeCategoryMenu(true);
|
|
@@ -4538,7 +4538,7 @@ function SuiteIntegrationPicker({
|
|
|
4538
4538
|
}
|
|
4539
4539
|
) : /* @__PURE__ */ jsxs21("div", { className: "grid gap-3 sm:grid-cols-2 lg:grid-cols-3", children: [
|
|
4540
4540
|
filtered.map((item) => {
|
|
4541
|
-
var
|
|
4541
|
+
var _a2, _b;
|
|
4542
4542
|
const isExpanded = expanded === item.id;
|
|
4543
4543
|
const longDescription = item.description.length > DESCRIPTION_LIMIT;
|
|
4544
4544
|
const text = isExpanded || !longDescription ? item.description : `${item.description.slice(0, DESCRIPTION_LIMIT).trimEnd()}...`;
|
|
@@ -4555,7 +4555,7 @@ function SuiteIntegrationPicker({
|
|
|
4555
4555
|
onClick: () => longDescription && setExpanded(isExpanded ? null : item.id),
|
|
4556
4556
|
"aria-expanded": isExpanded,
|
|
4557
4557
|
children: /* @__PURE__ */ jsxs21("span", { className: "flex items-start gap-3", children: [
|
|
4558
|
-
/* @__PURE__ */ jsx25("span", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-ph-muted text-ph-ink", children: (
|
|
4558
|
+
/* @__PURE__ */ jsx25("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__ */ jsx25(Plug, { className: "h-5 w-5", "aria-hidden": true }) }),
|
|
4559
4559
|
/* @__PURE__ */ jsxs21("span", { className: "min-w-0", children: [
|
|
4560
4560
|
/* @__PURE__ */ jsx25("span", { className: "block truncate font-medium text-ph-ink", children: item.label }),
|
|
4561
4561
|
/* @__PURE__ */ jsx25("span", { className: "mt-1 block text-xs text-ph-subtle", children: text }),
|
|
@@ -4763,12 +4763,12 @@ function SuiteIntegrationPicker({
|
|
|
4763
4763
|
}
|
|
4764
4764
|
) : null,
|
|
4765
4765
|
authItem.fields.map((field) => {
|
|
4766
|
-
var
|
|
4766
|
+
var _a2, _b;
|
|
4767
4767
|
return /* @__PURE__ */ jsx25(
|
|
4768
4768
|
Input,
|
|
4769
4769
|
{
|
|
4770
4770
|
label: field.label,
|
|
4771
|
-
type: (
|
|
4771
|
+
type: (_a2 = field.type) != null ? _a2 : "password",
|
|
4772
4772
|
required: true,
|
|
4773
4773
|
value: (_b = authValues[field.name]) != null ? _b : "",
|
|
4774
4774
|
onChange: (event) => setAuthValues((current) => __spreadProps(__spreadValues({}, current), {
|
|
@@ -4811,8 +4811,8 @@ var ACTION_LABELS = {
|
|
|
4811
4811
|
create_suite_notification: "Send a suite notification"
|
|
4812
4812
|
};
|
|
4813
4813
|
function actionLabel(actionType) {
|
|
4814
|
-
var
|
|
4815
|
-
return (
|
|
4814
|
+
var _a2;
|
|
4815
|
+
return (_a2 = ACTION_LABELS[actionType]) != null ? _a2 : actionType;
|
|
4816
4816
|
}
|
|
4817
4817
|
function formatDateTime(value) {
|
|
4818
4818
|
if (!value) return "\u2014";
|
|
@@ -5201,225 +5201,583 @@ function SuiteIntegrationRules({
|
|
|
5201
5201
|
|
|
5202
5202
|
// src/suite/components/suite-clients-projects-directory.tsx
|
|
5203
5203
|
import {
|
|
5204
|
-
useEffect as
|
|
5205
|
-
useMemo as
|
|
5206
|
-
useRef as
|
|
5207
|
-
useState as
|
|
5204
|
+
useEffect as useEffect11,
|
|
5205
|
+
useMemo as useMemo4,
|
|
5206
|
+
useRef as useRef6,
|
|
5207
|
+
useState as useState14
|
|
5208
5208
|
} from "react";
|
|
5209
5209
|
import {
|
|
5210
5210
|
ArrowLeft,
|
|
5211
|
-
MediaImagePlus as ImagePlus,
|
|
5212
5211
|
MoreHoriz as MoreHorizontal,
|
|
5213
5212
|
Plus as Plus2,
|
|
5214
|
-
|
|
5213
|
+
Prohibition,
|
|
5214
|
+
Search as Search3,
|
|
5215
5215
|
Trash
|
|
5216
5216
|
} from "iconoir-react";
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
var
|
|
5220
|
-
var
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
[
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
["anvil", "Anvil"],
|
|
5230
|
-
["book", "Book"],
|
|
5231
|
-
["chessboard", "Chessboard"],
|
|
5232
|
-
["cog", "Settings"],
|
|
5233
|
-
["hammer", "Build"],
|
|
5234
|
-
["light-bulb", "Idea"],
|
|
5235
|
-
["microphone", "Communication"],
|
|
5236
|
-
["quill-ink", "Writing"],
|
|
5237
|
-
["scroll-unfurled", "Notes"],
|
|
5238
|
-
["hourglass", "Planning"],
|
|
5239
|
-
["wrench", "Tools"],
|
|
5240
|
-
["archer", "Archer"],
|
|
5241
|
-
["archery-target", "Target"],
|
|
5242
|
-
["axe", "Axe"],
|
|
5243
|
-
["campfire", "Campfire"],
|
|
5244
|
-
["compass", "Compass"],
|
|
5245
|
-
["crossed-swords", "Battle"],
|
|
5246
|
-
["knight-helmet", "Knight"],
|
|
5247
|
-
["mountains", "Mountains"],
|
|
5248
|
-
["shield", "Shield"],
|
|
5249
|
-
["ship-emblem", "Voyage"],
|
|
5250
|
-
["sword", "Sword"],
|
|
5251
|
-
["trophy", "Trophy"],
|
|
5252
|
-
["apple", "Apple"],
|
|
5253
|
-
["butterfly", "Butterfly"],
|
|
5254
|
-
["clover", "Clover"],
|
|
5255
|
-
["dragon", "Dragon"],
|
|
5256
|
-
["fire", "Fire"],
|
|
5257
|
-
["flower", "Flower"],
|
|
5258
|
-
["flowers", "Flowers"],
|
|
5259
|
-
["grass", "Grass"],
|
|
5260
|
-
["leaf", "Leaf"],
|
|
5261
|
-
["pine-tree", "Pine tree"],
|
|
5262
|
-
["sun", "Sun"],
|
|
5263
|
-
["water-drop", "Water"],
|
|
5264
|
-
["aura", "Aura"],
|
|
5265
|
-
["crystal-ball", "Crystal ball"],
|
|
5266
|
-
["diamond", "Diamond"],
|
|
5267
|
-
["explosion", "Explosion"],
|
|
5268
|
-
["fire-symbol", "Fire symbol"],
|
|
5269
|
-
["gem", "Gem"],
|
|
5270
|
-
["lightning-trio", "Lightning"],
|
|
5271
|
-
["potion", "Potion"],
|
|
5272
|
-
["rune-stone", "Rune stone"],
|
|
5273
|
-
["skull", "Skull"],
|
|
5274
|
-
["tentacle", "Tentacle"],
|
|
5275
|
-
["wolf-head", "Wolf"],
|
|
5276
|
-
["anchor", "Anchor"],
|
|
5277
|
-
["beer", "Beer"],
|
|
5278
|
-
["carrot", "Carrot"],
|
|
5279
|
-
["cat", "Cat"],
|
|
5280
|
-
["crown", "Crown"],
|
|
5281
|
-
["gold-bar", "Gold bar"],
|
|
5282
|
-
["helmet", "Helmet"],
|
|
5283
|
-
["key", "Key"],
|
|
5284
|
-
["three-keys", "Keys"]
|
|
5285
|
-
];
|
|
5286
|
-
function isDirectoryIcon(value) {
|
|
5287
|
-
return DIRECTORY_ICON_OPTIONS.some(([name]) => name === value);
|
|
5217
|
+
|
|
5218
|
+
// src/suite/lib/palette-api.ts
|
|
5219
|
+
var _a;
|
|
5220
|
+
var PALETTE_URL = ((_a = process.env.NEXT_PUBLIC_PALETTE_URL) != null ? _a : "http://localhost:8010").replace(/\/$/, "");
|
|
5221
|
+
function toQuery(params) {
|
|
5222
|
+
const query = new URLSearchParams();
|
|
5223
|
+
for (const [key, value] of Object.entries(params != null ? params : {})) {
|
|
5224
|
+
if (value !== void 0 && value !== null && value !== "") {
|
|
5225
|
+
query.set(key, String(value));
|
|
5226
|
+
}
|
|
5227
|
+
}
|
|
5228
|
+
return query.toString();
|
|
5288
5229
|
}
|
|
5289
|
-
function
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5230
|
+
async function paletteGet(path, params) {
|
|
5231
|
+
const suffix = toQuery(params);
|
|
5232
|
+
const response = await fetch(
|
|
5233
|
+
`${PALETTE_URL}${path}${suffix ? `?${suffix}` : ""}`,
|
|
5234
|
+
{ headers: { Accept: "application/json" } }
|
|
5235
|
+
);
|
|
5236
|
+
if (!response.ok) {
|
|
5237
|
+
throw new Error(`Palette request failed (${response.status}).`);
|
|
5238
|
+
}
|
|
5239
|
+
return await response.json();
|
|
5240
|
+
}
|
|
5241
|
+
var cache = /* @__PURE__ */ new Map();
|
|
5242
|
+
async function paletteGetCached(path, params, ttlMs) {
|
|
5243
|
+
const key = `${path}?${toQuery(params)}`;
|
|
5244
|
+
const now = Date.now();
|
|
5245
|
+
const hit = cache.get(key);
|
|
5246
|
+
if (hit && hit.expires > now) return hit.value;
|
|
5247
|
+
const value = await paletteGet(path, params);
|
|
5248
|
+
cache.set(key, { expires: now + ttlMs, value });
|
|
5249
|
+
return value;
|
|
5250
|
+
}
|
|
5251
|
+
function fetchPaletteLibrary(options) {
|
|
5252
|
+
return paletteGetCached("/library", options, 5 * 6e4);
|
|
5253
|
+
}
|
|
5254
|
+
function fetchPaletteCollection(slug, options) {
|
|
5255
|
+
return paletteGetCached(
|
|
5256
|
+
`/collections/${slug}`,
|
|
5257
|
+
options,
|
|
5258
|
+
2 * 6e4
|
|
5259
|
+
);
|
|
5260
|
+
}
|
|
5261
|
+
function findPaletteIcons(options) {
|
|
5262
|
+
return paletteGet("/find", options);
|
|
5263
|
+
}
|
|
5264
|
+
function paletteIconSrc(imageUrl, color) {
|
|
5265
|
+
if (!imageUrl || !color) return imageUrl;
|
|
5266
|
+
if (!imageUrl.includes("/svgrepo/")) return imageUrl;
|
|
5267
|
+
return `${PALETTE_URL}/render?src=${encodeURIComponent(imageUrl)}&color=${encodeURIComponent(color)}`;
|
|
5268
|
+
}
|
|
5269
|
+
|
|
5270
|
+
// src/suite/components/suite-entity-icon.tsx
|
|
5271
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
5272
|
+
function SuiteEntityIcon({
|
|
5273
|
+
imageUrl,
|
|
5274
|
+
label,
|
|
5275
|
+
color,
|
|
5276
|
+
className,
|
|
5277
|
+
roundedClass = "rounded-md",
|
|
5278
|
+
style,
|
|
5279
|
+
tinted = false
|
|
5295
5280
|
}) {
|
|
5296
|
-
const
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5281
|
+
const hasColor = typeof color === "string" && /^#[0-9a-fA-F]{3,8}$/.test(color);
|
|
5282
|
+
const tint = hasColor ? color : null;
|
|
5283
|
+
const neutralBackground = "var(--ph-muted, rgba(127,127,127,0.08))";
|
|
5284
|
+
if (imageUrl) {
|
|
5285
|
+
const src = tinted && tint ? paletteIconSrc(imageUrl, tint) : imageUrl;
|
|
5286
|
+
return /* @__PURE__ */ jsx27(
|
|
5287
|
+
"span",
|
|
5288
|
+
{
|
|
5289
|
+
className: cn(
|
|
5290
|
+
"inline-flex shrink-0 items-center justify-center overflow-hidden leading-none",
|
|
5291
|
+
roundedClass,
|
|
5292
|
+
className
|
|
5293
|
+
),
|
|
5294
|
+
style: __spreadValues({
|
|
5295
|
+
backgroundColor: tint ? `${tint}18` : neutralBackground
|
|
5296
|
+
}, style),
|
|
5297
|
+
children: /* @__PURE__ */ jsx27("img", { src: src != null ? src : void 0, alt: "", className: "h-full w-full object-cover" })
|
|
5298
|
+
}
|
|
5299
|
+
);
|
|
5314
5300
|
}
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5301
|
+
const initial = label == null ? void 0 : label.trim().charAt(0).toUpperCase();
|
|
5302
|
+
return /* @__PURE__ */ jsx27(
|
|
5303
|
+
"span",
|
|
5304
|
+
{
|
|
5305
|
+
className: cn(
|
|
5306
|
+
"inline-flex shrink-0 items-center justify-center font-semibold leading-none",
|
|
5307
|
+
roundedClass,
|
|
5308
|
+
className
|
|
5309
|
+
),
|
|
5310
|
+
style: __spreadValues({
|
|
5311
|
+
color: tint != null ? tint : "var(--ph-mutedtext)",
|
|
5312
|
+
backgroundColor: tint ? `${tint}18` : neutralBackground
|
|
5313
|
+
}, style),
|
|
5314
|
+
"aria-hidden": "true",
|
|
5315
|
+
children: initial ? /* @__PURE__ */ jsx27("span", { className: "text-[0.7em]", children: initial }) : /* @__PURE__ */ jsx27("span", { className: "block h-1.5 w-1.5 rounded-full bg-current opacity-40" })
|
|
5316
|
+
}
|
|
5317
|
+
);
|
|
5318
|
+
}
|
|
5319
|
+
|
|
5320
|
+
// src/suite/components/suite-palette-library.tsx
|
|
5321
|
+
import {
|
|
5322
|
+
useCallback as useCallback6,
|
|
5323
|
+
useEffect as useEffect10,
|
|
5324
|
+
useMemo as useMemo3,
|
|
5325
|
+
useRef as useRef5,
|
|
5326
|
+
useState as useState13
|
|
5327
|
+
} from "react";
|
|
5328
|
+
import { Filter as Filter2, FilterList, NavArrowDown as NavArrowDown3, Search as Search2 } from "iconoir-react";
|
|
5329
|
+
import { Fragment as Fragment9, jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
5330
|
+
var PAGE_SIZE = 60;
|
|
5331
|
+
var DISCOVER_LIMIT = 120;
|
|
5332
|
+
var ICON_TYPES = [
|
|
5333
|
+
{ value: "all", label: "All types" },
|
|
5334
|
+
{ value: "line", label: "Line" },
|
|
5335
|
+
{ value: "solid", label: "Solid" },
|
|
5336
|
+
{ value: "duotone", label: "Duotone" },
|
|
5337
|
+
{ value: "color", label: "Colour" },
|
|
5338
|
+
{ value: "mixed", label: "Mixed" }
|
|
5339
|
+
];
|
|
5340
|
+
function FilterSelect({
|
|
5341
|
+
icon: Icon,
|
|
5342
|
+
label,
|
|
5343
|
+
value,
|
|
5344
|
+
onChange,
|
|
5345
|
+
children
|
|
5346
|
+
}) {
|
|
5347
|
+
return /* @__PURE__ */ jsxs23("div", { className: "relative", children: [
|
|
5348
|
+
/* @__PURE__ */ jsx28(
|
|
5349
|
+
Icon,
|
|
5319
5350
|
{
|
|
5320
|
-
|
|
5321
|
-
"aria-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5351
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
5352
|
+
"aria-hidden": true
|
|
5353
|
+
}
|
|
5354
|
+
),
|
|
5355
|
+
/* @__PURE__ */ jsx28(
|
|
5356
|
+
"select",
|
|
5357
|
+
{
|
|
5358
|
+
"aria-label": label,
|
|
5359
|
+
value,
|
|
5360
|
+
onChange: (event) => onChange(event.target.value),
|
|
5361
|
+
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",
|
|
5362
|
+
children
|
|
5363
|
+
}
|
|
5364
|
+
),
|
|
5365
|
+
/* @__PURE__ */ jsx28(
|
|
5366
|
+
NavArrowDown3,
|
|
5367
|
+
{
|
|
5368
|
+
className: "pointer-events-none absolute right-2 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-ph-mutedtext",
|
|
5369
|
+
"aria-hidden": true
|
|
5370
|
+
}
|
|
5371
|
+
)
|
|
5372
|
+
] });
|
|
5373
|
+
}
|
|
5374
|
+
function SuitePaletteLibrary({
|
|
5375
|
+
onPick
|
|
5376
|
+
}) {
|
|
5377
|
+
var _a2, _b;
|
|
5378
|
+
const [collections, setCollections] = useState13([]);
|
|
5379
|
+
const [typeFilter, setTypeFilter] = useState13("all");
|
|
5380
|
+
const [collectionFilter, setCollectionFilter] = useState13("");
|
|
5381
|
+
const [libraryOpen, setLibraryOpen] = useState13(false);
|
|
5382
|
+
const [libraryQuery, setLibraryQuery] = useState13("");
|
|
5383
|
+
const libraryRef = useRef5(null);
|
|
5384
|
+
const [icons, setIcons] = useState13([]);
|
|
5385
|
+
const [total, setTotal] = useState13(0);
|
|
5386
|
+
const [page, setPage] = useState13(1);
|
|
5387
|
+
const [query, setQuery] = useState13("");
|
|
5388
|
+
const [loading, setLoading] = useState13(true);
|
|
5389
|
+
const [loadingMore, setLoadingMore] = useState13(false);
|
|
5390
|
+
const [error, setError] = useState13(null);
|
|
5391
|
+
const requestId = useRef5(0);
|
|
5392
|
+
const libraryOptions = useMemo3(() => {
|
|
5393
|
+
const list = collections.filter(
|
|
5394
|
+
(item) => typeFilter === "all" || item.style === typeFilter
|
|
5395
|
+
);
|
|
5396
|
+
return [...list].sort(
|
|
5397
|
+
(a, b) => Number(b.featured) - Number(a.featured) || a.name.localeCompare(b.name)
|
|
5398
|
+
);
|
|
5399
|
+
}, [collections, typeFilter]);
|
|
5400
|
+
const discoverIcons = useMemo3(() => {
|
|
5401
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5402
|
+
const out = [];
|
|
5403
|
+
for (const collection of libraryOptions) {
|
|
5404
|
+
for (const url of collection.preview) {
|
|
5405
|
+
if (seen.has(url)) continue;
|
|
5406
|
+
seen.add(url);
|
|
5407
|
+
out.push({ id: url, name: collection.name, tags: [], url });
|
|
5408
|
+
if (out.length >= DISCOVER_LIMIT) return out;
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
return out;
|
|
5412
|
+
}, [libraryOptions]);
|
|
5413
|
+
const loadCollection = useCallback6(async (slug, nextPage = 1) => {
|
|
5414
|
+
const id = ++requestId.current;
|
|
5415
|
+
if (nextPage === 1) {
|
|
5416
|
+
setLoading(true);
|
|
5417
|
+
setIcons([]);
|
|
5418
|
+
} else {
|
|
5419
|
+
setLoadingMore(true);
|
|
5420
|
+
}
|
|
5421
|
+
setError(null);
|
|
5422
|
+
try {
|
|
5423
|
+
const detail = await fetchPaletteCollection(slug, {
|
|
5424
|
+
page: nextPage,
|
|
5425
|
+
size: PAGE_SIZE
|
|
5426
|
+
});
|
|
5427
|
+
if (id !== requestId.current) return;
|
|
5428
|
+
setTotal(detail.count);
|
|
5429
|
+
setPage(nextPage);
|
|
5430
|
+
setIcons(
|
|
5431
|
+
(current) => nextPage === 1 ? detail.icons : [...current, ...detail.icons]
|
|
5432
|
+
);
|
|
5433
|
+
} catch (err) {
|
|
5434
|
+
if (id === requestId.current) {
|
|
5435
|
+
setError(err instanceof Error ? err.message : "Could not load icons.");
|
|
5436
|
+
}
|
|
5437
|
+
} finally {
|
|
5438
|
+
if (id === requestId.current) {
|
|
5439
|
+
setLoading(false);
|
|
5440
|
+
setLoadingMore(false);
|
|
5441
|
+
}
|
|
5442
|
+
}
|
|
5443
|
+
}, []);
|
|
5444
|
+
useEffect10(() => {
|
|
5445
|
+
let cancelled = false;
|
|
5446
|
+
fetchPaletteLibrary().then((library) => {
|
|
5447
|
+
if (cancelled) return;
|
|
5448
|
+
setCollections(library.collections);
|
|
5449
|
+
}).catch((err) => {
|
|
5450
|
+
if (cancelled) return;
|
|
5451
|
+
setError(err instanceof Error ? err.message : "Could not load the library.");
|
|
5452
|
+
setLoading(false);
|
|
5453
|
+
});
|
|
5454
|
+
return () => {
|
|
5455
|
+
cancelled = true;
|
|
5456
|
+
};
|
|
5457
|
+
}, []);
|
|
5458
|
+
useEffect10(() => {
|
|
5459
|
+
if (!collections.length) return;
|
|
5460
|
+
if (collectionFilter && !libraryOptions.some((c) => c.slug === collectionFilter)) {
|
|
5461
|
+
setCollectionFilter("");
|
|
5462
|
+
}
|
|
5463
|
+
}, [libraryOptions, collectionFilter, collections.length]);
|
|
5464
|
+
useEffect10(() => {
|
|
5465
|
+
if (query.trim()) return;
|
|
5466
|
+
if (collectionFilter) {
|
|
5467
|
+
void loadCollection(collectionFilter, 1);
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
requestId.current += 1;
|
|
5471
|
+
setLoading(false);
|
|
5472
|
+
setPage(1);
|
|
5473
|
+
setIcons(discoverIcons);
|
|
5474
|
+
setTotal(discoverIcons.length);
|
|
5475
|
+
}, [collectionFilter, query, loadCollection, discoverIcons]);
|
|
5476
|
+
useEffect10(() => {
|
|
5477
|
+
const term = query.trim();
|
|
5478
|
+
if (!term) return;
|
|
5479
|
+
const id = ++requestId.current;
|
|
5480
|
+
setLoading(true);
|
|
5481
|
+
setError(null);
|
|
5482
|
+
const handle = setTimeout(async () => {
|
|
5483
|
+
try {
|
|
5484
|
+
const results = await findPaletteIcons({
|
|
5485
|
+
q: term,
|
|
5486
|
+
collection: collectionFilter || void 0,
|
|
5487
|
+
style: typeFilter === "all" ? void 0 : typeFilter,
|
|
5488
|
+
limit: 120
|
|
5489
|
+
});
|
|
5490
|
+
if (id !== requestId.current) return;
|
|
5491
|
+
setTotal(results.total);
|
|
5492
|
+
setPage(1);
|
|
5493
|
+
setIcons(
|
|
5494
|
+
results.results.map((hit) => ({
|
|
5495
|
+
id: `${hit.collection}/${hit.id}`,
|
|
5496
|
+
name: hit.name,
|
|
5497
|
+
tags: hit.tags,
|
|
5498
|
+
url: hit.url
|
|
5499
|
+
}))
|
|
5500
|
+
);
|
|
5501
|
+
} catch (err) {
|
|
5502
|
+
if (id === requestId.current) {
|
|
5503
|
+
setError(err instanceof Error ? err.message : "Search failed.");
|
|
5504
|
+
}
|
|
5505
|
+
} finally {
|
|
5506
|
+
if (id === requestId.current) setLoading(false);
|
|
5507
|
+
}
|
|
5508
|
+
}, 250);
|
|
5509
|
+
return () => clearTimeout(handle);
|
|
5510
|
+
}, [query, collectionFilter, typeFilter]);
|
|
5511
|
+
const searching = Boolean(query.trim());
|
|
5512
|
+
const activeLibrary = (_a2 = collections.find((c) => c.slug === collectionFilter)) != null ? _a2 : null;
|
|
5513
|
+
const filteredLibraries = useMemo3(() => {
|
|
5514
|
+
const term = libraryQuery.trim().toLowerCase();
|
|
5515
|
+
if (!term) return libraryOptions;
|
|
5516
|
+
return libraryOptions.filter((c) => c.name.toLowerCase().includes(term));
|
|
5517
|
+
}, [libraryOptions, libraryQuery]);
|
|
5518
|
+
useEffect10(() => {
|
|
5519
|
+
if (!libraryOpen) return;
|
|
5520
|
+
const onPointerDown = (event) => {
|
|
5521
|
+
var _a3;
|
|
5522
|
+
if (!((_a3 = libraryRef.current) == null ? void 0 : _a3.contains(event.target))) setLibraryOpen(false);
|
|
5523
|
+
};
|
|
5524
|
+
document.addEventListener("pointerdown", onPointerDown);
|
|
5525
|
+
return () => document.removeEventListener("pointerdown", onPointerDown);
|
|
5526
|
+
}, [libraryOpen]);
|
|
5527
|
+
return /* @__PURE__ */ jsxs23("div", { className: "space-y-3", "data-test": "palette-icon-library", children: [
|
|
5528
|
+
/* @__PURE__ */ jsxs23("div", { ref: libraryRef, className: "space-y-2", children: [
|
|
5529
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-2 sm:flex-row", children: [
|
|
5530
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative flex-1", children: [
|
|
5531
|
+
/* @__PURE__ */ jsx28(
|
|
5532
|
+
Search2,
|
|
5327
5533
|
{
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5534
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
5535
|
+
"aria-hidden": true
|
|
5536
|
+
}
|
|
5537
|
+
),
|
|
5538
|
+
/* @__PURE__ */ jsx28(
|
|
5539
|
+
"input",
|
|
5540
|
+
{
|
|
5541
|
+
type: "search",
|
|
5542
|
+
value: query,
|
|
5543
|
+
onChange: (event) => setQuery(event.target.value),
|
|
5544
|
+
placeholder: "Search icons \u2014 handshake, rocket, briefcase\u2026",
|
|
5545
|
+
"aria-label": "Search icons",
|
|
5546
|
+
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"
|
|
5547
|
+
}
|
|
5548
|
+
)
|
|
5549
|
+
] }),
|
|
5550
|
+
/* @__PURE__ */ jsxs23(
|
|
5551
|
+
"button",
|
|
5552
|
+
{
|
|
5553
|
+
type: "button",
|
|
5554
|
+
"aria-haspopup": "listbox",
|
|
5555
|
+
"aria-expanded": libraryOpen,
|
|
5556
|
+
onClick: () => setLibraryOpen((open) => !open),
|
|
5557
|
+
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",
|
|
5558
|
+
children: [
|
|
5559
|
+
/* @__PURE__ */ jsx28(FilterList, { className: "h-4 w-4 shrink-0 text-ph-mutedtext", "aria-hidden": true }),
|
|
5560
|
+
/* @__PURE__ */ jsx28("span", { className: "max-w-[10rem] truncate", children: (_b = activeLibrary == null ? void 0 : activeLibrary.name) != null ? _b : "All libraries" }),
|
|
5561
|
+
/* @__PURE__ */ jsx28(
|
|
5562
|
+
NavArrowDown3,
|
|
5345
5563
|
{
|
|
5346
|
-
className: cn(
|
|
5564
|
+
className: cn(
|
|
5565
|
+
"h-3.5 w-3.5 shrink-0 text-ph-mutedtext transition-transform",
|
|
5566
|
+
libraryOpen && "rotate-180"
|
|
5567
|
+
),
|
|
5347
5568
|
"aria-hidden": true
|
|
5348
5569
|
}
|
|
5349
5570
|
)
|
|
5350
|
-
|
|
5351
|
-
name
|
|
5352
|
-
);
|
|
5353
|
-
})
|
|
5354
|
-
}
|
|
5355
|
-
),
|
|
5356
|
-
/* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-ph-border bg-ph-muted p-2", children: [
|
|
5357
|
-
/* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 text-sm font-medium text-ph-ink", children: [
|
|
5358
|
-
/* @__PURE__ */ jsx27(ImagePlus, { className: "h-4 w-4", "aria-hidden": true }),
|
|
5359
|
-
" Custom image"
|
|
5360
|
-
] }),
|
|
5361
|
-
/* @__PURE__ */ jsx27("p", { className: "mt-1 text-xs text-ph-mutedtext", children: "PNG, JPG, GIF, WebP, or SVG \u2014 max 512 KB." }),
|
|
5362
|
-
/* @__PURE__ */ jsx27(
|
|
5363
|
-
FileUpload,
|
|
5364
|
-
{
|
|
5365
|
-
accept: "image/png,image/jpeg,image/gif,image/webp,image/svg+xml,.svg",
|
|
5366
|
-
onChange: (event) => {
|
|
5367
|
-
var _a, _b;
|
|
5368
|
-
return onFileChange((_b = (_a = event.target.files) == null ? void 0 : _a[0]) != null ? _b : null);
|
|
5571
|
+
]
|
|
5369
5572
|
}
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
/* @__PURE__ */ jsx27(
|
|
5374
|
-
"img",
|
|
5573
|
+
),
|
|
5574
|
+
/* @__PURE__ */ jsx28(
|
|
5575
|
+
FilterSelect,
|
|
5375
5576
|
{
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5577
|
+
icon: Filter2,
|
|
5578
|
+
label: "Filter by icon type",
|
|
5579
|
+
value: typeFilter,
|
|
5580
|
+
onChange: setTypeFilter,
|
|
5581
|
+
children: ICON_TYPES.map((type) => /* @__PURE__ */ jsx28("option", { value: type.value, children: type.label }, type.value))
|
|
5379
5582
|
}
|
|
5380
|
-
)
|
|
5583
|
+
)
|
|
5584
|
+
] }),
|
|
5585
|
+
libraryOpen ? /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-ph-border bg-ph-surface p-2", children: [
|
|
5586
|
+
/* @__PURE__ */ jsxs23("div", { className: "relative mb-2", children: [
|
|
5587
|
+
/* @__PURE__ */ jsx28(
|
|
5588
|
+
Search2,
|
|
5589
|
+
{
|
|
5590
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
5591
|
+
"aria-hidden": true
|
|
5592
|
+
}
|
|
5593
|
+
),
|
|
5594
|
+
/* @__PURE__ */ jsx28(
|
|
5595
|
+
"input",
|
|
5596
|
+
{
|
|
5597
|
+
type: "search",
|
|
5598
|
+
autoFocus: true,
|
|
5599
|
+
value: libraryQuery,
|
|
5600
|
+
onChange: (event) => setLibraryQuery(event.target.value),
|
|
5601
|
+
placeholder: "Search libraries\u2026",
|
|
5602
|
+
"aria-label": "Search libraries",
|
|
5603
|
+
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"
|
|
5604
|
+
}
|
|
5605
|
+
)
|
|
5606
|
+
] }),
|
|
5381
5607
|
/* @__PURE__ */ jsxs23(
|
|
5382
|
-
"
|
|
5608
|
+
"ul",
|
|
5383
5609
|
{
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5610
|
+
role: "listbox",
|
|
5611
|
+
"aria-label": "Libraries",
|
|
5612
|
+
className: "max-h-56 overflow-y-auto",
|
|
5387
5613
|
children: [
|
|
5388
|
-
/* @__PURE__ */
|
|
5389
|
-
|
|
5614
|
+
/* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsx28(
|
|
5615
|
+
"button",
|
|
5616
|
+
{
|
|
5617
|
+
type: "button",
|
|
5618
|
+
role: "option",
|
|
5619
|
+
"aria-selected": !collectionFilter,
|
|
5620
|
+
onClick: () => {
|
|
5621
|
+
setCollectionFilter("");
|
|
5622
|
+
setLibraryOpen(false);
|
|
5623
|
+
},
|
|
5624
|
+
className: cn(
|
|
5625
|
+
"flex w-full items-center rounded-md px-2 py-1.5 text-left text-sm",
|
|
5626
|
+
!collectionFilter ? "bg-ph-muted text-ph-ink" : "text-ph-ink hover:bg-ph-muted"
|
|
5627
|
+
),
|
|
5628
|
+
children: "All libraries"
|
|
5629
|
+
}
|
|
5630
|
+
) }),
|
|
5631
|
+
filteredLibraries.map((collection) => /* @__PURE__ */ jsx28("li", { children: /* @__PURE__ */ jsxs23(
|
|
5632
|
+
"button",
|
|
5633
|
+
{
|
|
5634
|
+
type: "button",
|
|
5635
|
+
role: "option",
|
|
5636
|
+
"aria-selected": collectionFilter === collection.slug,
|
|
5637
|
+
onClick: () => {
|
|
5638
|
+
setCollectionFilter(collection.slug);
|
|
5639
|
+
setLibraryOpen(false);
|
|
5640
|
+
},
|
|
5641
|
+
className: cn(
|
|
5642
|
+
"flex w-full items-center justify-between gap-2 rounded-md px-2 py-1.5 text-left text-sm",
|
|
5643
|
+
collectionFilter === collection.slug ? "bg-ph-muted text-ph-ink" : "text-ph-ink hover:bg-ph-muted"
|
|
5644
|
+
),
|
|
5645
|
+
children: [
|
|
5646
|
+
/* @__PURE__ */ jsx28("span", { className: "truncate", children: collection.name }),
|
|
5647
|
+
/* @__PURE__ */ jsx28("span", { className: "shrink-0 text-xs text-ph-mutedtext", children: collection.count })
|
|
5648
|
+
]
|
|
5649
|
+
}
|
|
5650
|
+
) }, collection.slug)),
|
|
5651
|
+
filteredLibraries.length === 0 ? /* @__PURE__ */ jsx28("li", { className: "px-2 py-4 text-center text-sm text-ph-mutedtext", children: "No libraries match." }) : null
|
|
5390
5652
|
]
|
|
5391
5653
|
}
|
|
5392
5654
|
)
|
|
5393
5655
|
] }) : null
|
|
5656
|
+
] }),
|
|
5657
|
+
error ? /* @__PURE__ */ jsx28("p", { className: "text-sm text-ph-danger", children: error }) : loading ? /* @__PURE__ */ jsx28("p", { className: "py-8 text-center text-sm text-ph-mutedtext", children: "Loading icons\u2026" }) : icons.length === 0 ? /* @__PURE__ */ jsx28("p", { className: "py-8 text-center text-sm text-ph-mutedtext", children: "No icons matched. Try another word or filter." }) : /* @__PURE__ */ jsxs23(Fragment9, { children: [
|
|
5658
|
+
/* @__PURE__ */ jsx28("div", { className: "max-h-[320px] overflow-y-auto rounded-lg border border-ph-border p-2", children: /* @__PURE__ */ jsx28("div", { className: "grid grid-cols-6 gap-1.5 sm:grid-cols-8", children: icons.map((icon) => /* @__PURE__ */ jsx28(
|
|
5659
|
+
"button",
|
|
5660
|
+
{
|
|
5661
|
+
type: "button",
|
|
5662
|
+
onClick: () => onPick({ url: icon.url, name: icon.name }),
|
|
5663
|
+
title: icon.name,
|
|
5664
|
+
"aria-label": `Use ${icon.name}`,
|
|
5665
|
+
className: "flex h-10 items-center justify-center rounded-md border border-transparent p-1.5 hover:border-ph-brand hover:bg-ph-muted",
|
|
5666
|
+
children: /* @__PURE__ */ jsx28(
|
|
5667
|
+
"img",
|
|
5668
|
+
{
|
|
5669
|
+
src: icon.url,
|
|
5670
|
+
alt: "",
|
|
5671
|
+
loading: "lazy",
|
|
5672
|
+
decoding: "async",
|
|
5673
|
+
className: "h-6 w-6"
|
|
5674
|
+
}
|
|
5675
|
+
)
|
|
5676
|
+
},
|
|
5677
|
+
icon.id
|
|
5678
|
+
)) }) }),
|
|
5679
|
+
/* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between text-xs text-ph-mutedtext", children: [
|
|
5680
|
+
/* @__PURE__ */ jsxs23("span", { children: [
|
|
5681
|
+
icons.length,
|
|
5682
|
+
" of ",
|
|
5683
|
+
total,
|
|
5684
|
+
searching ? " matching" : activeLibrary ? ` in ${activeLibrary.name}` : " across all libraries"
|
|
5685
|
+
] }),
|
|
5686
|
+
!searching && activeLibrary && icons.length < total ? /* @__PURE__ */ jsx28(
|
|
5687
|
+
"button",
|
|
5688
|
+
{
|
|
5689
|
+
type: "button",
|
|
5690
|
+
disabled: loadingMore,
|
|
5691
|
+
onClick: () => void loadCollection(activeLibrary.slug, page + 1),
|
|
5692
|
+
className: cn(
|
|
5693
|
+
"font-medium text-ph-brand hover:underline",
|
|
5694
|
+
loadingMore && "opacity-50"
|
|
5695
|
+
),
|
|
5696
|
+
children: loadingMore ? "Loading\u2026" : "Load more"
|
|
5697
|
+
}
|
|
5698
|
+
) : null
|
|
5699
|
+
] })
|
|
5394
5700
|
] })
|
|
5395
5701
|
] });
|
|
5396
5702
|
}
|
|
5397
|
-
|
|
5398
|
-
|
|
5703
|
+
|
|
5704
|
+
// src/suite/components/suite-clients-projects-directory.tsx
|
|
5705
|
+
import { Fragment as Fragment10, jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
5706
|
+
var DEFAULT_ICON = "";
|
|
5707
|
+
var DEFAULT_COLOR = "#6366f1";
|
|
5708
|
+
function DirectoryIconPicker({
|
|
5709
|
+
preview,
|
|
5710
|
+
label,
|
|
5711
|
+
color,
|
|
5712
|
+
onFileChange,
|
|
5713
|
+
onClear,
|
|
5714
|
+
onBrowse
|
|
5399
5715
|
}) {
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
"
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
children: item.icon_image ? (
|
|
5407
|
-
// eslint-disable-next-line @next/next/no-img-element
|
|
5408
|
-
/* @__PURE__ */ jsx27(
|
|
5409
|
-
"img",
|
|
5716
|
+
return /* @__PURE__ */ jsxs24("div", { className: "space-y-2", children: [
|
|
5717
|
+
/* @__PURE__ */ jsx29("span", { className: "mb-1.5 block text-sm font-medium text-ph-ink", children: "Icon" }),
|
|
5718
|
+
/* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-ph-border bg-ph-muted p-3", children: [
|
|
5719
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex items-center gap-3", children: [
|
|
5720
|
+
/* @__PURE__ */ jsx29(
|
|
5721
|
+
SuiteEntityIcon,
|
|
5410
5722
|
{
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5723
|
+
imageUrl: preview,
|
|
5724
|
+
label,
|
|
5725
|
+
color,
|
|
5726
|
+
tinted: true,
|
|
5727
|
+
className: "h-9 w-9 text-base"
|
|
5414
5728
|
}
|
|
5415
|
-
)
|
|
5416
|
-
|
|
5417
|
-
|
|
5729
|
+
),
|
|
5730
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
5731
|
+
/* @__PURE__ */ jsx29("p", { className: "text-sm font-medium text-ph-ink", children: preview ? "Custom image" : "No icon yet" }),
|
|
5732
|
+
/* @__PURE__ */ jsx29("p", { className: "text-xs text-ph-mutedtext", children: preview ? "Shown on cards and lists." : "Browse the library or upload your own." })
|
|
5733
|
+
] }),
|
|
5734
|
+
onBrowse ? /* @__PURE__ */ jsx29(
|
|
5735
|
+
"button",
|
|
5736
|
+
{
|
|
5737
|
+
type: "button",
|
|
5738
|
+
onClick: onBrowse,
|
|
5739
|
+
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",
|
|
5740
|
+
children: "Browse library"
|
|
5741
|
+
}
|
|
5742
|
+
) : null
|
|
5743
|
+
] }),
|
|
5744
|
+
/* @__PURE__ */ jsx29("div", { className: "mt-3", children: /* @__PURE__ */ jsx29(
|
|
5745
|
+
FileUpload,
|
|
5418
5746
|
{
|
|
5419
|
-
|
|
5420
|
-
|
|
5747
|
+
accept: "image/png,image/jpeg,image/gif,image/webp,image/svg+xml,.svg",
|
|
5748
|
+
onChange: (event) => {
|
|
5749
|
+
var _a2, _b;
|
|
5750
|
+
return onFileChange((_b = (_a2 = event.target.files) == null ? void 0 : _a2[0]) != null ? _b : null);
|
|
5751
|
+
}
|
|
5421
5752
|
}
|
|
5422
|
-
)
|
|
5753
|
+
) }),
|
|
5754
|
+
preview ? /* @__PURE__ */ jsxs24(
|
|
5755
|
+
"button",
|
|
5756
|
+
{
|
|
5757
|
+
type: "button",
|
|
5758
|
+
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",
|
|
5759
|
+
onClick: onClear,
|
|
5760
|
+
children: [
|
|
5761
|
+
/* @__PURE__ */ jsx29(Trash, { className: "h-3.5 w-3.5", "aria-hidden": true }),
|
|
5762
|
+
" Remove image"
|
|
5763
|
+
]
|
|
5764
|
+
}
|
|
5765
|
+
) : null
|
|
5766
|
+
] })
|
|
5767
|
+
] });
|
|
5768
|
+
}
|
|
5769
|
+
function DirectoryIcon({
|
|
5770
|
+
item
|
|
5771
|
+
}) {
|
|
5772
|
+
return /* @__PURE__ */ jsx29(
|
|
5773
|
+
SuiteEntityIcon,
|
|
5774
|
+
{
|
|
5775
|
+
imageUrl: item.icon_image,
|
|
5776
|
+
label: item.name,
|
|
5777
|
+
color: item.color,
|
|
5778
|
+
tinted: true,
|
|
5779
|
+
className: "h-8 w-8 text-sm",
|
|
5780
|
+
roundedClass: "rounded-lg"
|
|
5423
5781
|
}
|
|
5424
5782
|
);
|
|
5425
5783
|
}
|
|
@@ -5435,51 +5793,53 @@ function SuiteClientsProjectsDirectory({
|
|
|
5435
5793
|
onCreateProject,
|
|
5436
5794
|
onUpdateProject,
|
|
5437
5795
|
onDeleteProject,
|
|
5796
|
+
renderIconLibrary,
|
|
5438
5797
|
dataTest = "suite-clients-projects-directory"
|
|
5439
5798
|
}) {
|
|
5440
|
-
var
|
|
5441
|
-
const [query, setQuery] =
|
|
5442
|
-
const [selectedClientId, setSelectedClientId] =
|
|
5443
|
-
const [mobileDetail, setMobileDetail] =
|
|
5444
|
-
const [editing, setEditing] =
|
|
5445
|
-
const [draft, setDraft] =
|
|
5799
|
+
var _a2;
|
|
5800
|
+
const [query, setQuery] = useState14("");
|
|
5801
|
+
const [selectedClientId, setSelectedClientId] = useState14(null);
|
|
5802
|
+
const [mobileDetail, setMobileDetail] = useState14(false);
|
|
5803
|
+
const [editing, setEditing] = useState14(null);
|
|
5804
|
+
const [draft, setDraft] = useState14({
|
|
5446
5805
|
name: "",
|
|
5447
5806
|
icon: DEFAULT_ICON,
|
|
5448
5807
|
color: DEFAULT_COLOR
|
|
5449
5808
|
});
|
|
5450
|
-
const [draftClientId, setDraftClientId] =
|
|
5451
|
-
const [preview, setPreview] =
|
|
5452
|
-
const [
|
|
5453
|
-
const [
|
|
5454
|
-
const [
|
|
5455
|
-
const [
|
|
5456
|
-
const
|
|
5457
|
-
const
|
|
5458
|
-
const
|
|
5459
|
-
|
|
5460
|
-
|
|
5809
|
+
const [draftClientId, setDraftClientId] = useState14(null);
|
|
5810
|
+
const [preview, setPreview] = useState14(null);
|
|
5811
|
+
const [libraryOpen, setLibraryOpen] = useState14(false);
|
|
5812
|
+
const [draftArchived, setDraftArchived] = useState14(false);
|
|
5813
|
+
const [confirming, setConfirming] = useState14(null);
|
|
5814
|
+
const [saving, setSaving] = useState14(false);
|
|
5815
|
+
const [mutationError, setMutationError] = useState14(null);
|
|
5816
|
+
const clientButtonRefs = useRef6({});
|
|
5817
|
+
const backToClientsRef = useRef6(null);
|
|
5818
|
+
const mobileFocusTarget = useRef6(null);
|
|
5819
|
+
useEffect11(() => {
|
|
5820
|
+
var _a3, _b;
|
|
5461
5821
|
if (selectedClientId && clients.some((client) => client.id === selectedClientId))
|
|
5462
5822
|
return;
|
|
5463
|
-
setSelectedClientId((_b = (
|
|
5823
|
+
setSelectedClientId((_b = (_a3 = clients[0]) == null ? void 0 : _a3.id) != null ? _b : null);
|
|
5464
5824
|
}, [clients, selectedClientId]);
|
|
5465
|
-
|
|
5466
|
-
var
|
|
5825
|
+
useEffect11(() => {
|
|
5826
|
+
var _a3, _b;
|
|
5467
5827
|
const target = mobileFocusTarget.current;
|
|
5468
5828
|
if (!target) return;
|
|
5469
5829
|
mobileFocusTarget.current = null;
|
|
5470
|
-
if (target === "detail") (
|
|
5830
|
+
if (target === "detail") (_a3 = backToClientsRef.current) == null ? void 0 : _a3.focus();
|
|
5471
5831
|
else if (selectedClientId)
|
|
5472
5832
|
(_b = clientButtonRefs.current[selectedClientId]) == null ? void 0 : _b.focus();
|
|
5473
5833
|
}, [mobileDetail, selectedClientId]);
|
|
5474
|
-
const filteredClients =
|
|
5834
|
+
const filteredClients = useMemo4(() => {
|
|
5475
5835
|
const value = query.trim().toLowerCase();
|
|
5476
5836
|
return [...clients].sort((a, b) => a.name.localeCompare(b.name)).filter((client) => !value || client.name.toLowerCase().includes(value));
|
|
5477
5837
|
}, [clients, query]);
|
|
5478
|
-
const selectedClient = (
|
|
5838
|
+
const selectedClient = (_a2 = clients.find((client) => client.id === selectedClientId)) != null ? _a2 : null;
|
|
5479
5839
|
const selectedProjects = projects.filter((project) => project.clientId === selectedClientId).sort((a, b) => a.name.localeCompare(b.name));
|
|
5480
5840
|
function isMobileDirectoryView() {
|
|
5481
|
-
var
|
|
5482
|
-
return (_b = (
|
|
5841
|
+
var _a3, _b;
|
|
5842
|
+
return (_b = (_a3 = window.matchMedia) == null ? void 0 : _a3.call(window, "(max-width: 1023px)").matches) != null ? _b : false;
|
|
5483
5843
|
}
|
|
5484
5844
|
function selectClient(client) {
|
|
5485
5845
|
setSelectedClientId(client.id);
|
|
@@ -5487,7 +5847,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5487
5847
|
if (isMobileDirectoryView()) mobileFocusTarget.current = "detail";
|
|
5488
5848
|
}
|
|
5489
5849
|
function moveClientSelection(event, index) {
|
|
5490
|
-
var
|
|
5850
|
+
var _a3;
|
|
5491
5851
|
let nextIndex = null;
|
|
5492
5852
|
if (event.key === "ArrowDown") {
|
|
5493
5853
|
nextIndex = (index + 1) % filteredClients.length;
|
|
@@ -5502,7 +5862,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5502
5862
|
event.preventDefault();
|
|
5503
5863
|
const client = filteredClients[nextIndex];
|
|
5504
5864
|
selectClient(client);
|
|
5505
|
-
if (!isMobileDirectoryView()) (
|
|
5865
|
+
if (!isMobileDirectoryView()) (_a3 = clientButtonRefs.current[client.id]) == null ? void 0 : _a3.focus();
|
|
5506
5866
|
}
|
|
5507
5867
|
function openNew(kind) {
|
|
5508
5868
|
setMutationError(null);
|
|
@@ -5511,6 +5871,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5511
5871
|
icon: DEFAULT_ICON,
|
|
5512
5872
|
color: DEFAULT_COLOR,
|
|
5513
5873
|
iconImageFile: null,
|
|
5874
|
+
iconImageUrl: null,
|
|
5514
5875
|
clearIconImage: false
|
|
5515
5876
|
});
|
|
5516
5877
|
setPreview(null);
|
|
@@ -5519,13 +5880,14 @@ function SuiteClientsProjectsDirectory({
|
|
|
5519
5880
|
setEditing({ kind: kind === "client" ? "new-client" : "new-project" });
|
|
5520
5881
|
}
|
|
5521
5882
|
function openEdit(item, kind) {
|
|
5522
|
-
var
|
|
5883
|
+
var _a3, _b;
|
|
5523
5884
|
setMutationError(null);
|
|
5524
5885
|
setDraft({
|
|
5525
5886
|
name: item.name,
|
|
5526
|
-
icon:
|
|
5887
|
+
icon: (_a3 = item.icon) != null ? _a3 : DEFAULT_ICON,
|
|
5527
5888
|
color: item.color || DEFAULT_COLOR,
|
|
5528
5889
|
iconImageFile: null,
|
|
5890
|
+
iconImageUrl: null,
|
|
5529
5891
|
clearIconImage: false
|
|
5530
5892
|
});
|
|
5531
5893
|
setPreview(item.icon_image || null);
|
|
@@ -5533,7 +5895,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5533
5895
|
kind === "project" && Boolean(item.isArchived)
|
|
5534
5896
|
);
|
|
5535
5897
|
setDraftClientId(
|
|
5536
|
-
kind === "project" ? (
|
|
5898
|
+
kind === "project" ? (_b = item.clientId) != null ? _b : null : null
|
|
5537
5899
|
);
|
|
5538
5900
|
setEditing({ kind, item });
|
|
5539
5901
|
}
|
|
@@ -5547,6 +5909,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5547
5909
|
if (preview == null ? void 0 : preview.startsWith("blob:")) URL.revokeObjectURL(preview);
|
|
5548
5910
|
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
5549
5911
|
iconImageFile: file,
|
|
5912
|
+
iconImageUrl: null,
|
|
5550
5913
|
clearIconImage: false
|
|
5551
5914
|
}));
|
|
5552
5915
|
setPreview(URL.createObjectURL(file));
|
|
@@ -5556,9 +5919,21 @@ function SuiteClientsProjectsDirectory({
|
|
|
5556
5919
|
setPreview(null);
|
|
5557
5920
|
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
5558
5921
|
iconImageFile: null,
|
|
5922
|
+
iconImageUrl: null,
|
|
5559
5923
|
clearIconImage: true
|
|
5560
5924
|
}));
|
|
5561
5925
|
}
|
|
5926
|
+
function pickFromLibrary(icon) {
|
|
5927
|
+
if (preview == null ? void 0 : preview.startsWith("blob:")) URL.revokeObjectURL(preview);
|
|
5928
|
+
setMutationError(null);
|
|
5929
|
+
setPreview(icon.url);
|
|
5930
|
+
setDraft((current) => __spreadProps(__spreadValues({}, current), {
|
|
5931
|
+
iconImageFile: null,
|
|
5932
|
+
iconImageUrl: icon.url,
|
|
5933
|
+
clearIconImage: false
|
|
5934
|
+
}));
|
|
5935
|
+
setLibraryOpen(false);
|
|
5936
|
+
}
|
|
5562
5937
|
function closeEditor() {
|
|
5563
5938
|
if (!saving) setEditing(null);
|
|
5564
5939
|
}
|
|
@@ -5594,14 +5969,14 @@ function SuiteClientsProjectsDirectory({
|
|
|
5594
5969
|
setConfirming({ item, kind });
|
|
5595
5970
|
}
|
|
5596
5971
|
async function toggleArchive(project) {
|
|
5597
|
-
var
|
|
5972
|
+
var _a3, _b;
|
|
5598
5973
|
if (!onUpdateProject) return;
|
|
5599
5974
|
try {
|
|
5600
5975
|
await onUpdateProject(project, {
|
|
5601
5976
|
name: project.name,
|
|
5602
|
-
icon:
|
|
5977
|
+
icon: (_a3 = project.icon) != null ? _a3 : DEFAULT_ICON,
|
|
5603
5978
|
color: project.color || DEFAULT_COLOR,
|
|
5604
|
-
clientId: (
|
|
5979
|
+
clientId: (_b = project.clientId) != null ? _b : null,
|
|
5605
5980
|
isArchived: !project.isArchived
|
|
5606
5981
|
});
|
|
5607
5982
|
} catch (err) {
|
|
@@ -5624,10 +5999,10 @@ function SuiteClientsProjectsDirectory({
|
|
|
5624
5999
|
);
|
|
5625
6000
|
}
|
|
5626
6001
|
}
|
|
5627
|
-
return /* @__PURE__ */
|
|
5628
|
-
error || mutationError ? /* @__PURE__ */
|
|
5629
|
-
loading ? /* @__PURE__ */
|
|
5630
|
-
/* @__PURE__ */
|
|
6002
|
+
return /* @__PURE__ */ jsxs24("div", { "data-test": dataTest, className: "space-y-3", children: [
|
|
6003
|
+
error || mutationError ? /* @__PURE__ */ jsx29(Alert, { status: "danger", live: "assertive", children: error || mutationError }) : null,
|
|
6004
|
+
loading ? /* @__PURE__ */ jsx29("p", { className: "text-sm text-ph-mutedtext", children: "Loading directory..." }) : /* @__PURE__ */ jsxs24("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: [
|
|
6005
|
+
/* @__PURE__ */ jsxs24(
|
|
5631
6006
|
"section",
|
|
5632
6007
|
{
|
|
5633
6008
|
className: cn(
|
|
@@ -5635,16 +6010,16 @@ function SuiteClientsProjectsDirectory({
|
|
|
5635
6010
|
mobileDetail ? "hidden lg:block" : "block"
|
|
5636
6011
|
),
|
|
5637
6012
|
children: [
|
|
5638
|
-
/* @__PURE__ */
|
|
5639
|
-
/* @__PURE__ */
|
|
5640
|
-
/* @__PURE__ */
|
|
5641
|
-
|
|
6013
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex h-14 items-center gap-2 border-b border-ph-border px-3", children: [
|
|
6014
|
+
/* @__PURE__ */ jsxs24("div", { className: "relative min-w-0 flex-1", children: [
|
|
6015
|
+
/* @__PURE__ */ jsx29(
|
|
6016
|
+
Search3,
|
|
5642
6017
|
{
|
|
5643
6018
|
className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-ph-mutedtext",
|
|
5644
6019
|
"aria-hidden": true
|
|
5645
6020
|
}
|
|
5646
6021
|
),
|
|
5647
|
-
/* @__PURE__ */
|
|
6022
|
+
/* @__PURE__ */ jsx29(
|
|
5648
6023
|
Input,
|
|
5649
6024
|
{
|
|
5650
6025
|
hideLabel: true,
|
|
@@ -5656,18 +6031,18 @@ function SuiteClientsProjectsDirectory({
|
|
|
5656
6031
|
}
|
|
5657
6032
|
)
|
|
5658
6033
|
] }),
|
|
5659
|
-
canEdit && onCreateClient ? /* @__PURE__ */
|
|
6034
|
+
canEdit && onCreateClient ? /* @__PURE__ */ jsx29(
|
|
5660
6035
|
Button,
|
|
5661
6036
|
{
|
|
5662
6037
|
size: "sm",
|
|
5663
6038
|
variant: "primary",
|
|
5664
|
-
icon: /* @__PURE__ */
|
|
6039
|
+
icon: /* @__PURE__ */ jsx29(Plus2, { className: "h-4 w-4" }),
|
|
5665
6040
|
onClick: () => openNew("client"),
|
|
5666
6041
|
children: "New client"
|
|
5667
6042
|
}
|
|
5668
6043
|
) : null
|
|
5669
6044
|
] }),
|
|
5670
|
-
/* @__PURE__ */
|
|
6045
|
+
/* @__PURE__ */ jsx29(
|
|
5671
6046
|
"ul",
|
|
5672
6047
|
{
|
|
5673
6048
|
role: "listbox",
|
|
@@ -5678,7 +6053,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5678
6053
|
const count = projects.filter(
|
|
5679
6054
|
(project) => project.clientId === client.id
|
|
5680
6055
|
).length;
|
|
5681
|
-
return /* @__PURE__ */
|
|
6056
|
+
return /* @__PURE__ */ jsx29("li", { role: "none", children: /* @__PURE__ */ jsxs24(
|
|
5682
6057
|
"button",
|
|
5683
6058
|
{
|
|
5684
6059
|
type: "button",
|
|
@@ -5695,10 +6070,10 @@ function SuiteClientsProjectsDirectory({
|
|
|
5695
6070
|
selected ? "bg-ph-muted" : "hover:bg-ph-canvas"
|
|
5696
6071
|
),
|
|
5697
6072
|
children: [
|
|
5698
|
-
/* @__PURE__ */
|
|
5699
|
-
/* @__PURE__ */
|
|
5700
|
-
/* @__PURE__ */
|
|
5701
|
-
/* @__PURE__ */
|
|
6073
|
+
/* @__PURE__ */ jsx29(DirectoryIcon, { item: client }),
|
|
6074
|
+
/* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex-1", children: [
|
|
6075
|
+
/* @__PURE__ */ jsx29("span", { className: "block truncate text-sm font-medium text-ph-ink", children: client.name }),
|
|
6076
|
+
/* @__PURE__ */ jsxs24("span", { className: "text-xs text-ph-mutedtext", children: [
|
|
5702
6077
|
count,
|
|
5703
6078
|
" project",
|
|
5704
6079
|
count === 1 ? "" : "s"
|
|
@@ -5707,13 +6082,13 @@ function SuiteClientsProjectsDirectory({
|
|
|
5707
6082
|
]
|
|
5708
6083
|
}
|
|
5709
6084
|
) }, client.id);
|
|
5710
|
-
}) : /* @__PURE__ */
|
|
6085
|
+
}) : /* @__PURE__ */ jsx29("li", { className: "px-3 py-8 text-center text-sm text-ph-mutedtext", children: clients.length ? "No matches." : "Add a client to get started." })
|
|
5711
6086
|
}
|
|
5712
6087
|
)
|
|
5713
6088
|
]
|
|
5714
6089
|
}
|
|
5715
6090
|
),
|
|
5716
|
-
/* @__PURE__ */
|
|
6091
|
+
/* @__PURE__ */ jsxs24(
|
|
5717
6092
|
"section",
|
|
5718
6093
|
{
|
|
5719
6094
|
className: cn(
|
|
@@ -5721,8 +6096,8 @@ function SuiteClientsProjectsDirectory({
|
|
|
5721
6096
|
mobileDetail ? "flex" : "hidden lg:flex"
|
|
5722
6097
|
),
|
|
5723
6098
|
children: [
|
|
5724
|
-
/* @__PURE__ */
|
|
5725
|
-
/* @__PURE__ */
|
|
6099
|
+
/* @__PURE__ */ jsx29("div", { className: "flex min-h-14 items-center gap-2 border-b border-ph-border px-3 py-2", children: selectedClient ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
6100
|
+
/* @__PURE__ */ jsx29(
|
|
5726
6101
|
"button",
|
|
5727
6102
|
{
|
|
5728
6103
|
type: "button",
|
|
@@ -5733,36 +6108,36 @@ function SuiteClientsProjectsDirectory({
|
|
|
5733
6108
|
setMobileDetail(false);
|
|
5734
6109
|
},
|
|
5735
6110
|
"aria-label": "Back to clients",
|
|
5736
|
-
children: /* @__PURE__ */
|
|
6111
|
+
children: /* @__PURE__ */ jsx29(ArrowLeft, { className: "h-4 w-4" })
|
|
5737
6112
|
}
|
|
5738
6113
|
),
|
|
5739
|
-
/* @__PURE__ */
|
|
5740
|
-
/* @__PURE__ */
|
|
5741
|
-
/* @__PURE__ */
|
|
5742
|
-
/* @__PURE__ */
|
|
6114
|
+
/* @__PURE__ */ jsx29(DirectoryIcon, { item: selectedClient }),
|
|
6115
|
+
/* @__PURE__ */ jsxs24("div", { className: "min-w-0 flex-1", children: [
|
|
6116
|
+
/* @__PURE__ */ jsx29("h3", { className: "truncate text-sm font-semibold text-ph-ink", children: selectedClient.name }),
|
|
6117
|
+
/* @__PURE__ */ jsxs24("p", { className: "text-xs text-ph-mutedtext", children: [
|
|
5743
6118
|
selectedProjects.length,
|
|
5744
6119
|
" project",
|
|
5745
6120
|
selectedProjects.length === 1 ? "" : "s"
|
|
5746
6121
|
] })
|
|
5747
6122
|
] }),
|
|
5748
|
-
canEdit && (onUpdateClient || onDeleteClient) ? /* @__PURE__ */
|
|
6123
|
+
canEdit && (onUpdateClient || onDeleteClient) ? /* @__PURE__ */ jsx29("div", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx29(
|
|
5749
6124
|
DropdownMenu,
|
|
5750
6125
|
{
|
|
5751
6126
|
"aria-label": `Actions for ${selectedClient.name}`,
|
|
5752
6127
|
align: "end",
|
|
5753
|
-
trigger: /* @__PURE__ */
|
|
5754
|
-
/* @__PURE__ */
|
|
5755
|
-
/* @__PURE__ */
|
|
6128
|
+
trigger: /* @__PURE__ */ jsxs24("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: [
|
|
6129
|
+
/* @__PURE__ */ jsx29(MoreHorizontal, { className: "h-4 w-4", "aria-hidden": true }),
|
|
6130
|
+
/* @__PURE__ */ jsx29("span", { className: "sr-only", children: "Client actions" })
|
|
5756
6131
|
] }),
|
|
5757
|
-
children: /* @__PURE__ */
|
|
5758
|
-
onUpdateClient ? /* @__PURE__ */
|
|
6132
|
+
children: /* @__PURE__ */ jsxs24("div", { className: "p-1", children: [
|
|
6133
|
+
onUpdateClient ? /* @__PURE__ */ jsx29(
|
|
5759
6134
|
DropdownItem,
|
|
5760
6135
|
{
|
|
5761
6136
|
onClick: () => openEdit(selectedClient, "client"),
|
|
5762
6137
|
children: "Edit client"
|
|
5763
6138
|
}
|
|
5764
6139
|
) : null,
|
|
5765
|
-
onDeleteClient ? /* @__PURE__ */
|
|
6140
|
+
onDeleteClient ? /* @__PURE__ */ jsx29(
|
|
5766
6141
|
DropdownItem,
|
|
5767
6142
|
{
|
|
5768
6143
|
className: "text-red-600",
|
|
@@ -5773,32 +6148,32 @@ function SuiteClientsProjectsDirectory({
|
|
|
5773
6148
|
] })
|
|
5774
6149
|
}
|
|
5775
6150
|
) }) : null
|
|
5776
|
-
] }) : /* @__PURE__ */
|
|
5777
|
-
canEdit && onCreateProject ? /* @__PURE__ */
|
|
6151
|
+
] }) : /* @__PURE__ */ jsx29("p", { className: "text-sm text-ph-mutedtext", children: "Select a client" }) }),
|
|
6152
|
+
canEdit && onCreateProject ? /* @__PURE__ */ jsx29("div", { className: "border-b border-ph-border p-3", children: /* @__PURE__ */ jsx29(
|
|
5778
6153
|
Button,
|
|
5779
6154
|
{
|
|
5780
6155
|
variant: "primary",
|
|
5781
|
-
icon: /* @__PURE__ */
|
|
6156
|
+
icon: /* @__PURE__ */ jsx29(Plus2, { className: "h-4 w-4" }),
|
|
5782
6157
|
onClick: () => openNew("project"),
|
|
5783
6158
|
children: "Add project"
|
|
5784
6159
|
}
|
|
5785
6160
|
) }) : null,
|
|
5786
|
-
/* @__PURE__ */
|
|
6161
|
+
/* @__PURE__ */ jsx29("ul", { className: "flex-1 p-2", children: selectedClient && selectedProjects.length ? selectedProjects.map((project) => /* @__PURE__ */ jsx29("li", { children: /* @__PURE__ */ jsxs24(
|
|
5787
6162
|
"div",
|
|
5788
6163
|
{
|
|
5789
6164
|
className: "flex items-center gap-3 rounded-lg px-2 py-1 hover:bg-ph-canvas",
|
|
5790
6165
|
onClick: () => openEdit(project, "project"),
|
|
5791
6166
|
children: [
|
|
5792
|
-
/* @__PURE__ */
|
|
6167
|
+
/* @__PURE__ */ jsxs24(
|
|
5793
6168
|
"button",
|
|
5794
6169
|
{
|
|
5795
6170
|
type: "button",
|
|
5796
6171
|
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",
|
|
5797
6172
|
onClick: () => openEdit(project, "project"),
|
|
5798
6173
|
children: [
|
|
5799
|
-
/* @__PURE__ */
|
|
5800
|
-
/* @__PURE__ */
|
|
5801
|
-
/* @__PURE__ */
|
|
6174
|
+
/* @__PURE__ */ jsx29(DirectoryIcon, { item: project }),
|
|
6175
|
+
/* @__PURE__ */ jsxs24("span", { className: "min-w-0 flex-1", children: [
|
|
6176
|
+
/* @__PURE__ */ jsx29(
|
|
5802
6177
|
"span",
|
|
5803
6178
|
{
|
|
5804
6179
|
className: cn(
|
|
@@ -5808,36 +6183,36 @@ function SuiteClientsProjectsDirectory({
|
|
|
5808
6183
|
children: project.name
|
|
5809
6184
|
}
|
|
5810
6185
|
),
|
|
5811
|
-
/* @__PURE__ */
|
|
6186
|
+
/* @__PURE__ */ jsx29("span", { className: "text-xs text-ph-mutedtext", children: project.isArchived ? "Archived" : "Active" })
|
|
5812
6187
|
] })
|
|
5813
6188
|
]
|
|
5814
6189
|
}
|
|
5815
6190
|
),
|
|
5816
|
-
canEdit && (onUpdateProject || onDeleteProject) ? /* @__PURE__ */
|
|
6191
|
+
canEdit && (onUpdateProject || onDeleteProject) ? /* @__PURE__ */ jsx29("div", { onClick: (event) => event.stopPropagation(), children: /* @__PURE__ */ jsx29(
|
|
5817
6192
|
DropdownMenu,
|
|
5818
6193
|
{
|
|
5819
6194
|
"aria-label": `Actions for ${project.name}`,
|
|
5820
6195
|
align: "end",
|
|
5821
|
-
trigger: /* @__PURE__ */
|
|
5822
|
-
/* @__PURE__ */
|
|
6196
|
+
trigger: /* @__PURE__ */ jsxs24("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: [
|
|
6197
|
+
/* @__PURE__ */ jsx29(
|
|
5823
6198
|
MoreHorizontal,
|
|
5824
6199
|
{
|
|
5825
6200
|
className: "h-4 w-4",
|
|
5826
6201
|
"aria-hidden": true
|
|
5827
6202
|
}
|
|
5828
6203
|
),
|
|
5829
|
-
/* @__PURE__ */
|
|
6204
|
+
/* @__PURE__ */ jsx29("span", { className: "sr-only", children: "Project actions" })
|
|
5830
6205
|
] }),
|
|
5831
|
-
children: /* @__PURE__ */
|
|
5832
|
-
onUpdateProject ? /* @__PURE__ */
|
|
5833
|
-
/* @__PURE__ */
|
|
6206
|
+
children: /* @__PURE__ */ jsxs24("div", { className: "p-1", children: [
|
|
6207
|
+
onUpdateProject ? /* @__PURE__ */ jsxs24(Fragment10, { children: [
|
|
6208
|
+
/* @__PURE__ */ jsx29(
|
|
5834
6209
|
DropdownItem,
|
|
5835
6210
|
{
|
|
5836
6211
|
onClick: () => openEdit(project, "project"),
|
|
5837
6212
|
children: "Edit project"
|
|
5838
6213
|
}
|
|
5839
6214
|
),
|
|
5840
|
-
/* @__PURE__ */
|
|
6215
|
+
/* @__PURE__ */ jsx29(
|
|
5841
6216
|
DropdownItem,
|
|
5842
6217
|
{
|
|
5843
6218
|
onClick: () => void toggleArchive(project),
|
|
@@ -5845,7 +6220,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5845
6220
|
}
|
|
5846
6221
|
)
|
|
5847
6222
|
] }) : null,
|
|
5848
|
-
onDeleteProject ? /* @__PURE__ */
|
|
6223
|
+
onDeleteProject ? /* @__PURE__ */ jsx29(
|
|
5849
6224
|
DropdownItem,
|
|
5850
6225
|
{
|
|
5851
6226
|
className: "text-red-600",
|
|
@@ -5858,20 +6233,20 @@ function SuiteClientsProjectsDirectory({
|
|
|
5858
6233
|
) }) : null
|
|
5859
6234
|
]
|
|
5860
6235
|
}
|
|
5861
|
-
) }, project.id)) : /* @__PURE__ */
|
|
6236
|
+
) }, project.id)) : /* @__PURE__ */ jsx29("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." }) })
|
|
5862
6237
|
]
|
|
5863
6238
|
}
|
|
5864
6239
|
)
|
|
5865
6240
|
] }),
|
|
5866
|
-
/* @__PURE__ */
|
|
6241
|
+
/* @__PURE__ */ jsx29(
|
|
5867
6242
|
Modal,
|
|
5868
6243
|
{
|
|
5869
6244
|
open: editing !== null,
|
|
5870
6245
|
onClose: closeEditor,
|
|
5871
6246
|
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",
|
|
5872
|
-
footer: /* @__PURE__ */
|
|
5873
|
-
/* @__PURE__ */
|
|
5874
|
-
/* @__PURE__ */
|
|
6247
|
+
footer: /* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2", children: [
|
|
6248
|
+
/* @__PURE__ */ jsx29(Button, { variant: "tertiary", onClick: closeEditor, disabled: saving, children: "Cancel" }),
|
|
6249
|
+
/* @__PURE__ */ jsx29(
|
|
5875
6250
|
Button,
|
|
5876
6251
|
{
|
|
5877
6252
|
variant: "primary",
|
|
@@ -5881,8 +6256,8 @@ function SuiteClientsProjectsDirectory({
|
|
|
5881
6256
|
}
|
|
5882
6257
|
)
|
|
5883
6258
|
] }),
|
|
5884
|
-
children: /* @__PURE__ */
|
|
5885
|
-
/* @__PURE__ */
|
|
6259
|
+
children: /* @__PURE__ */ jsxs24("div", { className: "space-y-3", children: [
|
|
6260
|
+
/* @__PURE__ */ jsx29(
|
|
5886
6261
|
Input,
|
|
5887
6262
|
{
|
|
5888
6263
|
label: "Name",
|
|
@@ -5891,22 +6266,35 @@ function SuiteClientsProjectsDirectory({
|
|
|
5891
6266
|
onChange: (event) => setDraft(__spreadProps(__spreadValues({}, draft), { name: event.target.value }))
|
|
5892
6267
|
}
|
|
5893
6268
|
),
|
|
5894
|
-
/* @__PURE__ */
|
|
6269
|
+
/* @__PURE__ */ jsx29(
|
|
5895
6270
|
DirectoryIconPicker,
|
|
5896
6271
|
{
|
|
5897
|
-
value: isDirectoryIcon(draft.icon) ? draft.icon : DEFAULT_ICON,
|
|
5898
6272
|
preview,
|
|
6273
|
+
label: draft.name,
|
|
6274
|
+
color: draft.color,
|
|
5899
6275
|
onFileChange: chooseImage,
|
|
5900
6276
|
onClear: clearImage,
|
|
5901
|
-
|
|
5902
|
-
if (preview) clearImage();
|
|
5903
|
-
setDraft((current) => __spreadProps(__spreadValues({}, current), { icon }));
|
|
5904
|
-
}
|
|
6277
|
+
onBrowse: () => setLibraryOpen(true)
|
|
5905
6278
|
}
|
|
5906
6279
|
),
|
|
5907
|
-
/* @__PURE__ */
|
|
5908
|
-
/* @__PURE__ */
|
|
5909
|
-
/* @__PURE__ */
|
|
6280
|
+
/* @__PURE__ */ jsxs24("div", { children: [
|
|
6281
|
+
/* @__PURE__ */ jsx29("span", { className: "mb-1.5 block text-sm font-medium text-ph-ink", children: "Colour" }),
|
|
6282
|
+
/* @__PURE__ */ jsxs24("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
6283
|
+
/* @__PURE__ */ jsx29(
|
|
6284
|
+
"button",
|
|
6285
|
+
{
|
|
6286
|
+
type: "button",
|
|
6287
|
+
"aria-label": "No colour",
|
|
6288
|
+
"aria-pressed": !draft.color,
|
|
6289
|
+
title: "No colour",
|
|
6290
|
+
onClick: () => setDraft(__spreadProps(__spreadValues({}, draft), { color: "" })),
|
|
6291
|
+
className: cn(
|
|
6292
|
+
"flex h-8 w-8 items-center justify-center rounded-full border border-ph-border bg-ph-surface text-ph-mutedtext ring-offset-2",
|
|
6293
|
+
!draft.color && "ring-2 ring-ph-brand"
|
|
6294
|
+
),
|
|
6295
|
+
children: /* @__PURE__ */ jsx29(Prohibition, { className: "h-4 w-4", "aria-hidden": true })
|
|
6296
|
+
}
|
|
6297
|
+
),
|
|
5910
6298
|
[
|
|
5911
6299
|
"#6366f1",
|
|
5912
6300
|
"#0ea5e9",
|
|
@@ -5915,7 +6303,7 @@ function SuiteClientsProjectsDirectory({
|
|
|
5915
6303
|
"#ef4444",
|
|
5916
6304
|
"#a855f7",
|
|
5917
6305
|
"#64748b"
|
|
5918
|
-
].map((color) => /* @__PURE__ */
|
|
6306
|
+
].map((color) => /* @__PURE__ */ jsx29(
|
|
5919
6307
|
"button",
|
|
5920
6308
|
{
|
|
5921
6309
|
type: "button",
|
|
@@ -5930,33 +6318,70 @@ function SuiteClientsProjectsDirectory({
|
|
|
5930
6318
|
},
|
|
5931
6319
|
color
|
|
5932
6320
|
)),
|
|
5933
|
-
/* @__PURE__ */
|
|
5934
|
-
|
|
6321
|
+
/* @__PURE__ */ jsxs24(
|
|
6322
|
+
"label",
|
|
5935
6323
|
{
|
|
5936
|
-
|
|
5937
|
-
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
6324
|
+
className: cn(
|
|
6325
|
+
"relative inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-full ring-1 ring-ph-border ring-offset-2",
|
|
6326
|
+
![
|
|
6327
|
+
"#6366f1",
|
|
6328
|
+
"#0ea5e9",
|
|
6329
|
+
"#10b981",
|
|
6330
|
+
"#f59e0b",
|
|
6331
|
+
"#ef4444",
|
|
6332
|
+
"#a855f7",
|
|
6333
|
+
"#64748b"
|
|
6334
|
+
].includes(draft.color) && "ring-2 ring-ph-brand"
|
|
6335
|
+
),
|
|
6336
|
+
style: {
|
|
6337
|
+
background: "conic-gradient(from 0deg, #ef4444, #f59e0b, #eab308, #22c55e, #06b6d4, #3b82f6, #8b5cf6, #ec4899, #ef4444)"
|
|
6338
|
+
},
|
|
6339
|
+
title: "Custom colour",
|
|
6340
|
+
children: [
|
|
6341
|
+
/* @__PURE__ */ jsx29("span", { className: "flex h-4 w-4 items-center justify-center rounded-full bg-ph-surface", children: [
|
|
6342
|
+
"#6366f1",
|
|
6343
|
+
"#0ea5e9",
|
|
6344
|
+
"#10b981",
|
|
6345
|
+
"#f59e0b",
|
|
6346
|
+
"#ef4444",
|
|
6347
|
+
"#a855f7",
|
|
6348
|
+
"#64748b"
|
|
6349
|
+
].includes(draft.color) ? /* @__PURE__ */ jsx29(Plus2, { className: "h-3 w-3 text-ph-ink", "aria-hidden": true }) : /* @__PURE__ */ jsx29(
|
|
6350
|
+
"span",
|
|
6351
|
+
{
|
|
6352
|
+
className: "h-2.5 w-2.5 rounded-full",
|
|
6353
|
+
style: { backgroundColor: draft.color }
|
|
6354
|
+
}
|
|
6355
|
+
) }),
|
|
6356
|
+
/* @__PURE__ */ jsx29(
|
|
6357
|
+
"input",
|
|
6358
|
+
{
|
|
6359
|
+
type: "color",
|
|
6360
|
+
"aria-label": "Custom colour",
|
|
6361
|
+
value: draft.color,
|
|
6362
|
+
onChange: (event) => setDraft(__spreadProps(__spreadValues({}, draft), { color: event.target.value })),
|
|
6363
|
+
className: "sr-only"
|
|
6364
|
+
}
|
|
6365
|
+
)
|
|
6366
|
+
]
|
|
5942
6367
|
}
|
|
5943
6368
|
)
|
|
5944
6369
|
] })
|
|
5945
6370
|
] }),
|
|
5946
|
-
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */
|
|
6371
|
+
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ jsxs24(
|
|
5947
6372
|
Select,
|
|
5948
6373
|
{
|
|
5949
6374
|
label: "Client",
|
|
5950
6375
|
value: draftClientId != null ? draftClientId : "",
|
|
5951
6376
|
onChange: (event) => setDraftClientId(event.target.value || null),
|
|
5952
6377
|
children: [
|
|
5953
|
-
/* @__PURE__ */
|
|
5954
|
-
clients.map((client) => /* @__PURE__ */
|
|
6378
|
+
/* @__PURE__ */ jsx29("option", { value: "", children: "No client" }),
|
|
6379
|
+
clients.map((client) => /* @__PURE__ */ jsx29("option", { value: client.id, children: client.name }, client.id))
|
|
5955
6380
|
]
|
|
5956
6381
|
}
|
|
5957
6382
|
) : null,
|
|
5958
|
-
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */
|
|
5959
|
-
/* @__PURE__ */
|
|
6383
|
+
(editing == null ? void 0 : editing.kind.includes("project")) ? /* @__PURE__ */ jsxs24("label", { className: "flex items-center gap-2 text-sm text-ph-ink", children: [
|
|
6384
|
+
/* @__PURE__ */ jsx29(
|
|
5960
6385
|
"input",
|
|
5961
6386
|
{
|
|
5962
6387
|
type: "checkbox",
|
|
@@ -5969,17 +6394,26 @@ function SuiteClientsProjectsDirectory({
|
|
|
5969
6394
|
] })
|
|
5970
6395
|
}
|
|
5971
6396
|
),
|
|
5972
|
-
/* @__PURE__ */
|
|
6397
|
+
libraryOpen ? /* @__PURE__ */ jsx29(
|
|
6398
|
+
Modal,
|
|
6399
|
+
{
|
|
6400
|
+
open: true,
|
|
6401
|
+
onClose: () => setLibraryOpen(false),
|
|
6402
|
+
title: "Icon library",
|
|
6403
|
+
children: renderIconLibrary ? renderIconLibrary({ onPick: pickFromLibrary }) : /* @__PURE__ */ jsx29(SuitePaletteLibrary, { onPick: pickFromLibrary })
|
|
6404
|
+
}
|
|
6405
|
+
) : null,
|
|
6406
|
+
/* @__PURE__ */ jsx29(
|
|
5973
6407
|
Modal,
|
|
5974
6408
|
{
|
|
5975
6409
|
open: confirming !== null,
|
|
5976
6410
|
onClose: () => setConfirming(null),
|
|
5977
6411
|
title: "Confirm deletion",
|
|
5978
|
-
footer: /* @__PURE__ */
|
|
5979
|
-
/* @__PURE__ */
|
|
5980
|
-
/* @__PURE__ */
|
|
6412
|
+
footer: /* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2", children: [
|
|
6413
|
+
/* @__PURE__ */ jsx29(Button, { variant: "tertiary", onClick: () => setConfirming(null), children: "Cancel" }),
|
|
6414
|
+
/* @__PURE__ */ jsx29(Button, { variant: "primary", onClick: () => void confirmRemove(), children: "Delete" })
|
|
5981
6415
|
] }),
|
|
5982
|
-
children: /* @__PURE__ */
|
|
6416
|
+
children: /* @__PURE__ */ jsxs24("p", { className: "text-sm text-ph-ink", children: [
|
|
5983
6417
|
"Delete ",
|
|
5984
6418
|
confirming == null ? void 0 : confirming.item.name,
|
|
5985
6419
|
"? This cannot be undone."
|
|
@@ -6024,6 +6458,7 @@ export {
|
|
|
6024
6458
|
SuiteBreadcrumbs,
|
|
6025
6459
|
SuiteClientsProjectsDirectory,
|
|
6026
6460
|
SuiteEmptyState,
|
|
6461
|
+
SuiteEntityIcon,
|
|
6027
6462
|
SuiteIcon,
|
|
6028
6463
|
SuiteIntegrationPicker,
|
|
6029
6464
|
SuiteIntegrationRules,
|
|
@@ -6033,6 +6468,7 @@ export {
|
|
|
6033
6468
|
SuiteNotificationBell,
|
|
6034
6469
|
SuitePage,
|
|
6035
6470
|
SuitePageHeader,
|
|
6471
|
+
SuitePaletteLibrary,
|
|
6036
6472
|
SuiteSectionHeader,
|
|
6037
6473
|
SuiteSettingsLayout,
|
|
6038
6474
|
SuiteSettingsMobileNav,
|
|
@@ -6065,6 +6501,9 @@ export {
|
|
|
6065
6501
|
cn2 as cn,
|
|
6066
6502
|
consumePendingAskAiPrompt,
|
|
6067
6503
|
consumeSuiteAskAiOpenFromLocation,
|
|
6504
|
+
fetchPaletteCollection,
|
|
6505
|
+
fetchPaletteLibrary,
|
|
6506
|
+
findPaletteIcons,
|
|
6068
6507
|
getTodayGreeting,
|
|
6069
6508
|
m,
|
|
6070
6509
|
openSuiteAskAi,
|