Skip to content

Commit

Permalink
[FIXS NEEDED] Updates on Workspace management
Browse files Browse the repository at this point in the history
* Workspace context not fetching workspace
  • Loading branch information
GuilhermeF03 committed May 13, 2024
1 parent 2aaeae0 commit e21b69a
Show file tree
Hide file tree
Showing 19 changed files with 248 additions and 120 deletions.
30 changes: 12 additions & 18 deletions code/client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,18 @@ function App() {
element={
<WorkspaceProvider>
<Routes>
<Route
path="/"
element={
<>
<Sidebar />
<Workspace />
</>
}
/>
<Route
path="/:id"
element={
<>
<Sidebar />
<Document />
</>
}
/>
<Route path="/" element={
<>
<Sidebar />
<Workspace />
</>
} />
<Route path="/:id" element={
<>
<Sidebar />
<Document />
</>
}/>
</Routes>
</WorkspaceProvider>
}
Expand Down
75 changes: 75 additions & 0 deletions code/client/src/domain/workspace/tree/WorkspaceTree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { WorkspaceMetaData, WorkspaceResources } from '@notespace/shared/src/workspace/types/workspace.ts';
import { ResourceType, WorkspaceResourceMetadata } from '@notespace/shared/src/workspace/types/resource.ts';

export class WorkspaceTree{
private root: WorkspaceResourceMetadata

private nodes : WorkspaceResources = new Map()

constructor(meta : WorkspaceMetaData){
this.root = {...meta, type: ResourceType.DOCUMENT, parent: '', children: []}
this.nodes.set(meta.id, this.root);
}

setNodes(_nodes: WorkspaceResources, root : WorkspaceResourceMetadata){
this.nodes = _nodes
this.root = root
}

addNode(node: WorkspaceResourceMetadata){
const { parent } = node
const parentNode = this.nodes.get(parent);
if(parentNode) parentNode.children.push(node.id)
this.nodes.set(node.id, node)
}

updateNode(id: string, props: Partial<WorkspaceResourceMetadata>){
const node = this.nodes.get(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)
const { parent } = node;
const parentNode = this.nodes.get(parent);
if(parentNode){
const index = parentNode.children.indexOf(node.id);
if(index !== -1) parentNode.children.splice(index, 1);
this.nodes.delete(node.id)
}
}

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

if(parentNode){
const index = parentNode.children.indexOf(node.id);
if(index !== -1) parentNode.children.splice(index, 1);
}
const newParentNode = this.nodes.get(newParent);
if(!newParentNode) throw new Error("Invalid parent id:" + newParent)
newParentNode.children.push(node.id)

node.parent = newParent
}

*traverse() : IterableIterator<WorkspaceResourceMetadata>{
const stack: WorkspaceResourceMetadata[] = [];
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());
}
}

get resources() {
return this.nodes
}
}
7 changes: 7 additions & 0 deletions code/client/src/domain/workspace/tree/useWorkspaceTree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useMemo } from 'react';
import { WorkspaceTree } from '@domain/workspace/tree/WorkspaceTree.ts';
import { WorkspaceMetaData } from '@notespace/shared/src/workspace/types/workspace.ts';

export function useWorkspaceTree(meta : WorkspaceMetaData) {
return useMemo(() => new WorkspaceTree(meta), [meta]);
}
Empty file.
2 changes: 1 addition & 1 deletion code/client/src/services/document/documentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ function documentService(http: HttpCommunication, wid: string) {
};
}

export default documentService;
export default documentService;
2 changes: 1 addition & 1 deletion code/client/src/services/document/useDocumentService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import documentService from '@/services/document/documentService.ts';
import { useMemo } from 'react';
import { useCommunication } from '@/services/communication/context/useCommunication.ts';
import { useParams } from 'react-router-dom';
import documentService from '@/services/document/documentService.ts';

function useDocumentService() {
const { http } = useCommunication();
Expand Down
35 changes: 35 additions & 0 deletions code/client/src/services/resource/resourceService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { HttpCommunication } from '@/services/communication/http/httpCommunication.ts';
import {
ResourceInputModel,
ResourceType,
WorkspaceResource,
} from '@notespace/shared/src/workspace/types/resource.ts';

function resourceService(http: HttpCommunication, wid: string) {
async function getResource(id: string): Promise<WorkspaceResource> {
return await http.get(`/workspaces/${wid}/${id}`);
}

async function createResource(name: string, type: ResourceType): Promise<string> {
const resource: ResourceInputModel = { name, type };
const { id } = await http.post(`/workspaces/${wid}`, resource);
return id;
}

async function deleteResource(id: string): Promise<void> {
await http.delete(`/workspaces/${wid}/${id}`);
}

async function updateResource(id: string, newProps: Partial<ResourceInputModel>): Promise<void> {
await http.put(`/workspaces/${wid}/${id}`, newProps);
}

return {
getResource,
createResource,
deleteResource,
updateResource,
};
}

export default resourceService;
13 changes: 13 additions & 0 deletions code/client/src/services/resource/useResourceService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useMemo } from 'react';
import { useCommunication } from '@/services/communication/context/useCommunication.ts';
import { useParams } from 'react-router-dom';
import resourceService from '@/services/resource/resourceService.ts';

