Skip to content

Commit 2662157

Browse files
authored
feat(canvas): collapse channels by default, hash icon, and starred channels (#2683)
1 parent 96595f7 commit 2662157

5 files changed

Lines changed: 532 additions & 61 deletions

File tree

packages/api-client/src/posthog-client.ts

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,88 @@ export class PostHogAPIClient {
970970
}
971971
}
972972

973+
// Desktop file system shortcuts — the user-scoped "starred" items on the
974+
// desktop surface (e.g. starred channels). Unlike the file system rows above,
975+
// shortcuts are per-user, so they back cross-device starring without leaking
976+
// one user's stars to their teammates. Not in the generated OpenAPI client,
977+
// so we use the raw fetcher.
978+
async getDesktopFileSystemShortcuts(): Promise<Schemas.FileSystemShortcut[]> {
979+
const SHORTCUTS_MAX_PAGES = 50;
980+
const SHORTCUTS_PAGE_SIZE = 200;
981+
const teamId = await this.getTeamId();
982+
const all: Schemas.FileSystemShortcut[] = [];
983+
let urlPath: string = `/api/projects/${teamId}/desktop_file_system_shortcut/?limit=${SHORTCUTS_PAGE_SIZE}`;
984+
for (let i = 0; i < SHORTCUTS_MAX_PAGES; i++) {
985+
const url = new URL(`${this.api.baseUrl}${urlPath}`);
986+
const response = await this.api.fetcher.fetch({
987+
method: "get",
988+
url,
989+
path: urlPath,
990+
});
991+
if (!response.ok) {
992+
throw new Error(
993+
`Failed to fetch desktop file system shortcuts: ${response.statusText}`,
994+
);
995+
}
996+
const page =
997+
(await response.json()) as Schemas.PaginatedFileSystemShortcutList;
998+
all.push(...page.results);
999+
if (!page.next) return all;
1000+
const nextUrl = new URL(page.next);
1001+
urlPath = `${nextUrl.pathname}${nextUrl.search}`;
1002+
}
1003+
log.warn(
1004+
`getDesktopFileSystemShortcuts hit MAX_PAGES (${SHORTCUTS_MAX_PAGES}); returning partial results`,
1005+
{ returned: all.length },
1006+
);
1007+
return all;
1008+
}
1009+
1010+
// Create a desktop shortcut for the current user. For a folder/channel the
1011+
// backend links by `ref` (the folder's full path), with `path` as the label.
1012+
async createDesktopFileSystemShortcut(input: {
1013+
path: string;
1014+
type: string;
1015+
ref?: string;
1016+
href?: string;
1017+
}): Promise<Schemas.FileSystemShortcut> {
1018+
const teamId = await this.getTeamId();
1019+
const urlPath = `/api/projects/${teamId}/desktop_file_system_shortcut/`;
1020+
const url = new URL(`${this.api.baseUrl}${urlPath}`);
1021+
const response = await this.api.fetcher.fetch({
1022+
method: "post",
1023+
url,
1024+
path: urlPath,
1025+
overrides: {
1026+
body: JSON.stringify(input),
1027+
},
1028+
});
1029+
if (!response.ok) {
1030+
throw new Error(
1031+
`Failed to create desktop file system shortcut: ${response.statusText}`,
1032+
);
1033+
}
1034+
return (await response.json()) as Schemas.FileSystemShortcut;
1035+
}
1036+
1037+
// Delete a desktop shortcut by id (used to unstar). A 404 means it's already
1038+
// gone, which is the desired end state, so we treat it as success.
1039+
async deleteDesktopFileSystemShortcut(id: string): Promise<void> {
1040+
const teamId = await this.getTeamId();
1041+
const urlPath = `/api/projects/${teamId}/desktop_file_system_shortcut/${encodeURIComponent(id)}/`;
1042+
const url = new URL(`${this.api.baseUrl}${urlPath}`);
1043+
const response = await this.api.fetcher.fetch({
1044+
method: "delete",
1045+
url,
1046+
path: urlPath,
1047+
});
1048+
if (!response.ok && response.status !== 404) {
1049+
throw new Error(
1050+
`Failed to delete desktop file system shortcut: ${response.statusText}`,
1051+
);
1052+
}
1053+
}
1054+
9731055
// Per-folder, versioned markdown instructions for a desktop folder. The
9741056
// endpoint is keyed on the FileSystem row id (must be `type === "folder"`).
9751057
// Returns the current latest version or null when none has been published.

0 commit comments

Comments
 (0)