Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolve DOO-118: Add user and permissions #77

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-portal": "^1.0.4",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slider": "^1.1.2",
Expand Down
3 changes: 3 additions & 0 deletions client/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

173 changes: 90 additions & 83 deletions client/src/components/lib/BoardHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ const BoardHeader = ({
folder: '',
tags: [],
collabID: '',
users: [],
permission: '',
});
}}
>
Expand Down Expand Up @@ -159,96 +161,101 @@ const BoardHeader = ({
{/* Avatars of active tenants */}
<UserList />
{/* Comment section button */}
<Button
variant="secondary"
className="border-solid border-2 border-indigo-300 hover:border-indigo-400 stroke-indigo-300 hover:stroke-indigo-400 px-3 py-2 "
onClick={() => {
setIsViewingComments(!isViewingComments);
!isViewingComments && setIsUsingStableDiffusion(false);
}}
disabled={selectedElementIds.length !== 1}
>
<ChatBubbleIcon className="h-4 w-4" />
</Button>
{boardMeta.permission !== 'view' && (
<Button
variant="secondary"
className="border-solid border-2 border-indigo-300 hover:border-indigo-400 stroke-indigo-300 hover:stroke-indigo-400 px-3 py-2 "
onClick={() => {
setIsViewingComments(!isViewingComments);
!isViewingComments && setIsUsingStableDiffusion(false);
}}
disabled={selectedElementIds.length !== 1}
>
<ChatBubbleIcon className="h-4 w-4" />
</Button>
)}
{/* Share Dialog */}
<div
className={
'flex flex-row gap-2 items-center transition-spacing duration-300 ease-in-out'
}
>
<Button
className={cn(
buttonVariants({ variant: 'ghost', size: 'sm' }),
'h-full bg-muted text-gray-200 bg-indigo-300 hover:bg-indigo-400 hover:text-white justify-start items-center border-2 border-indigo-300 hover:border-indigo-400',
)}
onClick={() => setIsShareDialogOpen(!isShareDialogOpen)}
>
<Users2Icon className="h-4 w-4 mr-2" />
<span className="ml-auto">Share</span>
</Button>
{boardMeta.permission !== 'view' && (
<React.Fragment>
<Button
className={cn(
buttonVariants({ variant: 'ghost', size: 'sm' }),
'h-full bg-muted text-gray-200 bg-indigo-300 hover:bg-indigo-400 hover:text-white justify-start items-center border-2 border-indigo-300 hover:border-indigo-400',
)}
onClick={() => setIsShareDialogOpen(!isShareDialogOpen)}
>
<Users2Icon className="h-4 w-4 mr-2" />
<span className="ml-auto">Share</span>
</Button>
<Button
className={cn(
buttonVariants({ variant: 'ghost', size: 'sm' }),
'h-full bg-muted text-gray-200 bg-indigo-300 hover:bg-indigo-400 hover:text-white justify-start items-center border-2 border-indigo-300 hover:border-indigo-400',
)}
onClick={async () => {
try {
const state = {
allIds,
types,
strokeColors,
fillColors,
fontFamilies,
fontSizes,
bowings,
roughnesses,
strokeWidths,
fillStyles,
strokeLineDashes,
opacities,
freehandPoints,
p1,
p2,
textStrings,
isImagePlaceds,
freehandBounds,
angles,
fileIds,
};

<Button
className={cn(
buttonVariants({ variant: 'ghost', size: 'sm' }),
'h-full bg-muted text-gray-200 bg-indigo-300 hover:bg-indigo-400 hover:text-white justify-start items-center border-2 border-indigo-300 hover:border-indigo-400',
)}
onClick={async () => {
try {
const state = {
allIds,
types,
strokeColors,
fillColors,
fontFamilies,
fontSizes,
bowings,
roughnesses,
strokeWidths,
fillStyles,
strokeLineDashes,
opacities,
freehandPoints,
p1,
p2,
textStrings,
isImagePlaceds,
freehandBounds,
angles,
fileIds,
};

const updated = await axios.put(REST.board.updateBoard, {
id: boardMeta.id,
fields: { serialized: state },
});
setBoardMeta({ lastModified: updated.data.updatedAt });
updateCanvas(boardMeta.id, updated.data.updatedAt);
setWebsocketAction(
{
boardID: boardMeta.id,
lastModified: updated.data.updatedAt,
},
'updateUpdatedTime',
);
} catch (error) {
toast({
variant: 'destructive',
title: 'Something went wrong.',
description: 'There was a problem with your request.',
action: (
<ToastAction
onClick={() => window.location.reload()}
altText="Refresh"
>
Refresh
</ToastAction>
),
});
}
}}
>
<span className="ml-auto">Save</span>
</Button>
const updated = await axios.put(REST.board.updateBoard, {
id: boardMeta.id,
fields: { serialized: state },
});
setBoardMeta({ lastModified: updated.data.updatedAt });
updateCanvas(boardMeta.id, updated.data.updatedAt);
setWebsocketAction(
{
boardID: boardMeta.id,
lastModified: updated.data.updatedAt,
},
'updateUpdatedTime',
);
} catch (error) {
toast({
variant: 'destructive',
title: 'Something went wrong.',
description: 'There was a problem with your request.',
action: (
<ToastAction
onClick={() => window.location.reload()}
altText="Refresh"
>
Refresh
</ToastAction>
),
});
}
}}
>
<span className="ml-auto">Save</span>
</Button>{' '}
</React.Fragment>
)}
</div>
</div>
</div>
Expand Down
7 changes: 7 additions & 0 deletions client/src/components/lib/BoardScroll.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export const BoardScroll = () => {
return (
<div className="relative flex flex-col mx-2 h-full">
<div className="w-full h-[250px] overflow-x-scroll scroll whitespace-nowrap scroll-smooth">
{/* eslint-disable-next-line sonarjs/cognitive-complexity */}
{canvases.map((board) => (
<div
key={board.id}
Expand All @@ -94,13 +95,17 @@ export const BoardScroll = () => {

try {
let collabID = ' ';
let users = [];
let permission = '';
if (!isSelected) {
//todo
const boardState = await axios.get(REST.board.getBoard, {
params: { id: board.id, userID },
});

collabID = boardState.data.collabID;
users = boardState.data.users;
permission = boardState.data.permissionLevel;

const state = createStateWithRoughElement(
boardState.data.board.serialized,
Expand Down Expand Up @@ -164,6 +169,8 @@ export const BoardScroll = () => {
tags: isSelected ? [] : board.tags,
collabID: isSelected ? '' : collabID,
collaboratorAvatars: collaboratorAvatarUrlsMap,
users: isSelected ? '' : users,
permission: isSelected ? '' : permission,
});
} catch (error) {
toast({
Expand Down
22 changes: 20 additions & 2 deletions client/src/components/lib/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getScaleOffset } from '@/lib/canvasElements/render';
import {
IS_ELECTRON_INSTANCE,
PERIPHERAL_CODES,
REST,
SECONDS_TO_MS,
WS_TOPICS,
} from '@/constants';
Expand All @@ -42,6 +43,7 @@ import { useAuthStore } from '@/stores/AuthStore';
import CursorPresence from './CursorPresence';
import { throttle } from 'lodash';
import { idToColour } from '@/lib/userColours';
import axios from 'axios';

/**
* Main Canvas View
Expand Down Expand Up @@ -142,7 +144,7 @@ export default function Canvas() {
'setTenants',
'clearTenants',
]);
const { boardMeta } = useCanvasBoardStore(['boardMeta']);
const { boardMeta, addUser } = useCanvasBoardStore(['boardMeta', 'addUser']);
const { userEmail } = useAuthStore(['userEmail']);

// Id of the element currently being drawn.
Expand All @@ -164,7 +166,7 @@ export default function Canvas() {
socket?.on(WS_TOPICS.NOTIFY_JOIN_ROOM, initTenants);
socket?.on(WS_TOPICS.NOTIFY_LEAVE_ROOM, initTenants);
return clearTenants;
}, [socket]);
}, [socket, boardMeta.users]);

/**
* Called everytime someone joins or leaves the room, and once we initially join, to maintain
Expand All @@ -174,6 +176,22 @@ export default function Canvas() {
*/
const initTenants = async () => {
const tenantIds = (await tenancy.get(boardMeta.roomID)) as string[];

tenantIds
.map((id) => extractCollabID(id) as string)
.filter(
(id) => !new Set(boardMeta.users.map((user) => user.collabID)).has(id),
)
.forEach(async (collabID) => {
if (!collabID) return;
const userInfo = await axios.get(REST.collaborator.getUserInfo, {
params: {
id: collabID,
},
});
addUser(userInfo.data.userInfo);
});

const activeTenants = tenantIds.reduce(
(acc, id) => {
const collabId = extractCollabID(id);
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/lib/DeleteCanvasDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export const DeleteCanavasDialog = ({
folder: '',
tags: [],
collabID: '',
users: [],
permission: '',
});
axios.delete(REST.board.deleteBoard, {
params: { id: boardMeta.id },
Expand Down
Loading
Loading