Skip to content

Commit

Permalink
refactor(materials): streamline loading of default material folder
Browse files Browse the repository at this point in the history
  • Loading branch information
phungmanhcuong committed Oct 29, 2024
1 parent 24ceec1 commit 06c8e88
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 42 deletions.
11 changes: 10 additions & 1 deletion app/controllers/course/material/materials_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# frozen_string_literal: true
class Course::Material::MaterialsController < Course::Material::Controller
load_and_authorize_resource :material, through: :folder, class: 'Course::Material'
load_and_authorize_resource :material, through: :folder, class: 'Course::Material', except: :load_default

def load_default
@folder = Course::Material::Folder.where(course_id: current_course.id, parent_id: nil).order(:created_at).first
if @folder
render json: @folder, status: :ok

Check warning on line 8 in app/controllers/course/material/materials_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/material/materials_controller.rb#L6-L8

Added lines #L6 - L8 were not covered by tests
else
render json: { error: 'No folders available' }, status: :not_found

Check warning on line 10 in app/controllers/course/material/materials_controller.rb

View check run for this annotation

Codecov / codecov/patch

app/controllers/course/material/materials_controller.rb#L10

Added line #L10 was not covered by tests
end
end

def show
authorize!(:read_owner, @material.folder)
Expand Down
12 changes: 11 additions & 1 deletion client/app/api/course/Materials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { FileListData } from 'types/course/material/files';

import { APIResponse } from 'api/types';

import {FolderMiniEntity} from '../../types/course/material/folders';

import BaseCourseAPI from './Base';

const getShouldDownloadFromContentDisposition = (
Expand All @@ -15,8 +17,12 @@ const getShouldDownloadFromContentDisposition = (
};

export default class MaterialsAPI extends BaseCourseAPI {
get #materialPrefix(): string {
return `/courses/${this.courseId}/materials`;
}

get #urlPrefix(): string {
return `/courses/${this.courseId}/materials/folders`;
return `${this.#materialPrefix}/folders`;
}

fetch(folderId: number, materialId: number): APIResponse<FileListData> {
Expand All @@ -25,6 +31,10 @@ export default class MaterialsAPI extends BaseCourseAPI {
);
}

fetchDefault(): APIResponse<FolderMiniEntity> {
return this.client.get(`${this.#materialPrefix}`);
}

/**
* Attempts to download the file at the given `url` as a `Blob` and returns
* its URL and disposition. Remember to `revoke` the URL when no longer needed.
Expand Down
53 changes: 18 additions & 35 deletions client/app/bundles/course/material/folders/handles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,35 @@ import { getIdFromUnknown } from 'utilities';
import CourseAPI from 'api/course';
import { CrumbPath, DataHandle } from 'lib/hooks/router/dynamicNest';

const extractMaterial = (
sidebar: { label: string; key: string; path: string }[],
): { label: string; key: string; path: string } | undefined =>
sidebar.find((item) => item.key === 'materials');

export const loadDefaultMaterial = async (
courseId: number,
): Promise<{
label: string;
key: string;
path: string;
} | null> => {
export const loadDefaultMaterialId = async (): Promise<number> => {
const {
data: { sidebar },
} = await CourseAPI.courses.fetchLayout(courseId);
return sidebar ? extractMaterial(sidebar) || null : null;
data: { id },
} = await CourseAPI.materials.fetchDefault();
return id;
};

const getFolderTitle = async (
courseId: string,
folderId: number,
): Promise<CrumbPath> => {
const courseUrl = `/courses/${courseId}`;
let data;
try {
const { data } = await CourseAPI.folders.fetch(folderId);
const workbinUrl = `${courseUrl}/materials/folders/${data.breadcrumbs[0].id}`;

return {
activePath: workbinUrl,
content: data.breadcrumbs.map((crumb) => ({
title: crumb.name,
url: `materials/folders/${crumb.id}`,
})),
};
({ data } = await CourseAPI.folders.fetch(folderId));
} catch (error) {
const defaultMaterial = await loadDefaultMaterial(+courseId);
const title = defaultMaterial ? defaultMaterial.label : 'Materials';

return {
activePath: courseUrl,
content: {
title,
url: courseUrl,
},
};
const defaultMaterialId = await loadDefaultMaterialId();
({ data } = await CourseAPI.folders.fetch(defaultMaterialId));
}

const workbinUrl = `${courseUrl}/materials/folders/${data.breadcrumbs[0].id}`;

return {
activePath: workbinUrl,
content: data.breadcrumbs.map((crumb) => ({
title: crumb.name,
url: `materials/folders/${crumb.id}`,
})),
};
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { defineMessages } from 'react-intl';
import { useParams } from 'react-router-dom';
import { Cancel, FolderOutlined } from '@mui/icons-material';

import { loadDefaultMaterial } from 'course/material/folders/handles';
import { loadDefaultMaterialId } from 'course/material/folders/handles';
import Link from 'lib/components/core/Link';
import useTranslation from 'lib/hooks/useTranslation';

Expand Down Expand Up @@ -40,10 +40,10 @@ const useWorkbinURL = (courseId: string | undefined): string => {

useEffect(() => {
if (courseId) {
loadDefaultMaterial(+courseId).then((materialsItem) => {
if (materialsItem?.path) {
setWorkbinURL(materialsItem.path);
}
loadDefaultMaterialId().then((defaultMaterialId) => {
setWorkbinURL(
`/courses/${courseId}/materials/folders/${defaultMaterialId}`,
);
});
}
}, [courseId]);
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@
end

namespace :material, path: 'materials' do
get '/', to: 'materials#load_default'
resources :folders, except: [:index, :new, :create] do
post 'create/subfolder', on: :member, as: 'create_subfolder', action: 'create_subfolder'
put 'upload_materials', on: :member
Expand Down

0 comments on commit 06c8e88

Please sign in to comment.