({
+ filePickerMode: false,
+});
+
+interface FilesPageProviderProps extends FilesPageContextInterface {
+ children: React.ReactNode;
+}
+
+const FilesPageProvider = ({
+ children,
+ filePickerMode = false,
+ filePickerOptions,
+}: FilesPageProviderProps) => {
+ const contextValue = useMemo(() => ({
+ filePickerMode,
+ filePickerOptions,
+ }), []);
+ return (
+
+ {children}
+
+ );
+};
+
+export default FilesPageProvider;
diff --git a/src/files-and-videos/generic/FileTable.jsx b/src/files-and-videos/generic/FileTable.jsx
index 0dd632aacb..db5e45bc98 100644
--- a/src/files-and-videos/generic/FileTable.jsx
+++ b/src/files-and-videos/generic/FileTable.jsx
@@ -1,4 +1,10 @@
-import { useCallback, useEffect, useState } from 'react';
+import { FilesPageContext } from '@src/files-and-videos/files-page/FilesPageProvider';
+import {
+ useCallback,
+ useContext,
+ useEffect,
+ useState,
+} from 'react';
import { useSelector } from 'react-redux';
import PropTypes from 'prop-types';
import isEmpty from 'lodash/isEmpty';
@@ -11,7 +17,7 @@ import {
useToggle,
} from '@openedx/paragon';
-import { RequestStatus } from '../../data/constants';
+import { RequestStatus } from '@src/data/constants';
import { sortFiles } from './utils';
import messages from './messages';
@@ -79,6 +85,7 @@ const FileTable = ({
const defaultCurrentView = (fileType === 'video' && localStorage.getItem('videosCurrentView')) ||
(fileType === 'file' && localStorage.getItem('filesCurrentView')) || defaultView;
const [currentView, setCurrentView] = useState(defaultCurrentView);
+ const { filePickerOptions } = useContext(FilesPageContext);
useEffect(() => {
if (!isEmpty(selectedRows) && Object.keys(selectedRows[0]).length > 0) {
@@ -189,6 +196,7 @@ const FileTable = ({
if (!hasMoreInfoColumn) {
tableColumns.push({ ...moreInfoColumn });
}
+ const maxSelectedRows = filePickerOptions?.multiSelect === false ? 1 : undefined;
return (
@@ -198,6 +206,7 @@ const FileTable = ({
isSortable
isSelectable
isPaginated
+ maxSelectedRows={maxSelectedRows}
defaultColumnValues={{ Filter: TextFilter }}
dataViewToggleOptions={{
isDataViewToggleEnabled: true,
diff --git a/src/files-and-videos/generic/table-components/TableActions.jsx b/src/files-and-videos/generic/table-components/TableActions.jsx
index 188de71315..cd2a339aba 100644
--- a/src/files-and-videos/generic/table-components/TableActions.jsx
+++ b/src/files-and-videos/generic/table-components/TableActions.jsx
@@ -1,8 +1,5 @@
-import React, { useContext, useEffect } from 'react';
-import { isEmpty } from 'lodash';
-import { PropTypes } from 'prop-types';
-import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { getConfig } from '@edx/frontend-platform';
+import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import {
Button,
DataTableContext,
@@ -10,6 +7,10 @@ import {
useToggle,
} from '@openedx/paragon';
import { Add, Tune } from '@openedx/paragon/icons';
+import { FilesPageContext } from '@src/files-and-videos/files-page/FilesPageProvider';
+import { isEmpty } from 'lodash';
+import { PropTypes } from 'prop-types';
+import React, { useContext, useEffect } from 'react';
import messages from '../messages';
import SortAndFilterModal from './sort-and-filter-modal';
@@ -27,6 +28,9 @@ const TableActions = ({
const [isSortOpen, openSort, closeSort] = useToggle(false);
const { state, clearSelection } = useContext(DataTableContext);
+ const { filePickerMode } = useContext(FilesPageContext);
+ // If window.opener is not available, show the user some error message.
+ const showFilePicker = filePickerMode; // && Boolean(window.opener);
// This useEffect saves DataTable state so it can persist after table re-renders due to data reload.
useEffect(() => {
setInitialState(state);
@@ -80,6 +84,21 @@ const TableActions = ({
+ {showFilePicker && (
+
+ )}
>
);
diff --git a/src/index.jsx b/src/index.jsx
index b62a9e58cf..e8126e4503 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -7,7 +7,8 @@ import {
getConfig,
getPath,
} from '@edx/frontend-platform';
-import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
+import { AppProvider, ErrorPage, PageWrap } from '@edx/frontend-platform/react';
+import { FilePickerPage } from '@src/files-and-videos/files-page/FilePickerPage';
import React, { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
import {
@@ -102,6 +103,14 @@ const App = () => {
} />
} />
} />
+
+
+
+ }
+ />
{getConfig().ENABLE_ACCESSIBILITY_PAGE === 'true' && (
} />
)}
diff --git a/src/store.ts b/src/store.ts
index 99d9331b30..37f5e8bd61 100644
--- a/src/store.ts
+++ b/src/store.ts
@@ -33,7 +33,23 @@ type InferState = ReducerType extends Reducer ? T : never;
export interface DeprecatedReduxState {
customPages: Record;
discussions: Record;
- assets: Record;
+ assets: {
+ assetIds: string[];
+ loadingStatus: RequestStatusType;
+ duplicateFiles: string[];
+ updatingStatus: string;
+ addingStatus: string;
+ deletingStatus: string;
+ usageStatus: string;
+ errors: {
+ add: string[];
+ delete: string[];
+ lock: string[];
+ download: string[];
+ usageMetrics: string[];
+ loading: string;
+ };
+ };
pagesAndResources: Record;
scheduleAndDetails: Record;
studioHome: InferState;