add: markdown permission setting

improve: template
This commit is contained in:
h z
2025-04-25 00:39:01 +01:00
parent c20cb168ff
commit 9ea44385ee
17 changed files with 893 additions and 372 deletions

View File

@@ -1,95 +1,50 @@
import PermissionGuard from "../PermissionGuard";
import PathNode from "./PathNode";
import React, { useContext, useEffect } from 'react';
import "./SideNavigation.css";
import {useDeletePath, usePaths, useUpdatePath} from "../../utils/queries/path-queries";
import React from 'react';
import {useTree} from "../../utils/queries/tree-queries";
import TreeTab from "./SideTabs/TreeTab";
import TemplateTab from "./SideTabs/TemplateTab";
import { AuthContext } from "../../AuthProvider";
const SideNavigation = () => {
const {data: tree, isLoading, error} = useTree();
const deletePath = useDeletePath();
const updatePath = useUpdatePath();
const [keyword, setKeyword] = React.useState("");
const handleDelete = (id) => {
if (window.confirm("Are you sure you want to delete this path?")){
deletePath.mutate(id, {
onError: (err) => {
alert("Failed to delete path");
},
});
const { roles } = useContext(AuthContext);
const [selectedTab, setSelectedTab] = React.useState("tree");
const allTabs = [
{ id: "tree", label: "Tree", component: <TreeTab /> },
{ id: "templates", label: "Templates", component: <TemplateTab /> },
];
const visibleTabs = roles.includes("admin")
? allTabs
: allTabs.filter(tab => tab.id === "tree");
useEffect(() => {
if (!visibleTabs.find(tab => tab.id === selectedTab)) {
setSelectedTab(visibleTabs[0]?.id || "");
}
};
}, [visibleTabs, selectedTab]);
const filterTree = (t, k) => {
if(t === undefined)
return undefined;
if (t.type === "path") {
if (t.name.includes(k)) {
return { ...t };
}
const filteredChildren = (t.children || [])
.map(c => filterTree(c, k))
.filter(Boolean);
const current = visibleTabs.find(t => t.id === selectedTab);
if (filteredChildren.length > 0) {
return { ...t, children: filteredChildren };
}
} else if (t.type === "markdown") {
if (t.title.includes(k)) {
return { ...t };
}
}
return undefined;
};
const filteredTree = filterTree(tree, keyword);
const handleSave = (id, newName) => {
updatePath.mutate({ id, data: {name: newName }} , {
onError: (err) => {
alert("Failed to update path");
}
});
};
if (isLoading) return <aside className="menu"><p>Loading...</p></aside>;
if (error) return <aside className="menu"><p>Error loading tree</p></aside>;
return (
<aside className="menu">
<div className="control is-expanded">
<input
className="input is-small"
type="text"
placeholder="Search..."
onChange={(e) => setKeyword(e.target.value)}
/>
<aside className="side-nav">
<div className="tabs is-small">
<ul>
{visibleTabs.map(tab => (
<li
key={tab.id}
className={tab.id === selectedTab ? "is-active" : ""}
>
<a onClick={() => setSelectedTab(tab.id)}>
{tab.label}
</a>
</li>
))}
</ul>
</div>
<div className="tab-content">
{current?.component}
</div>
<PermissionGuard rolesRequired={["admin", "creator"]}>
<a
href="/markdown/create"
className="button is-primary is-small"
>
Create New Markdown
</a>
<a
href="/template/create"
className="button is-primary is-small"
>
Create New Template
</a>
</PermissionGuard>
{!filteredTree || filteredTree.length === 0 ?
<p>No Result</p> :
<PathNode
key={1}
path={filteredTree}
isRoot={true}
onSave={handleSave}
onDelete={handleDelete}
/>
}
</aside>
);
};