|
@@ -1,11 +1,19 @@
|
|
|
-import React, { createContext, useContext, useReducer, useEffect } from 'react'
|
|
|
|
|
|
|
+import React, {
|
|
|
|
|
+ createContext,
|
|
|
|
|
+ useContext,
|
|
|
|
|
+ useReducer,
|
|
|
|
|
+ useEffect,
|
|
|
|
|
+ useState
|
|
|
|
|
+} from 'react'
|
|
|
import PropTypes from 'prop-types'
|
|
import PropTypes from 'prop-types'
|
|
|
import classNames from 'classnames'
|
|
import classNames from 'classnames'
|
|
|
|
|
|
|
|
import { findInTree } from '../util/find-in-tree'
|
|
import { findInTree } from '../util/find-in-tree'
|
|
|
import { useFileTreeMutable } from './file-tree-mutable'
|
|
import { useFileTreeMutable } from './file-tree-mutable'
|
|
|
|
|
+import { FileTreeMainContext } from './file-tree-main'
|
|
|
|
|
+import usePersistedState from '../../../infrastructure/persisted-state-hook'
|
|
|
|
|
|
|
|
-const FileTreeSelectableContext = createContext(new Set())
|
|
|
|
|
|
|
+const FileTreeSelectableContext = createContext()
|
|
|
|
|
|
|
|
const ACTION_TYPES = {
|
|
const ACTION_TYPES = {
|
|
|
SELECT: 'SELECT',
|
|
SELECT: 'SELECT',
|
|
@@ -63,10 +71,17 @@ function fileTreeSelectableReadOnlyReducer(selectedEntityIds, action) {
|
|
|
|
|
|
|
|
export function FileTreeSelectableProvider({
|
|
export function FileTreeSelectableProvider({
|
|
|
hasWritePermissions,
|
|
hasWritePermissions,
|
|
|
- initialSelectedEntityId = null,
|
|
|
|
|
|
|
+ rootDocId,
|
|
|
onSelect,
|
|
onSelect,
|
|
|
children
|
|
children
|
|
|
}) {
|
|
}) {
|
|
|
|
|
+ const { projectId } = useContext(FileTreeMainContext)
|
|
|
|
|
+
|
|
|
|
|
+ const [initialSelectedEntityId] = usePersistedState(
|
|
|
|
|
+ `doc.open_id.${projectId}`,
|
|
|
|
|
+ rootDocId
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
const [selectedEntityIds, dispatch] = useReducer(
|
|
const [selectedEntityIds, dispatch] = useReducer(
|
|
|
hasWritePermissions
|
|
hasWritePermissions
|
|
|
? fileTreeSelectableReadWriteReducer
|
|
? fileTreeSelectableReadWriteReducer
|
|
@@ -75,6 +90,22 @@ export function FileTreeSelectableProvider({
|
|
|
)
|
|
)
|
|
|
const { fileTreeData } = useFileTreeMutable()
|
|
const { fileTreeData } = useFileTreeMutable()
|
|
|
|
|
|
|
|
|
|
+ const [selectedEntityParentIds, setSelectedEntityParentIds] = useState(
|
|
|
|
|
+ new Set()
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ // fills `selectedEntityParentIds` set
|
|
|
|
|
+ useEffect(() => {
|
|
|
|
|
+ const ids = new Set()
|
|
|
|
|
+ selectedEntityIds.forEach(id => {
|
|
|
|
|
+ const found = findInTree(fileTreeData, id)
|
|
|
|
|
+ if (found) {
|
|
|
|
|
+ found.path.forEach(pathItem => ids.add(pathItem))
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ setSelectedEntityParentIds(ids)
|
|
|
|
|
+ }, [fileTreeData, selectedEntityIds])
|
|
|
|
|
+
|
|
|
// calls `onSelect` on entities selection
|
|
// calls `onSelect` on entities selection
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
const selectedEntities = Array.from(selectedEntityIds).map(id =>
|
|
const selectedEntities = Array.from(selectedEntityIds).map(id =>
|
|
@@ -93,7 +124,9 @@ export function FileTreeSelectableProvider({
|
|
|
}, [])
|
|
}, [])
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
- <FileTreeSelectableContext.Provider value={{ selectedEntityIds, dispatch }}>
|
|
|
|
|
|
|
+ <FileTreeSelectableContext.Provider
|
|
|
|
|
+ value={{ selectedEntityIds, selectedEntityParentIds, dispatch }}
|
|
|
|
|
+ >
|
|
|
{children}
|
|
{children}
|
|
|
</FileTreeSelectableContext.Provider>
|
|
</FileTreeSelectableContext.Provider>
|
|
|
)
|
|
)
|
|
@@ -101,7 +134,7 @@ export function FileTreeSelectableProvider({
|
|
|
|
|
|
|
|
FileTreeSelectableProvider.propTypes = {
|
|
FileTreeSelectableProvider.propTypes = {
|
|
|
hasWritePermissions: PropTypes.bool.isRequired,
|
|
hasWritePermissions: PropTypes.bool.isRequired,
|
|
|
- initialSelectedEntityId: PropTypes.string,
|
|
|
|
|
|
|
+ rootDocId: PropTypes.string,
|
|
|
onSelect: PropTypes.func.isRequired,
|
|
onSelect: PropTypes.func.isRequired,
|
|
|
children: PropTypes.oneOfType([
|
|
children: PropTypes.oneOfType([
|
|
|
PropTypes.arrayOf(PropTypes.node),
|
|
PropTypes.arrayOf(PropTypes.node),
|
|
@@ -151,7 +184,9 @@ export function useSelectableEntity(id) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export function useFileTreeSelectable() {
|
|
export function useFileTreeSelectable() {
|
|
|
- const { selectedEntityIds, dispatch } = useContext(FileTreeSelectableContext)
|
|
|
|
|
|
|
+ const { selectedEntityIds, selectedEntityParentIds, dispatch } = useContext(
|
|
|
|
|
+ FileTreeSelectableContext
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
function select(id) {
|
|
function select(id) {
|
|
|
dispatch({ type: ACTION_TYPES.SELECT, id })
|
|
dispatch({ type: ACTION_TYPES.SELECT, id })
|
|
@@ -163,6 +198,7 @@ export function useFileTreeSelectable() {
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
selectedEntityIds,
|
|
selectedEntityIds,
|
|
|
|
|
+ selectedEntityParentIds,
|
|
|
select,
|
|
select,
|
|
|
unselect
|
|
unselect
|
|
|
}
|
|
}
|