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

Buckets view feature implementation #567

Merged
merged 28 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c25bbad
Added board defaut view attribute
vkorir Aug 22, 2023
88fa688
Option to set default view: canvas,workspace,buckets
vkorir Aug 22, 2023
1cdccd6
Generated ck buckets component view
vkorir Aug 22, 2023
c173818
Configurable board view settings: teacher can enable/disable canvas/w…
vkorir Aug 23, 2023
d89d8d9
Refactored toolbar menu
vkorir Sep 5, 2023
bd50c1a
Added navbar menu placeholder for ck-buckets
vkorir Sep 5, 2023
b603306
Enabled adding/removing buckets from buckets view
vkorir Sep 6, 2023
4c0d801
Added button for creating new buckets
vkorir Sep 6, 2023
ea07f8b
Common shared toolbar menu component for canvas,workspace,monitor,buc…
vkorir Sep 11, 2023
451773e
Redirect users when view is disabled
vkorir Sep 23, 2023
b5af120
Display bucket posts on buckets view
vkorir Oct 2, 2023
2592155
Persisted post transfer between buckets
vkorir Oct 16, 2023
8d7b3d1
Updated bucket model to persist display on bucket view
vkorir Oct 16, 2023
73a0ffb
Run prettier code formatter
vkorir Oct 16, 2023
ec1230b
Following fixes:
LunarFang416 Nov 13, 2023
0aa1ab3
Add monitor as one of the default and changeble views
LunarFang416 Nov 13, 2023
1a0c7e5
list post only shown to teachers
LunarFang416 Nov 13, 2023
11ad507
increase the post width in bucket view
LunarFang416 Nov 13, 2023
d73d648
bucket height responsive
LunarFang416 Nov 13, 2023
36c85b4
allow more column in bucket view if there is space
LunarFang416 Nov 13, 2023
f341e0e
handle duplicate posts in bucket view
LunarFang416 Nov 13, 2023
87cea66
Merge branch 'develop' of https://github.com/encorelab/ck-board into …
LunarFang416 Nov 13, 2023
a0a00fa
run linter
LunarFang416 Nov 13, 2023
91b3e4b
Add view navigation for enabled views in a board
LunarFang416 Nov 13, 2023
bba91cd
further bucket view tweaks
LunarFang416 Nov 18, 2023
8526e05
styling tweaks
LunarFang416 Nov 28, 2023
fbaa3a6
Merge branch 'develop' of https://github.com/encorelab/ck-board into …
LunarFang416 Nov 28, 2023
4bb709b
Merge branch 'develop' into vk/bucket-view
LunarFang416 Mar 15, 2024
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
6 changes: 5 additions & 1 deletion backend/src/api/boards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ router.post('/:id', async (req, res) => {
upvoteLimit,
visible,
defaultTodoDateRange,
defaultView,
viewSettings,
} = req.body;

const board: Partial<BoardModel> = Object.assign(
Expand All @@ -73,7 +75,9 @@ router.post('/:id', async (req, res) => {
initialZoom === undefined ? null : { initialZoom },
upvoteLimit === undefined ? null : { upvoteLimit },
visible === undefined ? true : { visible },
defaultTodoDateRange === undefined ? null : { defaultTodoDateRange }
defaultTodoDateRange === undefined ? null : { defaultTodoDateRange },
defaultView === undefined ? null : { defaultView },
viewSettings === undefined ? null : { viewSettings }
);

const updatedBoard = await dalBoard.update(id, board);
Expand Down
5 changes: 3 additions & 2 deletions backend/src/api/buckets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ router.post('/', async (req, res) => {

router.post('/:id', async (req, res) => {
const id = req.params.id;
const { name, posts } = req.body;
const { name, posts, addedToView } = req.body;

const bucket: Partial<BucketModel> = Object.assign(
{},
name === null ? null : { name },
posts === null ? null : { posts }
posts === null ? null : { posts },
addedToView === null ? null : { addedToView }
);

const updatedBucket = await dalBucket.update(id, bucket);
Expand Down
31 changes: 29 additions & 2 deletions backend/src/models/Board.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
prop,
Severity,
getModelForClass,
modelOptions,
Severity,
prop,
setGlobalOptions,
} from '@typegoose/typegoose';
import { TagModel } from './Tag';
Expand Down Expand Up @@ -85,6 +85,20 @@ export class DateRange {
public end!: Date;
}

export class ViewSettings {
@prop({ required: false })
public allowCanvas?: boolean;

@prop({ required: false })
public allowWorkspace?: boolean;

@prop({ required: false })
public allowBuckets?: boolean;

@prop({ required: false })
public allowMonitor?: boolean;
}

export enum BoardScope {
PROJECT_SHARED = 'PROJECT_SHARED',
PROJECT_PERSONAL = 'PROJECT_PERSONAL',
Expand All @@ -95,6 +109,13 @@ export enum BoardType {
QUESTION_AUTHORING = 'QUESTION_AUTHORING',
}

export enum ViewType {
CANVAS = 'CANVAS',
WORKSPACE = 'WORKSPACE',
BUCKETS = 'BUCKETS',
MONITOR = 'MONITOR',
}

@modelOptions({ schemaOptions: { collection: 'boards', timestamps: true } })
export class BoardModel {
@prop({ required: true })
Expand Down Expand Up @@ -138,6 +159,12 @@ export class BoardModel {

@prop({ required: false })
public defaultTodoDateRange?: DateRange;

@prop({ required: false })
public defaultView?: ViewType;

@prop({ required: false, type: () => ViewSettings })
public viewSettings?: ViewSettings;
}

export default getModelForClass(BoardModel);
3 changes: 3 additions & 0 deletions backend/src/models/Bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export class BucketModel {

@prop({ required: true })
public posts!: string[];

@prop({ required: false })
public addedToView?: boolean;
}

export default getModelForClass(BucketModel);
21 changes: 16 additions & 5 deletions frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CanvasComponent } from './components/canvas/canvas.component';
import { CkWorkspaceComponent } from './components/ck-workspace/ck-workspace.component';
import { CkBucketsComponent } from './components/ck-buckets/ck-buckets.component';
import { CkMonitorComponent } from './components/ck-monitor/ck-monitor.component';
import { CkWorkspaceComponent } from './components/ck-workspace/ck-workspace.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ErrorComponent } from './components/error/error.component';
import { LoginComponent } from './components/login/login.component';
import { ProjectDashboardComponent } from './components/project-dashboard/project-dashboard.component';
import { ProjectTodoListModalComponent } from './components/project-todo-list-modal/project-todo-list-modal.component';
import { RegisterComponent } from './components/register/register.component';
import { SsoLoginComponent } from './components/sso-login/sso-login.component';
import { AuthGuard } from './guards/auth.guard';
import { BoardGuard } from './guards/board.guard';
import { ProjectGuard } from './guards/project.guard';
import { SsoLoginComponent } from './components/sso-login/sso-login.component';
import { SsoGuard } from './guards/sso.guard';
import { ProjectTodoListModalComponent } from './components/project-todo-list-modal/project-todo-list-modal.component';

const routes: Routes = [
{ path: '', canActivate: [SsoGuard], component: LoginComponent },
Expand Down Expand Up @@ -43,15 +44,25 @@ const routes: Routes = [
component: CanvasComponent,
canActivate: [SsoGuard, AuthGuard, ProjectGuard],
},
{
path: 'project/:projectID/board/:boardID/canvas',
component: CanvasComponent,
canActivate: [AuthGuard, ProjectGuard, BoardGuard],
},
{
path: 'project/:projectID/board/:boardID/workspace',
component: CkWorkspaceComponent,
canActivate: [AuthGuard, ProjectGuard],
canActivate: [AuthGuard, ProjectGuard, BoardGuard],
},
{
path: 'project/:projectID/board/:boardID/buckets',
component: CkBucketsComponent,
canActivate: [AuthGuard, ProjectGuard, BoardGuard],
},
{
path: 'project/:projectID/board/:boardID/monitor',
component: CkMonitorComponent,
canActivate: [AuthGuard, ProjectGuard],
canActivate: [AuthGuard, ProjectGuard, BoardGuard],
},
{
path: 'project/:projectID/todo',
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,13 @@
import { TodoItemCardModalComponent } from './components/todo-item-card-modal/todo-item-card-modal.component';
import { LearnerModelsComponent } from './components/learner-models/learner-models.component';
import { AddLearnerModalComponent } from './components/add-learner-modal/add-learner-modal.component';
import { CkBucketsComponent } from './components/ck-buckets/ck-buckets.component';
import { ToolbarMenuComponent } from './components/toolbar-menu/toolbar-menu.component';
import { ViewNavigationComponent } from './components/view-navigation/view-navigation.component';

const config: SocketIoConfig = { url: 'http://localhost:8000', options: {} };

export function tokenGetter() {

Check warning on line 71 in frontend/src/app/app.module.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Missing return type on function
return localStorage.getItem('access_token');
}

Expand Down Expand Up @@ -109,6 +112,9 @@
TodoItemCardModalComponent,
LearnerModelsComponent,
AddLearnerModalComponent,
CkBucketsComponent,
ToolbarMenuComponent,
ViewNavigationComponent,
],
imports: [
BrowserModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,30 @@ <h2 style="margin-top: 20px">Board Type</h2>
Display task description when board is opened
</mat-checkbox>
</p>
<p>
<label><strong>Default View</strong></label>
<mat-radio-group [(ngModel)]="defaultView">
<mat-radio-button style="margin-left: 10px;" value="CANVAS"
[disabled]="viewSettings.allowCanvas === false">Canvas</mat-radio-button>
<mat-radio-button style="margin-left: 10px;" value="WORKSPACE"
[disabled]="viewSettings.allowWorkspace === false">Workspace</mat-radio-button>
<mat-radio-button style="margin-left: 10px;" value="BUCKETS"
[disabled]="viewSettings.allowBuckets === false">Buckets</mat-radio-button>
<mat-radio-button style="margin-left: 10px;" value="MONITOR"
[disabled]="viewSettings.allowMonitor === false">Monitor</mat-radio-button>
</mat-radio-group>
</p>
<p>
<label><strong>Enable/Disable Views</strong></label>
<mat-checkbox style="margin-left: 10px;" [(ngModel)]="viewSettings.allowCanvas"
[disabled]="defaultView === 'CANVAS'">Canvas</mat-checkbox>
<mat-checkbox style="margin-left: 10px;" [(ngModel)]="viewSettings.allowWorkspace"
[disabled]="defaultView === 'WORKSPACE'">Workspace</mat-checkbox>
<mat-checkbox style="margin-left: 10px;" [(ngModel)]="viewSettings.allowBuckets"
[disabled]="defaultView === 'BUCKETS'">Buckets</mat-checkbox>
<mat-checkbox style="margin-left: 10px;" [(ngModel)]="viewSettings.allowMonitor"
[disabled]="defaultView === 'MONITOR'">Monitor</mat-checkbox>
</p>
<h4>Set Background Image:</h4>
<mat-chip (click)="compressFile()" color="primary" selected>
<mat-icon class="chip-icon">upload</mat-icon>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { UserService } from 'src/app/services/user.service';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { fabric } from 'fabric';
import {
BoardPermissions,
BoardScope,
BoardType,
ViewSettings,
ViewType,
} from 'src/app/models/board';
import { Project } from 'src/app/models/project';
import { FileUploadService } from 'src/app/services/fileUpload.service';
import { TAG_DEFAULT_COLOR } from 'src/app/utils/constants';
import { Tag } from 'src/app/models/tag';
import Utils, { generateUniqueID } from 'src/app/utils/Utils';
import { FileUploadService } from 'src/app/services/fileUpload.service';
import { UserService } from 'src/app/services/user.service';
import { FabricUtils, ImageSettings } from 'src/app/utils/FabricUtils';
import { fabric } from 'fabric';
import { BoardPermissions, BoardScope, BoardType } from 'src/app/models/board';
import { generateUniqueID } from 'src/app/utils/Utils';
import { TAG_DEFAULT_COLOR } from 'src/app/utils/constants';

@Component({
selector: 'app-add-board-modal',
Expand All @@ -23,10 +29,13 @@
permissions: BoardPermissions;
boardType: BoardType = BoardType.BRAINSTORMING;

defaultView: ViewType = ViewType.BUCKETS;
viewSettings: ViewSettings;

boardName = '';
boardScope = BoardScope.PROJECT_SHARED;

bgImgURL: any = null;

Check warning on line 38 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Unexpected any. Specify a different type
bgImgSettings: ImageSettings;

taskTitle = '';
Expand All @@ -36,7 +45,7 @@
defaultTags: Tag[];

newTagText = '';
newTagColor: any = TAG_DEFAULT_COLOR;

Check warning on line 48 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Unexpected any. Specify a different type

initialZoom = 100;
backgroundSize = 100;
Expand All @@ -53,7 +62,7 @@
public userService: UserService,
public fileUploadService: FileUploadService,
public fabricUtils: FabricUtils,
@Inject(MAT_DIALOG_DATA) public data: any

Check warning on line 65 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Argument 'data' should be typed with a non-any type

Check warning on line 65 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Unexpected any. Specify a different type
) {
this.permissions = {
allowStudentMoveAny: true,
Expand All @@ -67,6 +76,12 @@
showSnackBarStudent: false,
allowTracing: false,
};
this.viewSettings = {
allowCanvas: true,
allowWorkspace: true,
allowBuckets: true,
allowMonitor: true,
};
this.projects = data.projects;
this.selectedProject = data.defaultProject || '';
}
Expand All @@ -76,7 +91,7 @@
this.defaultTags = this.fabricUtils.getDefaultTagsForBoard(this.boardID);
}

addTag() {

Check warning on line 94 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Missing return type on function
this.tags.push({
tagID: generateUniqueID(),
boardID: this.boardID,
Expand All @@ -86,11 +101,11 @@
this.newTagText = '';
}

removeTag(tagRemove) {

Check warning on line 104 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Missing return type on function

Check warning on line 104 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Argument 'tagRemove' should be typed
this.tags = this.tags.filter((tag) => tag != tagRemove);
}

async compressFile() {

Check warning on line 108 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Missing return type on function
const image = await this.fileUploadService.compressFile();
this.bgImgURL = await this.fileUploadService.upload(image);
fabric.Image.fromURL(this.bgImgURL, async (image) => {
Expand All @@ -98,7 +113,7 @@
});
}

handleDialogSubmit() {

Check warning on line 116 in frontend/src/app/components/add-board-modal/add-board-modal.component.ts

View workflow job for this annotation

GitHub Actions / Linting and Code Formating Check CI (frontend)

Missing return type on function
this.data.createBoard(
{
projectID: this.selectedProject,
Expand All @@ -119,6 +134,8 @@
initialZoom: this.initialZoom,
upvoteLimit: this.upvoteLimit,
visible: true,
defaultView: this.defaultView,
viewSettings: this.viewSettings,
},
this.selectedProject
);
Expand Down
89 changes: 3 additions & 86 deletions frontend/src/app/components/canvas/canvas.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,97 +14,14 @@
<mat-icon>file_copy</mat-icon>
</button>
<span style="flex: 1 1 auto"></span>
<!-- HAMBURGER -->
<button navbarMenu mat-icon-button [matMenuTriggerFor]="navbarMenu">
<mat-icon>dehaze</mat-icon>
</button>
<mat-menu #navbarMenu="matMenu">
<button
mat-menu-item
(click)="openCkMonitor()"
>
<mat-icon>
<span class="material-symbols-outlined">monitoring</span>
</mat-icon>
CK Monitor
</button>
<button mat-menu-item (click)="openWorkspace()">
<mat-icon>
check_box
</mat-icon>
CK Workspace
</button>
<button
mat-menu-item
*ngIf="user.role === Role.TEACHER && board.scope === BoardScope.PROJECT_SHARED"
(click)="openWorkflowDialog()"
>
<mat-icon>timeline</mat-icon>
Manage Buckets & Workflows
</button>
<button
mat-menu-item
*ngIf="
!(user.role === Role.STUDENT && !board.permissions.showBucketStudent) && board.scope === BoardScope.PROJECT_SHARED
"
(click)="showBucketsModal()"
>
<mat-icon>shopping_basket</mat-icon>
View Buckets
</button>
<button mat-menu-item (click)="showListModal()">
<mat-icon>list_alt</mat-icon>
List Posts
</button>
<button
mat-menu-item
*ngIf="user && user.role === Role.STUDENT"
(click)="openTodoList()"
>
<mat-icon>assignment</mat-icon>
Todo List
</button>
<button
mat-menu-item
*ngIf="user && user.role === Role.TEACHER"
(click)="openProjectTodoList()"
>
<mat-icon>assignment_ind</mat-icon>
View All Todo Lists
</button>
<button
*ngIf="user.role === Role.TEACHER && board.scope === BoardScope.PROJECT_SHARED"
mat-menu-item
(click)="openGroupDialog()"
>
<mat-icon>group_work</mat-icon>
Manage Groups
</button>
<button
*ngIf="user.role === Role.TEACHER"
mat-menu-item
(click)="openSettingsDialog()"
>
<mat-icon>settings</mat-icon>
Adjust Settings
</button>
<a href="https://score.oise.utoronto.ca/" style="text-decoration:none;color:black" target="_blank" >
<button mat-menu-item style="text-decoration:none;color:black">
<mat-icon>launch</mat-icon>
Go to SCORE
</button>
</a>
<button mat-menu-item (click)="signOut()">
<mat-icon class="material-icons-outlined">logout</mat-icon>
Log Out
</button>
</mat-menu>
<app-view-navigation [boardID]="boardID" [currentView]="viewType"></app-view-navigation>
<div *ngIf="board">
<app-notification-dropdown
[user]="user"
[board]="board"
></app-notification-dropdown>
</div>
<app-toolbar-menu navbarMenu [board]="board" [project]="project"></app-toolbar-menu>
</app-toolbar>
<div class="canvas-area">
<canvas id="canvas" (window:resize)="onResize($event)"></canvas>
Expand Down Expand Up @@ -198,4 +115,4 @@
</div>
</div>
</div>
</div>
</div>
Loading
Loading