Uniformize folder structure (#693)

* Uniformize folder structure

* Fix icons

* Fix icons

* Fix tests

* Fix tests
This commit is contained in:
Charles Bochet
2023-07-16 14:29:28 -07:00
committed by GitHub
parent 900ec5572f
commit 6ced8434bd
462 changed files with 931 additions and 960 deletions

View File

@ -0,0 +1,22 @@
import { useRecoilCallback } from 'recoil';
import { currentCellInEditModePositionState } from '../states/currentCellInEditModePositionState';
import { isCellInEditModeFamilyState } from '../states/isCellInEditModeFamilyState';
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
export function useCloseCurrentCellInEditMode() {
return useRecoilCallback(({ set, snapshot }) => {
return async () => {
const currentCellInEditModePosition = await snapshot.getPromise(
currentCellInEditModePositionState,
);
set(isCellInEditModeFamilyState(currentCellInEditModePosition), false);
// TODO: find a way to remove this
await new Promise((resolve) => setTimeout(resolve, 20));
set(isSomeInputInEditModeState, false);
};
}, []);
}

View File

@ -0,0 +1,18 @@
import { useRecoilScopedValue } from '@/ui/recoil-scope/hooks/useRecoilScopedValue';
import { currentRowEntityIdScopedState } from '../states/currentRowEntityIdScopedState';
import { RowContext } from '../states/RowContext';
export type TableDimensions = {
numberOfColumns: number;
numberOfRows: number;
};
export function useCurrentRowEntityId() {
const currentRowEntityIdScoped = useRecoilScopedValue(
currentRowEntityIdScopedState,
RowContext,
);
return currentRowEntityIdScoped;
}

View File

@ -0,0 +1,36 @@
import { useRecoilCallback, useRecoilState } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
import { useCurrentRowEntityId } from './useCurrentEntityId';
export function useCurrentRowSelected() {
const currentRowId = useCurrentRowEntityId();
const [isRowSelected] = useRecoilState(
isRowSelectedFamilyState(currentRowId ?? ''),
);
const setCurrentRowSelected = useRecoilCallback(
({ set, snapshot }) =>
(newSelectedState: boolean) => {
if (!currentRowId) return;
const isRowSelected = snapshot
.getLoadable(isRowSelectedFamilyState(currentRowId))
.valueOrThrow();
if (newSelectedState && !isRowSelected) {
set(isRowSelectedFamilyState(currentRowId), true);
} else if (!newSelectedState && isRowSelected) {
set(isRowSelectedFamilyState(currentRowId), false);
}
},
[currentRowId],
);
return {
currentRowSelected: isRowSelected,
setCurrentRowSelected,
};
}

View File

@ -0,0 +1,19 @@
import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
import { isSoftFocusOnCellFamilyState } from '../states/isSoftFocusOnCellFamilyState';
import { softFocusPositionState } from '../states/softFocusPositionState';
export function useDisableSoftFocus() {
return useRecoilCallback(({ set, snapshot }) => {
return () => {
const currentPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
set(isSoftFocusActiveState, false);
set(isSoftFocusOnCellFamilyState(currentPosition), false);
};
}, []);
}

View File

@ -0,0 +1,35 @@
import { useEffect } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { entityTableDimensionsState } from '../states/entityTableDimensionsState';
import { tableRowIdsState } from '../states/tableRowIdsState';
import { useResetTableRowSelection } from './useResetTableRowSelection';
export type TableDimensions = {
numberOfColumns: number;
numberOfRows: number;
};
export function useInitializeEntityTable({
numberOfColumns,
}: {
numberOfColumns: number;
}) {
const resetTableRowSelection = useResetTableRowSelection();
const tableRowIds = useRecoilValue(tableRowIdsState);
useEffect(() => {
resetTableRowSelection();
}, [resetTableRowSelection]);
const [, setTableDimensions] = useRecoilState(entityTableDimensionsState);
useEffect(() => {
setTableDimensions({
numberOfColumns,
numberOfRows: tableRowIds?.length,
});
}, [tableRowIds, numberOfColumns, setTableDimensions]);
}

View File

@ -0,0 +1,22 @@
import { useEffect } from 'react';
import { availableFiltersScopedState } from '@/ui/filter-n-sort/states/availableFiltersScopedState';
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { TableContext } from '../states/TableContext';
export function useInitializeEntityTableFilters({
availableFilters,
}: {
availableFilters: FilterDefinition[];
}) {
const [, setAvailableFilters] = useRecoilScopedState(
availableFiltersScopedState,
TableContext,
);
useEffect(() => {
setAvailableFilters(availableFilters);
}, [setAvailableFilters, availableFilters]);
}

View File

@ -0,0 +1,53 @@
import { useRecoilCallback } from 'recoil';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { currentHotkeyScopeState } from '@/ui/hotkey/states/internal/currentHotkeyScopeState';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { useCloseCurrentCellInEditMode } from './useClearCellInEditMode';
import { useDisableSoftFocus } from './useDisableSoftFocus';
export function useLeaveTableFocus() {
const disableSoftFocus = useDisableSoftFocus();
const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode();
const setHotkeyScope = useSetHotkeyScope();
return useRecoilCallback(
({ snapshot }) =>
() => {
const isSoftFocusActive = snapshot
.getLoadable(isSoftFocusActiveState)
.valueOrThrow();
const isSomeInputInEditMode = snapshot
.getLoadable(isSomeInputInEditModeState)
.valueOrThrow();
const currentHotkeyScope = snapshot
.getLoadable(currentHotkeyScopeState)
.valueOrThrow();
if (isSomeInputInEditMode) {
return;
}
if (!isSoftFocusActive && !isSomeInputInEditMode) {
return;
}
if (currentHotkeyScope?.scope === TableHotkeyScope.Table) {
return;
}
closeCurrentCellInEditMode();
disableSoftFocus();
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
},
[setHotkeyScope, closeCurrentCellInEditMode, disableSoftFocus],
);
}

View File

@ -0,0 +1,74 @@
import { useRecoilState } from 'recoil';
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { isSomeInputInEditModeState } from '../states/isSomeInputInEditModeState';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { useDisableSoftFocus } from './useDisableSoftFocus';
import { useMoveSoftFocus } from './useMoveSoftFocus';
export function useMapKeyboardToSoftFocus() {
const { moveDown, moveLeft, moveRight, moveUp } = useMoveSoftFocus();
const disableSoftFocus = useDisableSoftFocus();
const setHotkeyScope = useSetHotkeyScope();
const [isSomeInputInEditMode] = useRecoilState(isSomeInputInEditModeState);
useScopedHotkeys(
[Key.ArrowUp, `${Key.Shift}+${Key.Enter}`],
() => {
if (!isSomeInputInEditMode) {
moveUp();
}
},
TableHotkeyScope.TableSoftFocus,
[moveUp, isSomeInputInEditMode],
);
useScopedHotkeys(
Key.ArrowDown,
() => {
if (!isSomeInputInEditMode) {
moveDown();
}
},
TableHotkeyScope.TableSoftFocus,
[moveDown, isSomeInputInEditMode],
);
useScopedHotkeys(
[Key.ArrowLeft, `${Key.Shift}+${Key.Tab}`],
() => {
if (!isSomeInputInEditMode) {
moveLeft();
}
},
TableHotkeyScope.TableSoftFocus,
[moveLeft, isSomeInputInEditMode],
);
useScopedHotkeys(
[Key.ArrowRight, Key.Tab],
() => {
if (!isSomeInputInEditMode) {
moveRight();
}
},
TableHotkeyScope.TableSoftFocus,
[moveRight, isSomeInputInEditMode],
);
useScopedHotkeys(
[Key.Escape],
() => {
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
disableSoftFocus();
},
TableHotkeyScope.TableSoftFocus,
[disableSoftFocus],
);
}

View File

@ -0,0 +1,21 @@
import { useRecoilCallback } from 'recoil';
import { currentCellInEditModePositionState } from '../states/currentCellInEditModePositionState';
import { isCellInEditModeFamilyState } from '../states/isCellInEditModeFamilyState';
import { CellPosition } from '../types/CellPosition';
export function useMoveEditModeToCellPosition() {
return useRecoilCallback(({ set, snapshot }) => {
return (newPosition: CellPosition) => {
const currentCellInEditModePosition = snapshot
.getLoadable(currentCellInEditModePositionState)
.valueOrThrow();
set(isCellInEditModeFamilyState(currentCellInEditModePosition), false);
set(currentCellInEditModePositionState, newPosition);
set(isCellInEditModeFamilyState(newPosition), true);
};
}, []);
}

View File

@ -0,0 +1,154 @@
import { useRecoilCallback } from 'recoil';
import { numberOfTableColumnsSelectorState } from '../states/numberOfTableColumnsSelectorState';
import { numberOfTableRowsSelectorState } from '../states/numberOfTableRowsSelectorState';
import { softFocusPositionState } from '../states/softFocusPositionState';
import { useSetSoftFocusPosition } from './useSetSoftFocusPosition';
// TODO: stories
export function useMoveSoftFocus() {
const setSoftFocusPosition = useSetSoftFocusPosition();
const moveUp = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row - 1;
if (newRowNumber < 0) {
newRowNumber = 0;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveDown = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsSelectorState)
.valueOrThrow();
let newRowNumber = softFocusPosition.row + 1;
if (newRowNumber >= numberOfTableRows) {
newRowNumber = numberOfTableRows - 1;
}
setSoftFocusPosition({
...softFocusPosition,
row: newRowNumber,
});
},
[setSoftFocusPosition],
);
const moveRight = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsSelectorState)
.valueOrThrow();
const numberOfTableRows = snapshot
.getLoadable(numberOfTableRowsSelectorState)
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isLastRowAndLastColumn =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber === numberOfTableRows - 1;
const isLastColumnButNotLastRow =
currentColumnNumber === numberOfTableColumns - 1 &&
currentRowNumber !== numberOfTableRows - 1;
const isNotLastColumn =
currentColumnNumber !== numberOfTableColumns - 1;
if (isLastRowAndLastColumn) {
return;
}
if (isNotLastColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber + 1,
});
} else if (isLastColumnButNotLastRow) {
setSoftFocusPosition({
row: currentRowNumber + 1,
column: 0,
});
}
},
[setSoftFocusPosition],
);
const moveLeft = useRecoilCallback(
({ snapshot }) =>
() => {
const softFocusPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
const numberOfTableColumns = snapshot
.getLoadable(numberOfTableColumnsSelectorState)
.valueOrThrow();
const currentColumnNumber = softFocusPosition.column;
const currentRowNumber = softFocusPosition.row;
const isFirstRowAndFirstColumn =
currentColumnNumber === 0 && currentRowNumber === 0;
const isFirstColumnButNotFirstRow =
currentColumnNumber === 0 && currentRowNumber > 0;
const isNotFirstColumn = currentColumnNumber > 0;
if (isFirstRowAndFirstColumn) {
return;
}
if (isNotFirstColumn) {
setSoftFocusPosition({
row: currentRowNumber,
column: currentColumnNumber - 1,
});
} else if (isFirstColumnButNotFirstRow) {
setSoftFocusPosition({
row: currentRowNumber - 1,
column: numberOfTableColumns - 1,
});
}
},
[setSoftFocusPosition],
);
return {
moveDown,
moveLeft,
moveRight,
moveUp,
};
}

