Migrate view field to new data model - Part 2 (#2270)
* Migrate view field to new data model * Migrate view fields to new model
This commit is contained in:
@ -23,8 +23,8 @@ export const ActivityAssigneeEditableField = ({
|
||||
entityId: activity.id,
|
||||
recoilScopeId: 'assignee',
|
||||
fieldDefinition: {
|
||||
key: 'assignee',
|
||||
name: 'Assignee',
|
||||
fieldId: 'assignee',
|
||||
label: 'Assignee',
|
||||
Icon: IconUserCircle,
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
|
||||
@ -21,8 +21,8 @@ export const ActivityEditorDateField = ({
|
||||
entityId: activityId,
|
||||
recoilScopeId: 'activityDueAt',
|
||||
fieldDefinition: {
|
||||
key: 'activityDueAt',
|
||||
name: 'Due date',
|
||||
fieldId: 'activityDueAt',
|
||||
label: 'Due date',
|
||||
Icon: IconCalendar,
|
||||
type: 'date',
|
||||
metadata: {
|
||||
|
||||
@ -3,11 +3,8 @@ import { useRecoilState } from 'recoil';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { turnFilterIntoWhereClause } from '@/ui/data/filter/utils/turnFilterIntoWhereClause';
|
||||
import {
|
||||
ActivityType,
|
||||
useGetActivitiesQuery,
|
||||
ViewFilterOperand,
|
||||
} from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { ActivityType, useGetActivitiesQuery } from '~/generated/graphql';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
export const useCurrentUserTaskCount = () => {
|
||||
|
||||
@ -7,31 +7,31 @@ export const pipeline = {
|
||||
{
|
||||
id: 'pipeline-stage-1',
|
||||
name: 'New',
|
||||
index: 0,
|
||||
position: 0,
|
||||
color: 'red',
|
||||
},
|
||||
{
|
||||
id: 'pipeline-stage-2',
|
||||
name: 'Screening',
|
||||
index: 1,
|
||||
position: 1,
|
||||
color: 'purple',
|
||||
},
|
||||
{
|
||||
id: 'pipeline-stage-3',
|
||||
name: 'Meeting',
|
||||
index: 2,
|
||||
position: 2,
|
||||
color: 'sky',
|
||||
},
|
||||
{
|
||||
id: 'pipeline-stage-4',
|
||||
name: 'Proposal',
|
||||
index: 3,
|
||||
position: 3,
|
||||
color: 'turquoise',
|
||||
},
|
||||
{
|
||||
id: 'pipeline-stage-5',
|
||||
name: 'Customer',
|
||||
index: 4,
|
||||
position: 4,
|
||||
color: 'yellow',
|
||||
},
|
||||
],
|
||||
|
||||
@ -222,14 +222,14 @@ export const CompanyBoardCard = () => {
|
||||
<StyledBoardCardBody>
|
||||
<AnimatedEaseInOut isOpen={!showCompactView}>
|
||||
{visibleBoardCardFields.map((viewField) => (
|
||||
<PreventSelectOnClickContainer key={viewField.key}>
|
||||
<PreventSelectOnClickContainer key={viewField.fieldId}>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
entityId: boardCardId,
|
||||
recoilScopeId: boardCardId + viewField.key,
|
||||
recoilScopeId: boardCardId + viewField.fieldId,
|
||||
fieldDefinition: {
|
||||
key: viewField.key,
|
||||
name: viewField.name,
|
||||
fieldId: viewField.fieldId,
|
||||
label: viewField.label,
|
||||
Icon: viewField.Icon,
|
||||
type: viewField.type,
|
||||
metadata: viewField.metadata,
|
||||
|
||||
@ -28,11 +28,11 @@ import { User } from '~/generated/graphql';
|
||||
export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
key: 'name',
|
||||
name: 'Name',
|
||||
fieldId: 'name',
|
||||
label: 'Name',
|
||||
Icon: IconBuildingSkyscraper,
|
||||
size: 180,
|
||||
index: 0,
|
||||
position: 0,
|
||||
type: 'chip',
|
||||
metadata: {
|
||||
urlFieldName: 'domainName',
|
||||
@ -45,11 +45,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
basePathToShowPage: '/companies/',
|
||||
} satisfies ColumnDefinition<FieldChipMetadata>,
|
||||
{
|
||||
key: 'domainName',
|
||||
name: 'URL',
|
||||
fieldId: 'domainName',
|
||||
label: 'URL',
|
||||
Icon: IconLink,
|
||||
size: 100,
|
||||
index: 1,
|
||||
position: 1,
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'domainName',
|
||||
@ -60,11 +60,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
'The company website URL. We use this url to fetch the company icon.',
|
||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
||||
{
|
||||
key: 'accountOwner',
|
||||
name: 'Account Owner',
|
||||
fieldId: 'accountOwner',
|
||||
label: 'Account Owner',
|
||||
Icon: IconUserCircle,
|
||||
size: 150,
|
||||
index: 2,
|
||||
position: 2,
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'accountOwner',
|
||||
@ -82,11 +82,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
},
|
||||
} satisfies ColumnDefinition<FieldRelationMetadata>,
|
||||
{
|
||||
key: 'createdAt',
|
||||
name: 'Creation',
|
||||
fieldId: 'createdAt',
|
||||
label: 'Creation',
|
||||
Icon: IconCalendarEvent,
|
||||
size: 150,
|
||||
index: 3,
|
||||
position: 3,
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'createdAt',
|
||||
@ -95,11 +95,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
infoTooltipContent: "Date when the company's record was created.",
|
||||
} satisfies ColumnDefinition<FieldDateMetadata>,
|
||||
{
|
||||
key: 'employees',
|
||||
name: 'Employees',
|
||||
fieldId: 'employees',
|
||||
label: 'Employees',
|
||||
Icon: IconUsers,
|
||||
size: 150,
|
||||
index: 4,
|
||||
position: 4,
|
||||
type: 'number',
|
||||
metadata: {
|
||||
fieldName: 'employees',
|
||||
@ -110,11 +110,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
infoTooltipContent: 'Number of employees in the company.',
|
||||
} satisfies ColumnDefinition<FieldNumberMetadata>,
|
||||
{
|
||||
key: 'linkedin',
|
||||
name: 'LinkedIn',
|
||||
fieldId: 'linkedin',
|
||||
label: 'LinkedIn',
|
||||
Icon: IconBrandLinkedin,
|
||||
size: 170,
|
||||
index: 5,
|
||||
position: 5,
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'linkedinUrl',
|
||||
@ -124,11 +124,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
infoTooltipContent: 'The company Linkedin account.',
|
||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
||||
{
|
||||
key: 'address',
|
||||
name: 'Address',
|
||||
fieldId: 'address',
|
||||
label: 'Address',
|
||||
Icon: IconMap,
|
||||
size: 170,
|
||||
index: 6,
|
||||
position: 6,
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'address',
|
||||
@ -138,11 +138,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
infoTooltipContent: 'The company address.',
|
||||
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||
{
|
||||
key: 'idealCustomerProfile',
|
||||
name: 'ICP',
|
||||
fieldId: 'idealCustomerProfile',
|
||||
label: 'ICP',
|
||||
Icon: IconTarget,
|
||||
size: 150,
|
||||
index: 7,
|
||||
position: 7,
|
||||
type: 'boolean',
|
||||
metadata: {
|
||||
fieldName: 'idealCustomerProfile',
|
||||
@ -152,11 +152,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
'Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you.',
|
||||
} satisfies ColumnDefinition<FieldBooleanMetadata>,
|
||||
{
|
||||
key: 'annualRecurringRevenue',
|
||||
name: 'ARR',
|
||||
fieldId: 'annualRecurringRevenue',
|
||||
label: 'ARR',
|
||||
Icon: IconMoneybag,
|
||||
size: 150,
|
||||
index: 8,
|
||||
position: 8,
|
||||
type: 'moneyAmount',
|
||||
metadata: {
|
||||
fieldName: 'annualRecurringRevenue',
|
||||
@ -166,11 +166,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
'Annual Recurring Revenue: The actual or estimated annual revenue of the company.',
|
||||
} satisfies ColumnDefinition<FieldMoneyMetadata>,
|
||||
{
|
||||
key: 'xUrl',
|
||||
name: 'Twitter',
|
||||
fieldId: 'xUrl',
|
||||
label: 'Twitter',
|
||||
Icon: IconBrandX,
|
||||
size: 150,
|
||||
index: 9,
|
||||
position: 9,
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'xUrl',
|
||||
@ -184,11 +184,11 @@ export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>
|
||||
export const suppliersAvailableColumnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
key: 'name',
|
||||
name: 'Name',
|
||||
fieldId: 'name',
|
||||
label: 'Name',
|
||||
Icon: IconBuildingSkyscraper,
|
||||
size: 180,
|
||||
index: 0,
|
||||
position: 0,
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'name',
|
||||
@ -199,11 +199,11 @@ export const suppliersAvailableColumnDefinitions: ColumnDefinition<FieldMetadata
|
||||
basePathToShowPage: '/companies/',
|
||||
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||
{
|
||||
key: 'city',
|
||||
name: 'City',
|
||||
fieldId: 'city',
|
||||
label: 'City',
|
||||
Icon: IconBuildingSkyscraper,
|
||||
size: 180,
|
||||
index: 0,
|
||||
position: 0,
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'city',
|
||||
|
||||
@ -92,8 +92,8 @@ export const useUpdateCompanyBoard = () =>
|
||||
const pipelineStages = pipeline?.pipelineStages ?? [];
|
||||
|
||||
const orderedPipelineStages = [...pipelineStages].sort((a, b) => {
|
||||
if (!a.index || !b.index) return 0;
|
||||
return a.index - b.index;
|
||||
if (!a.position || !b.position) return 0;
|
||||
return a.position - b.position;
|
||||
});
|
||||
|
||||
const newBoardColumns: BoardColumnDefinition[] =
|
||||
@ -110,7 +110,7 @@ export const useUpdateCompanyBoard = () =>
|
||||
colorCode: isThemeColor(pipelineStage.color)
|
||||
? pipelineStage.color
|
||||
: undefined,
|
||||
index: pipelineStage.index ?? 0,
|
||||
position: pipelineStage.position ?? 0,
|
||||
};
|
||||
});
|
||||
if (currentBoardColumns.length === 0) {
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
||||
|
||||
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
|
||||
import { getCompaniesOptimisticEffectDefinition } from '@/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition';
|
||||
import { useCompanyTableActionBarEntries } from '@/companies/hooks/useCompanyTableActionBarEntries';
|
||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
||||
@ -9,10 +11,13 @@ import { DataTableEffect } from '@/ui/data/data-table/components/DataTableEffect
|
||||
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
|
||||
import { useUpsertDataTableItem } from '@/ui/data/data-table/hooks/useUpsertDataTableItem';
|
||||
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
||||
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
|
||||
import { ViewBar } from '@/views/components/ViewBar';
|
||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import { columnDefinitionsToViewFields } from '@/views/utils/columnDefinitionToViewField';
|
||||
import { viewFieldsToColumnDefinitions } from '@/views/utils/viewFieldsToColumnDefinitions';
|
||||
import {
|
||||
UpdateOneCompanyMutationVariables,
|
||||
useGetCompaniesQuery,
|
||||
@ -26,13 +31,18 @@ import CompanyTableEffect from './CompanyTableEffect';
|
||||
|
||||
export const CompanyTable = () => {
|
||||
const tableViewScopeId = 'company-table';
|
||||
const setTableColumns = useSetRecoilState(
|
||||
tableColumnsScopedState('companies'),
|
||||
);
|
||||
|
||||
const [updateEntityMutation] = useUpdateOneCompanyMutation();
|
||||
const upsertDataTableItem = useUpsertDataTableItem();
|
||||
|
||||
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
|
||||
const { persistViewFields } = useViewFields(tableViewScopeId);
|
||||
const { setCurrentViewFields } = useView({ viewScopeId: tableViewScopeId });
|
||||
const { setCurrentViewFields, currentViewId } = useView({
|
||||
viewScopeId: tableViewScopeId,
|
||||
});
|
||||
|
||||
const { setContextMenuEntries } = useCompanyTableContextMenuEntries();
|
||||
const { setActionBarEntries } = useCompanyTableActionBarEntries();
|
||||
@ -77,14 +87,25 @@ export const CompanyTable = () => {
|
||||
`;
|
||||
|
||||
return (
|
||||
<ViewScope viewScopeId={tableViewScopeId}>
|
||||
<ViewScope
|
||||
viewScopeId={tableViewScopeId}
|
||||
onViewFieldsChange={(viewFields) => {
|
||||
setTableColumns(
|
||||
viewFieldsToColumnDefinitions(
|
||||
viewFields,
|
||||
companiesAvailableFieldDefinitions,
|
||||
),
|
||||
);
|
||||
}}
|
||||
onViewFiltersChange={() => {}}
|
||||
>
|
||||
<StyledContainer>
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
onColumnsChange: (columns) => {
|
||||
setCurrentViewFields?.(columns);
|
||||
persistViewFields(columns);
|
||||
},
|
||||
onColumnsChange: useRecoilCallback(() => (columns) => {
|
||||
setCurrentViewFields?.(columnDefinitionsToViewFields(columns));
|
||||
persistViewFields(columnDefinitionsToViewFields(columns));
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<ViewBar
|
||||
|
||||
@ -3,13 +3,9 @@ import { useEffect } from 'react';
|
||||
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
|
||||
import { availableTableColumnsScopedState } from '@/ui/data/data-table/states/availableTableColumnsScopedState';
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
|
||||
import { tableFiltersScopedState } from '@/ui/data/data-table/states/tableFiltersScopedState';
|
||||
import { tableSortsScopedState } from '@/ui/data/data-table/states/tableSortsScopedState';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { useViewInternalStates } from '@/views/hooks/useViewInternalStates';
|
||||
import { ViewType } from '~/generated/graphql';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { companyAvailableFilters } from '~/pages/companies/companies-filters';
|
||||
import { companyAvailableSorts } from '~/pages/companies/companies-sorts';
|
||||
|
||||
@ -21,23 +17,6 @@ const CompanyTableEffect = () => {
|
||||
setViewType,
|
||||
setViewObjectId,
|
||||
} = useView();
|
||||
const { currentViewFields, currentViewSorts, currentViewFilters } =
|
||||
useViewInternalStates();
|
||||
|
||||
const [, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setTableSorts] = useRecoilScopedState(
|
||||
tableSortsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setTableFilters] = useRecoilScopedState(
|
||||
tableFiltersScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setAvailableTableColumns] = useRecoilScopedState(
|
||||
availableTableColumnsScopedState,
|
||||
@ -57,33 +36,32 @@ const CompanyTableEffect = () => {
|
||||
setAvailableFilters,
|
||||
setAvailableSorts,
|
||||
setAvailableTableColumns,
|
||||
setTableColumns,
|
||||
setViewObjectId,
|
||||
setViewType,
|
||||
]);
|
||||
useEffect(() => {
|
||||
if (currentViewFields) {
|
||||
setTableColumns([...currentViewFields].sort((a, b) => a.index - b.index));
|
||||
}
|
||||
}, [currentViewFields, setTableColumns]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewFields) {
|
||||
// setTableColumns([...currentViewFields].sort((a, b) => a.index - b.index));
|
||||
// }
|
||||
// }, [currentViewFields, setTableColumns]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentViewSorts) {
|
||||
setTableSorts(currentViewSorts);
|
||||
}
|
||||
}, [currentViewFields, currentViewSorts, setTableColumns, setTableSorts]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewSorts) {
|
||||
// setTableSorts(currentViewSorts);
|
||||
// }
|
||||
// }, [currentViewFields, currentViewSorts, setTableColumns, setTableSorts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentViewFilters) {
|
||||
setTableFilters(currentViewFilters);
|
||||
}
|
||||
}, [
|
||||
currentViewFields,
|
||||
currentViewFilters,
|
||||
setTableColumns,
|
||||
setTableFilters,
|
||||
setTableSorts,
|
||||
]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewFilters) {
|
||||
// setTableFilters(currentViewFilters);
|
||||
// }
|
||||
// }, [
|
||||
// currentViewFields,
|
||||
// currentViewFilters,
|
||||
// setTableColumns,
|
||||
// setTableFilters,
|
||||
// setTableSorts,
|
||||
// ]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@ -1,52 +1,30 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { IconArchive } from '@/ui/display/icon';
|
||||
import { IconBuildingSkyscraper } from '@/ui/display/icon';
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
import { IconButton } from '@/ui/input/button/components/IconButton';
|
||||
import NavItem from '@/ui/navigation/navbar/components/NavItem';
|
||||
import { capitalize } from '~/utils/string/capitalize';
|
||||
|
||||
import { useCreateNewTempsCustomObject } from '../hooks/useCreateNewTempCustomObject';
|
||||
import { useDeleteOneMetadataObject } from '../hooks/useDeleteOneMetadataObject';
|
||||
import { useFindManyMetadataObjects } from '../hooks/useFindManyMetadataObjects';
|
||||
|
||||
export const MetadataObjectNavItems = () => {
|
||||
const { metadataObjects } = useFindManyMetadataObjects();
|
||||
|
||||
const createNewTempCustomObject = useCreateNewTempsCustomObject();
|
||||
|
||||
const { deleteOneMetadataObject } = useDeleteOneMetadataObject();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
title="+ Create new object"
|
||||
variant="secondary"
|
||||
onClick={createNewTempCustomObject}
|
||||
/>
|
||||
{metadataObjects
|
||||
.filter((metadataObject) => !!metadataObject.isActive)
|
||||
.map((metadataObject) => (
|
||||
<div style={{ display: 'flex', flexDirection: 'row', width: '60%' }}>
|
||||
<IconButton
|
||||
Icon={IconArchive}
|
||||
onClick={() => {
|
||||
deleteOneMetadataObject(metadataObject.id);
|
||||
}}
|
||||
/>
|
||||
<NavItem
|
||||
key={metadataObject.id}
|
||||
label={capitalize(metadataObject.namePlural)}
|
||||
to={`/objects/${metadataObject.namePlural}`}
|
||||
Icon={IconBuildingSkyscraper}
|
||||
onClick={() => {
|
||||
navigate(`/objects/${metadataObject.namePlural}`);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<NavItem
|
||||
key={metadataObject.id}
|
||||
label={capitalize(metadataObject.namePlural)}
|
||||
to={`/objects/${metadataObject.namePlural}`}
|
||||
Icon={IconBuildingSkyscraper}
|
||||
onClick={() => {
|
||||
navigate(`/objects/${metadataObject.namePlural}`);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
@ -128,7 +128,7 @@ export const ObjectShowPage = () => {
|
||||
fieldDefinition:
|
||||
formatMetadataFieldAsColumnDefinition({
|
||||
field: metadataField,
|
||||
index: index,
|
||||
position: index,
|
||||
metadataObject: foundMetadataObject,
|
||||
}),
|
||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
||||
|
||||
@ -1,15 +1,9 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { DataTable } from '@/ui/data/data-table/components/DataTable';
|
||||
import { TableContext } from '@/ui/data/data-table/contexts/TableContext';
|
||||
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
||||
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { ViewBar } from '@/views/components/ViewBar';
|
||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
|
||||
import { useUpdateOneObject } from '../hooks/useUpdateOneObject';
|
||||
@ -37,9 +31,6 @@ export const ObjectTable = ({ objectNamePlural }: ObjectTableProps) => {
|
||||
|
||||
const viewScopeId = objectNamePlural ?? '';
|
||||
|
||||
const { persistViewFields } = useViewFields(viewScopeId);
|
||||
const { setCurrentViewFields } = useView({ viewScopeId: viewScopeId });
|
||||
|
||||
const updateEntity = ({
|
||||
variables,
|
||||
}: {
|
||||
@ -56,27 +47,12 @@ export const ObjectTable = ({ objectNamePlural }: ObjectTableProps) => {
|
||||
});
|
||||
};
|
||||
|
||||
const updateTableColumns = useRecoilCallback(
|
||||
({ set, snapshot }) =>
|
||||
(viewFields: ColumnDefinition<FieldMetadata>[]) => {
|
||||
set(tableColumnsScopedState(viewScopeId), viewFields);
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<ViewScope
|
||||
viewScopeId={viewScopeId}
|
||||
onViewFieldsChange={(viewFields) => {
|
||||
// updateTableColumns(viewFields);
|
||||
}}
|
||||
>
|
||||
<ViewScope viewScopeId={viewScopeId} onViewFieldsChange={() => {}}>
|
||||
<StyledContainer>
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
onColumnsChange: (columns) => {
|
||||
// setCurrentViewFields?.(columns);
|
||||
// persistViewFields(columns);
|
||||
},
|
||||
onColumnsChange: () => {},
|
||||
}}
|
||||
>
|
||||
<ViewBar
|
||||
|
||||
@ -3,13 +3,11 @@ import { useSetRecoilState } from 'recoil';
|
||||
|
||||
import { availableTableColumnsScopedState } from '@/ui/data/data-table/states/availableTableColumnsScopedState';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewType } from '~/generated/graphql';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
|
||||
import { useMetadataObjectInContext } from '../hooks/useMetadataObjectInContext';
|
||||
|
||||
export const ObjectTableEffect = () => {
|
||||
console.log('ObjectTableEffect');
|
||||
|
||||
const {
|
||||
setAvailableSorts,
|
||||
setAvailableFilters,
|
||||
|
||||
@ -1,208 +0,0 @@
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { FieldType } from '@/ui/data/field/types/FieldType';
|
||||
import { IconBrandLinkedin } from '@/ui/display/icon';
|
||||
import { GET_VIEW_FIELDS } from '@/views/graphql/queries/getViewFields';
|
||||
import { GET_VIEWS } from '@/views/graphql/queries/getViews';
|
||||
import { toViewFieldInput } from '@/views/hooks/internal/useViewFields';
|
||||
import {
|
||||
useCreateViewFieldsMutation,
|
||||
useCreateViewMutation,
|
||||
ViewType,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
import { useCreateOneMetadataField } from './useCreateOneMetadataField';
|
||||
import { useCreateOneMetadataObject } from './useCreateOneMetadataObject';
|
||||
import { useUpdateOneMetadataField } from './useUpdateOneMetadataField';
|
||||
import { useUpdateOneMetadataObject } from './useUpdateOneMetadataObject';
|
||||
|
||||
const useCreateActiveMetadataField = () => {
|
||||
const { createOneMetadataField } = useCreateOneMetadataField();
|
||||
const { updateOneMetadataField } = useUpdateOneMetadataField();
|
||||
|
||||
return async ({
|
||||
objectId,
|
||||
label,
|
||||
name,
|
||||
type,
|
||||
}: {
|
||||
objectId: string;
|
||||
label: string;
|
||||
name: string;
|
||||
type: FieldType;
|
||||
}) => {
|
||||
const { data: createdField } = await createOneMetadataField({
|
||||
objectId: objectId,
|
||||
label: label,
|
||||
name: name,
|
||||
type: type,
|
||||
description: label,
|
||||
icon: 'IconMap',
|
||||
});
|
||||
|
||||
if (!createdField || !createdField.createOneField.name) {
|
||||
throw new Error('Could not create metadata field');
|
||||
}
|
||||
|
||||
await updateOneMetadataField({
|
||||
fieldIdToUpdate: createdField?.createOneField?.id ?? '',
|
||||
updatePayload: {
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
return createdField.createOneField;
|
||||
};
|
||||
};
|
||||
|
||||
export const useCreateNewTempsCustomObject = () => {
|
||||
const { createOneMetadataObject } = useCreateOneMetadataObject();
|
||||
|
||||
const { updateOneMetadataObject } = useUpdateOneMetadataObject();
|
||||
|
||||
const [createViewMutation] = useCreateViewMutation();
|
||||
const [createViewFieldsMutation] = useCreateViewFieldsMutation();
|
||||
|
||||
const createActiveMetadataField = useCreateActiveMetadataField();
|
||||
|
||||
return async () => {
|
||||
const date = new Date().toISOString().replace(/[\/:\.\-\_]/g, '');
|
||||
|
||||
const { data: createdMetadataObject } = await createOneMetadataObject({
|
||||
labelPlural: 'Suppliers' + date,
|
||||
labelSingular: 'Supplier' + date,
|
||||
nameSingular: 'supplier' + date,
|
||||
namePlural: 'suppliers' + date,
|
||||
description: 'Suppliers' + date,
|
||||
icon: 'IconBuilding',
|
||||
});
|
||||
|
||||
const supplierObjectId = createdMetadataObject?.createOneObject?.id ?? '';
|
||||
|
||||
if (!createdMetadataObject) {
|
||||
throw new Error('Could not create metadata object');
|
||||
}
|
||||
|
||||
await updateOneMetadataObject({
|
||||
idToUpdate: supplierObjectId,
|
||||
updatePayload: {
|
||||
isActive: true,
|
||||
},
|
||||
});
|
||||
|
||||
const nameFieldData = await createActiveMetadataField({
|
||||
label: 'Name',
|
||||
name: 'name',
|
||||
objectId: supplierObjectId,
|
||||
type: 'text',
|
||||
});
|
||||
|
||||
const cityFieldData = await createActiveMetadataField({
|
||||
label: 'City',
|
||||
name: 'city',
|
||||
objectId: supplierObjectId,
|
||||
type: 'text',
|
||||
});
|
||||
|
||||
const emailFieldData = await createActiveMetadataField({
|
||||
label: 'Email',
|
||||
name: 'email',
|
||||
objectId: supplierObjectId,
|
||||
type: 'email',
|
||||
});
|
||||
|
||||
const phoneFieldData = await createActiveMetadataField({
|
||||
label: 'Phone',
|
||||
name: 'phone',
|
||||
objectId: supplierObjectId,
|
||||
type: 'phone',
|
||||
});
|
||||
|
||||
const twitterFieldData = await createActiveMetadataField({
|
||||
label: 'Twitter',
|
||||
name: 'twitter',
|
||||
objectId: supplierObjectId,
|
||||
type: 'url',
|
||||
});
|
||||
|
||||
const booleanFieldData = await createActiveMetadataField({
|
||||
label: 'Boolean example',
|
||||
name: 'boolexample',
|
||||
objectId: supplierObjectId,
|
||||
type: 'boolean',
|
||||
});
|
||||
|
||||
const employeesFieldData = await createActiveMetadataField({
|
||||
label: 'Employees',
|
||||
name: 'employees',
|
||||
objectId: supplierObjectId,
|
||||
type: 'number',
|
||||
});
|
||||
|
||||
const ARRFieldData = await createActiveMetadataField({
|
||||
label: 'ARR',
|
||||
name: 'arr',
|
||||
objectId: supplierObjectId,
|
||||
type: 'money',
|
||||
});
|
||||
|
||||
const createdAt = await createActiveMetadataField({
|
||||
label: 'Created at',
|
||||
name: 'createdAt',
|
||||
objectId: supplierObjectId,
|
||||
type: 'date',
|
||||
});
|
||||
|
||||
const objectId = 'suppliers' + date;
|
||||
|
||||
const { data: newView } = await createViewMutation({
|
||||
variables: {
|
||||
data: {
|
||||
name: 'Default',
|
||||
objectId: objectId,
|
||||
type: ViewType.Table,
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_VIEWS) ?? ''],
|
||||
});
|
||||
|
||||
const createdFields = [
|
||||
nameFieldData,
|
||||
emailFieldData,
|
||||
cityFieldData,
|
||||
phoneFieldData,
|
||||
twitterFieldData,
|
||||
booleanFieldData,
|
||||
employeesFieldData,
|
||||
ARRFieldData,
|
||||
createdAt,
|
||||
];
|
||||
|
||||
const tempColumnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||
createdFields.map((field, index) => ({
|
||||
index,
|
||||
key: field.name,
|
||||
name: field.label,
|
||||
size: 100,
|
||||
type: field.type as FieldType,
|
||||
metadata: {
|
||||
fieldName: field.name,
|
||||
placeHolder: field.label,
|
||||
},
|
||||
Icon: IconBrandLinkedin,
|
||||
isVisible: true,
|
||||
})) ?? [];
|
||||
|
||||
await createViewFieldsMutation({
|
||||
variables: {
|
||||
data: tempColumnDefinitions.map((column) => ({
|
||||
...toViewFieldInput(objectId, column),
|
||||
viewId: newView?.view.id ?? '',
|
||||
})),
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_VIEW_FIELDS) ?? ''],
|
||||
});
|
||||
};
|
||||
};
|
||||
@ -6,6 +6,7 @@ import {
|
||||
MetadataObjectsQuery,
|
||||
MetadataObjectsQueryVariables,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
import { FIND_MANY_METADATA_OBJECTS } from '../graphql/queries';
|
||||
import { formatPagedMetadataObjectsToMetadataObjects } from '../utils/formatPagedMetadataObjectsToMetadataObjects';
|
||||
@ -29,8 +30,7 @@ export const useFindManyMetadataObjects = () => {
|
||||
client: apolloMetadataClient ?? undefined,
|
||||
skip: !apolloMetadataClient,
|
||||
onError: (error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('useFindManyMetadataObjects error : ', error);
|
||||
logError('useFindManyMetadataObjects error : ' + error);
|
||||
enqueueSnackBar(
|
||||
`Error during useFindManyMetadataObjects, ${error.message}`,
|
||||
{
|
||||
@ -38,10 +38,7 @@ export const useFindManyMetadataObjects = () => {
|
||||
},
|
||||
);
|
||||
},
|
||||
onCompleted: (data) => {
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('useFindManyMetadataObjects data : ', data);
|
||||
},
|
||||
onCompleted: () => {},
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ import { useMemo } from 'react';
|
||||
import { useQuery } from '@apollo/client';
|
||||
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
||||
import { logError } from '~/utils/logError';
|
||||
|
||||
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
|
||||
import { PaginatedObjectType } from '../types/PaginatedObjectType';
|
||||
@ -41,10 +42,8 @@ export const useFindManyObjects = <
|
||||
onCompleted: (data) =>
|
||||
objectNamePlural && onCompleted?.(data[objectNamePlural]),
|
||||
onError: (error) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`useFindManyObjects for "${objectNamePlural}" error : `,
|
||||
error,
|
||||
logError(
|
||||
`useFindManyObjects for "${objectNamePlural}" error : ` + error,
|
||||
);
|
||||
enqueueSnackBar(
|
||||
`Error during useFindManyObjects for "${objectNamePlural}", ${error.message}`,
|
||||
|
||||
@ -8,6 +8,7 @@ import { formatMetadataFieldAsColumnDefinition } from '../utils/formatMetadataFi
|
||||
import { generateCreateOneObjectMutation } from '../utils/generateCreateOneObjectMutation';
|
||||
import { generateFindManyCustomObjectsQuery } from '../utils/generateFindManyCustomObjectsQuery';
|
||||
import { generateFindOneCustomObjectQuery } from '../utils/generateFindOneCustomObjectQuery';
|
||||
import { generateUpdateOneObjectMutation } from '../utils/generateUpdateOneObjectMutation';
|
||||
|
||||
import { useFindManyMetadataObjects } from './useFindManyMetadataObjects';
|
||||
|
||||
@ -30,7 +31,7 @@ export const useFindOneMetadataObject = ({
|
||||
const columnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||
foundMetadataObject?.fields.map((field, index) =>
|
||||
formatMetadataFieldAsColumnDefinition({
|
||||
index,
|
||||
position: index,
|
||||
field,
|
||||
metadataObject: foundMetadataObject,
|
||||
}),
|
||||
@ -66,6 +67,16 @@ export const useFindOneMetadataObject = ({
|
||||
}
|
||||
`;
|
||||
|
||||
const updateOneMutation = foundMetadataObject
|
||||
? generateUpdateOneObjectMutation({
|
||||
metadataObject: foundMetadataObject,
|
||||
})
|
||||
: gql`
|
||||
mutation EmptyMutation {
|
||||
empty
|
||||
}
|
||||
`;
|
||||
|
||||
// TODO: implement backend delete
|
||||
const deleteOneMutation = foundMetadataObject
|
||||
? generateCreateOneObjectMutation({
|
||||
@ -84,6 +95,7 @@ export const useFindOneMetadataObject = ({
|
||||
findManyQuery,
|
||||
findOneQuery,
|
||||
createOneMutation,
|
||||
updateOneMutation,
|
||||
deleteOneMutation,
|
||||
loading,
|
||||
};
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { gql, useMutation } from '@apollo/client';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import { MetadataObjectIdentifier } from '../types/MetadataObjectIdentifier';
|
||||
import { generateUpdateOneObjectMutation } from '../utils/generateUpdateOneObjectMutation';
|
||||
|
||||
import { useFindOneMetadataObject } from './useFindOneMetadataObject';
|
||||
|
||||
@ -10,24 +9,18 @@ export const useUpdateOneObject = ({
|
||||
objectNamePlural,
|
||||
objectNameSingular,
|
||||
}: MetadataObjectIdentifier) => {
|
||||
const { foundMetadataObject, objectNotFoundInMetadata, findManyQuery } =
|
||||
useFindOneMetadataObject({
|
||||
objectNamePlural,
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const generatedMutation = foundMetadataObject
|
||||
? generateUpdateOneObjectMutation({
|
||||
metadataObject: foundMetadataObject,
|
||||
})
|
||||
: gql`
|
||||
mutation EmptyMutation {
|
||||
empty
|
||||
}
|
||||
`;
|
||||
const {
|
||||
foundMetadataObject,
|
||||
objectNotFoundInMetadata,
|
||||
findManyQuery,
|
||||
updateOneMutation,
|
||||
} = useFindOneMetadataObject({
|
||||
objectNamePlural,
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
// TODO: type this with a minimal type at least with Record<string, any>
|
||||
const [mutate] = useMutation(generatedMutation, {
|
||||
const [mutate] = useMutation(updateOneMutation, {
|
||||
refetchQueries: [getOperationName(findManyQuery) ?? ''],
|
||||
});
|
||||
|
||||
|
||||
@ -18,17 +18,17 @@ const parseFieldType = (fieldType: string): FieldType => {
|
||||
};
|
||||
|
||||
export const formatMetadataFieldAsColumnDefinition = ({
|
||||
index,
|
||||
position,
|
||||
field,
|
||||
metadataObject,
|
||||
}: {
|
||||
index: number;
|
||||
position: number;
|
||||
field: MetadataObject['fields'][0];
|
||||
metadataObject: Omit<MetadataObject, 'fields'>;
|
||||
}): ColumnDefinition<FieldMetadata> => ({
|
||||
index,
|
||||
key: field.name,
|
||||
name: field.label,
|
||||
position,
|
||||
fieldId: field.id,
|
||||
label: field.label,
|
||||
size: 100,
|
||||
type: parseFieldType(field.type),
|
||||
metadata: {
|
||||
|
||||
@ -27,11 +27,11 @@ import { getLogoUrlFromDomainName } from '~/utils';
|
||||
export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
key: 'displayName',
|
||||
name: 'People',
|
||||
fieldId: 'displayName',
|
||||
label: 'People',
|
||||
Icon: IconUser,
|
||||
size: 210,
|
||||
index: 0,
|
||||
position: 0,
|
||||
type: 'double-text-chip',
|
||||
metadata: {
|
||||
firstValueFieldName: 'firstName',
|
||||
@ -45,12 +45,12 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
basePathToShowPage: '/person/',
|
||||
} satisfies ColumnDefinition<FieldDoubleTextChipMetadata>,
|
||||
{
|
||||
key: 'email',
|
||||
name: 'Email',
|
||||
fieldId: 'email',
|
||||
label: 'Email',
|
||||
Icon: IconMail,
|
||||
size: 150,
|
||||
type: 'email',
|
||||
index: 1,
|
||||
position: 1,
|
||||
metadata: {
|
||||
fieldName: 'email',
|
||||
placeHolder: 'Email', // Hack: Fake character to prevent password-manager from filling the field
|
||||
@ -58,11 +58,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Contact’s Email.',
|
||||
} satisfies ColumnDefinition<FieldEmailMetadata>,
|
||||
{
|
||||
key: 'company',
|
||||
name: 'Company',
|
||||
fieldId: 'company',
|
||||
label: 'Company',
|
||||
Icon: IconBuildingSkyscraper,
|
||||
size: 150,
|
||||
index: 2,
|
||||
position: 2,
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'company',
|
||||
@ -78,11 +78,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
},
|
||||
} satisfies ColumnDefinition<FieldRelationMetadata>,
|
||||
{
|
||||
key: 'phone',
|
||||
name: 'Phone',
|
||||
fieldId: 'phone',
|
||||
label: 'Phone',
|
||||
Icon: IconPhone,
|
||||
size: 150,
|
||||
index: 3,
|
||||
position: 3,
|
||||
type: 'phone',
|
||||
metadata: {
|
||||
fieldName: 'phone',
|
||||
@ -91,11 +91,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Contact’s phone number.',
|
||||
} satisfies ColumnDefinition<FieldPhoneMetadata>,
|
||||
{
|
||||
key: 'createdAt',
|
||||
name: 'Creation',
|
||||
fieldId: 'createdAt',
|
||||
label: 'Creation',
|
||||
Icon: IconCalendarEvent,
|
||||
size: 150,
|
||||
index: 4,
|
||||
position: 4,
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'createdAt',
|
||||
@ -103,11 +103,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Date when the contact was added.',
|
||||
} satisfies ColumnDefinition<FieldDateMetadata>,
|
||||
{
|
||||
key: 'city',
|
||||
name: 'City',
|
||||
fieldId: 'city',
|
||||
label: 'City',
|
||||
Icon: IconMap,
|
||||
size: 150,
|
||||
index: 5,
|
||||
position: 5,
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'city',
|
||||
@ -116,11 +116,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Contact’s city.',
|
||||
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||
{
|
||||
key: 'jobTitle',
|
||||
name: 'Job title',
|
||||
fieldId: 'jobTitle',
|
||||
label: 'Job title',
|
||||
Icon: IconBriefcase,
|
||||
size: 150,
|
||||
index: 6,
|
||||
position: 6,
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'jobTitle',
|
||||
@ -129,11 +129,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Contact’s job title.',
|
||||
} satisfies ColumnDefinition<FieldTextMetadata>,
|
||||
{
|
||||
key: 'linkedin',
|
||||
name: 'LinkedIn',
|
||||
fieldId: 'linkedin',
|
||||
label: 'LinkedIn',
|
||||
Icon: IconBrandLinkedin,
|
||||
size: 150,
|
||||
index: 7,
|
||||
position: 7,
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'linkedinUrl',
|
||||
@ -142,11 +142,11 @@ export const peopleAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[]
|
||||
infoTooltipContent: 'Contact’s Linkedin account.',
|
||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
||||
{
|
||||
key: 'x',
|
||||
name: 'Twitter',
|
||||
fieldId: 'x',
|
||||
label: 'Twitter',
|
||||
Icon: IconBrandX,
|
||||
size: 150,
|
||||
index: 8,
|
||||
position: 8,
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'xUrl',
|
||||
|
||||
@ -11,8 +11,6 @@ import { useUpsertDataTableItem } from '@/ui/data/data-table/hooks/useUpsertData
|
||||
import { TableOptionsDropdown } from '@/ui/data/data-table/options/components/TableOptionsDropdown';
|
||||
import { ViewBar } from '@/views/components/ViewBar';
|
||||
import { ViewBarEffect } from '@/views/components/ViewBarEffect';
|
||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||
import {
|
||||
UpdateOnePersonMutationVariables,
|
||||
@ -30,9 +28,6 @@ export const PeopleTable = () => {
|
||||
const [updateEntityMutation] = useUpdateOnePersonMutation();
|
||||
const upsertDataTableItem = useUpsertDataTableItem();
|
||||
|
||||
const { persistViewFields } = useViewFields(tableViewScopeId);
|
||||
const { setCurrentViewFields } = useView({ viewScopeId: tableViewScopeId });
|
||||
|
||||
const { setContextMenuEntries } = usePersonTableContextMenuEntries();
|
||||
const { setActionBarEntries } = usePersonTableActionBarEntries();
|
||||
|
||||
@ -56,10 +51,7 @@ export const PeopleTable = () => {
|
||||
<StyledContainer>
|
||||
<TableContext.Provider
|
||||
value={{
|
||||
onColumnsChange: (columns) => {
|
||||
setCurrentViewFields?.(columns);
|
||||
persistViewFields(columns);
|
||||
},
|
||||
onColumnsChange: () => {},
|
||||
}}
|
||||
>
|
||||
<ViewBarEffect />
|
||||
|
||||
@ -4,12 +4,9 @@ import { peopleAvailableFieldDefinitions } from '@/people/constants/peopleAvaila
|
||||
import { availableTableColumnsScopedState } from '@/ui/data/data-table/states/availableTableColumnsScopedState';
|
||||
import { TableRecoilScopeContext } from '@/ui/data/data-table/states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { tableColumnsScopedState } from '@/ui/data/data-table/states/tableColumnsScopedState';
|
||||
import { tableFiltersScopedState } from '@/ui/data/data-table/states/tableFiltersScopedState';
|
||||
import { tableSortsScopedState } from '@/ui/data/data-table/states/tableSortsScopedState';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { useViewInternalStates } from '@/views/hooks/useViewInternalStates';
|
||||
import { ViewType } from '~/generated/graphql';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { peopleAvailableFilters } from '~/pages/people/people-filters';
|
||||
import { peopleAvailableSorts } from '~/pages/people/people-sorts';
|
||||
|
||||
@ -21,24 +18,12 @@ const PeopleTableEffect = () => {
|
||||
setViewType,
|
||||
setViewObjectId,
|
||||
} = useView();
|
||||
const { currentViewFields, currentViewSorts, currentViewFilters } =
|
||||
useViewInternalStates();
|
||||
|
||||
const [, setTableColumns] = useRecoilScopedState(
|
||||
tableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setTableSorts] = useRecoilScopedState(
|
||||
tableSortsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setTableFilters] = useRecoilScopedState(
|
||||
tableFiltersScopedState,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setAvailableTableColumns] = useRecoilScopedState(
|
||||
availableTableColumnsScopedState,
|
||||
TableRecoilScopeContext,
|
||||
@ -61,29 +46,29 @@ const PeopleTableEffect = () => {
|
||||
setViewObjectId,
|
||||
setViewType,
|
||||
]);
|
||||
useEffect(() => {
|
||||
if (currentViewFields) {
|
||||
setTableColumns([...currentViewFields].sort((a, b) => a.index - b.index));
|
||||
}
|
||||
}, [currentViewFields, setTableColumns]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewFields) {
|
||||
// setTableColumns([...currentViewFields].sort((a, b) => a.index - b.index));
|
||||
// }
|
||||
// }, [currentViewFields, setTableColumns]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentViewSorts) {
|
||||
setTableSorts(currentViewSorts);
|
||||
}
|
||||
}, [currentViewFields, currentViewSorts, setTableColumns, setTableSorts]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewSorts) {
|
||||
// setTableSorts(currentViewSorts);
|
||||
// }
|
||||
// }, [currentViewFields, currentViewSorts, setTableColumns, setTableSorts]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentViewFilters) {
|
||||
setTableFilters(currentViewFilters);
|
||||
}
|
||||
}, [
|
||||
currentViewFields,
|
||||
currentViewFilters,
|
||||
setTableColumns,
|
||||
setTableFilters,
|
||||
setTableSorts,
|
||||
]);
|
||||
// useEffect(() => {
|
||||
// if (currentViewFilters) {
|
||||
// setTableFilters(currentViewFilters);
|
||||
// }
|
||||
// }, [
|
||||
// currentViewFields,
|
||||
// currentViewFilters,
|
||||
// setTableColumns,
|
||||
// setTableFilters,
|
||||
// setTableSorts,
|
||||
// ]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@ -18,10 +18,10 @@ import { Person } from '~/generated/graphql';
|
||||
export const pipelineAvailableFieldDefinitions: BoardFieldDefinition<FieldMetadata>[] =
|
||||
[
|
||||
{
|
||||
key: 'closeDate',
|
||||
name: 'Close Date',
|
||||
fieldId: 'closeDate',
|
||||
label: 'Close Date',
|
||||
Icon: IconCalendarEvent,
|
||||
index: 0,
|
||||
position: 0,
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'closeDate',
|
||||
@ -31,10 +31,10 @@ export const pipelineAvailableFieldDefinitions: BoardFieldDefinition<FieldMetada
|
||||
'Specified date by which an opportunity must be completed.',
|
||||
} satisfies BoardFieldDefinition<FieldDateMetadata>,
|
||||
{
|
||||
key: 'amount',
|
||||
name: 'Amount',
|
||||
fieldId: 'amount',
|
||||
label: 'Amount',
|
||||
Icon: IconCurrencyDollar,
|
||||
index: 1,
|
||||
position: 1,
|
||||
type: 'number',
|
||||
metadata: {
|
||||
fieldName: 'amount',
|
||||
@ -44,10 +44,10 @@ export const pipelineAvailableFieldDefinitions: BoardFieldDefinition<FieldMetada
|
||||
infoTooltipContent: 'Potential monetary value of a business opportunity.',
|
||||
} satisfies BoardFieldDefinition<FieldNumberMetadata>,
|
||||
{
|
||||
key: 'probability',
|
||||
name: 'Probability',
|
||||
fieldId: 'probability',
|
||||
label: 'Probability',
|
||||
Icon: IconProgressCheck,
|
||||
index: 2,
|
||||
position: 2,
|
||||
type: 'probability',
|
||||
metadata: {
|
||||
fieldName: 'probability',
|
||||
@ -57,10 +57,10 @@ export const pipelineAvailableFieldDefinitions: BoardFieldDefinition<FieldMetada
|
||||
"Level of certainty in the lead's potential to convert into a success.",
|
||||
} satisfies BoardFieldDefinition<FieldProbabilityMetadata>,
|
||||
{
|
||||
key: 'pointOfContact',
|
||||
name: 'Point of Contact',
|
||||
fieldId: 'pointOfContact',
|
||||
label: 'Point of Contact',
|
||||
Icon: IconUser,
|
||||
index: 3,
|
||||
position: 3,
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'pointOfContact',
|
||||
|
||||
@ -10,7 +10,7 @@ export const GET_PIPELINES = gql`
|
||||
id
|
||||
name
|
||||
color
|
||||
index
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ export const usePipelineStages = () => {
|
||||
data: {
|
||||
color: boardColumn.colorCode ?? 'gray',
|
||||
id: boardColumn.id,
|
||||
index: boardColumn.index,
|
||||
position: boardColumn.position,
|
||||
name: boardColumn.title,
|
||||
pipeline: { connect: { id: currentPipeline.id } },
|
||||
type: 'ongoing',
|
||||
|
||||
@ -44,7 +44,7 @@ export const ColumnHead = ({ column }: ColumnHeadProps) => {
|
||||
<StyledIcon>
|
||||
{column.Icon && <column.Icon size={theme.icon.size.md} />}
|
||||
</StyledIcon>
|
||||
<StyledText>{column.name}</StyledText>
|
||||
<StyledText>{column.label}</StyledText>
|
||||
</StyledTitle>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -21,7 +21,7 @@ export const ColumnHeadWithDropdown = ({
|
||||
primaryColumnKey,
|
||||
}: ColumnHeadWithDropdownProps) => {
|
||||
return (
|
||||
<DropdownScope dropdownScopeId={column.key + '-header'}>
|
||||
<DropdownScope dropdownScopeId={column.fieldId + '-header'}>
|
||||
<Dropdown
|
||||
clickableComponent={<ColumnHead column={column} />}
|
||||
dropdownComponents={
|
||||
@ -34,7 +34,7 @@ export const ColumnHeadWithDropdown = ({
|
||||
}
|
||||
dropdownOffset={{ x: -1 }}
|
||||
dropdownPlacement="bottom-start"
|
||||
dropdownHotkeyScope={{ scope: column.key + '-header' }}
|
||||
dropdownHotkeyScope={{ scope: column.fieldId + '-header' }}
|
||||
/>
|
||||
</DropdownScope>
|
||||
);
|
||||
|
||||
@ -51,7 +51,7 @@ export const DataTableCell = ({ cellIndex }: { cellIndex: number }) => {
|
||||
<td onContextMenu={(event) => handleContextMenu(event)}>
|
||||
<FieldContext.Provider
|
||||
value={{
|
||||
recoilScopeId: currentRowId + columnDefinition.name,
|
||||
recoilScopeId: currentRowId + columnDefinition.label,
|
||||
entityId: currentRowId,
|
||||
fieldDefinition: columnDefinition,
|
||||
useUpdateEntityMutation: () => [updateEntityMutation, {}],
|
||||
|
||||
@ -46,7 +46,7 @@ export const DataTableColumnDropdownMenu = ({
|
||||
handleColumnVisibilityChange(column);
|
||||
};
|
||||
|
||||
return column.key === primaryColumnKey ? (
|
||||
return column.fieldId === primaryColumnKey ? (
|
||||
<></>
|
||||
) : (
|
||||
<DropdownMenuItemsContainer>
|
||||
|
||||
@ -6,7 +6,6 @@ import { useOptimisticEffect } from '@/apollo/optimistic-effect/hooks/useOptimis
|
||||
import { OptimisticEffectDefinition } from '@/apollo/optimistic-effect/types/OptimisticEffectDefinition';
|
||||
import { FilterDefinition } from '@/ui/data/filter/types/FilterDefinition';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import {
|
||||
SortOrder,
|
||||
useGetCompaniesQuery,
|
||||
@ -40,7 +39,6 @@ export const DataTableEffect = ({
|
||||
}) => {
|
||||
const setDataTableData = useSetDataTableData();
|
||||
const { registerOptimisticEffect } = useOptimisticEffect();
|
||||
const { setCurrentViewId } = useView();
|
||||
|
||||
const tableSortsOrderBy = useRecoilScopedValue(
|
||||
tableSortsOrderByScopedSelector,
|
||||
|
||||
@ -134,7 +134,7 @@ export const DataTableHeader = () => {
|
||||
|
||||
if (nextWidth !== tableColumnsByKey[resizedFieldKey].size) {
|
||||
const nextColumns = tableColumns.map((column) =>
|
||||
column.key === resizedFieldKey
|
||||
column.fieldId === resizedFieldKey
|
||||
? { ...column, size: nextWidth }
|
||||
: column,
|
||||
);
|
||||
@ -152,7 +152,9 @@ export const DataTableHeader = () => {
|
||||
onMouseUp: handleResizeHandlerEnd,
|
||||
});
|
||||
|
||||
const primaryColumn = visibleTableColumns[0];
|
||||
const primaryColumn = visibleTableColumns.find(
|
||||
(column) => column.position === 0,
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledTableHead data-select-disable>
|
||||
@ -167,30 +169,32 @@ export const DataTableHeader = () => {
|
||||
<SelectAllCheckbox />
|
||||
</th>
|
||||
{[...visibleTableColumns]
|
||||
.sort((columnA, columnB) => columnA.index - columnB.index)
|
||||
.map((column, index) => (
|
||||
.sort((columnA, columnB) => columnA.position - columnB.position)
|
||||
.map((column) => (
|
||||
<StyledColumnHeaderCell
|
||||
key={column.key}
|
||||
isResizing={resizedFieldKey === column.key}
|
||||
key={column.fieldId}
|
||||
isResizing={resizedFieldKey === column.fieldId}
|
||||
columnWidth={Math.max(
|
||||
tableColumnsByKey[column.key].size +
|
||||
(resizedFieldKey === column.key ? resizeFieldOffset : 0),
|
||||
tableColumnsByKey[column.fieldId].size +
|
||||
(resizedFieldKey === column.fieldId ? resizeFieldOffset : 0),
|
||||
COLUMN_MIN_WIDTH,
|
||||
)}
|
||||
>
|
||||
<StyledColumnHeadContainer>
|
||||
<ColumnHeadWithDropdown
|
||||
column={column}
|
||||
isFirstColumn={index === 1}
|
||||
isLastColumn={index === visibleTableColumns.length - 1}
|
||||
primaryColumnKey={primaryColumn.key}
|
||||
isFirstColumn={column.position === 1}
|
||||
isLastColumn={
|
||||
column.position === visibleTableColumns.length - 1
|
||||
}
|
||||
primaryColumnKey={primaryColumn?.fieldId || ''}
|
||||
/>
|
||||
</StyledColumnHeadContainer>
|
||||
<StyledResizeHandler
|
||||
className="cursor-col-resize"
|
||||
role="separator"
|
||||
onPointerDown={() => {
|
||||
setResizedFieldKey(column.key);
|
||||
setResizedFieldKey(column.fieldId);
|
||||
}}
|
||||
/>
|
||||
</StyledColumnHeaderCell>
|
||||
|
||||
@ -34,7 +34,7 @@ export const DataTableHeaderPlusButtonContent = () => {
|
||||
<DropdownMenuItemsContainer>
|
||||
{hiddenTableColumns.map((column) => (
|
||||
<MenuItem
|
||||
key={column.key}
|
||||
key={column.fieldId}
|
||||
iconButtons={[
|
||||
{
|
||||
Icon: IconPlus,
|
||||
@ -42,7 +42,7 @@ export const DataTableHeaderPlusButtonContent = () => {
|
||||
},
|
||||
]}
|
||||
LeftIcon={column.Icon}
|
||||
text={column.name}
|
||||
text={column.label}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
|
||||
@ -39,10 +39,10 @@ export const DataTableRow = forwardRef<HTMLTableRowElement, DataTableRowProps>(
|
||||
<CheckboxCell />
|
||||
</td>
|
||||
{[...visibleTableColumns]
|
||||
.sort((columnA, columnB) => columnA.index - columnB.index)
|
||||
.sort((columnA, columnB) => columnA.position - columnB.position)
|
||||
.map((column, columnIndex) => {
|
||||
return (
|
||||
<ColumnContext.Provider value={column} key={column.key}>
|
||||
<ColumnContext.Provider value={column} key={column.fieldId}>
|
||||
<DataTableCell cellIndex={columnIndex} />
|
||||
</ColumnContext.Provider>
|
||||
);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export const useMoveViewColumns = () => {
|
||||
const handleColumnMove = <T extends { index: number }>(
|
||||
const handleColumnMove = <T extends { position: number }>(
|
||||
direction: 'left' | 'right',
|
||||
currentArrayindex: number,
|
||||
targetArray: T[],
|
||||
@ -19,13 +19,17 @@ export const useMoveViewColumns = () => {
|
||||
|
||||
newArray[currentArrayindex] = {
|
||||
...targetEntity,
|
||||
index: currentEntity.index,
|
||||
index: currentEntity.position,
|
||||
};
|
||||
newArray[targetArrayIndex] = {
|
||||
...currentEntity,
|
||||
index: targetEntity.index,
|
||||
index: targetEntity.position,
|
||||
};
|
||||
return newArray;
|
||||
|
||||
return newArray.map((column, index) => ({
|
||||
...column,
|
||||
position: index,
|
||||
}));
|
||||
}
|
||||
|
||||
return targetArray;
|
||||
|
||||
@ -4,13 +4,14 @@ import { useSetRecoilState } from 'recoil';
|
||||
import { useMoveViewColumns } from '@/ui/data/data-table/hooks/useMoveViewColumns';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewFieldForVisibility } from '@/views/types/ViewFieldForVisibility';
|
||||
|
||||
import { TableContext } from '../contexts/TableContext';
|
||||
import { availableTableColumnsScopedState } from '../states/availableTableColumnsScopedState';
|
||||
import { TableRecoilScopeContext } from '../states/recoil-scope-contexts/TableRecoilScopeContext';
|
||||
import { savedTableColumnsFamilyState } from '../states/savedTableColumnsFamilyState';
|
||||
import { visibleTableColumnsScopedSelector } from '../states/selectors/visibleTableColumnsScopedSelector';
|
||||
import { tableColumnsScopedState } from '../states/tableColumnsScopedState';
|
||||
import { ColumnDefinition } from '../types/ColumnDefinition';
|
||||
|
||||
@ -32,6 +33,10 @@ export const useTableColumns = () => {
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
|
||||
const visibleTableColumns = useRecoilScopedValue(
|
||||
visibleTableColumnsScopedSelector,
|
||||
TableRecoilScopeContext,
|
||||
);
|
||||
const { handleColumnMove } = useMoveViewColumns();
|
||||
|
||||
const handleColumnsChange = useCallback(
|
||||
@ -44,27 +49,18 @@ export const useTableColumns = () => {
|
||||
[onColumnsChange, setSavedTableColumns, setTableColumns],
|
||||
);
|
||||
|
||||
const handleColumnReorder = useCallback(
|
||||
async (columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
const updatedColumns = columns.map((column, index) => ({
|
||||
...column,
|
||||
index,
|
||||
}));
|
||||
|
||||
await handleColumnsChange(updatedColumns);
|
||||
},
|
||||
[handleColumnsChange],
|
||||
);
|
||||
|
||||
const handleColumnVisibilityChange = useCallback(
|
||||
async (viewField: ViewFieldForVisibility) => {
|
||||
async (
|
||||
viewField: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => {
|
||||
const isNewColumn = !tableColumns.some(
|
||||
(tableColumns) => tableColumns.key === viewField.key,
|
||||
(tableColumns) => tableColumns.fieldId === viewField.fieldId,
|
||||
);
|
||||
|
||||
if (isNewColumn) {
|
||||
const newColumn = availableTableColumns.find(
|
||||
(availableTableColumn) => availableTableColumn.key === viewField.key,
|
||||
(availableTableColumn) =>
|
||||
availableTableColumn.fieldId === viewField.fieldId,
|
||||
);
|
||||
if (!newColumn) return;
|
||||
|
||||
@ -76,7 +72,7 @@ export const useTableColumns = () => {
|
||||
await handleColumnsChange(nextColumns);
|
||||
} else {
|
||||
const nextColumns = tableColumns.map((previousColumn) =>
|
||||
previousColumn.key === viewField.key
|
||||
previousColumn.fieldId === viewField.fieldId
|
||||
? { ...previousColumn, isVisible: !viewField.isVisible }
|
||||
: previousColumn,
|
||||
);
|
||||
@ -92,18 +88,31 @@ export const useTableColumns = () => {
|
||||
direction: 'left' | 'right',
|
||||
column: ColumnDefinition<FieldMetadata>,
|
||||
) => {
|
||||
const currentColumnArrayIndex = tableColumns.findIndex(
|
||||
(tableColumn) => tableColumn.key === column.key,
|
||||
const currentColumnArrayIndex = visibleTableColumns.findIndex(
|
||||
(visibleColumn) => visibleColumn.fieldId === column.fieldId,
|
||||
);
|
||||
|
||||
const columns = handleColumnMove(
|
||||
direction,
|
||||
currentColumnArrayIndex,
|
||||
tableColumns,
|
||||
visibleTableColumns,
|
||||
);
|
||||
|
||||
await handleColumnsChange(columns);
|
||||
},
|
||||
[tableColumns, handleColumnMove, handleColumnsChange],
|
||||
[visibleTableColumns, handleColumnMove, handleColumnsChange],
|
||||
);
|
||||
|
||||
const handleColumnReorder = useCallback(
|
||||
async (columns: ColumnDefinition<FieldMetadata>[]) => {
|
||||
const updatedColumns = columns.map((column, index) => ({
|
||||
...column,
|
||||
position: index,
|
||||
}));
|
||||
|
||||
await handleColumnsChange(updatedColumns);
|
||||
},
|
||||
[handleColumnsChange],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -59,13 +59,17 @@ export const TableOptionsDropdownContent = ({
|
||||
|
||||
const handleReorderField: OnDragEndResponder = useCallback(
|
||||
(result) => {
|
||||
if (!result.destination || result.destination.index === 0) {
|
||||
if (
|
||||
!result.destination ||
|
||||
result.destination.index === 1 ||
|
||||
result.source.index === 1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reorderFields = Array.from(visibleTableColumns);
|
||||
const [removed] = reorderFields.splice(result.source.index, 1);
|
||||
reorderFields.splice(result.destination.index, 0, removed);
|
||||
const reorderFields = [...visibleTableColumns];
|
||||
const [removed] = reorderFields.splice(result.source.index - 1, 1);
|
||||
reorderFields.splice(result.destination.index - 1, 0, removed);
|
||||
|
||||
handleColumnReorder(reorderFields);
|
||||
},
|
||||
|
||||
@ -9,10 +9,10 @@ export const hiddenTableColumnsScopedSelector = selectorFamily({
|
||||
(scopeId: string) =>
|
||||
({ get }) => {
|
||||
const columns = get(tableColumnsScopedState(scopeId));
|
||||
const columnKeys = columns.map(({ key }) => key);
|
||||
const columnKeys = columns.map(({ fieldId }) => fieldId);
|
||||
const otherAvailableColumns = get(
|
||||
availableTableColumnsScopedState(scopeId),
|
||||
).filter(({ key }) => !columnKeys.includes(key));
|
||||
).filter(({ fieldId }) => !columnKeys.includes(fieldId));
|
||||
|
||||
return [
|
||||
...columns.filter((column) => !column.isVisible),
|
||||
|
||||
@ -12,5 +12,5 @@ export const savedTableColumnsByKeyFamilySelector = selectorFamily({
|
||||
({ get }) =>
|
||||
get(savedTableColumnsFamilyState(viewId)).reduce<
|
||||
Record<string, ColumnDefinition<FieldMetadata>>
|
||||
>((result, column) => ({ ...result, [column.key]: column }), {}),
|
||||
>((result, column) => ({ ...result, [column.fieldId]: column }), {}),
|
||||
});
|
||||
|
||||
@ -12,5 +12,5 @@ export const tableColumnsByKeyScopedSelector = selectorFamily({
|
||||
({ get }) =>
|
||||
get(tableColumnsScopedState(scopeId)).reduce<
|
||||
Record<string, ColumnDefinition<FieldMetadata>>
|
||||
>((result, column) => ({ ...result, [column.key]: column }), {}),
|
||||
>((result, column) => ({ ...result, [column.fieldId]: column }), {}),
|
||||
});
|
||||
|
||||
@ -7,7 +7,9 @@ export const visibleTableColumnsScopedSelector = selectorFamily({
|
||||
get:
|
||||
(scopeId: string) =>
|
||||
({ get }) =>
|
||||
get(tableColumnsScopedState(scopeId)).filter(
|
||||
(column) => column.isVisible,
|
||||
),
|
||||
[
|
||||
...get(tableColumnsScopedState(scopeId)).filter(
|
||||
(column) => column.isVisible,
|
||||
),
|
||||
].sort((a, b) => a.position - b.position),
|
||||
});
|
||||
|
||||
@ -3,6 +3,7 @@ import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
|
||||
export type ColumnDefinition<T extends FieldMetadata> = FieldDefinition<T> & {
|
||||
size: number;
|
||||
index: number;
|
||||
position: number;
|
||||
isVisible?: boolean;
|
||||
viewFieldId?: string;
|
||||
};
|
||||
|
||||
@ -10,8 +10,8 @@ export const useIsFieldEmpty = () => {
|
||||
const isFieldEmpty = useRecoilValue(
|
||||
isEntityFieldEmptyFamilySelector({
|
||||
fieldDefinition: {
|
||||
key: fieldDefinition.key,
|
||||
name: fieldDefinition.name,
|
||||
fieldId: fieldDefinition.fieldId,
|
||||
label: fieldDefinition.label,
|
||||
type: fieldDefinition.type,
|
||||
metadata: fieldDefinition.metadata,
|
||||
},
|
||||
|
||||
@ -31,8 +31,8 @@ const DateFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'date',
|
||||
name: 'Date',
|
||||
fieldId: 'date',
|
||||
label: 'Date',
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'Date',
|
||||
|
||||
@ -38,8 +38,8 @@ const DoubleTextFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text',
|
||||
name: 'Double-Text',
|
||||
fieldId: 'double-text',
|
||||
label: 'Double-Text',
|
||||
type: 'double-text',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
|
||||
@ -30,8 +30,8 @@ const EmailFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'email',
|
||||
name: 'Email',
|
||||
fieldId: 'email',
|
||||
label: 'Email',
|
||||
type: 'email',
|
||||
metadata: {
|
||||
fieldName: 'Email',
|
||||
|
||||
@ -32,8 +32,8 @@ const MoneyFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'money',
|
||||
name: 'Money',
|
||||
fieldId: 'money',
|
||||
label: 'Money',
|
||||
type: 'moneyAmount',
|
||||
metadata: {
|
||||
fieldName: 'Amount',
|
||||
|
||||
@ -32,8 +32,8 @@ const NumberFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'number',
|
||||
name: 'Number',
|
||||
fieldId: 'number',
|
||||
label: 'Number',
|
||||
type: 'number',
|
||||
metadata: {
|
||||
fieldName: 'Number',
|
||||
|
||||
@ -30,8 +30,8 @@ const PhoneFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'phone',
|
||||
name: 'Phone',
|
||||
fieldId: 'phone',
|
||||
label: 'Phone',
|
||||
type: 'phone',
|
||||
metadata: {
|
||||
fieldName: 'Phone',
|
||||
|
||||
@ -32,8 +32,8 @@ const TextFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
fieldId: 'text',
|
||||
label: 'Text',
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'Text',
|
||||
|
||||
@ -30,8 +30,8 @@ const URLFieldDisplayWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'URL',
|
||||
name: 'URL',
|
||||
fieldId: 'URL',
|
||||
label: 'URL',
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'URL',
|
||||
|
||||
@ -34,8 +34,8 @@ const BooleanFieldInputWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'boolean',
|
||||
name: 'Boolean',
|
||||
fieldId: 'boolean',
|
||||
label: 'Boolean',
|
||||
type: 'boolean',
|
||||
metadata: {
|
||||
fieldName: 'Boolean',
|
||||
|
||||
@ -44,8 +44,8 @@ const ChipFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'chip',
|
||||
name: 'Chip',
|
||||
fieldId: 'chip',
|
||||
label: 'Chip',
|
||||
type: 'chip',
|
||||
metadata: {
|
||||
contentFieldName: 'name',
|
||||
|
||||
@ -44,8 +44,8 @@ const DateFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'date',
|
||||
name: 'Date',
|
||||
fieldId: 'date',
|
||||
label: 'Date',
|
||||
type: 'date',
|
||||
metadata: {
|
||||
fieldName: 'Date',
|
||||
|
||||
@ -57,8 +57,8 @@ const DoubleTextChipFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text-chip',
|
||||
name: 'Double-Text-Chip',
|
||||
fieldId: 'double-text-chip',
|
||||
label: 'Double-Text-Chip',
|
||||
type: 'double-text-chip',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
|
||||
@ -55,8 +55,8 @@ const DoubleTextFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'double-text',
|
||||
name: 'Double-Text',
|
||||
fieldId: 'double-text',
|
||||
label: 'Double-Text',
|
||||
type: 'double-text',
|
||||
metadata: {
|
||||
firstValueFieldName: 'First-text',
|
||||
|
||||
@ -43,8 +43,8 @@ const EmailFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'email',
|
||||
name: 'Email',
|
||||
fieldId: 'email',
|
||||
label: 'Email',
|
||||
type: 'email',
|
||||
metadata: {
|
||||
fieldName: 'email',
|
||||
|
||||
@ -43,8 +43,8 @@ const MoneyFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'moneyAmount',
|
||||
name: 'MoneyAmout',
|
||||
fieldId: 'moneyAmount',
|
||||
label: 'MoneyAmout',
|
||||
type: 'moneyAmount',
|
||||
metadata: {
|
||||
fieldName: 'moneyAmount',
|
||||
|
||||
@ -43,8 +43,8 @@ const NumberFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'number',
|
||||
name: 'Number',
|
||||
fieldId: 'number',
|
||||
label: 'Number',
|
||||
type: 'number',
|
||||
metadata: {
|
||||
fieldName: 'number',
|
||||
|
||||
@ -43,8 +43,8 @@ const PhoneFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'phone',
|
||||
name: 'Phone',
|
||||
fieldId: 'phone',
|
||||
label: 'Phone',
|
||||
type: 'phone',
|
||||
metadata: {
|
||||
fieldName: 'Phone',
|
||||
|
||||
@ -41,8 +41,8 @@ const ProbabilityFieldInputWithContext = ({
|
||||
return (
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'probability',
|
||||
name: 'Probability',
|
||||
fieldId: 'probability',
|
||||
label: 'Probability',
|
||||
type: 'probability',
|
||||
metadata: {
|
||||
fieldName: 'Probability',
|
||||
|
||||
@ -46,8 +46,8 @@ const RelationFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'relation',
|
||||
name: 'Relation',
|
||||
fieldId: 'relation',
|
||||
label: 'Relation',
|
||||
type: 'relation',
|
||||
metadata: {
|
||||
fieldName: 'Relation',
|
||||
|
||||
@ -43,8 +43,8 @@ const TextFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'text',
|
||||
name: 'Text',
|
||||
fieldId: 'text',
|
||||
label: 'Text',
|
||||
type: 'text',
|
||||
metadata: {
|
||||
fieldName: 'Text',
|
||||
|
||||
@ -43,8 +43,8 @@ const URLFieldInputWithContext = ({
|
||||
<div>
|
||||
<FieldContextProvider
|
||||
fieldDefinition={{
|
||||
key: 'url',
|
||||
name: 'URL',
|
||||
fieldId: 'url',
|
||||
label: 'URL',
|
||||
type: 'url',
|
||||
metadata: {
|
||||
fieldName: 'URL',
|
||||
|
||||
@ -23,7 +23,7 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
|
||||
}: {
|
||||
fieldDefinition: Pick<
|
||||
FieldDefinition<FieldMetadata>,
|
||||
'type' | 'metadata' | 'key' | 'name'
|
||||
'type' | 'metadata' | 'fieldId' | 'label'
|
||||
>;
|
||||
entityId: string;
|
||||
}) => {
|
||||
|
||||
@ -5,8 +5,8 @@ import { FieldMetadata } from './FieldMetadata';
|
||||
import { FieldType } from './FieldType';
|
||||
|
||||
export type FieldDefinition<T extends FieldMetadata> = {
|
||||
key: string;
|
||||
name: string;
|
||||
fieldId: string;
|
||||
label: string;
|
||||
Icon?: IconComponent;
|
||||
type: FieldType;
|
||||
metadata: T;
|
||||
|
||||
@ -6,7 +6,7 @@ import { SingleEntitySelectBase } from '@/ui/input/relation-picker/components/Si
|
||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
||||
import { useRemoveFilter } from '@/views/hooks/useRemoveFilter';
|
||||
import { useUpsertFilter } from '@/views/hooks/useUpsertFilter';
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { useFilter } from '../hooks/useFilter';
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { useUpsertFilter } from '../../../../views/hooks/useUpsertFilter';
|
||||
import { useFilter } from '../hooks/useFilter';
|
||||
|
||||
@ -6,7 +6,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { useFilter } from '../hooks/useFilter';
|
||||
import { getOperandsForFilterType } from '../utils/getOperandsForFilterType';
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { createScopedState } from '@/ui/utilities/recoil-scope/utils/createScopedState';
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
export const selectedOperandInDropdownScopedState =
|
||||
createScopedState<ViewFilterOperand | null>({
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { FilterType } from './FilterType';
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
export { ViewFilterOperand as FilterOperand } from '~/generated/graphql';
|
||||
export { ViewFilterOperand as FilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
export const getOperandLabel = (
|
||||
operand: ViewFilterOperand | null | undefined,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { FilterType } from '../types/FilterType';
|
||||
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { QueryMode, ViewFilterOperand } from '~/generated/graphql';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { QueryMode } from '~/generated/graphql';
|
||||
|
||||
import { Filter } from '../types/Filter';
|
||||
|
||||
|
||||
@ -49,7 +49,7 @@ type BoardOptionsMenu = 'fields' | 'stage-creation' | 'stages';
|
||||
type ColumnForCreate = {
|
||||
id: string;
|
||||
colorCode: ThemeColor;
|
||||
index: number;
|
||||
position: number;
|
||||
title: string;
|
||||
};
|
||||
|
||||
@ -93,7 +93,7 @@ export const BoardOptionsDropdownContent = ({
|
||||
const columnToCreate: ColumnForCreate = {
|
||||
id: v4(),
|
||||
colorCode: 'gray',
|
||||
index: boardColumns.length,
|
||||
position: boardColumns.length,
|
||||
title: stageInputRef.current.value,
|
||||
};
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ export const EntityBoard = ({
|
||||
);
|
||||
|
||||
const sortedBoardColumns = [...boardColumns].sort((a, b) => {
|
||||
return a.index - b.index;
|
||||
return a.position - b.position;
|
||||
});
|
||||
|
||||
const boardRef = useRef<HTMLDivElement>(null);
|
||||
@ -155,8 +155,9 @@ export const EntityBoard = ({
|
||||
value={{
|
||||
id: column.id,
|
||||
columnDefinition: column,
|
||||
isFirstColumn: column.index === 0,
|
||||
isLastColumn: column.index === sortedBoardColumns.length - 1,
|
||||
isFirstColumn: column.position === 0,
|
||||
isLastColumn:
|
||||
column.position === sortedBoardColumns.length - 1,
|
||||
}}
|
||||
>
|
||||
<RecoilScope
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { ViewFieldForVisibility } from '@/views/types/ViewFieldForVisibility';
|
||||
|
||||
import { boardCardFieldsScopedState } from '../states/boardCardFieldsScopedState';
|
||||
|
||||
@ -13,10 +14,12 @@ export const useBoardCardFields = () => {
|
||||
BoardRecoilScopeContext,
|
||||
);
|
||||
|
||||
const handleFieldVisibilityChange = (field: ViewFieldForVisibility) => {
|
||||
const handleFieldVisibilityChange = (
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => {
|
||||
setBoardCardFields((previousFields) =>
|
||||
previousFields.map((previousField) =>
|
||||
previousField.key === field.key
|
||||
previousField.fieldId === field.fieldId
|
||||
? { ...previousField, isVisible: !field.isVisible }
|
||||
: previousField,
|
||||
),
|
||||
|
||||
@ -21,7 +21,7 @@ export const useBoardColumns = () => {
|
||||
updatePipelineStageMutation({
|
||||
variables: {
|
||||
data: {
|
||||
index: stage.index,
|
||||
position: stage.position,
|
||||
},
|
||||
id: stage.id,
|
||||
},
|
||||
|
||||
@ -12,5 +12,5 @@ export const boardCardFieldsByKeyScopedSelector = selectorFamily({
|
||||
({ get }) =>
|
||||
get(boardCardFieldsScopedState(scopeId)).reduce<
|
||||
Record<string, BoardFieldDefinition<FieldMetadata>>
|
||||
>((result, field) => ({ ...result, [field.key]: field }), {}),
|
||||
>((result, field) => ({ ...result, [field.fieldId]: field }), {}),
|
||||
});
|
||||
|
||||
@ -9,10 +9,10 @@ export const hiddenBoardCardFieldsScopedSelector = selectorFamily({
|
||||
(scopeId: string) =>
|
||||
({ get }) => {
|
||||
const fields = get(boardCardFieldsScopedState(scopeId));
|
||||
const fieldKeys = fields.map(({ key }) => key);
|
||||
const fieldKeys = fields.map(({ fieldId }) => fieldId);
|
||||
const otherAvailableKeys = get(
|
||||
availableBoardCardFieldsScopedState(scopeId),
|
||||
).filter(({ key }) => !fieldKeys.includes(key));
|
||||
).filter(({ fieldId }) => !fieldKeys.includes(fieldId));
|
||||
|
||||
return [
|
||||
...fields.filter((field) => !field.isVisible),
|
||||
|
||||
@ -12,5 +12,5 @@ export const savedBoardCardFieldsByKeyFamilySelector = selectorFamily({
|
||||
({ get }) =>
|
||||
get(savedBoardCardFieldsFamilyState(viewId)).reduce<
|
||||
Record<string, BoardFieldDefinition<FieldMetadata>>
|
||||
>((result, field) => ({ ...result, [field.key]: field }), {}),
|
||||
>((result, field) => ({ ...result, [field.fieldId]: field }), {}),
|
||||
});
|
||||
|
||||
@ -3,6 +3,6 @@ import { ThemeColor } from '@/ui/theme/constants/colors';
|
||||
export type BoardColumnDefinition = {
|
||||
id: string;
|
||||
title: string;
|
||||
index: number;
|
||||
position: number;
|
||||
colorCode?: ThemeColor;
|
||||
};
|
||||
|
||||
@ -3,6 +3,6 @@ import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
|
||||
export type BoardFieldDefinition<T extends FieldMetadata> =
|
||||
FieldDefinition<T> & {
|
||||
index: number;
|
||||
position: number;
|
||||
isVisible?: boolean;
|
||||
};
|
||||
|
||||
@ -4,25 +4,14 @@ import { useRecoilCallback } from 'recoil';
|
||||
|
||||
import { useFindManyObjects } from '@/metadata/hooks/useFindManyObjects';
|
||||
import { PaginatedObjectTypeResults } from '@/metadata/types/PaginatedObjectTypeResults';
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { Filter } from '@/ui/data/filter/types/Filter';
|
||||
import { Sort } from '@/ui/data/sort/types/Sort';
|
||||
import {
|
||||
useGetViewFiltersQuery,
|
||||
useGetViewSortsQuery,
|
||||
} from '~/generated/graphql';
|
||||
import { assertNotNull } from '~/utils/assert';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { useView } from '../hooks/useView';
|
||||
import { useViewInternalStates } from '../hooks/useViewInternalStates';
|
||||
import { availableFieldsScopedState } from '../states/availableFieldsScopedState';
|
||||
import { availableFiltersScopedState } from '../states/availableFiltersScopedState';
|
||||
import { availableSortsScopedState } from '../states/availableSortsScopedState';
|
||||
import { onViewFieldsChangeScopedState } from '../states/onViewFieldsChangeScopedState';
|
||||
import { savedViewFieldsScopedFamilyState } from '../states/savedViewFieldsScopedFamilyState';
|
||||
import { savedViewFiltersScopedFamilyState } from '../states/savedViewFiltersScopedFamilyState';
|
||||
import { savedViewSortsScopedFamilyState } from '../states/savedViewSortsScopedFamilyState';
|
||||
import { viewsScopedState } from '../states/viewsScopedState';
|
||||
import { View } from '../types/View';
|
||||
import { ViewField } from '../types/ViewField';
|
||||
@ -32,10 +21,6 @@ export const ViewBarEffect = () => {
|
||||
scopeId: viewScopeId,
|
||||
setCurrentViewFields,
|
||||
setSavedViewFields,
|
||||
setCurrentViewSorts,
|
||||
setSavedViewSorts,
|
||||
setCurrentViewFilters,
|
||||
setSavedViewFilters,
|
||||
currentViewId,
|
||||
setViews,
|
||||
changeView,
|
||||
@ -56,6 +41,12 @@ export const ViewBarEffect = () => {
|
||||
.getLoadable(availableFieldsScopedState({ scopeId: viewScopeId }))
|
||||
.getValue();
|
||||
|
||||
const onViewFieldsChange = snapshot
|
||||
.getLoadable(
|
||||
onViewFieldsChangeScopedState({ scopeId: viewScopeId }),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
if (!availableFields || !currentViewId) {
|
||||
return;
|
||||
}
|
||||
@ -70,27 +61,13 @@ export const ViewBarEffect = () => {
|
||||
.getValue();
|
||||
|
||||
const queriedViewFields = data.edges
|
||||
.map<ColumnDefinition<FieldMetadata> | null>((viewField) => {
|
||||
const columnDefinition = availableFields.find(
|
||||
({ key }) => viewField.node.fieldId === key,
|
||||
);
|
||||
|
||||
return columnDefinition
|
||||
? {
|
||||
...columnDefinition,
|
||||
key: viewField.node.fieldId,
|
||||
name: viewField.node.fieldId,
|
||||
index: viewField.node.position,
|
||||
size: viewField.node.size ?? columnDefinition.size,
|
||||
isVisible: viewField.node.isVisible,
|
||||
}
|
||||
: null;
|
||||
})
|
||||
.filter<ColumnDefinition<FieldMetadata>>(assertNotNull);
|
||||
.map((viewField) => viewField.node)
|
||||
.filter(assertNotNull);
|
||||
|
||||
if (!isDeeplyEqual(savedViewFields, queriedViewFields)) {
|
||||
setCurrentViewFields?.(queriedViewFields);
|
||||
setSavedViewFields?.(queriedViewFields);
|
||||
onViewFieldsChange?.(queriedViewFields);
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -115,108 +92,108 @@ export const ViewBarEffect = () => {
|
||||
|
||||
if (!nextViews.length) return;
|
||||
|
||||
if (!currentViewId) return setCurrentViewId(nextViews[0].id);
|
||||
if (!currentViewId) return changeView(nextViews[0].id);
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
useGetViewSortsQuery({
|
||||
skip: !currentViewId,
|
||||
variables: {
|
||||
where: {
|
||||
viewId: { equals: currentViewId },
|
||||
},
|
||||
},
|
||||
onCompleted: useRecoilCallback(({ snapshot }) => async (data) => {
|
||||
const availableSorts = snapshot
|
||||
.getLoadable(availableSortsScopedState({ scopeId: viewScopeId }))
|
||||
.getValue();
|
||||
// useGetViewSortsQuery({
|
||||
// skip: !currentViewId,
|
||||
// variables: {
|
||||
// where: {
|
||||
// viewId: { equals: currentViewId },
|
||||
// },
|
||||
// },
|
||||
// onCompleted: useRecoilCallback(({ snapshot }) => async (data) => {
|
||||
// const availableSorts = snapshot
|
||||
// .getLoadable(availableSortsScopedState({ scopeId: viewScopeId }))
|
||||
// .getValue();
|
||||
|
||||
if (!availableSorts || !currentViewId) {
|
||||
return;
|
||||
}
|
||||
// if (!availableSorts || !currentViewId) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const savedViewSorts = snapshot
|
||||
.getLoadable(
|
||||
savedViewSortsScopedFamilyState({
|
||||
scopeId: viewScopeId,
|
||||
familyKey: currentViewId,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
// const savedViewSorts = snapshot
|
||||
// .getLoadable(
|
||||
// savedViewSortsScopedFamilyState({
|
||||
// scopeId: viewScopeId,
|
||||
// familyKey: currentViewId,
|
||||
// }),
|
||||
// )
|
||||
// .getValue();
|
||||
|
||||
const queriedViewSorts = data.viewSorts
|
||||
.map((viewSort) => {
|
||||
const foundCorrespondingSortDefinition = availableSorts.find(
|
||||
(sort) => sort.key === viewSort.key,
|
||||
);
|
||||
// const queriedViewSorts = data.viewSorts
|
||||
// .map((viewSort) => {
|
||||
// const foundCorrespondingSortDefinition = availableSorts.find(
|
||||
// (sort) => sort.key === viewSort.key,
|
||||
// );
|
||||
|
||||
if (foundCorrespondingSortDefinition) {
|
||||
return {
|
||||
key: viewSort.key,
|
||||
definition: foundCorrespondingSortDefinition,
|
||||
direction: viewSort.direction.toLowerCase(),
|
||||
} as Sort;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
})
|
||||
.filter((sort): sort is Sort => !!sort);
|
||||
// if (foundCorrespondingSortDefinition) {
|
||||
// return {
|
||||
// key: viewSort.key,
|
||||
// definition: foundCorrespondingSortDefinition,
|
||||
// direction: viewSort.direction.toLowerCase(),
|
||||
// } as Sort;
|
||||
// } else {
|
||||
// return undefined;
|
||||
// }
|
||||
// })
|
||||
// .filter((sort): sort is Sort => !!sort);
|
||||
|
||||
if (!isDeeplyEqual(savedViewSorts, queriedViewSorts)) {
|
||||
setSavedViewSorts?.(queriedViewSorts);
|
||||
setCurrentViewSorts?.(queriedViewSorts);
|
||||
}
|
||||
}),
|
||||
});
|
||||
// if (!isDeeplyEqual(savedViewSorts, queriedViewSorts)) {
|
||||
// setSavedViewSorts?.(queriedViewSorts);
|
||||
// setCurrentViewSorts?.(queriedViewSorts);
|
||||
// }
|
||||
// }),
|
||||
// });
|
||||
|
||||
useGetViewFiltersQuery({
|
||||
skip: !currentViewId,
|
||||
variables: {
|
||||
where: {
|
||||
viewId: { equals: currentViewId },
|
||||
},
|
||||
},
|
||||
onCompleted: useRecoilCallback(({ snapshot }) => (data) => {
|
||||
const availableFilters = snapshot
|
||||
.getLoadable(availableFiltersScopedState({ scopeId: viewScopeId }))
|
||||
.getValue();
|
||||
// useGetViewFiltersQuery({
|
||||
// skip: !currentViewId,
|
||||
// variables: {
|
||||
// where: {
|
||||
// viewId: { equals: currentViewId },
|
||||
// },
|
||||
// },
|
||||
// onCompleted: useRecoilCallback(({ snapshot }) => (data) => {
|
||||
// const availableFilters = snapshot
|
||||
// .getLoadable(availableFiltersScopedState({ scopeId: viewScopeId }))
|
||||
// .getValue();
|
||||
|
||||
if (!availableFilters || !currentViewId) {
|
||||
return;
|
||||
}
|
||||
// if (!availableFilters || !currentViewId) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const savedViewFilters = snapshot
|
||||
.getLoadable(
|
||||
savedViewFiltersScopedFamilyState({
|
||||
scopeId: viewScopeId,
|
||||
familyKey: currentViewId,
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
// const savedViewFilters = snapshot
|
||||
// .getLoadable(
|
||||
// savedViewFiltersScopedFamilyState({
|
||||
// scopeId: viewScopeId,
|
||||
// familyKey: currentViewId,
|
||||
// }),
|
||||
// )
|
||||
// .getValue();
|
||||
|
||||
const queriedViewFilters = data.viewFilters
|
||||
.map(({ __typename, name: _name, ...viewFilter }) => {
|
||||
const availableFilter = availableFilters.find(
|
||||
(filter) => filter.key === viewFilter.key,
|
||||
);
|
||||
// const queriedViewFilters = data.viewFilters
|
||||
// .map(({ __typename, name: _name, ...viewFilter }) => {
|
||||
// const availableFilter = availableFilters.find(
|
||||
// (filter) => filter.key === viewFilter.key,
|
||||
// );
|
||||
|
||||
return availableFilter
|
||||
? {
|
||||
...viewFilter,
|
||||
displayValue: viewFilter.displayValue ?? viewFilter.value,
|
||||
type: availableFilter.type,
|
||||
}
|
||||
: undefined;
|
||||
})
|
||||
.filter((filter): filter is Filter => !!filter);
|
||||
// return availableFilter
|
||||
// ? {
|
||||
// ...viewFilter,
|
||||
// displayValue: viewFilter.displayValue ?? viewFilter.value,
|
||||
// type: availableFilter.type,
|
||||
// }
|
||||
// : undefined;
|
||||
// })
|
||||
// .filter((filter): filter is Filter => !!filter);
|
||||
|
||||
if (!isDeeplyEqual(savedViewFilters, queriedViewFilters)) {
|
||||
setSavedViewFilters?.(queriedViewFilters);
|
||||
setCurrentViewFilters?.(queriedViewFilters);
|
||||
}
|
||||
}),
|
||||
});
|
||||
// if (!isDeeplyEqual(savedViewFilters, queriedViewFilters)) {
|
||||
// setSavedViewFilters?.(queriedViewFilters);
|
||||
// setCurrentViewFilters?.(queriedViewFilters);
|
||||
// }
|
||||
// }),
|
||||
// });
|
||||
|
||||
const currentViewIdFromUrl = searchParams.get('view');
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@ import {
|
||||
ResponderProvided,
|
||||
} from '@hello-pangea/dnd';
|
||||
|
||||
import { ColumnDefinition } from '@/ui/data/data-table/types/ColumnDefinition';
|
||||
import { FieldMetadata } from '@/ui/data/field/types/FieldMetadata';
|
||||
import { IconMinus, IconPlus } from '@/ui/display/icon';
|
||||
import { AppTooltip } from '@/ui/display/tooltip/AppTooltip';
|
||||
import { IconInfoCircle } from '@/ui/input/constants/icons';
|
||||
@ -18,11 +20,11 @@ import { MenuItemDraggable } from '@/ui/navigation/menu-item/components/MenuItem
|
||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
import { ViewFieldForVisibility } from '../types/ViewFieldForVisibility';
|
||||
|
||||
type ViewFieldsVisibilityDropdownSectionProps = {
|
||||
fields: ViewFieldForVisibility[];
|
||||
onVisibilityChange: (field: ViewFieldForVisibility) => void;
|
||||
fields: Omit<ColumnDefinition<FieldMetadata>, 'size'>[];
|
||||
onVisibilityChange: (
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => void;
|
||||
title: string;
|
||||
isDraggable: boolean;
|
||||
onDragEnd?: OnDragEndResponder;
|
||||
@ -46,7 +48,10 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
else setOpenToolTipIndex(index);
|
||||
};
|
||||
|
||||
const getIconButtons = (index: number, field: ViewFieldForVisibility) => {
|
||||
const getIconButtons = (
|
||||
index: number,
|
||||
field: Omit<ColumnDefinition<FieldMetadata>, 'size' | 'position'>,
|
||||
) => {
|
||||
if (field.infoTooltipContent) {
|
||||
return [
|
||||
{
|
||||
@ -88,20 +93,20 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
onDragEnd={handleOnDrag}
|
||||
draggableItems={
|
||||
<>
|
||||
{fields
|
||||
.filter(({ index, size }) => index !== 0 || !size)
|
||||
{[...fields]
|
||||
.sort((a, b) => a.position - b.position)
|
||||
.map((field, index) => (
|
||||
<DraggableItem
|
||||
key={field.key}
|
||||
draggableId={field.key}
|
||||
key={field.fieldId}
|
||||
draggableId={field.fieldId}
|
||||
index={index + 1}
|
||||
itemComponent={
|
||||
<MenuItemDraggable
|
||||
key={field.key}
|
||||
key={field.fieldId}
|
||||
LeftIcon={field.Icon}
|
||||
iconButtons={getIconButtons(index + 1, field)}
|
||||
isTooltipOpen={openToolTipIndex === index + 1}
|
||||
text={field.name}
|
||||
text={field.label}
|
||||
className={`${title}-draggable-item-tooltip-anchor-${
|
||||
index + 1
|
||||
}`}
|
||||
@ -115,11 +120,11 @@ export const ViewFieldsVisibilityDropdownSection = ({
|
||||
) : (
|
||||
fields.map((field, index) => (
|
||||
<MenuItem
|
||||
key={field.key}
|
||||
key={field.fieldId}
|
||||
LeftIcon={field.Icon}
|
||||
iconButtons={getIconButtons(index, field)}
|
||||
isTooltipOpen={openToolTipIndex === index}
|
||||
text={field.name}
|
||||
text={field.label}
|
||||
className={`${title}-fixed-item-tooltip-anchor-${index}`}
|
||||
/>
|
||||
))
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const VIEW_FIELD_FRAGMENT = gql`
|
||||
fragment ViewFieldFragment on ViewField {
|
||||
index
|
||||
isVisible
|
||||
key
|
||||
name
|
||||
size
|
||||
viewId
|
||||
}
|
||||
`;
|
||||
@ -1,10 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_VIEW = gql`
|
||||
mutation CreateView($data: ViewCreateInput!) {
|
||||
view: createOneView(data: $data) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,9 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_VIEW_FIELDS = gql`
|
||||
mutation CreateViewFields($data: [ViewFieldCreateManyInput!]!) {
|
||||
createManyViewField(data: $data) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,9 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_VIEW_FILTERS = gql`
|
||||
mutation CreateViewFilters($data: [ViewFilterCreateManyInput!]!) {
|
||||
createManyViewFilter(data: $data) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,9 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_VIEW_SORTS = gql`
|
||||
mutation CreateViewSorts($data: [ViewSortCreateManyInput!]!) {
|
||||
createManyViewSort(data: $data) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,10 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const DELETE_VIEW = gql`
|
||||
mutation DeleteView($where: ViewWhereUniqueInput!) {
|
||||
view: deleteOneView(where: $where) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,9 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const DELETE_VIEW_FILTERS = gql`
|
||||
mutation DeleteViewFilters($where: ViewFilterWhereInput!) {
|
||||
deleteManyViewFilter(where: $where) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,9 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const DELETE_VIEW_SORTS = gql`
|
||||
mutation DeleteViewSorts($where: ViewSortWhereInput!) {
|
||||
deleteManyViewSort(where: $where) {
|
||||
count
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,10 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const UPDATE_VIEW = gql`
|
||||
mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) {
|
||||
view: updateOneView(data: $data, where: $where) {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,12 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const UPDATE_VIEW_FIELD = gql`
|
||||
mutation UpdateViewField(
|
||||
$data: ViewFieldUpdateInput!
|
||||
$where: ViewFieldWhereUniqueInput!
|
||||
) {
|
||||
updateOneViewField(data: $data, where: $where) {
|
||||
...ViewFieldFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,16 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const UPDATE_VIEW_FILTER = gql`
|
||||
mutation UpdateViewFilter(
|
||||
$data: ViewFilterUpdateInput!
|
||||
$where: ViewFilterWhereUniqueInput!
|
||||
) {
|
||||
viewFilter: updateOneViewFilter(data: $data, where: $where) {
|
||||
displayValue
|
||||
key
|
||||
name
|
||||
operand
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,14 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const UPDATE_VIEW_SORT = gql`
|
||||
mutation UpdateViewSort(
|
||||
$data: ViewSortUpdateInput!
|
||||
$where: ViewSortWhereUniqueInput!
|
||||
) {
|
||||
viewSort: updateOneViewSort(data: $data, where: $where) {
|
||||
direction
|
||||
key
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,12 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_VIEW_FIELDS = gql`
|
||||
query GetViewFields(
|
||||
$where: ViewFieldWhereInput
|
||||
$orderBy: [ViewFieldOrderByWithRelationInput!]
|
||||
) {
|
||||
viewFields: findManyViewField(where: $where, orderBy: $orderBy) {
|
||||
...ViewFieldFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,13 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_VIEW_FILTERS = gql`
|
||||
query GetViewFilters($where: ViewFilterWhereInput) {
|
||||
viewFilters: findManyViewFilter(where: $where) {
|
||||
displayValue
|
||||
key
|
||||
name
|
||||
operand
|
||||
value
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -1,11 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const GET_VIEW_SORTS = gql`
|
||||
query GetViewSorts($where: ViewSortWhereInput) {
|
||||
viewSorts: findManyViewSort(where: $where) {
|
||||
direction
|
||||
key
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user