channel_folders: Add support for channel folders in webapp.

This commit adds code to handle channel folders data in
webapp.
This commit is contained in:
Sahil Batra 2025-05-29 12:37:51 +05:30 committed by Tim Abbott
parent e643d7e6fd
commit 403b73e1a6
4 changed files with 111 additions and 0 deletions

View File

@ -0,0 +1,34 @@
import type {z} from "zod";
import {FoldDict} from "./fold_dict.ts";
import type {StateData, channel_folder_schema} from "./state_data.ts";
export type ChannelFolder = z.infer<typeof channel_folder_schema>;
let channel_folder_name_dict: FoldDict<ChannelFolder>;
let channel_folder_by_id_dict: Map<number, ChannelFolder>;
export function add(channel_folder: ChannelFolder): void {
channel_folder_name_dict.set(channel_folder.name, channel_folder);
channel_folder_by_id_dict.set(channel_folder.id, channel_folder);
}
export function initialize(params: StateData["channel_folders"]): void {
channel_folder_name_dict = new FoldDict();
channel_folder_by_id_dict = new Map<number, ChannelFolder>();
for (const channel_folder of params.channel_folders) {
add(channel_folder);
}
}
export function get_channel_folders(include_archived = false): ChannelFolder[] {
const channel_folders = [...channel_folder_by_id_dict.values()].sort((a, b) => a.id - b.id);
return channel_folders.filter((channel_folder) => {
if (!include_archived && channel_folder.is_archived) {
return false;
}
return true;
});
}

View File

@ -141,6 +141,15 @@ export const raw_user_group_schema = z.object({
deactivated: z.boolean(),
});
export const channel_folder_schema = z.object({
id: z.number(),
name: z.string(),
rendered_description: z.string(),
creator_id: z.number().nullable(),
date_created: z.number(),
is_archived: z.boolean(),
});
export const user_topic_schema = z.object({
stream_id: z.number(),
topic_name: z.string(),
@ -499,6 +508,11 @@ export const state_data_schema = z
.object({realm_user_groups: z.array(raw_user_group_schema)})
.transform((user_groups) => ({user_groups})),
)
.and(
z
.object({channel_folders: z.array(channel_folder_schema)})
.transform((channel_folders) => ({channel_folders})),
)
.and(
z
.object({

View File

@ -21,6 +21,7 @@ import * as banners from "./banners.ts";
import * as blueslip from "./blueslip.ts";
import * as bot_data from "./bot_data.ts";
import * as channel from "./channel.ts";
import * as channel_folders from "./channel_folders.ts";
import * as click_handlers from "./click_handlers.ts";
import * as color_picker_popover from "./color_picker_popover.ts";
import * as common from "./common.ts";
@ -475,6 +476,9 @@ export async function initialize_everything(state_data) {
// user_group whose members are allowed to create multiuse invite.
user_groups.initialize(state_data.user_groups);
// Channel folders data must be initialized before left sidebar.
channel_folders.initialize(state_data.channel_folders);
// These components must be initialized early, because other
// modules' initialization has not been audited for whether they
// expect DOM elements to always exist (As that did before these

View File

@ -0,0 +1,59 @@
"use strict";
const assert = require("node:assert/strict");
const {zrequire} = require("./lib/namespace.cjs");
const {run_test} = require("./lib/test.cjs");
const channel_folders = zrequire("channel_folders");
run_test("basics", () => {
const params = {};
const frontend_folder = {
name: "Frontend",
description: "Channels for frontend discussions",
rendered_description: "<p>Channels for frontend discussions</p>",
creator_id: null,
date_created: 1596710000,
id: 1,
is_archived: false,
};
const backend_folder = {
name: "Backend",
description: "Channels for backend discussions",
rendered_description: "<p>Channels for backend discussions</p>",
creator_id: null,
date_created: 1596720000,
id: 2,
is_archived: false,
};
params.channel_folders = [frontend_folder, backend_folder];
channel_folders.initialize(params);
assert.deepEqual(channel_folders.get_channel_folders(), [frontend_folder, backend_folder]);
const devops_folder = {
name: "Devops",
description: "",
rendered_description: "",
creator_id: 1,
date_created: 1596810000,
id: 3,
is_archived: false,
};
channel_folders.add(devops_folder);
assert.deepEqual(channel_folders.get_channel_folders(), [
frontend_folder,
backend_folder,
devops_folder,
]);
devops_folder.is_archived = true;
assert.deepEqual(channel_folders.get_channel_folders(), [frontend_folder, backend_folder]);
assert.deepEqual(channel_folders.get_channel_folders(true), [
frontend_folder,
backend_folder,
devops_folder,
]);
});