@xenide-io/the-old-ui-theme 0.6.7 → 0.6.9
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/{chunk-3G43JEI3.mjs → chunk-VOCHIR3W.mjs} +2 -2
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/suite.d.mts +64 -15
- package/dist/suite.d.ts +64 -15
- package/dist/suite.js +751 -759
- package/dist/suite.mjs +572 -586
- package/dist/ui.js +2 -2
- package/dist/ui.mjs +1 -1
- package/package.json +1 -1
- package/src/styles/suite-skin.css +6 -0
- package/src/styles/themes.css +35 -33
- package/src/suite/components/ai-panel.test.ts +14 -40
- package/src/suite/components/ai-panel.tsx +305 -633
- package/src/suite/components/suite-app-layout.tsx +3 -2
- package/src/suite/components/suite-layout.test.tsx +36 -2
- package/src/suite/components/suite-sidebar.tsx +235 -102
- package/src/suite/components/today-ui.tsx +1 -1
- package/src/suite/components/workspace-switcher.tsx +162 -0
- package/src/suite/index.ts +9 -0
- package/src/suite/lib/apps.test.ts +40 -0
- package/src/suite/lib/apps.ts +37 -0
- package/src/suite/lib/use-sidebar-width.ts +11 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { classifySuiteHref } from "./apps";
|
|
4
|
+
|
|
5
|
+
const BASES = {
|
|
6
|
+
tides: "http://localhost:3001",
|
|
7
|
+
turtletime: "http://localhost:3000",
|
|
8
|
+
kraken: "http://localhost:3003",
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe("classifySuiteHref", () => {
|
|
12
|
+
it("maps a Tides task URL to the Tides app and path", () => {
|
|
13
|
+
const match = classifySuiteHref(
|
|
14
|
+
"http://localhost:3001/dashboard/projects/abc/tasks/def",
|
|
15
|
+
BASES,
|
|
16
|
+
"http://localhost:3000",
|
|
17
|
+
);
|
|
18
|
+
expect(match).toEqual({
|
|
19
|
+
slug: "tides",
|
|
20
|
+
path: "/dashboard/projects/abc/tasks/def",
|
|
21
|
+
sameApp: false,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("marks a same-origin TurtleTime link as sameApp", () => {
|
|
26
|
+
const match = classifySuiteHref(
|
|
27
|
+
"http://localhost:3000/tracker",
|
|
28
|
+
BASES,
|
|
29
|
+
"http://localhost:3000",
|
|
30
|
+
);
|
|
31
|
+
expect(match?.sameApp).toBe(true);
|
|
32
|
+
expect(match?.path).toBe("/tracker");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("ignores urls that are not a suite app", () => {
|
|
36
|
+
expect(
|
|
37
|
+
classifySuiteHref("https://example.com/x", BASES, "http://localhost:3000"),
|
|
38
|
+
).toBeNull();
|
|
39
|
+
});
|
|
40
|
+
});
|
package/src/suite/lib/apps.ts
CHANGED
|
@@ -114,3 +114,40 @@ export function resolveSuiteNotificationHref(
|
|
|
114
114
|
if (!slug) return path;
|
|
115
115
|
return `${suiteAppBaseUrl(slug)}${path}`;
|
|
116
116
|
}
|
|
117
|
+
|
|
118
|
+
export interface SuiteHrefTarget {
|
|
119
|
+
slug: SuiteAppSlug;
|
|
120
|
+
path: string;
|
|
121
|
+
sameApp: boolean;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Match a URL to a suite app origin so Ask AI links can switch apps. */
|
|
125
|
+
export function classifySuiteHref(
|
|
126
|
+
href: string,
|
|
127
|
+
bases: Partial<Record<SuiteAppSlug, string>>,
|
|
128
|
+
currentOrigin = '',
|
|
129
|
+
): SuiteHrefTarget | null {
|
|
130
|
+
let url: URL;
|
|
131
|
+
try {
|
|
132
|
+
url = new URL(href, currentOrigin || 'http://local.invalid');
|
|
133
|
+
} catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') return null;
|
|
137
|
+
for (const slug of Object.keys(bases) as SuiteAppSlug[]) {
|
|
138
|
+
const base = bases[slug];
|
|
139
|
+
if (!base) continue;
|
|
140
|
+
try {
|
|
141
|
+
if (new URL(base).origin !== url.origin) continue;
|
|
142
|
+
} catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const path = `${url.pathname}${url.search}${url.hash}` || '/';
|
|
146
|
+
return {
|
|
147
|
+
slug,
|
|
148
|
+
path,
|
|
149
|
+
sameApp: Boolean(currentOrigin && url.origin === currentOrigin),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
@@ -10,9 +10,19 @@ import {
|
|
|
10
10
|
export const SIDEBAR_RAIL_WIDTH = 56;
|
|
11
11
|
export const SIDEBAR_COLLAPSE_THRESHOLD = 80;
|
|
12
12
|
export const SIDEBAR_MIN_EXPANDED_WIDTH = 180;
|
|
13
|
-
export const SIDEBAR_MAX_WIDTH =
|
|
13
|
+
export const SIDEBAR_MAX_WIDTH = 640;
|
|
14
14
|
export const SIDEBAR_DEFAULT_WIDTH = 320;
|
|
15
15
|
|
|
16
|
+
/** Desktop column width: icon rail when collapsed, otherwise the persisted width. */
|
|
17
|
+
export function sidebarColumnWidth(
|
|
18
|
+
width: number,
|
|
19
|
+
collapsed: boolean,
|
|
20
|
+
_chatOpen = false,
|
|
21
|
+
): number {
|
|
22
|
+
if (collapsed) return SIDEBAR_RAIL_WIDTH;
|
|
23
|
+
return width;
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
function clampWidth(width: number): number {
|
|
17
27
|
return Math.min(SIDEBAR_MAX_WIDTH, Math.max(SIDEBAR_RAIL_WIDTH, width));
|
|
18
28
|
}
|