Skip to content

Commit

Permalink
Progress on Workspace Tree
Browse files Browse the repository at this point in the history
  • Loading branch information
R1c4rdCo5t4 committed May 17, 2024
1 parent 12af28c commit a860e67
Show file tree
Hide file tree
Showing 42 changed files with 381 additions and 270 deletions.
99 changes: 51 additions & 48 deletions code/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,63 @@ import './App.scss';
import { ErrorProvider } from '@ui/contexts/error/ErrorContext';
import Sidebar from '@ui/components/sidebar/Sidebar';
import { WorkspaceProvider } from '@ui/contexts/workspace/WorkspaceContext';
import Home from "@ui/pages/home/Home";
import {ClientLogCaller} from "@/utils/logging";
import Home from '@ui/pages/home/Home';
import { ClientLogCaller } from '@/utils/logging';
import getLogger from '@notespace/shared/src/utils/logging';
import {CommunicationProvider} from "@ui/contexts/communication/CommunicationContext";

import { CommunicationProvider } from '@ui/contexts/communication/CommunicationContext';
import { useEffect } from 'react';

const logger = getLogger(ClientLogCaller.React);

function App() {
useEffect(() => {
logger.logSuccess('App started');
return (
<div className="app">
<ErrorProvider>
<CommunicationProvider>
<Router>
<Header />
<div className="content">
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/workspaces/:wid/*"
element={
<WorkspaceProvider>
<Routes>
<Route
path="/"
element={
<>
<Sidebar />
<Workspace />
</>
}
/>
<Route
path="/:id"
element={
<>
<Sidebar />
<Document />
</>
}
/>
</Routes>
</WorkspaceProvider>
}
/>
<Route path="*" element={<NotFound />} />
</Routes>
</div>
</Router>
</CommunicationProvider>
</ErrorProvider>
</div>
);
}, []);

return (
<div className="app">
<ErrorProvider>
<CommunicationProvider>
<Router>
<Header />
<div className="content">
<Routes>
<Route path="/" element={<Home />} />
<Route
path="/workspaces/:wid/*"
element={
<WorkspaceProvider>
<Routes>
<Route
path="/"
element={
<>
<Sidebar />
<Workspace />
</>
}
/>
<Route
path="/:id"
element={
<>
<Sidebar />
<Document />
</>
}
/>
</Routes>
</WorkspaceProvider>
}
/>
<Route path="*" element={<NotFound />} />
</Routes>
</div>
</Router>
</CommunicationProvider>
</ErrorProvider>
</div>
);
}

export default App;
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
SplitNodeOperation,
UnsetNodeOperation,
} from '@domain/editor/operations/history/types';
import {pointToCursor} from '@domain/editor/slate/utils/selection';
import { pointToCursor } from '@domain/editor/slate/utils/selection';

const reverseTypes: { [key: string]: HistoryOperation['type'] } = {
insert_text: 'remove_text',
Expand Down Expand Up @@ -133,23 +133,23 @@ function toHistoryOperations(editor: Editor, operations: Batch | undefined, reve
const lineOffset = (line: number) => (line === 0 ? 0 : 1);

// Remove whole line
if(operation.path.length === 1) {
const start = pointToCursor(editor, {path: operation.path, offset: 0});
const end = pointToCursor(editor, {path: [operation.path[0] + 1, 0], offset: 0});

const selection = { start, end };
return {
type: insert_mode ? 'insert_node' : 'remove_node',
selection,
node: operation.node,
};
if (operation.path.length === 1) {
const start = pointToCursor(editor, { path: operation.path, offset: 0 });
const end = pointToCursor(editor, { path: [operation.path[0] + 1, 0], offset: 0 });

const selection = { start, end };
return {
type: insert_mode ? 'insert_node' : 'remove_node',
selection,
node: operation.node,
};
}

if (!Text.isText(operation.node)) return;

if (operation.node.text === '') return undefined;

if(!selectionBefore) return undefined
if (!selectionBefore) return undefined;

const cursor = pointToCursor(editor, selectionBefore.anchor);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@ export const getLeafRenderer = ({ attributes, leaf, children }: RenderLeafProps)
if (!renderer) continue;
children = renderer(children);
}
if(leaf.cursor){
if (leaf.cursor) {
const { color, range, styles } = leaf.cursor;
children = Range.isCollapsed(range!)
? <Cursor color={color} styles={styles} children={children} />
: <Selection color={color} children={children} />
children = Range.isCollapsed(range!) ? (
<Cursor color={color} styles={styles} children={children} />
) : (
<Selection color={color} children={children} />
);
}
return <span {...attributes}>{children}</span>;
};
2 changes: 0 additions & 2 deletions code/client/src/domain/editor/slate/utils/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,6 @@ export function pointToCursor(editor: Editor, point: Point): Cursor {
}
}



return cursor;
}

Expand Down
64 changes: 38 additions & 26 deletions code/client/src/domain/workspaces/tree/WorkspaceTree.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import { ResourceType, WorkspaceResourceMetadata } from '@notespace/shared/src/workspace/types/resource';

type WorkspaceTreeNode = WorkspaceResourceMetadata;
export type WorkspaceTreeNode = WorkspaceResourceMetadata;

export class WorkspaceTree {
private root: WorkspaceTreeNode;
private nodes: Map<string, WorkspaceTreeNode> = new Map();

constructor() {
this.root = {
id: 'root',
name: 'root',
parent: '',
children: [],
type: ResourceType.FOLDER,
};
this.root = this.rootNode();
}

setNodes(nodes: Record<string, WorkspaceTreeNode>) {
const rootNode = nodes['root'];
if (!rootNode) throw new Error('Workspace tree root node missing');
this.root = rootNode;
this.nodes = new Map(Object.entries(nodes));
setNodes(nodes: WorkspaceTreeNode[]) {
this.nodes = new Map(nodes.map(node => [node.id, node]));
this.nodes.set('root', this.root);
this.root = this.rootNode();
}

addNode(node: WorkspaceTreeNode) {
Expand All @@ -32,13 +25,13 @@ export class WorkspaceTree {

updateNode(id: string, props: Partial<WorkspaceResourceMetadata>) {
const node = this.nodes.get(id);
if (!node) throw new Error('Invalid id:' + id);
if (!node) throw new Error('Invalid id: ' + id);
Object.assign(node, props);
}

removeNode(id: string) {
const node = this.nodes.get(id);
if (!node) throw new Error('Invalid id:' + id);
if (!node) throw new Error('Invalid id: ' + id);
const { parent } = node;
const parentNode = this.nodes.get(parent);
if (parentNode) {
Expand All @@ -50,7 +43,7 @@ export class WorkspaceTree {

moveNode(id: string, newParent: string) {
const node = this.nodes.get(id);
if (!node) throw new Error('Invalid id:' + id);
if (!node) throw new Error('Invalid id: ' + id);
const { parent } = node;
const parentNode = this.nodes.get(parent);

Expand All @@ -59,24 +52,43 @@ export class WorkspaceTree {
if (index !== -1) parentNode.children.splice(index, 1);
}
const newParentNode = this.nodes.get(newParent);
if (!newParentNode) throw new Error('Invalid parent id:' + newParent);
if (!newParentNode) throw new Error('Invalid parent id: ' + newParent);
newParentNode.children.push(node.id);

node.parent = newParent;
}

*traverse(): IterableIterator<WorkspaceTreeNode> {
const stack: WorkspaceTreeNode[] = [];
stack.push(this.root);

while (stack.length > 0) {
const node = stack.pop()!;
yield node;
stack.push(...node.children.map(id => this.nodes.get(id)!).reverse());
*traverse(node = this.root, set = new Set()): IterableIterator<[WorkspaceTreeNode, WorkspaceTreeNode[]]> {
const children = (node.children?.map(id => this.nodes.get(id)) as WorkspaceTreeNode[]) || [];
if (node.id !== 'root' && !set.has(node.id)) {
children.forEach(child => set.add(child.id));
yield [node, children];
}
for (const child of children) {
yield* this.traverse(child, set);
}
}

clone() {
const newTree = new WorkspaceTree();
newTree.root = { ...this.root }; // shallow copy guarantees re-render
newTree.nodes = this.nodes;
return newTree;
}

get resources() {
return this.nodes;
}

rootNode() {
const children = Array.from(this.nodes.values())
.filter(node => node.parent === 'root')
.map(node => node.id);
return {
id: 'root',
name: 'root',
parent: '',
children: children,
type: ResourceType.FOLDER,
};
}
}
4 changes: 2 additions & 2 deletions code/client/src/services/resource/resourceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ function resourceService(http: HttpCommunication, wid: string) {
return await http.get(`/workspaces/${wid}/${id}`);
}

async function createResource(name: string, type: ResourceType): Promise<string> {
const resource: ResourceInputModel = { name, type };
async function createResource(name: string, type: ResourceType, parent: string): Promise<string> {
const resource: ResourceInputModel = { name, type, parent };
const { id } = await http.post(`/workspaces/${wid}`, resource);
return id;
}
Expand Down
10 changes: 0 additions & 10 deletions code/client/src/ui/components/sidebar/Sidebar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,4 @@
button:hover {
color: dimgray;
}

.files {
li > * {
display: flex;
flex-direction: row;
align-items: center;
justify-content: left;
gap: 1vh;
}
}
}
21 changes: 6 additions & 15 deletions code/client/src/ui/components/sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { IoMenu } from 'react-icons/io5';
import { Link, useParams } from 'react-router-dom';
import { Link } from 'react-router-dom';
import { RiMenuFold2Line, RiMenuFoldLine } from 'react-icons/ri';
import useWorkspace from '@ui/contexts/workspace/useWorkspace';
import useSidebarState from '@ui/components/sidebar/hooks/useSidebarState.ts';
import ResourceView from '@ui/components/sidebar/components/ResourceView.tsx';
import useSidebarState from '@ui/components/sidebar/hooks/useSidebarState';
import './Sidebar.scss';
import WorkspaceTree from '@ui/components/sidebar/components/WorkspaceTree';
import { useEffect } from 'react';

function Sidebar() {
const { isOpen, isLocked, handleClick, handleMouseEnter, handleMouseLeave } = useSidebarState();
const { workspace, resources } = useWorkspace();
const { wid } = useParams();
const { workspace, tree } = useWorkspace();

return (
<div
Expand All @@ -31,23 +31,14 @@ function Sidebar() {
<Link to="/">Home</Link>
</li>
<li>Recent</li>
<li>Workspaces</li>
<li>Settings</li>
{workspace && (
<>
<hr />
<h3>
<Link to={`/workspaces/${workspace.id}`}>{workspace.name}</Link>
</h3>
{resources && (
<ul className="files">
{resources?.map(resource => (
<li key={resource.id}>
<ResourceView resource={{ ...resource, workspace: wid! }} />
</li>
))}
</ul>
)}
<WorkspaceTree workspace={workspace} tree={tree} />
</>
)}
</ul>
Expand Down
Loading

0 comments on commit a860e67

Please sign in to comment.