Skip to content

Commit

Permalink
feat: wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rayzhou-bit committed Oct 25, 2023
1 parent 27b2c6f commit 1a3bc9b
Show file tree
Hide file tree
Showing 25 changed files with 638 additions and 313 deletions.
71 changes: 71 additions & 0 deletions src/editors/containers/LibraryContentEditor/BlocksSelector.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';

import { Button, DataTable, Form } from '@edx/paragon';
import { actions, selectors } from './data';
import { useBlocksHook } from './hooks';

export const BlocksSelector = ({
studioEndpointUrl,

// redux
blocksInSelectedLibrary,
loadBlocksInLibrary,
selectedLibrary,
}) => {
if (selectedLibrary === null || !blocksInSelectedLibrary) return <></>;

const {
blockLinks,
blocksTableData,
} = useBlocksHook({
blocksInSelectedLibrary,
loadBlocksInLibrary,
studioEndpointUrl,
});

return (
<div className='mb-5'>
<label>Select the blocks you want to show: </label>
<DataTable
isSelectable
initialState={{
pageSize: 1,
}}
columns={[
{ Header: 'Name', accessor: 'display_name' },
{ Header: 'Block Type', accessor: 'block_type'},
]}
isSortable
itemCount={blocksTableData.length}
data={blocksTableData}
// additionalColumns={[
// {
// id: 'view',
// Header: 'View',
// Cell: ({ row }) => {
// <Button variant="link" onClick={() => console.log("View", row)}>
// View
// </Button>
// }
// }
// ]}
>
<DataTable.Table />
<DataTable.EmptyTable content="No blocks" />
</DataTable>
</div>
);
};

export const mapStateToProps = (state) => ({
blocksInSelectedLibrary: selectors.blocksInSelectedLibrary(state),
selectedLibrary: selectors.selectedLibrary(state),
})

export const mapDispatchToProps = {
loadBlocksInLibrary: actions.loadBlocksInLibrary,
};

export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(BlocksSelector));
63 changes: 63 additions & 0 deletions src/editors/containers/LibraryContentEditor/LibrarySelector.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { connect, useSelector } from 'react-redux';
import PropTypes from 'prop-types';

import { Dropdown, DropdownButton } from '@edx/paragon';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { actions, selectors } from './data';

export const LibrarySelector = ({
// redux
libraries,
selectedLibrary,
onSelectLibrary,
}) => {
const title = () => {
if (selectedLibrary === null) return 'Select a library';
return libraries[selectedLibrary]?.display_name;
};

return (
<div className='mb-5'>
{libraries
? (
<Dropdown className='w-100'>
<Dropdown.Toggle
className='w-100'
id='library-selector'
title={title()}
variant='outline-primary'
>
{title()}
</Dropdown.Toggle>
<Dropdown.Menu>
<Dropdown.Item onClick={() => onSelectLibrary({ selectedLibrary: null })}>
Select a library
</Dropdown.Item>
{libraries.map((library, index) => (
<Dropdown.Item onClick={() => onSelectLibrary({ selectedLibrary: index })}>
{library.display_name}
</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
)
: (
<span>There is no library!</span>
)}
</div>
);
};

export const mapStateToProps = (state) => ({
libraries: selectors.libraries(state),
selectedLibrary: selectors.selectedLibrary(state),
});

export const mapDispatchToProps = {
onSelectLibrary: actions.onSelectLibrary,
};

export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(LibrarySelector));


60 changes: 60 additions & 0 deletions src/editors/containers/LibraryContentEditor/LibrarySettings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import { connect } from 'react-redux';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';

import { Button, Form } from '@edx/paragon';
import { modes } from './constants';
import { actions, selectors } from './data';
import { thunkActions } from '../../data/redux';

export const LibrarySettings = ({
// redux
onShowResetSettingsChange,
onCountSettingsChange,
selectedLibrary,
selectionSettings,
}) => {
if (selectedLibrary === null) return <></>;

return (
<div className='row mb-4'>
<div className='row col mb-3'>
<Form.Control
className='col col-3'
// floatingLabel="Number of Blocks"
onChange= {(e) => onCountSettingsChange({
count: e.target.value,
})}
value={selectionSettings.count}
type="number"
/>
<label className='col'>How many blocks do you want to show?</label>
</div>
<div className='col'>
<Form.Switch
checked={selectionSettings.showReset}
onChange={(e) => onShowResetSettingsChange({
showReset: e.target.checked,
})}
>
Show Reset Button
</Form.Switch>
<div className="x-small mt-2">
Determines whether a 'Reset Problems' button is shown, so users may reset their answers and reshuffle selected items.
</div>
</div>
</div>
);
};

export const mapStateToProps = (state) => ({
selectedLibrary: selectors.selectedLibrary(state),
selectionSettings: selectors.selectionSettings(state),
})

export const mapDispatchToProps = {
onShowResetSettingsChange: actions.onShowResetSettingsChange,
onCountSettingsChange: actions.onCountSettingsChange,
};

export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(LibrarySettings));
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import messages from "./messages"
export const modes = {
all: {
description: messages.modeAll,
value: 'all'
value: 'all',
},
random: {
description: messages.modeRandom,
value: 'random'
value: 'random',
},
selected: {
description: messages.modeSelected,
value: 'selected'
value: 'selected',
}
}
};
29 changes: 29 additions & 0 deletions src/editors/containers/LibraryContentEditor/data/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { get, post, deleteObject } from '../../../data/services/cms/utils';
// import * as urls from '../../../data/services/cms/urls';
import * as urls from './urls';
import * as module from './api';
import * as mockApi from './mockApi';

