Skip to content

Commit

Permalink
feat(UI): update components to support material text chunking
Browse files Browse the repository at this point in the history
Integrate new backend API changes by updating the UI components and related files:
- Updated `store.ts` to handle new state management for the backend changes
- Modified `operations.ts` to incorporate new API calls
- Adjusted types in `types.ts` to reflect backend schema changes
- Updated React components to work with the updated state and API logic
  • Loading branch information
Jonaspng committed Jan 5, 2025
1 parent 19be732 commit cab6072
Show file tree
Hide file tree
Showing 10 changed files with 184 additions and 7 deletions.
21 changes: 21 additions & 0 deletions client/app/api/course/Material/Folders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ export default class FoldersAPI extends BaseCourseAPI {
);
}

/**
* Chunks a material (file)
*/
chunkMaterial(
currFolderId: number,
materialId: number,
): APIResponse<JobSubmitted> {
return this.client.put(
`${this.#urlPrefix}/${currFolderId}/files/${materialId}/create_text_chunks`,
);
}

/**
* Deletes Chunks associated with a material (file)
*/
deleteMaterialChunks(currFolderId: number, materialId: number): APIResponse {
return this.client.delete(
`${this.#urlPrefix}/${currFolderId}/files/${materialId}/destroy_text_chunks`,
);
}

