Skip to content

Commit d61d585

Browse files
gitstart-app[bot]gitstart-twentylucasbordeau
authored
View becomes blank after deleting select (#6703)
This PR was created by [GitStart](https://gitstart.com/) to address the requirements from this ticket: [TWNTY-6027](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-6027). This ticket was imported from: [TWNTY-6027](#6027) --- ### Description - Delete corresponding view simultaneously once select field is deactivated instead of deleted because the bug happens on the deactivation (one step before deleting), confirmation: <https://discord.com/channels/1130383047699738754/1268662542172028971/1270367244509249651> - Is still possible to create Kanban views with deactivated Select fields, but this is not related to the PR. - The changes on the frontend are for refreshing the data after the view deletion ### Refs #6027 ### Demo <https://www.loom.com/share/4f705344e3054cd5b3d5eadd398d2c9c?sid=8db3d8b9-4dce-4e31-8359-0e31cbc0e2e7> Fixes #6027 --------- Co-authored-by: gitstart-twenty <[email protected]> Co-authored-by: Lucas Bordeau <[email protected]>
1 parent b1fbf4b commit d61d585

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

packages/twenty-front/src/modules/object-record/record-index/options/components/RecordIndexOptionsDropdownContent.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from 'twenty-ui';
1313

1414
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
15+
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
1516
import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
1617
import {
1718
displayedExportProgress,
@@ -38,7 +39,6 @@ import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
3839
import { ViewType } from '@/views/types/ViewType';
3940
import { useLocation } from 'react-router-dom';
4041
import { useSetRecoilState } from 'recoil';
41-
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
4242

4343
type RecordIndexOptionsMenu = 'fields' | 'hiddenFields';
4444

@@ -218,6 +218,7 @@ export const RecordIndexOptionsDropdownContent = ({
218218
to={settingsUrl}
219219
onClick={() => {
220220
setNavigationMemorizedUrl(location.pathname + location.search);
221+
closeDropdown();
221222
}}
222223
>
223224
<DropdownMenuItemsContainer>

packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow.tsx

+46-2
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,18 @@ import { RELATION_TYPES } from '../../constants/RelationTypes';
1515
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
1616
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
1717
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
18+
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
1819
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
1920
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
21+
import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache';
22+
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
23+
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
2024
import { SettingsObjectFieldActiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldActiveActionDropdown';
2125
import { SettingsObjectFieldInactiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown';
2226
import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
2327
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
28+
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
29+
import { View } from '@/views/types/View';
2430
import { useNavigate } from 'react-router-dom';
2531
import { useRecoilState } from 'recoil';
2632
import { RelationMetadataType } from '~/generated-metadata/graphql';
@@ -61,6 +67,10 @@ export const SettingsObjectFieldItemTableRow = ({
6167

6268
const navigate = useNavigate();
6369

70+
const [navigationMemorizedUrl, setNavigationMemorizedUrl] = useRecoilState(
71+
navigationMemorizedUrlState,
72+
);
73+
6474
const theme = useTheme();
6575
const { getIcon } = useIcons();
6676
const Icon = getIcon(fieldMetadataItem.icon);
@@ -100,8 +110,42 @@ export const SettingsObjectFieldItemTableRow = ({
100110
deleteMetadataField,
101111
} = useFieldMetadataItem();
102112

103-
const handleDisableField = (activeFieldMetadatItem: FieldMetadataItem) => {
104-
deactivateMetadataField(activeFieldMetadatItem);
113+
const { records: allViews } = usePrefetchedData<View>(PrefetchKey.AllViews);
114+
115+
const deleteViewFromCache = useDeleteRecordFromCache({
116+
objectNameSingular: CoreObjectNameSingular.View,
117+
});
118+
119+
const handleDisableField = async (
120+
activeFieldMetadatItem: FieldMetadataItem,
121+
) => {
122+
await deactivateMetadataField(activeFieldMetadatItem);
123+
124+
const deletedViewIds = allViews
125+
.map((view) => {
126+
if (view.kanbanFieldMetadataId === activeFieldMetadatItem.id) {
127+
deleteViewFromCache(view);
128+
return view.id;
129+
}
130+
131+
return null;
132+
})
133+
.filter(isDefined);
134+
135+
const [baseUrl, queryParams] = navigationMemorizedUrl.includes('?')
136+
? navigationMemorizedUrl.split('?')
137+
: [navigationMemorizedUrl, ''];
138+
139+
const params = new URLSearchParams(queryParams);
140+
const currentViewId = params.get('view');
141+
142+
if (isDefined(currentViewId) && deletedViewIds.includes(currentViewId)) {
143+
params.delete('view');
144+
const updatedUrl = params.toString()
145+
? `${baseUrl}?${params.toString()}`
146+
: baseUrl;
147+
setNavigationMemorizedUrl(updatedUrl);
148+
}
105149
};
106150

107151
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();

packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.service.ts

+14
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import {
5151
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
5252
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
5353
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
54+
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
5455
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
5556
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
5657
import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity';
@@ -78,6 +79,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
7879
private readonly dataSourceService: DataSourceService,
7980
private readonly typeORMService: TypeORMService,
8081
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
82+
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
8183
) {
8284
super(fieldMetadataRepository);
8385
}
@@ -348,6 +350,18 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
348350
);
349351
}
350352

353+
if (fieldMetadataInput.isActive === false) {
354+
const viewsRepository =
355+
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
356+
fieldMetadataInput.workspaceId,
357+
'view',
358+
);
359+
360+
await viewsRepository.delete({
361+
kanbanFieldMetadataId: id,
362+
});
363+
}
364+
351365
if (fieldMetadataInput.options) {
352366
for (const option of fieldMetadataInput.options) {
353367
if (!option.id) {

0 commit comments

Comments
 (0)