Skip to content

Commit df7405e

Browse files
authored
feat: create unit workflow (#1741)
Implements the basic workflow to create a Unit in a Library.
1 parent d497bf2 commit df7405e

17 files changed

Lines changed: 409 additions & 110 deletions

File tree

src/generic/block-type-utils/constants.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import {
33
BackHand as BackHandIcon,
44
BookOpen as BookOpenIcon,
55
Casino as ProblemBankIcon,
6+
ContentPaste as ContentPasteIcon,
67
Edit as EditIcon,
78
EditNote as EditNoteIcon,
8-
FormatListBulleted as FormatListBulletedIcon,
9+
CalendarViewDay,
910
HelpOutline as HelpOutlineIcon,
1011
LibraryAdd as LibraryIcon,
1112
Lock as LockIcon,
@@ -35,7 +36,7 @@ export const COMPONENT_TYPES = {
3536
export const UNIT_TYPE_ICONS_MAP: Record<string, React.ComponentType> = {
3637
video: VideoCameraIcon,
3738
other: BookOpenIcon,
38-
vertical: FormatListBulletedIcon,
39+
vertical: CalendarViewDay,
3940
problem: EditIcon,
4041
lock: LockIcon,
4142
};
@@ -58,6 +59,8 @@ export const STRUCTURAL_TYPE_ICONS: Record<string, React.ComponentType> = {
5859
sequential: Folder,
5960
chapter: Folder,
6061
collection: Folder,
62+
libraryContent: Folder,
63+
paste: ContentPasteIcon,
6164
};
6265

6366
export const COMPONENT_TYPE_STYLE_COLOR_MAP = {

src/generic/key-utils.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ describe('component utils', () => {
3232
['lb:Axim:beta:problem:571fe018-f3ce-45c9-8f53-5dafcb422fdd', 'lib:Axim:beta'],
3333
['lib-collection:org:lib:coll', 'lib:org:lib'],
3434
['lib-collection:OpenCraftX:ALPHA:coll', 'lib:OpenCraftX:ALPHA'],
35+
['lct:org:lib:unit:my-unit-9284e2', 'lib:org:lib'],
36+
['lct:OpenCraftX:ALPHA:my-unit-a3223f', 'lib:OpenCraftX:ALPHA'],
3537
]) {
3638
it(`returns '${expected}' for usage key '${input}'`, () => {
3739
expect(getLibraryId(input)).toStrictEqual(expected);

src/generic/key-utils.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ export function getBlockType(usageKey: string): string {
1919
* @returns The library key, e.g. `lib:org:lib`
2020
*/
2121
export function getLibraryId(usageKey: string): string {
22-
if (usageKey && (usageKey.startsWith('lb:') || usageKey.startsWith('lib-collection:'))) {
23-
const org = usageKey.split(':')[1];
24-
const lib = usageKey.split(':')[2];
25-
if (org && lib) {
26-
return `lib:${org}:${lib}`;
27-
}
22+
const [blockType, org, lib] = usageKey?.split(':') || [];
23+
24+
if (['lb', 'lib-collection', 'lct'].includes(blockType) && org && lib) {
25+
return `lib:${org}:${lib}`;
2826
}
2927
throw new Error(`Invalid usageKey: ${usageKey}`);
3028
}

src/generic/loading-button/LoadingButton.test.jsx renamed to src/generic/loading-button/LoadingButton.test.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import React from 'react';
21
import {
32
act,
43
fireEvent,
@@ -9,7 +8,7 @@ import LoadingButton from '.';
98

109
const buttonTitle = 'Button Title';
1110

12-
const RootWrapper = (onClick) => (
11+
const RootWrapper = (onClick?: () => (Promise<void> | void)) => (
1312
<LoadingButton label={buttonTitle} onClick={onClick} />
1413
);
1514

@@ -31,8 +30,8 @@ describe('<LoadingButton />', () => {
3130
});
3231

3332
it('renders the spinner correctly', async () => {
34-
let resolver;
35-
const longFunction = () => new Promise((resolve) => {
33+
let resolver: () => void;
34+
const longFunction = () => new Promise<void>((resolve) => {
3635
resolver = resolve;
3736
});
3837
const { container, getByRole, getByText } = render(RootWrapper(longFunction));
@@ -51,8 +50,8 @@ describe('<LoadingButton />', () => {
5150
});
5251

5352
it('renders the spinner correctly even with error', async () => {
54-
let rejecter;
55-
const longFunction = () => new Promise((_resolve, reject) => {
53+
let rejecter: (err: Error) => void;
54+
const longFunction = () => new Promise<void>((_resolve, reject) => {
5655
rejecter = reject;
5756
});
5857
const { container, getByRole, getByText } = render(RootWrapper(longFunction));
Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// @ts-check
21
import React, {
32
useCallback,
43
useEffect,
@@ -8,20 +7,20 @@ import React, {
87
import {
98
StatefulButton,
109
} from '@openedx/paragon';
11-
import PropTypes from 'prop-types';
10+
11+
interface LoadingButtonProps {
12+
label: string;
13+
onClick?: (e: any) => (Promise<void> | void);
14+
disabled?: boolean;
15+
size?: string;
16+
variant?: string;
17+
className?: string;
18+
}
1219

1320
/**
14-
* A button that shows a loading spinner when clicked.
15-
* @param {object} props
16-
* @param {string} props.label
17-
* @param {function=} props.onClick
18-
* @param {boolean=} props.disabled
19-
* @param {string=} props.size
20-
* @param {string=} props.variant
21-
* @param {string=} props.className
22-
* @returns {JSX.Element}
21+
* A button that shows a loading spinner when clicked, if the onClick function returns a Promise.
2322
*/
24-
const LoadingButton = ({
23+
const LoadingButton: React.FC<LoadingButtonProps> = ({
2524
label,
2625
onClick,
2726
disabled,
@@ -37,7 +36,7 @@ const LoadingButton = ({
3736
componentMounted.current = false;
3837
}, []);
3938

40-
const loadingOnClick = useCallback(async (e) => {
39+
const loadingOnClick = useCallback(async (e: any) => {
4140
if (!onClick) {
4241
return;
4342
}
@@ -67,21 +66,4 @@ const LoadingButton = ({
6766
);
6867
};
6968

70-
LoadingButton.propTypes = {
71-
label: PropTypes.string.isRequired,
72-
onClick: PropTypes.func,
73-
disabled: PropTypes.bool,
74-
size: PropTypes.string,
75-
variant: PropTypes.string,
76-
className: PropTypes.string,
77-
};
78-
79-
LoadingButton.defaultProps = {
80-
onClick: undefined,
81-
disabled: undefined,
82-
size: undefined,
83-
variant: '',
84-
className: '',
85-
};
86-
8769
export default LoadingButton;

0 commit comments

Comments
 (0)