feat: update knowledge workspace and menu configuration
This commit is contained in:
1 parent
64a5305bbf
commit
8af4fed89d
28 files changed
+1250
-219
No files matched your search
@@ -78,7 +78,9 @@ export async function downloadMarkdownDocxFromBackend(options: {
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.status === 404) {
|
||||
// Older/offline gateways mount /api/writing but do not provide export/docx;
|
||||
// FastAPI then answers 404 or 405. The browser converter is feature-equivalent.
|
||||
if (response.status === 404 || response.status === 405) {
|
||||
await downloadMarkdownAsDocx(markdown, options.title?.trim() || "document", options.title);
|
||||
writeYLog({
|
||||
optType: OptType.export,
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { MenuItem } from "./sidebar-menu";
|
||||
|
||||
export type CompactMenuPlacement = "sidebar" | "settings";
|
||||
|
||||
export interface CompactMenuOverride {
|
||||
nodeId: string;
|
||||
placement: CompactMenuPlacement;
|
||||
sortOrder: number;
|
||||
label?: string | null;
|
||||
}
|
||||
|
||||
export interface CompactMenuItem extends MenuItem {
|
||||
compactPlacement: CompactMenuPlacement;
|
||||
compactOrder: number;
|
||||
}
|
||||
|
||||
function firstRoutePath(items?: MenuItem[]): string | undefined {
|
||||
for (const item of items ?? []) {
|
||||
if (item.path) return item.path;
|
||||
const nested = firstRoutePath(item.children);
|
||||
if (nested) return nested;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isNavigable(item: MenuItem): boolean {
|
||||
return Boolean(item.path ?? firstRoutePath(item.children));
|
||||
}
|
||||
|
||||
export function applyCompactMenuOverrides(
|
||||
items: MenuItem[],
|
||||
overrides: CompactMenuOverride[],
|
||||
): { sidebarItems: CompactMenuItem[]; settingsItems: CompactMenuItem[] } {
|
||||
const byId = new Map(overrides.map((override) => [override.nodeId, override]));
|
||||
const enhanced = items.filter(isNavigable).map((item, index) => {
|
||||
const override = byId.get(item.id);
|
||||
return {
|
||||
...item,
|
||||
label: override?.label != null && override.label !== "" ? override.label : item.label,
|
||||
compactPlacement: override?.placement ?? "sidebar",
|
||||
compactOrder: override?.sortOrder ?? index,
|
||||
};
|
||||
});
|
||||
|
||||
const sortItems = (list: CompactMenuItem[]) =>
|
||||
list.slice().sort((a, b) => a.compactOrder - b.compactOrder || a.id.localeCompare(b.id));
|
||||
|
||||
return {
|
||||
sidebarItems: sortItems(enhanced.filter((item) => item.compactPlacement === "sidebar")),
|
||||
settingsItems: sortItems(enhanced.filter((item) => item.compactPlacement === "settings")),
|
||||
};
|
||||
}
|
||||
|
||||
export function diffCompactMenuOverrides(items: CompactMenuEditorItem[]): CompactMenuOverride[] {
|
||||
return items.flatMap((item, index) => {
|
||||
const renamed = item.label !== item.defaultLabel;
|
||||
const moved = item.compactPlacement !== "sidebar";
|
||||
const reordered = index !== item.defaultIndex || item.compactOrder !== item.defaultIndex;
|
||||
if (!renamed && !moved && !reordered) return [];
|
||||
return {
|
||||
nodeId: item.id,
|
||||
placement: item.compactPlacement,
|
||||
sortOrder: index,
|
||||
label: renamed ? item.label : null,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export interface CompactMenuEditorItem extends CompactMenuItem {
|
||||
defaultLabel: string;
|
||||
defaultIndex: number;
|
||||
}
|
||||
@@ -250,6 +250,12 @@ export const sidebarMenuItems: MenuItem[] = [
|
||||
},
|
||||
{ id: "mgmt-skills", label: "技能管理", icon: Sparkles, path: "/page/strategy/skills" },
|
||||
{ id: "mgmt-memory", label: "记忆管理", icon: Brain, path: "/page/strategy/memory" },
|
||||
{
|
||||
id: "resource-markdown-docx-editor",
|
||||
label: "md转word",
|
||||
icon: FileText,
|
||||
path: "/page/workspace/knowledge/markdown-editor",
|
||||
},
|
||||
{
|
||||
id: "mgmt-tasks",
|
||||
label: "定时任务",
|
||||
@@ -313,16 +319,10 @@ export const sidebarMenuItems: MenuItem[] = [
|
||||
// },
|
||||
{
|
||||
id: "resource-knowledge-native",
|
||||
label: "问答梳理",
|
||||
label: "知识库管理",
|
||||
icon: BookOpen,
|
||||
path: "/page/workspace/knowledge",
|
||||
},
|
||||
{
|
||||
id: "resource-markdown-docx-editor",
|
||||
label: "Markdown 转 Word",
|
||||
icon: FileText,
|
||||
path: "/page/workspace/knowledge/markdown-editor",
|
||||
},
|
||||
{
|
||||
id: "resource-knowledge-base",
|
||||
label: "知识库资源管理",
|
||||
|
||||
@@ -69,6 +69,14 @@ function desensitizeLabels(items: MenuItem[], fn: (text: string) => string): Men
|
||||
}));
|
||||
}
|
||||
|
||||
function useDesensitizeLabel() {
|
||||
const { data: words = [] } = useSensitiveWords();
|
||||
return useMemo(
|
||||
() => (words.length > 0 ? makeDesensitizer(wordsToMap(words)) : desensitize),
|
||||
[words],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回合并了 iframe 轻应用、套用了后端「菜单覆盖层」(改名/停用/排序/层级)、
|
||||
* 按 admin 角色过滤、并对标签做**展示层脱敏**后的菜单。
|
||||
@@ -82,11 +90,7 @@ function desensitizeLabels(items: MenuItem[], fn: (text: string) => string): Men
|
||||
export function useSidebarMenuItems(isAdmin: boolean): MenuItem[] {
|
||||
const { data: iframeApps = [] } = useLightApps({ appType: "iframe", enabledOnly: true });
|
||||
const { data: overrides = [] } = useMenuOverrides();
|
||||
const { data: words = [] } = useSensitiveWords();
|
||||
const desensitizeLabel = useMemo(
|
||||
() => (words.length > 0 ? makeDesensitizer(wordsToMap(words)) : desensitize),
|
||||
[words],
|
||||
);
|
||||
const desensitizeLabel = useDesensitizeLabel();
|
||||
return useMemo(
|
||||
() =>
|
||||
desensitizeLabels(
|
||||
|
||||
Reference in new issue
Block a user