feat: persist board card fields (#1566)

Closes #1538
This commit is contained in:
Thaïs
2023-09-15 00:06:15 +02:00
committed by GitHub
parent 6462505a86
commit 2461a387ce
27 changed files with 541 additions and 342 deletions

View File

@ -0,0 +1,37 @@
import { type Context, useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
import { viewsScopedState } from '../states/viewsScopedState';
export const useRemoveView = ({
scopeContext,
}: {
scopeContext: Context<string | null>;
}) => {
const { onViewRemove } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
const removeView = useRecoilCallback(
({ set, snapshot }) =>
async (viewId: string) => {
const currentViewId = await snapshot.getPromise(
currentViewIdScopedState(recoilScopeId),
);
if (currentViewId === viewId)
set(currentViewIdScopedState(recoilScopeId), undefined);
set(viewsScopedState(recoilScopeId), (previousViews) =>
previousViews.filter((view) => view.id !== viewId),
);
await onViewRemove?.(viewId);
},
[onViewRemove, recoilScopeId],
);
return { removeView };
};

View File

@ -1,37 +1,30 @@
import { Context, useCallback } from 'react';
import { type Context, useCallback, useContext } from 'react';
import { useRecoilCallback, useRecoilState } from 'recoil';
import { v4 } from 'uuid';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { ViewBarContext } from '../contexts/ViewBarContext';
import { currentViewIdScopedState } from '../states/currentViewIdScopedState';
import { filtersScopedState } from '../states/filtersScopedState';
import { savedFiltersFamilyState } from '../states/savedFiltersFamilyState';
import { savedSortsFamilyState } from '../states/savedSortsFamilyState';
import { viewsByIdScopedSelector } from '../states/selectors/viewsByIdScopedSelector';
import { sortsScopedState } from '../states/sortsScopedState';
import { viewEditModeState } from '../states/viewEditModeState';
import { viewsScopedState } from '../states/viewsScopedState';
import type { View } from '../types/View';
export const useUpsertView = ({
onViewsChange,
scopeContext,
}: {
onViewsChange?: (views: View[]) => void | Promise<void>;
scopeContext: Context<string | null>;
}) => {
const { onViewCreate, onViewEdit } = useContext(ViewBarContext);
const recoilScopeId = useContextScopeId(scopeContext);
const filters = useRecoilScopedValue(filtersScopedState, scopeContext);
const sorts = useRecoilScopedValue(sortsScopedState, scopeContext);
const [, setCurrentViewId] = useRecoilScopedState(
currentViewIdScopedState,
scopeContext,
);
const [views, setViews] = useRecoilScopedState(
viewsScopedState,
scopeContext,
);
const [viewEditMode, setViewEditMode] = useRecoilState(viewEditModeState);
const resetViewEditMode = useCallback(
@ -40,44 +33,63 @@ export const useUpsertView = ({
);
const upsertView = useRecoilCallback(
({ set }) =>
({ set, snapshot }) =>
async (name?: string) => {
if (!viewEditMode.mode || !name) return resetViewEditMode();
if (!viewEditMode.mode || !name) {
resetViewEditMode();
return;
}
if (viewEditMode.mode === 'create') {
const viewToCreate = { id: v4(), name };
const nextViews = [...views, viewToCreate];
const createdView = { id: v4(), name };
set(savedFiltersFamilyState(viewToCreate.id), filters);
set(savedSortsFamilyState(viewToCreate.id), sorts);
set(savedFiltersFamilyState(createdView.id), filters);
set(savedSortsFamilyState(createdView.id), sorts);
setViews(nextViews);
await onViewsChange?.(nextViews);
set(viewsScopedState(recoilScopeId), (previousViews) => [
...previousViews,
createdView,
]);
setCurrentViewId(viewToCreate.id);
await onViewCreate?.(createdView);
resetViewEditMode();
set(currentViewIdScopedState(recoilScopeId), createdView.id);
return createdView;
}
if (viewEditMode.mode === 'edit') {
const nextViews = views.map((view) =>
view.id === viewEditMode.viewId ? { ...view, name } : view,
if (viewEditMode.mode === 'edit' && viewEditMode.viewId) {
const viewsById = await snapshot.getPromise(
viewsByIdScopedSelector(recoilScopeId),
);
const editedView = { ...viewsById[viewEditMode.viewId], name };
set(viewsScopedState(recoilScopeId), (previousViews) =>
previousViews.map((previousView) =>
previousView.id === viewEditMode.viewId
? editedView
: previousView,
),
);
setViews(nextViews);
await onViewsChange?.(nextViews);
}
await onViewEdit?.(editedView);
return resetViewEditMode();
resetViewEditMode();
return editedView;
}
},
[
filters,
onViewsChange,
onViewCreate,
onViewEdit,
recoilScopeId,
resetViewEditMode,
setCurrentViewId,
setViews,
sorts,
viewEditMode.mode,
viewEditMode.viewId,
views,
],
);