View File

@ -0,0 +1,20 @@
import { useRecoilCallback } from 'recoil';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
import { tableRowIdsState } from '../states/tableRowIdsState';
export function useResetTableRowSelection() {
return useRecoilCallback(
({ snapshot, set }) =>
() => {
const tableRowIds = snapshot
.getLoadable(tableRowIdsState)
.valueOrThrow();
for (const rowId of tableRowIds) {
set(isRowSelectedFamilyState(rowId), false);
}
},
[],
);
}

View File

@ -0,0 +1,41 @@
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { allRowsSelectedStatusSelector } from '../states/allRowsSelectedStatusSelector';
import { isRowSelectedFamilyState } from '../states/isRowSelectedFamilyState';
import { tableRowIdsState } from '../states/tableRowIdsState';
export function useSelectAllRows() {
const allRowsSelectedStatus = useRecoilValue(allRowsSelectedStatusSelector);
const selectAllRows = useRecoilCallback(
({ set, snapshot }) =>
() => {
const allRowsSelectedStatus = snapshot
.getLoadable(allRowsSelectedStatusSelector)
.valueOrThrow();
const tableRowIds = snapshot
.getLoadable(tableRowIdsState)
.valueOrThrow();
if (
allRowsSelectedStatus === 'none' ||
allRowsSelectedStatus === 'some'
) {
for (const rowId of tableRowIds) {
set(isRowSelectedFamilyState(rowId), true);
}
} else {
for (const rowId of tableRowIds) {
set(isRowSelectedFamilyState(rowId), false);
}
}
},
[],
);
return {
allRowsSelectedStatus,
selectAllRows,
};
}

View File

@ -0,0 +1,24 @@
import { useRecoilCallback } from 'recoil';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
import { isSoftFocusOnCellFamilyState } from '../states/isSoftFocusOnCellFamilyState';
import { softFocusPositionState } from '../states/softFocusPositionState';
import { CellPosition } from '../types/CellPosition';
export function useSetSoftFocusPosition() {
return useRecoilCallback(({ set, snapshot }) => {
return (newPosition: CellPosition) => {
const currentPosition = snapshot
.getLoadable(softFocusPositionState)
.valueOrThrow();
set(isSoftFocusActiveState, true);
set(isSoftFocusOnCellFamilyState(currentPosition), false);
set(softFocusPositionState, newPosition);
set(isSoftFocusOnCellFamilyState(newPosition), true);
};
}, []);
}