fix: view group followup (#9162)

This PR fixes all followup that @Bonapara add on Discord.

- [x] When no group by is set, clicking on group by should open the
"field selection" menu
- [x] When closed, chevron should be "chevron-right" instead of
"chevron-up"
- [x] Sort : Add ability to switch from alphabetical to manual when
moving a option in sort alphabetical
- [x] Add subtext for group by and sort
- [x] Group by menu display bug
- [x] Changing the sort should not close the menu
- [x] Group by Activation -> shows empty state + is slow
- [x] Switching from Kanban view Settings to Table Options menu displays
an empty menu
- [x] Unnecessary spacing under groups
- [x] When no "select" are set on an object, redirect the user directly
to the new Select field page
- [x] Sort : Default should be manual
- [x] Hidding "no value" displays all options and remove the "hide empty
group" toggle
- [x] Hide Empty group option disappeared
- [x] Group by should not be persisted on "Locked/Main view" (**For now
we just disable the group by on main view**)
- [x] Hide Empty group should not be activated by default on
Opportunities Kanban view
- [ ] Animate the group opening/closing (**We'll be done later**)

Performance improvement:

https://github.com/user-attachments/assets/fd2acf66-0e56-45d0-8b2f-99c62e57d6f7

https://github.com/user-attachments/assets/80f1a2e1-9f77-4923-b85d-acb9cad96886

Also fix #9036

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Jérémy M
2025-01-02 16:40:28 +01:00
committed by GitHub
parent 866c29e9ee
commit 0f1458cbe9
49 changed files with 676 additions and 320 deletions

View File

@ -1,77 +1,43 @@
import { useApolloClient } from '@apollo/client';
import { useCallback } from 'react';
import { v4 } from 'uuid';
import { triggerCreateRecordsOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerCreateRecordsOptimisticEffect';
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useCreateOneRecordMutation } from '@/object-record/hooks/useCreateOneRecordMutation';
import { useDeleteOneRecordMutation } from '@/object-record/hooks/useDeleteOneRecordMutation';
import { useCreateManyRecords } from '@/object-record/hooks/useCreateManyRecords';
import { useDestroyManyRecords } from '@/object-record/hooks/useDestroyManyRecords';
import { useUpdateOneRecordMutation } from '@/object-record/hooks/useUpdateOneRecordMutation';
import { GraphQLView } from '@/views/types/GraphQLView';
import { ViewGroup } from '@/views/types/ViewGroup';
import { useApolloClient } from '@apollo/client';
export const usePersistViewGroupRecords = () => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.ViewGroup,
});
const apolloClient = useApolloClient();
const { createOneRecordMutation } = useCreateOneRecordMutation({
const { createManyRecords } = useCreateManyRecords({
objectNameSingular: CoreObjectNameSingular.ViewGroup,
shouldMatchRootQueryFilter: true,
});
const { updateOneRecordMutation } = useUpdateOneRecordMutation({
objectNameSingular: CoreObjectNameSingular.ViewGroup,
});
const { deleteOneRecordMutation } = useDeleteOneRecordMutation({
const { destroyManyRecords } = useDestroyManyRecords({
objectNameSingular: CoreObjectNameSingular.ViewGroup,
});
const { objectMetadataItems } = useObjectMetadataItems();
const apolloClient = useApolloClient();
const createViewGroupRecords = useCallback(
(viewGroupsToCreate: ViewGroup[], view: GraphQLView) => {
if (!viewGroupsToCreate.length) return;
return Promise.all(
viewGroupsToCreate.map((viewGroup) =>
apolloClient.mutate({
mutation: createOneRecordMutation,
variables: {
input: {
fieldMetadataId: viewGroup.fieldMetadataId,
viewId: view.id,
isVisible: viewGroup.isVisible,
position: viewGroup.position,
id: v4(),
fieldValue: viewGroup.fieldValue,
},
},
update: (cache, { data }) => {
const record = data?.['createViewGroup'];
if (!record) return;
triggerCreateRecordsOptimisticEffect({
cache,
objectMetadataItem,
recordsToCreate: [record],
objectMetadataItems,
});
},
}),
),
return createManyRecords(
viewGroupsToCreate.map((viewGroup) => ({
...viewGroup,
view: {
id: view.id,
},
})),
);
},
[
apolloClient,
createOneRecordMutation,
objectMetadataItem,
objectMetadataItems,
],
[createManyRecords],
);
const updateViewGroupRecords = useCallback(
@ -95,7 +61,8 @@ export const usePersistViewGroupRecords = () => {
const mutationResults = await Promise.all(mutationPromises);
// FixMe: Using triggerCreateRecordsOptimisticEffect is actaully causing multiple records to be created
// FixMe: Using useUpdateOneRecord hook that call triggerUpdateRecordsOptimisticEffect is actaully causing multiple records to be created
// This is a temporary fix
mutationResults.forEach(({ data }) => {
const record = data?.['updateViewGroup'];
@ -120,33 +87,11 @@ export const usePersistViewGroupRecords = () => {
async (viewGroupsToDelete: ViewGroup[]) => {
if (!viewGroupsToDelete.length) return;
const mutationPromises = viewGroupsToDelete.map((viewGroup) =>
apolloClient.mutate<{ deleteViewGroup: ViewGroup }>({
mutation: deleteOneRecordMutation,
variables: {
idToDelete: viewGroup.id,
},
// Avoid cache being updated with stale data
fetchPolicy: 'no-cache',
}),
return destroyManyRecords(
viewGroupsToDelete.map((viewGroup) => viewGroup.id),
);
const mutationResults = await Promise.all(mutationPromises);
mutationResults.forEach(({ data }) => {
const record = data?.['deleteViewGroup'];
if (!record) return;
apolloClient.cache.evict({
id: apolloClient.cache.identify({
__typename: 'ViewGroup',
id: record.id,
}),
});
});
},
[apolloClient, deleteOneRecordMutation],
[destroyManyRecords],
);
return {