function useResourceService() {
const { http } = useCommunication();
const { wid } = useParams();
if (!wid) throw new Error('Cannot use document services outside of a workspace');
return useMemo(() => resourceService(http, wid), [http, wid]);
}

export default useResourceService;
2 changes: 1 addition & 1 deletion code/client/src/ui/pages/document/Document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import useFugue from '@domain/editor/crdt/useFugue';
import { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { useCommunication } from '@/services/communication/context/useCommunication';
import useDocumentService from '@/services/document/useDocumentService.ts';
import useError from '@domain/error/useError';
import './Document.scss';
import useDocumentService from '@/services/document/useDocumentService.ts';

function Document() {
const communication = useCommunication();
Expand Down
33 changes: 21 additions & 12 deletions code/client/src/ui/pages/workspace/Workspace.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
import WorkspaceHeader from '@ui/pages/workspace/components/WorkspaceHeader';
import DocumentView from '@ui/pages/workspace/components/DocumentView.tsx';
import useError from '@domain/error/useError';
import useDocuments from '@ui/pages/workspace/hooks/useDocuments.ts';
import useWorkspaceTreeOperations from '@ui/pages/workspace/hooks/useWorkspaceTreeOperations.ts';
import './Workspace.scss';
import useWorkspace from '@domain/workspace/useWorkspace.ts';
import { DocumentResourceMetadata, ResourceType } from '@notespace/shared/src/workspace/types/resource.ts';

function Workspace() {
const { workspace } = useWorkspace();
const { documents, createDocument, deleteDocument, updateDocument } = useDocuments();
const { workspace } = useWorkspace()
const { publishError } = useError();

const {
resources,
createResource,
deleteResource,
updateResource
} = useWorkspaceTreeOperations();

return (
<div className="workspace">
<h2>Workspace {workspace?.name}</h2>
<WorkspaceHeader onCreateNew={() => createDocument().catch(publishError)}></WorkspaceHeader>
<WorkspaceHeader onCreateNew={() => createResource(ResourceType.DOCUMENT).catch(publishError)}></WorkspaceHeader>
<ul className="items">
{documents.map(document => (
<DocumentView
key={document.id}
document={document}
onDelete={() => deleteDocument(document.id).catch(publishError)}
onDuplicate={() => createDocument(document.name).catch(publishError)}
onRename={title => updateDocument(document.id, title).catch(publishError)}
/>
{resources.map(resource => (
resource.type === ResourceType.DOCUMENT
? <DocumentView
key={resource.id}
document={resource as DocumentResourceMetadata}
onDelete={() => deleteResource(resource.id).catch(publishError)}
onDuplicate={() => createResource(ResourceType.DOCUMENT, resource.name).catch(publishError)}
onRename={name => updateResource(resource.id, {name}).catch(publishError)}
/>
: <></>
))}
</ul>
</div>
Expand Down
64 changes: 0 additions & 64 deletions code/client/src/ui/pages/workspace/hooks/useDocuments.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { WorkspaceResourceMetadata, } from '@notespace/shared/src/workspace/types/resource.ts';
import useSocketListeners from '@/services/communication/socket/useSocketListeners.ts';
import { ResourceType } from '@notespace/shared/src/workspace/types/resource.ts';
import { useCommunication } from '@/services/communication/context/useCommunication.ts';
import useResourceService from '@/services/resource/useResourceService.ts';
import { WorkspaceTree } from '@domain/workspace/tree/WorkspaceTree.ts';
import { WorkspaceMetaData } from '@notespace/shared/src/workspace/types/workspace.ts';
import useWorkspace from '@domain/workspace/useWorkspace.ts';

export function useWorkspaceTreeOperations() {
const { workspace } = useWorkspace();
const tree = new WorkspaceTree(workspace as WorkspaceMetaData);
const { socket } = useCommunication();
const services = useResourceService()

async function createResource(type: ResourceType, title: string = '') {
const id = await services.createResource(title, type);

const resourceMeta: WorkspaceResourceMetadata = {
id,
name: title,
type,
parent: '',
children:[]
};
tree.addNode(resourceMeta);
}

async function deleteResource(id: string) {
await services.deleteResource(id);
tree.removeNode(id)
}

async function updateResource(id: string, props : Partial<WorkspaceResourceMetadata>) {
await services.updateResource(id, props);
tree.updateNode(id, props)
}

useSocketListeners(socket, {
resourceCreated: tree.addNode,
resourceDeleted: tree.removeNode,
resourceUpdated: tree.updateNode,
});

return {
resources: Array.from(tree.traverse()),
createResource,
deleteResource,
updateResource,
};
}

export default useWorkspaceTreeOperations;
Loading

0 comments on commit e21b69a

Please sign in to comment.