export const apiMethods = {
// fetchLibraries: ({}) => get(
// urls
// ),
fetchContentStore: ({ studioEndpointUrl }) => get(
urls.contentStore({ studioEndpointUrl }),
),
fetchLibraryContent: ({ studioEndpointUrl, libraryId }) => get(
urls.libraryContent({ studioEndpointUrl, libraryId }),
),
};

export const checkMockApi = (key) => {
if (process.env.REACT_APP_DEVGALLERY) {
return mockApi[key] ? mockApi[key] : mockApi.emptyMock;
}
return module.apiMethods[key];
};

export default Object.keys(apiMethods).reduce(
(obj, key) => ({ ...obj, [key]: checkMockApi(key) }),
{},
);
2 changes: 2 additions & 0 deletions src/editors/containers/LibraryContentEditor/data/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { actions, reducer } from './reducer';
export { default as selectors } from './selectors';
108 changes: 108 additions & 0 deletions src/editors/containers/LibraryContentEditor/data/mockApi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
export const fetchContentStore = ({ studioEndpointUrl }) => {
return {
"allow_course_reruns": true,
"allow_to_create_new_org": true,
"allow_unicode_course_id": false,
"allowed_organizations": [],
"archived_courses": [
{
"course_key": "course-v1:edX+P315+2T2023",
"display_name": "Quantum Entanglement",
"lms_link": "//localhost:18000/courses/course-v1:edX+P315+2T2023",
"number": "P315",
"org": "edX",
"rerun_link": "/course_rerun/course-v1:edX+P315+2T2023",
"run": "2T2023",
"url": "/course/course-v1:edX+P315+2T2023",
},
],
"can_create_organizations": true,
"course_creator_status": "granted",
"courses": [
{
"course_key": "course-v1:edX+E2E-101+course",
"display_name": "E2E Test Course",
"lms_link": "//localhost:18000/courses/course-v1:edX+E2E-101+course",
"number": "E2E-101",
"org": "edX",
"rerun_link": "/course_rerun/course-v1:edX+E2E-101+course",
"run": "course",
"url": "/course/course-v1:edX+E2E-101+course"
},
],
"in_process_course_actions": [],
"libraries": [
{
"display_name": "My First Library",
"library_key": "library-v1:new+CPSPR",
"url": "/library/library-v1:new+CPSPR",
"org": "new",
"number": "CPSPR",
"can_edit": true
},
{
"display_name": "My Second Library",
"library_key": "library-v1:new+CPSPRsadf",
"url": "/library/library-v1:new+CPSPRasdf",
"org": "new",
"number": "CPSPRasdf",
"can_edit": true
},
{
"display_name": "My Third Library",
"library_key": "library-v1:new+CPSPRqwer",
"url": "/library/library-v1:new+CPSPRqwer",
"org": "new",
"number": "CPSPRqwer",
"can_edit": true
}
],
"libraries_enabled": true,
"library_authoring_mfe_url": "//localhost:3001/course/course-v1:edX+P315+2T2023",
"optimization_enabled": true,
"redirect_to_library_authoring_mfe": false,
"request_course_creator_url": "/request_course_creator",
"rerun_creator_status": true,
"show_new_library_button": true,
"split_studio_home": false,
"studio_name": "Studio",
"studio_short_name": "Studio",
"studio_request_email": "",
"tech_support_email": "[email protected]",
"platform_name": "Your Platform Name Here",
"user_is_active": true,
};
};

export const fetchLibraryContent = ({ studioEndpointUrl, libraryId }) => {
return {
"count": 3,
"next": null,
"previous": null,
"results": [
{
"id": "lb:edx:test202:html:3eb918b1-6ebd-4172-b1e7-bd7c4eaa51ab",
"def_key": "bundle-olx:539d7fcc-615c-4b6e-8b57-34cffc82bbd0:studio_draft:html:html/3eb918b1-6ebd-4172-b1e7-bd7c4eaa51ab/definition.xml",
"block_type": "html",
"display_name": "Text",
"has_unpublished_changes": true
},
{
"id": "lb:edx:test202:html:b7c18081-0bec-4de0-8d16-8b255924722e",
"def_key": "bundle-olx:539d7fcc-615c-4b6e-8b57-34cffc82bbd0:studio_draft:html:html/b7c18081-0bec-4de0-8d16-8b255924722e/definition.xml",
"block_type": "html",
"display_name": "Lorem texts",
"has_unpublished_changes": false
},
{
"id": "lb:edx:test202:problem:86e480e4-e31c-492f-822e-1a8b2501cfde",
"def_key": "bundle-olx:539d7fcc-615c-4b6e-8b57-34cffc82bbd0:studio_draft:problem:problem/86e480e4-e31c-492f-822e-1a8b2501cfde/definition.xml",
"block_type": "problem",
"display_name": "Blank Problem",
"has_unpublished_changes": true
}
]
};
};

export const emptyMock = () => mockPromise({});
Loading

0 comments on commit 1a3bc9b

Please sign in to comment.