feat: toggle board field visibilities (#1547)

Closes #1537, Closes #1539
This commit is contained in:
Thaïs
2023-09-13 11:58:52 +02:00
committed by GitHub
parent 67f1da038d
commit 28e12d492c
31 changed files with 492 additions and 168 deletions

View File

@ -0,0 +1,113 @@
import { type Context } from 'react';
import { availableBoardCardFieldsScopedState } from '@/ui/board/states/availableBoardCardFieldsScopedState';
import { boardCardFieldsScopedState } from '@/ui/board/states/boardCardFieldsScopedState';
import type {
ViewFieldDefinition,
ViewFieldMetadata,
} from '@/ui/editable-field/types/ViewField';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { currentViewIdScopedState } from '@/ui/view-bar/states/currentViewIdScopedState';
import {
SortOrder,
useCreateViewFieldsMutation,
useGetViewFieldsQuery,
} from '~/generated/graphql';
import { assertNotNull } from '~/utils/assert';
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
const toViewFieldInput = (
objectId: 'company' | 'person',
fieldDefinition: ViewFieldDefinition<ViewFieldMetadata>,
) => ({
key: fieldDefinition.key,
name: fieldDefinition.name,
index: fieldDefinition.index,
isVisible: fieldDefinition.isVisible ?? true,
objectId,
});
export const useBoardViewFields = ({
objectId,
fieldDefinitions,
scopeContext,
skipFetch,
}: {
objectId: 'company' | 'person';
fieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
scopeContext: Context<string | null>;
skipFetch?: boolean;
}) => {
const currentViewId = useRecoilScopedValue(
currentViewIdScopedState,
scopeContext,
);
const [availableBoardCardFields, setAvailableBoardCardFields] =
useRecoilScopedState(availableBoardCardFieldsScopedState, scopeContext);
const [boardCardFields, setBoardCardFields] = useRecoilScopedState(
boardCardFieldsScopedState,
scopeContext,
);
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
const createViewFields = (
fields: ViewFieldDefinition<ViewFieldMetadata>[],
viewId = currentViewId,
) => {
if (!viewId || !fields.length) return;
return createViewFieldsMutation({
variables: {
data: fields.map((field) => ({
...toViewFieldInput(objectId, field),
viewId,
})),
},
});
};
const { refetch } = useGetViewFieldsQuery({
skip: !currentViewId || skipFetch,
variables: {
orderBy: { index: SortOrder.Asc },
where: {
viewId: { equals: currentViewId },
},
},
onCompleted: async (data) => {
if (!data.viewFields.length) {
// Populate if empty
await createViewFields(fieldDefinitions);
return refetch();
}
const nextFields = data.viewFields
.map<ViewFieldDefinition<ViewFieldMetadata> | null>((viewField) => {
const fieldDefinition = fieldDefinitions.find(
({ key }) => viewField.key === key,
);
return fieldDefinition
? {
...fieldDefinition,
key: viewField.key,
name: viewField.name,
index: viewField.index,
isVisible: viewField.isVisible,
}
: null;
})
.filter<ViewFieldDefinition<ViewFieldMetadata>>(assertNotNull);
if (!isDeeplyEqual(boardCardFields, nextFields)) {
setBoardCardFields(nextFields);
}
if (!availableBoardCardFields.length) {
setAvailableBoardCardFields(fieldDefinitions);
}
},
});
};

View File

@ -1,5 +1,9 @@
import { type Context } from 'react';
import type { Context } from 'react';
import type {
ViewFieldDefinition,
ViewFieldMetadata,
} from '@/ui/editable-field/types/ViewField';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { filtersScopedState } from '@/ui/view-bar/states/filtersScopedState';
import { sortsScopedState } from '@/ui/view-bar/states/sortsScopedState';
@ -7,6 +11,7 @@ import type { FilterDefinitionByEntity } from '@/ui/view-bar/types/FilterDefinit
import type { SortType } from '@/ui/view-bar/types/interface';
import { ViewType } from '~/generated/graphql';
import { useBoardViewFields } from './useBoardViewFields';
import { useViewFilters } from './useViewFilters';
import { useViews } from './useViews';
import { useViewSorts } from './useViewSorts';
@ -14,11 +19,13 @@ import { useViewSorts } from './useViewSorts';
export const useBoardViews = <Entity, SortField>({
availableFilters,
availableSorts,
fieldDefinitions,
objectId,
scopeContext,
}: {
availableFilters: FilterDefinitionByEntity<Entity>[];
availableSorts: SortType<SortField>[];
fieldDefinitions: ViewFieldDefinition<ViewFieldMetadata>[];
objectId: 'company';
scopeContext: Context<string | null>;
}) => {
@ -31,6 +38,12 @@ export const useBoardViews = <Entity, SortField>({
type: ViewType.Pipeline,
scopeContext,
});
useBoardViewFields({
objectId,
fieldDefinitions,
scopeContext,
skipFetch: isFetchingViews,
});
const { createViewFilters, persistFilters } = useViewFilters({
availableFilters,
scopeContext,