/**
* Uploads materials (files)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ interface Props {
canEdit: boolean;
canDelete: boolean;
type: 'subfolder' | 'material';
state: 'not_chunked' | 'chunking' | 'chunked' | null;
folderInitialValues?: {
name: string;
description: string;
Expand Down Expand Up @@ -61,6 +62,7 @@ const WorkbinTableButtons: FC<Props> = (props) => {
isConcrete,
canEdit,
canDelete,
state,
type,
folderInitialValues,
materialInitialValues,
Expand Down Expand Up @@ -147,6 +149,7 @@ const WorkbinTableButtons: FC<Props> = (props) => {
<Stack direction={{ xs: 'column', sm: 'row' }}>
{canEdit && isConcrete && (
<EditButton
disabled={state === 'chunking'}
id={`${type}-edit-button-${itemId}`}
onClick={onEdit}
style={{ padding: 5 }}
Expand All @@ -157,7 +160,7 @@ const WorkbinTableButtons: FC<Props> = (props) => {
confirmMessage={`${t(
translations.deleteConfirmation,
)} "${itemName}"`}
disabled={isDeleting}
disabled={isDeleting || state === 'chunking'}
id={`${type}-delete-button-${itemId}`}
onClick={onDelete}
style={{ padding: 5 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ import Link from 'lib/components/core/Link';
import { getCourseId } from 'lib/helpers/url-helpers';
import { formatFullDateTime } from 'lib/moment';

import KnowledgeBaseSwitch from '../buttons/KnowledgeBaseSwitch';
import WorkbinTableButtons from '../buttons/WorkbinTableButtons';

interface Props {
currFolderId: number;
material: MaterialMiniEntity;
isCurrentCourseStudent: boolean;
isConcrete: boolean;
canManageKnowledgeBase: boolean;
}

const TableMaterialRow: FC<Props> = (props) => {
const { currFolderId, material, isCurrentCourseStudent, isConcrete } = props;
const {
currFolderId,
material,
isCurrentCourseStudent,
isConcrete,
canManageKnowledgeBase,
} = props;

return (
<TableRow id={`material-${material.id}`}>
Expand Down Expand Up @@ -80,6 +88,21 @@ const TableMaterialRow: FC<Props> = (props) => {
-
</TableCell>
)}
{canManageKnowledgeBase && (
<TableCell style={{ width: '60px' }}>
<Stack alignItems="center" direction="column" spacing={0.5}>
<KnowledgeBaseSwitch
canEdit={material.permissions.canEdit}
currFolderId={currFolderId}
isConcrete={isConcrete}
itemId={material.id}
itemName={material.name}
state={material.workflowState}
type="material"
/>
</Stack>
</TableCell>
)}
<TableCell style={{ width: '60px' }}>
<WorkbinTableButtons
canDelete={material.permissions.canDelete}
Expand All @@ -98,6 +121,7 @@ const TableMaterialRow: FC<Props> = (props) => {
}`,
},
}}
state={material.workflowState}
type="material"
/>
</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ interface Props {
subfolder: FolderMiniEntity;
isCurrentCourseStudent: boolean;
isConcrete: boolean;
canManageKnowledgeBase: boolean;
}

const translations = defineMessages({
Expand All @@ -37,7 +38,13 @@ const translations = defineMessages({
});

const TableSubfolderRow: FC<Props> = (props) => {
const { currFolderId, subfolder, isCurrentCourseStudent, isConcrete } = props;
const {
currFolderId,
subfolder,
isCurrentCourseStudent,
isConcrete,
canManageKnowledgeBase,
} = props;
const { t } = useTranslation();

return (
Expand All @@ -52,7 +59,9 @@ const TableSubfolderRow: FC<Props> = (props) => {
whiteSpace: 'normal',
wordBreak: 'break-word',
}}
to={`/courses/${getCourseId()}/materials/folders/${subfolder.id}`}
to={`/courses/${getCourseId()}/materials/folders/${
subfolder.id
}/`}
underline="hover"
>
{`${subfolder.name} (${subfolder.itemCount})`}
Expand Down Expand Up @@ -113,6 +122,13 @@ const TableSubfolderRow: FC<Props> = (props) => {
</Stack>
</TableCell>
)}
{canManageKnowledgeBase && (
<TableCell style={{ width: '60px' }}>
<Stack alignItems="center" direction="column" spacing={0.5}>
-
</Stack>
</TableCell>
)}
<TableCell
style={{
width: '60px',
Expand All @@ -132,6 +148,7 @@ const TableSubfolderRow: FC<Props> = (props) => {
isConcrete={isConcrete}
itemId={subfolder.id}
itemName={subfolder.name}
state={null}
type="subfolder"
/>
</TableCell>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface Props extends WrappedComponentProps {
subfolders: FolderMiniEntity[];
materials: MaterialMiniEntity[];
isCurrentCourseStudent: boolean;
canManageKnowledgeBase: boolean;
isConcrete: boolean;
}

Expand All @@ -36,6 +37,7 @@ const WorkbinTable: FC<Props> = (props) => {
subfolders,
materials,
isCurrentCourseStudent,
canManageKnowledgeBase,
isConcrete,
} = props;

Expand Down Expand Up @@ -126,6 +128,18 @@ const WorkbinTable: FC<Props> = (props) => {
);
};

const columnHeaderWithoutSort = (columnName: string): JSX.Element => {
return (
<Button
disableFocusRipple
disableRipple
style={{ padding: 0, alignItems: 'center', justifyContent: 'start' }}
>
{columnName}
</Button>
);
};

return (
<TableContainer dense variant="bare">
<TableHead>
Expand All @@ -135,14 +149,17 @@ const WorkbinTable: FC<Props> = (props) => {
{!isCurrentCourseStudent && (
<TableCell>{columnHeaderWithSort('Start At')}</TableCell>
)}
<TableCell />
{canManageKnowledgeBase && (
<TableCell>{columnHeaderWithoutSort('Knowledge Base')}</TableCell>
)}
</TableRow>
</TableHead>
<TableBody>
{sortedSubfolders.map((subfolder) => {
return (
<TableSubfolderRow
key={`subfolder-${subfolder.id}`}
canManageKnowledgeBase={canManageKnowledgeBase}
currFolderId={currFolderId}
isConcrete={isConcrete}
isCurrentCourseStudent={isCurrentCourseStudent}
Expand All @@ -154,6 +171,7 @@ const WorkbinTable: FC<Props> = (props) => {
return (
<TableMaterialRow
key={`material-${material.id}`}
canManageKnowledgeBase={canManageKnowledgeBase}
currFolderId={currFolderId}
isConcrete={isConcrete}
isCurrentCourseStudent={isCurrentCourseStudent}
Expand Down
56 changes: 56 additions & 0 deletions client/app/bundles/course/material/folders/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { actions } from './store';
import { SaveFolderAction } from './types';

const DOWNLOAD_FOLDER_JOB_POLL_INTERVAL_MS = 2000;
const CHUNK_MATERIAL_JOB_POLL_INTERVAL_MS = 1000;

const formatFolderAttributes = (data: FolderFormData): FormData => {
const payload = new FormData();
Expand Down Expand Up @@ -181,6 +182,61 @@ export function deleteMaterial(
});
}

export function removeChunks(
currFolderId: number,
materialId: number,
): Operation {
return async (dispatch) =>
CourseAPI.folders
.deleteMaterialChunks(currFolderId, materialId)
.then(() => {
dispatch(
actions.updateMaterialWorkflowStateList(materialId, 'not_chunked'),
);
});
}

export function chunkMaterial(
currFolderId: number,
materialId: number,
handleSuccess: () => void,
handleFailure: () => void,
): Operation {
return async (dispatch) => {
// Dispatch initial update to set workflow state to 'chunking'
dispatch(actions.updateMaterialWorkflowStateList(materialId, 'chunking'));

// Make the API call to start chunking the material
CourseAPI.folders
.chunkMaterial(currFolderId, materialId)
.then((response) => {
const jobUrl = response.data.jobUrl;
pollJob(
jobUrl,
() => {
// Dispatch update to set workflow state to 'chunked' when job completes
dispatch(
actions.updateMaterialWorkflowStateList(materialId, 'chunked'),
);
handleSuccess();
},
() => {
// Dispatch update to set workflow state to 'not chunked' when job errors
dispatch(
actions.updateMaterialWorkflowStateList(
materialId,
'not_chunked',
),
);
handleFailure();
},
CHUNK_MATERIAL_JOB_POLL_INTERVAL_MS,
);
})
.catch(handleFailure);
};
}

export function updateMaterial(
formData: MaterialFormData,
folderId: number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ const FolderShow: FC = () => {
>
<WorkbinTable
key={currFolderInfo.id}
canManageKnowledgeBase={permissions.canManageKnowledgeBase}
currFolderId={currFolderInfo.id}
isConcrete={currFolderInfo.isConcrete}
isCurrentCourseStudent={permissions.isCurrentCourseStudent}
Expand Down
19 changes: 19 additions & 0 deletions client/app/bundles/course/material/folders/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
SAVE_MATERIAL_LIST,
SaveFolderAction,
SaveMaterialListAction,
UPDATE_MATERIAL_WORKFLOW_STATE_LIST,
UpdateMaterialWorkflowStateAction,
} from './types';

const initialState: FoldersState = {
Expand All @@ -42,6 +44,7 @@ const initialState: FoldersState = {
canCreateSubfolder: false,
canUpload: false,
canEdit: false,
canManageKnowledgeBase: false,
},
};

Expand Down Expand Up @@ -85,6 +88,16 @@ const reducer = produce((draft: FoldersState, action: FoldersActionType) => {
break;
}

case UPDATE_MATERIAL_WORKFLOW_STATE_LIST: {
const materialId = action.materialId;
const material = draft.materials.byId[materialId];
if (material) {
material.workflowState = action.state;
saveListToStore(draft.materials, [material]);
}
break;
}

case DELETE_MATERIAL_LIST: {
const materialId = action.materialId;
if (draft.materials.byId[materialId]) {
Expand Down Expand Up @@ -135,6 +148,12 @@ export const actions = {
): SaveMaterialListAction => {
return { type: SAVE_MATERIAL_LIST, materialList };
},
updateMaterialWorkflowStateList: (
materialId: number,
state: 'not_chunked' | 'chunking' | 'chunked',
): UpdateMaterialWorkflowStateAction => {
return { type: UPDATE_MATERIAL_WORKFLOW_STATE_LIST, materialId, state };
},
};

export default reducer;
12 changes: 11 additions & 1 deletion client/app/bundles/course/material/folders/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { number, string } from 'prop-types';
import {
FolderListData,
FolderMiniEntity,
Expand All @@ -13,6 +14,8 @@ export const DELETE_FOLDER_LIST = 'course/materials/folders/DELETE_FOLDER_LIST';
export const DELETE_MATERIAL_LIST =
'course/materials/folders/DELETE_MATERIAL_LIST';
export const SAVE_MATERIAL_LIST = 'course/materials/folders/SAVE_MATERIAL_LIST';
export const UPDATE_MATERIAL_WORKFLOW_STATE_LIST =
'course/materials/folders/UPDATE_MATERIAL_WORKFLOW_STATE_LIST';

// Action Types
export interface SaveFolderAction {
Expand Down Expand Up @@ -46,11 +49,18 @@ export interface DeleteMaterialListAction {
materialId: number;
}

export interface UpdateMaterialWorkflowStateAction {
type: typeof UPDATE_MATERIAL_WORKFLOW_STATE_LIST;
materialId: number;
state: 'not_chunked' | 'chunking' | 'chunked' | null;
}

export type FoldersActionType =
| SaveFolderAction
| DeleteFolderListAction
| DeleteMaterialListAction
| SaveMaterialListAction;
| SaveMaterialListAction
| UpdateMaterialWorkflowStateAction;

// State Types
export interface FoldersState {
Expand Down
Loading

0 comments on commit cab6072

Please sign in to comment.