Fix meeting bot CalendarEvent field visibility and editability (#21883)
- Add the meeting bot preference field to the CalendarEvent record page fields view. - Use a Standard-app ownership gate for record field read-only logic. - Allow app-owned and workspace-custom fields on system objects to follow isUIEditable and permissions. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/21883?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { getIsMetadataItemFromStandardApplication } from '@/object-metadata/utils/getIsMetadataItemFromStandardApplication';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
|
||||
export const useGetIsMetadataItemFromStandardApplication = () => {
|
||||
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
|
||||
|
||||
const applications = currentWorkspace?.installedApplications;
|
||||
|
||||
return useCallback(
|
||||
(metadataItem: { applicationId?: string | null }) =>
|
||||
getIsMetadataItemFromStandardApplication(
|
||||
metadataItem,
|
||||
applications ?? [],
|
||||
),
|
||||
[applications],
|
||||
);
|
||||
};
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
import { getIsMetadataItemFromStandardApplication } from '@/object-metadata/utils/getIsMetadataItemFromStandardApplication';
|
||||
import { TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER } from 'twenty-shared/application';
|
||||
|
||||
describe('getIsMetadataItemFromStandardApplication', () => {
|
||||
const applications = [
|
||||
{
|
||||
id: 'standard-application-id',
|
||||
universalIdentifier: TWENTY_STANDARD_APPLICATION_UNIVERSAL_IDENTIFIER,
|
||||
},
|
||||
{
|
||||
id: 'workspace-custom-application-id',
|
||||
universalIdentifier: 'workspace-custom-application-universal-id',
|
||||
},
|
||||
{
|
||||
id: 'installed-application-id',
|
||||
universalIdentifier: 'installed-application-universal-id',
|
||||
},
|
||||
];
|
||||
|
||||
it('should return true when metadata item belongs to the standard application', () => {
|
||||
expect(
|
||||
getIsMetadataItemFromStandardApplication(
|
||||
{ applicationId: 'standard-application-id' },
|
||||
applications,
|
||||
),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when metadata item belongs to the workspace custom application', () => {
|
||||
expect(
|
||||
getIsMetadataItemFromStandardApplication(
|
||||
{ applicationId: 'workspace-custom-application-id' },
|
||||
applications,
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when metadata item belongs to an installed application', () => {
|
||||
expect(
|
||||
getIsMetadataItemFromStandardApplication(
|
||||
{ applicationId: 'installed-application-id' },
|
||||
applications,
|
||||
),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
it('should return undefined when metadata item application cannot be resolved', () => {
|
||||
expect(
|
||||
getIsMetadataItemFromStandardApplication(
|
||||
{ applicationId: 'unknown-application-id' },
|
||||
applications,
|
||||
),
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { isTwentyStandardApplication } from '@/applications/utils/isTwentyStandardApplication';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
type ApplicationLike = {
|
||||
id: string;
|
||||
universalIdentifier?: string | null;
|
||||
};
|
||||
|
||||
export const getIsMetadataItemFromStandardApplication = (
|
||||
metadataItem: { applicationId?: string | null },
|
||||
applications: ApplicationLike[],
|
||||
): boolean | undefined => {
|
||||
if (!isDefined(metadataItem.applicationId)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const application = applications.find(
|
||||
(application) => application.id === metadataItem.applicationId,
|
||||
);
|
||||
|
||||
if (!isDefined(application) || !isDefined(application.universalIdentifier)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return isTwentyStandardApplication(application);
|
||||
};
|
||||
Reference in New Issue
Block a user