//
// SPDX-License-Identifier: AGPL-3.0
-import { CollectionPanelFilesState } from "./collection-panel-files-state";
+import { CollectionPanelFilesState, CollectionPanelFile } from "./collection-panel-files-state";
import { CollectionPanelFilesAction, collectionPanelFilesAction } from "./collection-panel-files-actions";
+import { stat } from "fs";
-export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = [], action: CollectionPanelFilesAction) => {
+const initialState: CollectionPanelFilesState = [{
+ collapsed: true,
+ id: 'Directory 1',
+ name: 'Directory 1',
+ selected: false,
+ type: 'directory',
+}, {
+ parentId: 'Directory 1',
+ collapsed: true,
+ id: 'Directory 1.1',
+ name: 'Directory 1.1',
+ selected: false,
+ type: 'directory',
+}, {
+ parentId: 'Directory 1',
+ collapsed: true,
+ id: 'File 1.1',
+ name: 'File 1.1',
+ selected: false,
+ type: 'file',
+}, {
+ collapsed: true,
+ id: 'Directory 2',
+ name: 'Directory 2',
+ selected: false,
+ type: 'directory',
+}, {
+ parentId: 'Directory 2',
+ collapsed: true,
+ id: 'Directory 2.1',
+ name: 'Directory 2.1',
+ selected: false,
+ type: 'directory',
+}, {
+ parentId: 'Directory 2.1',
+ collapsed: true,
+ id: 'Directory 2.1.1',
+ name: 'Directory 2.1.1',
+ selected: false,
+ type: 'directory',
+}, {
+ parentId: 'Directory 2.1.1',
+ collapsed: true,
+ id: 'Directory 2.1.1.1',
+ name: 'Directory 2.1.1.1',
+ selected: false,
+ type: 'directory',
+}];
+
+export const collectionPanelFilesReducer = (state: CollectionPanelFilesState = initialState, action: CollectionPanelFilesAction) => {
return collectionPanelFilesAction.match(action, {
SET_COLLECTION_FILES: data => data.files,
- TOGGLE_COLLECTION_FILE_COLLAPSE: data => toggle(state, data.id, "collapsed"),
- TOGGLE_COLLECTION_FILE_SELECTION: data => toggle(state, data.id, "selected"),
+ TOGGLE_COLLECTION_FILE_COLLAPSE: data => toggleCollapsed(state, data.id),
+ TOGGLE_COLLECTION_FILE_SELECTION: data => toggleSelected(state, data.id),
default: () => state
});
};
-const toggle = (state: CollectionPanelFilesState, id: string, key: "collapsed" | "selected") =>
+const toggleCollapsed = (state: CollectionPanelFilesState, id: string) =>
state.map(file => file.id === id
- ? { ...file, [key]: !file[key] }
- : file);
\ No newline at end of file
+ ? { ...file, collapsed: !file.collapsed }
+ : file);
+
+const toggleSelected = (state: CollectionPanelFilesState, id: string) =>
+ toggleAncestors(toggleDescendants(state, id), id);
+
+const toggleDescendants = (state: CollectionPanelFilesState, id: string) => {
+ const ids = getDescendants(state)({ id }).map(file => file.id);
+ if (ids.length > 0) {
+ const selected = !state.find(f => f.id === ids[0])!.selected;
+ return state.map(file => ids.some(id => file.id === id) ? { ...file, selected } : file);
+ }
+ return state;
+};
+
+const toggleAncestors = (state: CollectionPanelFilesState, id: string): CollectionPanelFile[] => {
+ const file = state.find(f => f.id === id);
+ if (file) {
+ const selected = state
+ .filter(f => f.parentId === file.parentId)
+ .every(f => f.selected);
+ if (!selected) {
+ const newState = state.map(f => f.id === file.parentId ? { ...f, selected } : f);
+ return toggleAncestors(newState, file.parentId || "");
+ }
+ }
+ return state;
+};
+
+const getDescendants = (state: CollectionPanelFilesState) => ({ id }: { id: string }): CollectionPanelFile[] => {
+ const root = state.find(f => f.id === id);
+ if (root) {
+ return [root].concat(...state.filter(f => f.parentId === id).map(getDescendants(state)));
+ } else { return []; }
+};
+
import { reducer as formReducer } from 'redux-form';
import { FavoritesState, favoritesReducer } from './favorites/favorites-reducer';
import { snackbarReducer, SnackbarState } from './snackbar/snackbar-reducer';
+import { CollectionPanelFilesState } from './collection-panel/collection-panel-files/collection-panel-files-state';
+import { collectionPanelFilesReducer } from './collection-panel/collection-panel-files/collections-panel-files-reducer';
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
contextMenu: ContextMenuState;
favorites: FavoritesState;
snackbar: SnackbarState;
+ collectionPanelFiles: CollectionPanelFilesState;
}
const rootReducer = combineReducers({
form: formReducer,
favorites: favoritesReducer,
snackbar: snackbarReducer,
+ collectionPanelFiles: collectionPanelFilesReducer,
});
import { connect } from "react-redux";
import { CollectionPanelFiles as Component, CollectionPanelFilesProps } from "../../components/collection-panel-files/collection-panel-files";
import { RootState } from "../../store/store";
-import { TreeItemStatus } from "../../components/tree/tree";
+import { TreeItemStatus, TreeItem } from "../../components/tree/tree";
+import { CollectionPanelFile } from "../../store/collection-panel/collection-panel-files/collection-panel-files-state";
+import { FileTreeData } from "../../components/file-tree/file-tree-data";
+import { Dispatch } from "redux";
+import { collectionPanelFilesAction } from "../../store/collection-panel/collection-panel-files/collection-panel-files-actions";
const mapStateToProps = (state: RootState): Pick<CollectionPanelFilesProps, "items"> => ({
- items: [{
- active: false,
- data: {
- name: "Directory 1",
- type: "directory"
- },
- id: "Directory 1",
- open: true,
- status: TreeItemStatus.LOADED,
- items: [{
- active: false,
- data: {
- name: "Directory 1.1",
- type: "directory"
- },
- id: "Directory 1.1",
- open: false,
- status: TreeItemStatus.LOADED,
- items: []
- }, {
- active: false,
- data: {
- name: "File 1.1",
- type: "file",
- size: 20033
- },
- id: "File 1.1",
- open: false,
- status: TreeItemStatus.LOADED,
- items: []
- }]
- }, {
+ items: state.collectionPanelFiles
+ .filter(f => f.parentId === undefined)
+ .map(fileToTreeItem(state.collectionPanelFiles))
+});
+
+const mapDispatchToProps = (dispatch: Dispatch): Pick<CollectionPanelFilesProps, 'onCollapseToggle' | 'onSelectionToggle'> => ({
+ onCollapseToggle: (id) => dispatch(collectionPanelFilesAction.TOGGLE_COLLECTION_FILE_COLLAPSE({ id })),
+ onSelectionToggle: (event, item) => dispatch(collectionPanelFilesAction.TOGGLE_COLLECTION_FILE_SELECTION({id: item.id})),
+});
+
+
+export const CollectionPanelFiles = connect(mapStateToProps, mapDispatchToProps)(Component);
+
+const fileToTreeItem = (files: CollectionPanelFile[]) => (file: CollectionPanelFile): TreeItem<FileTreeData> => {
+ return {
active: false,
data: {
- name: "Directory 2",
- type: "directory"
+ name: file.name,
+ size: file.size,
+ type: file.type
},
- id: "Directory 2",
- open: false,
+ id: file.id,
+ items: files
+ .filter(f => f.parentId === file.id)
+ .map(fileToTreeItem(files)),
+ open: !file.collapsed,
+ selected: file.selected,
status: TreeItemStatus.LOADED
- }]
-});
-
-
-export const CollectionPanelFiles = connect(mapStateToProps)(Component);
+ };
+};