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](https://github.com/twentyhq/twenty/issues/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 <gitstart-twenty@users.noreply.github.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
committed by
GitHub
parent
b1fbf4b683
commit
d61d5857f8
@ -12,6 +12,7 @@ import {
|
|||||||
} from 'twenty-ui';
|
} from 'twenty-ui';
|
||||||
|
|
||||||
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
import { useObjectNamePluralFromSingular } from '@/object-metadata/hooks/useObjectNamePluralFromSingular';
|
||||||
|
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
|
||||||
import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
|
import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
|
||||||
import {
|
import {
|
||||||
displayedExportProgress,
|
displayedExportProgress,
|
||||||
@ -38,7 +39,6 @@ import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
|
|||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
import { useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
import { useHandleToggleTrashColumnFilter } from '@/object-record/record-index/hooks/useHandleToggleTrashColumnFilter';
|
|
||||||
|
|
||||||
type RecordIndexOptionsMenu = 'fields' | 'hiddenFields';
|
type RecordIndexOptionsMenu = 'fields' | 'hiddenFields';
|
||||||
|
|
||||||
@ -218,6 +218,7 @@ export const RecordIndexOptionsDropdownContent = ({
|
|||||||
to={settingsUrl}
|
to={settingsUrl}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setNavigationMemorizedUrl(location.pathname + location.search);
|
setNavigationMemorizedUrl(location.pathname + location.search);
|
||||||
|
closeDropdown();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
|
|||||||
@ -15,12 +15,18 @@ import { RELATION_TYPES } from '../../constants/RelationTypes';
|
|||||||
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
|
import { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from '@/object-metadata/constants/LabelIdentifierFieldMetadataTypes';
|
||||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
||||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||||
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
import { getFieldSlug } from '@/object-metadata/utils/getFieldSlug';
|
||||||
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
import { isLabelIdentifierField } from '@/object-metadata/utils/isLabelIdentifierField';
|
||||||
|
import { useDeleteRecordFromCache } from '@/object-record/cache/hooks/useDeleteRecordFromCache';
|
||||||
|
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||||
|
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||||
import { SettingsObjectFieldActiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldActiveActionDropdown';
|
import { SettingsObjectFieldActiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldActiveActionDropdown';
|
||||||
import { SettingsObjectFieldInactiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown';
|
import { SettingsObjectFieldInactiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown';
|
||||||
import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
|
import { settingsObjectFieldsFamilyState } from '@/settings/data-model/object-details/states/settingsObjectFieldsFamilyState';
|
||||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||||
|
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
|
||||||
|
import { View } from '@/views/types/View';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
import { RelationMetadataType } from '~/generated-metadata/graphql';
|
||||||
@ -61,6 +67,10 @@ export const SettingsObjectFieldItemTableRow = ({
|
|||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [navigationMemorizedUrl, setNavigationMemorizedUrl] = useRecoilState(
|
||||||
|
navigationMemorizedUrlState,
|
||||||
|
);
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { getIcon } = useIcons();
|
const { getIcon } = useIcons();
|
||||||
const Icon = getIcon(fieldMetadataItem.icon);
|
const Icon = getIcon(fieldMetadataItem.icon);
|
||||||
@ -100,8 +110,42 @@ export const SettingsObjectFieldItemTableRow = ({
|
|||||||
deleteMetadataField,
|
deleteMetadataField,
|
||||||
} = useFieldMetadataItem();
|
} = useFieldMetadataItem();
|
||||||
|
|
||||||
const handleDisableField = (activeFieldMetadatItem: FieldMetadataItem) => {
|
const { records: allViews } = usePrefetchedData<View>(PrefetchKey.AllViews);
|
||||||
deactivateMetadataField(activeFieldMetadatItem);
|
|
||||||
|
const deleteViewFromCache = useDeleteRecordFromCache({
|
||||||
|
objectNameSingular: CoreObjectNameSingular.View,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleDisableField = async (
|
||||||
|
activeFieldMetadatItem: FieldMetadataItem,
|
||||||
|
) => {
|
||||||
|
await deactivateMetadataField(activeFieldMetadatItem);
|
||||||
|
|
||||||
|
const deletedViewIds = allViews
|
||||||
|
.map((view) => {
|
||||||
|
if (view.kanbanFieldMetadataId === activeFieldMetadatItem.id) {
|
||||||
|
deleteViewFromCache(view);
|
||||||
|
return view.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.filter(isDefined);
|
||||||
|
|
||||||
|
const [baseUrl, queryParams] = navigationMemorizedUrl.includes('?')
|
||||||
|
? navigationMemorizedUrl.split('?')
|
||||||
|
: [navigationMemorizedUrl, ''];
|
||||||
|
|
||||||
|
const params = new URLSearchParams(queryParams);
|
||||||
|
const currentViewId = params.get('view');
|
||||||
|
|
||||||
|
if (isDefined(currentViewId) && deletedViewIds.includes(currentViewId)) {
|
||||||
|
params.delete('view');
|
||||||
|
const updatedUrl = params.toString()
|
||||||
|
? `${baseUrl}?${params.toString()}`
|
||||||
|
: baseUrl;
|
||||||
|
setNavigationMemorizedUrl(updatedUrl);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
||||||
|
|||||||
@ -51,6 +51,7 @@ import {
|
|||||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||||
|
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||||
import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity';
|
import { ViewFieldWorkspaceEntity } from 'src/modules/view/standard-objects/view-field.workspace-entity';
|
||||||
@ -78,6 +79,7 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
private readonly dataSourceService: DataSourceService,
|
private readonly dataSourceService: DataSourceService,
|
||||||
private readonly typeORMService: TypeORMService,
|
private readonly typeORMService: TypeORMService,
|
||||||
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
|
private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService,
|
||||||
|
private readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||||
) {
|
) {
|
||||||
super(fieldMetadataRepository);
|
super(fieldMetadataRepository);
|
||||||
}
|
}
|
||||||
@ -348,6 +350,18 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fieldMetadataInput.isActive === false) {
|
||||||
|
const viewsRepository =
|
||||||
|
await this.twentyORMGlobalManager.getRepositoryForWorkspace(
|
||||||
|
fieldMetadataInput.workspaceId,
|
||||||
|
'view',
|
||||||
|
);
|
||||||
|
|
||||||
|
await viewsRepository.delete({
|
||||||
|
kanbanFieldMetadataId: id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (fieldMetadataInput.options) {
|
if (fieldMetadataInput.options) {
|
||||||
for (const option of fieldMetadataInput.options) {
|
for (const option of fieldMetadataInput.options) {
|
||||||
if (!option.id) {
|
if (!option.id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user