Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f570b56b8b |
File diff suppressed because one or more lines are too long
@@ -4512,6 +4512,11 @@ export type UpdateCoreViewSortMutationVariables = Exact<{
|
||||
|
||||
export type UpdateCoreViewSortMutation = { __typename?: 'Mutation', updateCoreViewSort: { __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any } };
|
||||
|
||||
export type FindAllCoreViewsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type FindAllCoreViewsQuery = { __typename?: 'Query', getCoreViews: Array<{ __typename?: 'CoreView', id: any, name: string, objectMetadataId: any, type: ViewType, key?: ViewKey | null, icon: string, position: number, isCompact: boolean, openRecordIn: ViewOpenRecordIn, kanbanAggregateOperation?: AggregateOperations | null, kanbanAggregateOperationFieldMetadataId?: any | null, anyFieldFilterValue?: string | null, calendarFieldMetadataId?: any | null, calendarLayout?: ViewCalendarLayout | null, viewFields: Array<{ __typename?: 'CoreViewField', id: any, fieldMetadataId: any, viewId: any, isVisible: boolean, position: number, size: number, aggregateOperation?: AggregateOperations | null, createdAt: string, updatedAt: string, deletedAt?: string | null }>, viewFilters: Array<{ __typename?: 'CoreViewFilter', id: any, fieldMetadataId: any, operand: ViewFilterOperand, value: any, viewFilterGroupId?: any | null, positionInViewFilterGroup?: number | null, subFieldName?: string | null, viewId: any }>, viewFilterGroups: Array<{ __typename?: 'CoreViewFilterGroup', id: any, parentViewFilterGroupId?: any | null, logicalOperator: ViewFilterGroupLogicalOperator, positionInViewFilterGroup?: number | null, viewId: any }>, viewSorts: Array<{ __typename?: 'CoreViewSort', id: any, fieldMetadataId: any, direction: ViewSortDirection, viewId: any }>, viewGroups: Array<{ __typename?: 'CoreViewGroup', id: any, fieldMetadataId: any, isVisible: boolean, fieldValue: string, position: number, viewId: any }> }> };
|
||||
|
||||
export type FindManyCoreViewFieldsQueryVariables = Exact<{
|
||||
viewId: Scalars['String'];
|
||||
}>;
|
||||
@@ -5681,6 +5686,40 @@ export function useUpdateCoreViewSortMutation(baseOptions?: Apollo.MutationHookO
|
||||
export type UpdateCoreViewSortMutationHookResult = ReturnType<typeof useUpdateCoreViewSortMutation>;
|
||||
export type UpdateCoreViewSortMutationResult = Apollo.MutationResult<UpdateCoreViewSortMutation>;
|
||||
export type UpdateCoreViewSortMutationOptions = Apollo.BaseMutationOptions<UpdateCoreViewSortMutation, UpdateCoreViewSortMutationVariables>;
|
||||
export const FindAllCoreViewsDocument = gql`
|
||||
query FindAllCoreViews {
|
||||
getCoreViews {
|
||||
...ViewFragment
|
||||
}
|
||||
}
|
||||
${ViewFragmentFragmentDoc}`;
|
||||
|
||||
/**
|
||||
* __useFindAllCoreViewsQuery__
|
||||
*
|
||||
* To run a query within a React component, call `useFindAllCoreViewsQuery` and pass it any options that fit your needs.
|
||||
* When your component renders, `useFindAllCoreViewsQuery` returns an object from Apollo Client that contains loading, error, and data properties
|
||||
* you can use to render your UI.
|
||||
*
|
||||
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
|
||||
*
|
||||
* @example
|
||||
* const { data, loading, error } = useFindAllCoreViewsQuery({
|
||||
* variables: {
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
export function useFindAllCoreViewsQuery(baseOptions?: Apollo.QueryHookOptions<FindAllCoreViewsQuery, FindAllCoreViewsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useQuery<FindAllCoreViewsQuery, FindAllCoreViewsQueryVariables>(FindAllCoreViewsDocument, options);
|
||||
}
|
||||
export function useFindAllCoreViewsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<FindAllCoreViewsQuery, FindAllCoreViewsQueryVariables>) {
|
||||
const options = {...defaultOptions, ...baseOptions}
|
||||
return Apollo.useLazyQuery<FindAllCoreViewsQuery, FindAllCoreViewsQueryVariables>(FindAllCoreViewsDocument, options);
|
||||
}
|
||||
export type FindAllCoreViewsQueryHookResult = ReturnType<typeof useFindAllCoreViewsQuery>;
|
||||
export type FindAllCoreViewsLazyQueryHookResult = ReturnType<typeof useFindAllCoreViewsLazyQuery>;
|
||||
export type FindAllCoreViewsQueryResult = Apollo.QueryResult<FindAllCoreViewsQuery, FindAllCoreViewsQueryVariables>;
|
||||
export const FindManyCoreViewFieldsDocument = gql`
|
||||
query FindManyCoreViewFields($viewId: String!) {
|
||||
getCoreViewFields(viewId: $viewId) {
|
||||
|
||||
@@ -21,8 +21,8 @@ import { BaseThemeProvider } from '@/ui/theme/components/BaseThemeProvider';
|
||||
import { UserThemeProviderEffect } from '@/ui/theme/components/UserThemeProviderEffect';
|
||||
import { PageFavicon } from '@/ui/utilities/page-favicon/components/PageFavicon';
|
||||
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
|
||||
import { UserAndViewsProviderEffect } from '@/users/components/UserAndViewsProviderEffect';
|
||||
import { UserProvider } from '@/users/components/UserProvider';
|
||||
import { UserProviderEffect } from '@/users/components/UserProviderEffect';
|
||||
import { WorkspaceProviderEffect } from '@/workspace/components/WorkspaceProviderEffect';
|
||||
import { StrictMode } from 'react';
|
||||
import { Outlet, useLocation } from 'react-router-dom';
|
||||
@@ -36,7 +36,7 @@ export const AppRouterProviders = () => {
|
||||
<ApolloProvider>
|
||||
<BaseThemeProvider>
|
||||
<ClientConfigProviderEffect />
|
||||
<UserProviderEffect />
|
||||
<UserAndViewsProviderEffect />
|
||||
<WorkspaceProviderEffect />
|
||||
<ClientConfigProvider>
|
||||
<CaptchaProvider>
|
||||
|
||||
+35
-24
@@ -22,6 +22,7 @@ import { AppPath, type ObjectPermissions } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
type WorkspaceMember,
|
||||
useFindAllCoreViewsQuery,
|
||||
useGetCurrentUserQuery,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { dateLocaleState } from '~/localization/states/dateLocaleState';
|
||||
@@ -29,7 +30,7 @@ import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
import { isMatchingLocation } from '~/utils/isMatchingLocation';
|
||||
|
||||
export const UserProviderEffect = () => {
|
||||
export const UserAndViewsProviderEffect = () => {
|
||||
const location = useLocation();
|
||||
|
||||
const [isCurrentUserLoaded, setIsCurrentUserLoaded] = useRecoilState(
|
||||
@@ -82,53 +83,57 @@ export const UserProviderEffect = () => {
|
||||
currentWorkspaceDeletedMembersState,
|
||||
);
|
||||
|
||||
const { data: queryData, loading: queryLoading } = useGetCurrentUserQuery({
|
||||
skip:
|
||||
!isLoggedIn ||
|
||||
isCurrentUserLoaded ||
|
||||
isMatchingLocation(location, AppPath.Verify) ||
|
||||
isMatchingLocation(location, AppPath.VerifyEmail),
|
||||
const shouldSkip =
|
||||
!isLoggedIn ||
|
||||
isCurrentUserLoaded ||
|
||||
isMatchingLocation(location, AppPath.Verify) ||
|
||||
isMatchingLocation(location, AppPath.VerifyEmail);
|
||||
|
||||
const { data: userQueryData, loading: userQueryLoading } =
|
||||
useGetCurrentUserQuery({
|
||||
skip: shouldSkip,
|
||||
});
|
||||
|
||||
const { data: queryDataCoreViews } = useFindAllCoreViewsQuery({
|
||||
skip: shouldSkip,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!queryLoading) {
|
||||
if (!userQueryLoading) {
|
||||
setIsCurrentUserLoaded(true);
|
||||
}
|
||||
|
||||
if (!isDefined(queryData?.currentUser)) return;
|
||||
if (!isDefined(userQueryData?.currentUser)) return;
|
||||
|
||||
setCurrentUser(queryData.currentUser);
|
||||
setCurrentUser(userQueryData.currentUser);
|
||||
|
||||
if (isDefined(queryData.currentUser.currentWorkspace)) {
|
||||
if (isDefined(userQueryData.currentUser.currentWorkspace)) {
|
||||
setCurrentWorkspace({
|
||||
...queryData.currentUser.currentWorkspace,
|
||||
defaultRole: queryData.currentUser.currentWorkspace.defaultRole ?? null,
|
||||
...userQueryData.currentUser.currentWorkspace,
|
||||
defaultRole:
|
||||
userQueryData.currentUser.currentWorkspace.defaultRole ?? null,
|
||||
defaultAgent:
|
||||
queryData.currentUser.currentWorkspace.defaultAgent ?? null,
|
||||
userQueryData.currentUser.currentWorkspace.defaultAgent ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
if (isDefined(queryData.currentUser.currentUserWorkspace)) {
|
||||
if (isDefined(userQueryData.currentUser.currentUserWorkspace)) {
|
||||
setCurrentUserWorkspace({
|
||||
...queryData.currentUser.currentUserWorkspace,
|
||||
...userQueryData.currentUser.currentUserWorkspace,
|
||||
objectsPermissions:
|
||||
(queryData.currentUser.currentUserWorkspace
|
||||
(userQueryData.currentUser.currentUserWorkspace
|
||||
.objectsPermissions as Array<
|
||||
ObjectPermissions & { objectMetadataId: string }
|
||||
>) ?? [],
|
||||
});
|
||||
}
|
||||
|
||||
if (isDefined(queryData.currentUser?.currentWorkspace?.views)) {
|
||||
setCoreViews(queryData.currentUser.currentWorkspace.views);
|
||||
}
|
||||
|
||||
const {
|
||||
workspaceMember,
|
||||
workspaceMembers,
|
||||
deletedWorkspaceMembers,
|
||||
availableWorkspaces,
|
||||
} = queryData.currentUser;
|
||||
} = userQueryData.currentUser;
|
||||
|
||||
const affectDefaultValuesOnEmptyWorkspaceMemberFields = (
|
||||
workspaceMember: WorkspaceMember,
|
||||
@@ -168,8 +173,8 @@ export const UserProviderEffect = () => {
|
||||
setAvailableWorkspaces(availableWorkspaces);
|
||||
}
|
||||
}, [
|
||||
queryLoading,
|
||||
queryData?.currentUser,
|
||||
userQueryLoading,
|
||||
userQueryData?.currentUser,
|
||||
setCurrentUser,
|
||||
setCurrentUserWorkspace,
|
||||
setCurrentWorkspaceMembers,
|
||||
@@ -183,5 +188,11 @@ export const UserProviderEffect = () => {
|
||||
setCoreViews,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDefined(queryDataCoreViews?.getCoreViews)) return;
|
||||
|
||||
setCoreViews(queryDataCoreViews.getCoreViews);
|
||||
}, [queryDataCoreViews?.getCoreViews, setCoreViews]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@@ -4,14 +4,13 @@ import {
|
||||
} from '@/auth/graphql/fragments/authFragments';
|
||||
import { OBJECT_PERMISSION_FRAGMENT } from '@/settings/roles/graphql/fragments/objectPermissionFragment';
|
||||
import { ROLE_FRAGMENT } from '@/settings/roles/graphql/fragments/roleFragment';
|
||||
import { BILLING_SUBSCRIPTION_FRAGMENT } from '@/users/graphql/fragments/billingSubscriptionsFragment';
|
||||
import { CURRENT_BILLING_SUBSCRIPTION_FRAGMENT } from '@/users/graphql/fragments/currentBillingSubscriptionFragement';
|
||||
import { WORKSPACE_URLS_FRAGMENT } from '@/users/graphql/fragments/workspaceUrlsFragment';
|
||||
import { VIEW_FRAGMENT } from '@/views/graphql/fragments/viewFragment';
|
||||
import { DELETED_WORKSPACE_MEMBER_QUERY_FRAGMENT } from '@/workspace-member/graphql/fragments/deletedWorkspaceMemberQueryFragment';
|
||||
import { PARTIAL_WORKSPACE_MEMBER_QUERY_FRAGMENT } from '@/workspace-member/graphql/fragments/partialWorkspaceMemberQueryFragment';
|
||||
import { WORKSPACE_MEMBER_QUERY_FRAGMENT } from '@/workspace-member/graphql/fragments/workspaceMemberQueryFragment';
|
||||
import { gql } from '@apollo/client';
|
||||
import { CURRENT_BILLING_SUBSCRIPTION_FRAGMENT } from '@/users/graphql/fragments/currentBillingSubscriptionFragement';
|
||||
import { BILLING_SUBSCRIPTION_FRAGMENT } from '@/users/graphql/fragments/billingSubscriptionsFragment';
|
||||
|
||||
export const USER_QUERY_FRAGMENT = gql`
|
||||
fragment UserQueryFragment on User {
|
||||
@@ -80,9 +79,6 @@ export const USER_QUERY_FRAGMENT = gql`
|
||||
id
|
||||
}
|
||||
isTwoFactorAuthenticationEnforced
|
||||
views {
|
||||
...ViewFragment
|
||||
}
|
||||
}
|
||||
availableWorkspaces {
|
||||
...AvailableWorkspacesFragment
|
||||
@@ -96,7 +92,6 @@ export const USER_QUERY_FRAGMENT = gql`
|
||||
${OBJECT_PERMISSION_FRAGMENT}
|
||||
${WORKSPACE_URLS_FRAGMENT}
|
||||
${ROLE_FRAGMENT}
|
||||
${VIEW_FRAGMENT}
|
||||
${AVAILABLE_WORKSPACES_FOR_AUTH_FRAGMENT}
|
||||
${AVAILABLE_WORKSPACE_FOR_AUTH_FRAGMENT}
|
||||
${CURRENT_BILLING_SUBSCRIPTION_FRAGMENT}
|
||||
|
||||
@@ -14,7 +14,10 @@ import { SOURCE_LOCALE, type APP_LOCALES } from 'twenty-shared/translations';
|
||||
import { type ObjectPermissions } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type ColorScheme } from 'twenty-ui/input';
|
||||
import { useGetCurrentUserLazyQuery } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
useFindAllCoreViewsLazyQuery,
|
||||
useGetCurrentUserLazyQuery,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||
import { dynamicActivate } from '~/utils/i18n/dynamicActivate';
|
||||
|
||||
@@ -37,12 +40,17 @@ export const useLoadCurrentUser = () => {
|
||||
const { isOnAWorkspace } = useIsCurrentLocationOnAWorkspace();
|
||||
|
||||
const [getCurrentUser] = useGetCurrentUserLazyQuery();
|
||||
const [findAllCoreViews] = useFindAllCoreViewsLazyQuery();
|
||||
|
||||
const loadCurrentUser = useCallback(async () => {
|
||||
const currentUserResult = await getCurrentUser({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
const coreViewsResult = await findAllCoreViews({
|
||||
fetchPolicy: 'network-only',
|
||||
});
|
||||
|
||||
if (isDefined(currentUserResult.error)) {
|
||||
throw new Error(currentUserResult.error.message);
|
||||
}
|
||||
@@ -102,8 +110,8 @@ export const useLoadCurrentUser = () => {
|
||||
});
|
||||
}
|
||||
|
||||
if (isDefined(workspace) && isDefined(workspace.views)) {
|
||||
setCoreViews(workspace.views);
|
||||
if (isDefined(coreViewsResult.data?.getCoreViews)) {
|
||||
setCoreViews(coreViewsResult.data.getCoreViews);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -113,16 +121,17 @@ export const useLoadCurrentUser = () => {
|
||||
};
|
||||
}, [
|
||||
getCurrentUser,
|
||||
isOnAWorkspace,
|
||||
setAvailableWorkspaces,
|
||||
setCoreViews,
|
||||
findAllCoreViews,
|
||||
setCurrentUser,
|
||||
setCurrentUserWorkspace,
|
||||
setCurrentWorkspace,
|
||||
setCurrentWorkspaceMember,
|
||||
isOnAWorkspace,
|
||||
setCurrentWorkspaceMembers,
|
||||
setAvailableWorkspaces,
|
||||
setCurrentUserWorkspace,
|
||||
setCurrentWorkspaceMember,
|
||||
initializeFormatPreferences,
|
||||
setLastAuthenticateWorkspaceDomain,
|
||||
setCoreViews,
|
||||
]);
|
||||
|
||||
return {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { VIEW_FRAGMENT } from '@/views/graphql/fragments/viewFragment';
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const FIND_ALL_CORE_VIEWS = gql`
|
||||
${VIEW_FRAGMENT}
|
||||
query FindAllCoreViews {
|
||||
getCoreViews {
|
||||
...ViewFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
+6
-2
@@ -1,6 +1,7 @@
|
||||
import { anyFieldFilterValueComponentState } from '@/object-record/record-filter/states/anyFieldFilterValueComponentState';
|
||||
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
|
||||
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { compareNonEmptyStrings } from '~/utils/compareNonEmptyStrings';
|
||||
|
||||
export const useIsViewAnyFieldFilterDifferentFromCurrentAnyFieldFilter = () => {
|
||||
@@ -11,8 +12,11 @@ export const useIsViewAnyFieldFilterDifferentFromCurrentAnyFieldFilter = () => {
|
||||
|
||||
const viewAnyFieldFilterValue = currentView?.anyFieldFilterValue;
|
||||
|
||||
const viewAnyFieldFilterDifferentFromCurrentAnyFieldFilter =
|
||||
!compareNonEmptyStrings(viewAnyFieldFilterValue, anyFieldFilterValue);
|
||||
const viewAnyFieldFilterDifferentFromCurrentAnyFieldFilter = isNonEmptyString(
|
||||
anyFieldFilterValue,
|
||||
)
|
||||
? !compareNonEmptyStrings(viewAnyFieldFilterValue, anyFieldFilterValue)
|
||||
: isNonEmptyString(viewAnyFieldFilterValue);
|
||||
|
||||
return { viewAnyFieldFilterDifferentFromCurrentAnyFieldFilter };
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ClientConfigProviderEffect } from '@/client-config/components/ClientCon
|
||||
import { ApolloCoreClientMockedProvider } from '@/object-metadata/hooks/__mocks__/ApolloCoreClientMockedProvider';
|
||||
|
||||
import { DefaultLayout } from '@/ui/layout/page/components/DefaultLayout';
|
||||
import { UserProviderEffect } from '@/users/components/UserProviderEffect';
|
||||
import { UserAndViewsProviderEffect } from '@/users/components/UserAndViewsProviderEffect';
|
||||
import { ClientConfigProvider } from '~/modules/client-config/components/ClientConfigProvider';
|
||||
import { UserProvider } from '~/modules/users/components/UserProvider';
|
||||
import { mockedApolloClient } from '~/testing/mockedApolloClient';
|
||||
@@ -85,7 +85,7 @@ const Providers = () => {
|
||||
<ApolloStorybookDevLogEffect />
|
||||
<ClientConfigProviderEffect />
|
||||
<ClientConfigProvider>
|
||||
<UserProviderEffect />
|
||||
<UserAndViewsProviderEffect />
|
||||
<WorkspaceProviderEffect />
|
||||
<UserProvider>
|
||||
<ApolloCoreClientMockedProvider>
|
||||
|
||||
@@ -44,7 +44,7 @@ export const metadataModuleFactory = async (
|
||||
useCachedMetadata({
|
||||
cacheGetter: cacheStorageService.get.bind(cacheStorageService),
|
||||
cacheSetter: cacheStorageService.set.bind(cacheStorageService),
|
||||
operationsToCache: ['ObjectMetadataItems'],
|
||||
operationsToCache: ['ObjectMetadataItems', 'FindAllCoreViews'],
|
||||
}),
|
||||
],
|
||||
path: '/metadata',
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ export class CacheStorageService {
|
||||
|
||||
do {
|
||||
const result = await redisClient.scan(cursor, {
|
||||
MATCH: scanPattern,
|
||||
MATCH: `${this.namespace}:${scanPattern}`,
|
||||
COUNT: 100,
|
||||
});
|
||||
|
||||
|
||||
+1
@@ -53,6 +53,7 @@ describe('ViewFieldService', () => {
|
||||
provide: ViewService,
|
||||
useValue: {
|
||||
findByIdWithRelatedObjectMetadata: jest.fn(),
|
||||
flushGraphQLCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
+7
@@ -13,6 +13,7 @@ import {
|
||||
generateViewFilterGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-filter-group.exception';
|
||||
import { ViewFilterGroupService } from 'src/engine/core-modules/view/services/view-filter-group.service';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
describe('ViewFilterGroupService', () => {
|
||||
let viewFilterGroupService: ViewFilterGroupService;
|
||||
@@ -44,6 +45,12 @@ describe('ViewFilterGroupService', () => {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ViewService,
|
||||
useValue: {
|
||||
flushGraphQLCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
+7
@@ -13,6 +13,7 @@ import {
|
||||
generateViewFilterUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-filter.exception';
|
||||
import { ViewFilterService } from 'src/engine/core-modules/view/services/view-filter.service';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
describe('ViewFilterService', () => {
|
||||
let viewFilterService: ViewFilterService;
|
||||
@@ -35,6 +36,12 @@ describe('ViewFilterService', () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
ViewFilterService,
|
||||
{
|
||||
provide: ViewService,
|
||||
useValue: {
|
||||
flushGraphQLCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(ViewFilterEntity),
|
||||
useValue: {
|
||||
|
||||
+7
@@ -12,6 +12,7 @@ import {
|
||||
generateViewGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-group.exception';
|
||||
import { ViewGroupService } from 'src/engine/core-modules/view/services/view-group.service';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
describe('ViewGroupService', () => {
|
||||
let viewGroupService: ViewGroupService;
|
||||
@@ -45,6 +46,12 @@ describe('ViewGroupService', () => {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ViewService,
|
||||
useValue: {
|
||||
flushGraphQLCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
+7
@@ -13,6 +13,7 @@ import {
|
||||
generateViewSortUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-sort.exception';
|
||||
import { ViewSortService } from 'src/engine/core-modules/view/services/view-sort.service';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
describe('ViewSortService', () => {
|
||||
let viewSortService: ViewSortService;
|
||||
@@ -44,6 +45,12 @@ describe('ViewSortService', () => {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: ViewService,
|
||||
useValue: {
|
||||
flushGraphQLCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
|
||||
+7
@@ -15,6 +15,7 @@ import {
|
||||
generateViewUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view.exception';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
describe('ViewService', () => {
|
||||
let viewService: ViewService;
|
||||
@@ -56,6 +57,12 @@ describe('ViewService', () => {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceCacheStorageService,
|
||||
useValue: {
|
||||
flushGraphQLOperation: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: I18nService,
|
||||
useValue: {
|
||||
|
||||
@@ -95,6 +95,9 @@ export class ViewFieldService {
|
||||
);
|
||||
|
||||
const savedViewField = await this.viewFieldRepository.save(viewField);
|
||||
|
||||
await this.viewService.flushGraphQLCache(viewFieldData.workspaceId);
|
||||
|
||||
const createdViewField = await this.findById(
|
||||
savedViewField.id,
|
||||
viewFieldData.workspaceId,
|
||||
@@ -223,6 +226,8 @@ export class ViewFieldService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewField, ...updatedViewField };
|
||||
}
|
||||
|
||||
@@ -241,6 +246,8 @@ export class ViewFieldService {
|
||||
|
||||
await this.viewFieldRepository.softDelete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewField;
|
||||
}
|
||||
|
||||
@@ -259,6 +266,8 @@ export class ViewFieldService {
|
||||
|
||||
await this.viewFieldRepository.delete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewField;
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -12,12 +12,14 @@ import {
|
||||
generateViewFilterGroupExceptionMessage,
|
||||
generateViewFilterGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-filter-group.exception';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFilterGroupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterGroupEntity)
|
||||
private readonly viewFilterGroupRepository: Repository<ViewFilterGroupEntity>,
|
||||
private readonly viewService: ViewService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(
|
||||
@@ -118,7 +120,14 @@ export class ViewFilterGroupService {
|
||||
const viewFilterGroup =
|
||||
this.viewFilterGroupRepository.create(viewFilterGroupData);
|
||||
|
||||
return this.viewFilterGroupRepository.save(viewFilterGroup);
|
||||
await this.viewService.flushGraphQLCache(viewFilterGroupData.workspaceId);
|
||||
|
||||
const savedViewFilterGroup =
|
||||
await this.viewFilterGroupRepository.save(viewFilterGroup);
|
||||
|
||||
await this.viewService.flushGraphQLCache(viewFilterGroupData.workspaceId);
|
||||
|
||||
return savedViewFilterGroup;
|
||||
}
|
||||
|
||||
async update(
|
||||
@@ -143,6 +152,8 @@ export class ViewFilterGroupService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewFilterGroup, ...updatedViewFilterGroup };
|
||||
}
|
||||
|
||||
@@ -182,6 +193,8 @@ export class ViewFilterGroupService {
|
||||
|
||||
await this.viewFilterGroupRepository.delete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-1
@@ -12,12 +12,14 @@ import {
|
||||
generateViewFilterExceptionMessage,
|
||||
generateViewFilterUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-filter.exception';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewFilterService {
|
||||
constructor(
|
||||
@InjectRepository(ViewFilterEntity)
|
||||
private readonly viewFilterRepository: Repository<ViewFilterEntity>,
|
||||
private readonly viewService: ViewService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewFilterEntity[]> {
|
||||
@@ -109,7 +111,13 @@ export class ViewFilterService {
|
||||
|
||||
const viewFilter = this.viewFilterRepository.create(viewFilterData);
|
||||
|
||||
return this.viewFilterRepository.save(viewFilter);
|
||||
await this.viewService.flushGraphQLCache(viewFilterData.workspaceId);
|
||||
|
||||
const savedViewFilter = await this.viewFilterRepository.save(viewFilter);
|
||||
|
||||
await this.viewService.flushGraphQLCache(viewFilterData.workspaceId);
|
||||
|
||||
return savedViewFilter;
|
||||
}
|
||||
|
||||
async update(
|
||||
@@ -134,6 +142,8 @@ export class ViewFilterService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewFilter, ...updatedViewFilter };
|
||||
}
|
||||
|
||||
@@ -152,6 +162,8 @@ export class ViewFilterService {
|
||||
|
||||
await this.viewFilterRepository.softDelete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewFilter;
|
||||
}
|
||||
|
||||
@@ -170,6 +182,8 @@ export class ViewFilterService {
|
||||
|
||||
await this.viewFilterRepository.delete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@ import {
|
||||
generateViewGroupExceptionMessage,
|
||||
generateViewGroupUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-group.exception';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewGroupService {
|
||||
constructor(
|
||||
@InjectRepository(ViewGroupEntity)
|
||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||
private readonly viewService: ViewService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewGroupEntity[]> {
|
||||
@@ -109,7 +111,13 @@ export class ViewGroupService {
|
||||
|
||||
const viewGroup = this.viewGroupRepository.create(viewGroupData);
|
||||
|
||||
return this.viewGroupRepository.save(viewGroup);
|
||||
await this.viewService.flushGraphQLCache(viewGroupData.workspaceId);
|
||||
|
||||
const savedViewGroup = await this.viewGroupRepository.save(viewGroup);
|
||||
|
||||
await this.viewService.flushGraphQLCache(viewGroupData.workspaceId);
|
||||
|
||||
return savedViewGroup;
|
||||
}
|
||||
|
||||
async update(
|
||||
@@ -134,6 +142,8 @@ export class ViewGroupService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewGroup, ...updatedViewGroup };
|
||||
}
|
||||
|
||||
@@ -152,6 +162,8 @@ export class ViewGroupService {
|
||||
|
||||
await this.viewGroupRepository.softDelete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewGroup;
|
||||
}
|
||||
|
||||
@@ -170,6 +182,8 @@ export class ViewGroupService {
|
||||
|
||||
await this.viewGroupRepository.delete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@ import {
|
||||
generateViewSortExceptionMessage,
|
||||
generateViewSortUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view-sort.exception';
|
||||
import { ViewService } from 'src/engine/core-modules/view/services/view.service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewSortService {
|
||||
constructor(
|
||||
@InjectRepository(ViewSortEntity)
|
||||
private readonly viewSortRepository: Repository<ViewSortEntity>,
|
||||
private readonly viewService: ViewService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewSortEntity[]> {
|
||||
@@ -105,7 +107,11 @@ export class ViewSortService {
|
||||
|
||||
const viewSort = this.viewSortRepository.create(viewSortData);
|
||||
|
||||
return this.viewSortRepository.save(viewSort);
|
||||
const savedViewSort = await this.viewSortRepository.save(viewSort);
|
||||
|
||||
await this.viewService.flushGraphQLCache(viewSortData.workspaceId);
|
||||
|
||||
return savedViewSort;
|
||||
}
|
||||
|
||||
async update(
|
||||
@@ -130,6 +136,8 @@ export class ViewSortService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingViewSort, ...updatedViewSort };
|
||||
}
|
||||
|
||||
@@ -148,6 +156,8 @@ export class ViewSortService {
|
||||
|
||||
await this.viewSortRepository.softDelete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return viewSort;
|
||||
}
|
||||
|
||||
@@ -166,6 +176,8 @@ export class ViewSortService {
|
||||
|
||||
await this.viewSortRepository.delete(id);
|
||||
|
||||
await this.viewService.flushGraphQLCache(workspaceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
generateViewExceptionMessage,
|
||||
generateViewUserFriendlyExceptionMessage,
|
||||
} from 'src/engine/core-modules/view/exceptions/view.exception';
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
|
||||
@Injectable()
|
||||
export class ViewService {
|
||||
@@ -22,6 +23,7 @@ export class ViewService {
|
||||
@InjectRepository(ViewEntity)
|
||||
private readonly viewRepository: Repository<ViewEntity>,
|
||||
private readonly i18nService: I18nService,
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
) {}
|
||||
|
||||
async findByWorkspaceId(workspaceId: string): Promise<ViewEntity[]> {
|
||||
@@ -134,7 +136,11 @@ export class ViewService {
|
||||
isCustom: true,
|
||||
});
|
||||
|
||||
return this.viewRepository.save(view);
|
||||
const savedView = await this.viewRepository.save(view);
|
||||
|
||||
await this.flushGraphQLCache(viewData.workspaceId);
|
||||
|
||||
return savedView;
|
||||
}
|
||||
|
||||
async update(
|
||||
@@ -159,6 +165,8 @@ export class ViewService {
|
||||
...updateData,
|
||||
});
|
||||
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return { ...existingView, ...updatedView };
|
||||
}
|
||||
|
||||
@@ -177,6 +185,8 @@ export class ViewService {
|
||||
|
||||
await this.viewRepository.softDelete(id);
|
||||
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -194,6 +204,7 @@ export class ViewService {
|
||||
}
|
||||
|
||||
await this.viewRepository.delete(id);
|
||||
await this.flushGraphQLCache(workspaceId);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -235,4 +246,11 @@ export class ViewService {
|
||||
|
||||
return viewName;
|
||||
}
|
||||
|
||||
async flushGraphQLCache(workspaceId: string): Promise<void> {
|
||||
await this.workspaceCacheStorageService.flushGraphQLOperation({
|
||||
operationName: 'FindAllCoreViews',
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -116,6 +116,7 @@ export class FieldMetadataRelatedRecordsService {
|
||||
|
||||
await this.syncNoValueViewGroup(newFieldMetadata, view);
|
||||
}
|
||||
await this.viewService.flushGraphQLCache(newFieldMetadata.workspaceId);
|
||||
}
|
||||
|
||||
public async resetViewKanbanAggregateOperation(
|
||||
@@ -140,6 +141,7 @@ export class FieldMetadataRelatedRecordsService {
|
||||
kanbanAggregateOperation: null,
|
||||
});
|
||||
}
|
||||
await this.viewService.flushGraphQLCache(fieldMetadata.workspaceId);
|
||||
}
|
||||
|
||||
public async updateRelatedViewFilters(
|
||||
@@ -247,6 +249,7 @@ export class FieldMetadataRelatedRecordsService {
|
||||
);
|
||||
}
|
||||
}
|
||||
await this.viewService.flushGraphQLCache(newFieldMetadata.workspaceId);
|
||||
}
|
||||
|
||||
async syncNoValueViewGroup(
|
||||
@@ -274,6 +277,7 @@ export class FieldMetadataRelatedRecordsService {
|
||||
fieldMetadata.workspaceId,
|
||||
);
|
||||
}
|
||||
await this.viewService.flushGraphQLCache(fieldMetadata.workspaceId);
|
||||
}
|
||||
|
||||
public getOptionsDifferences(
|
||||
|
||||
+1
@@ -34,6 +34,7 @@ export class ObjectMetadataRelatedRecordsService {
|
||||
|
||||
await this.createViewFields(objectMetadata, view.id);
|
||||
await this.createViewWorkspaceFavorite(objectMetadata.workspaceId, view.id);
|
||||
await this.viewService.flushGraphQLCache(objectMetadata.workspaceId);
|
||||
}
|
||||
|
||||
public async updateLabelMetadataIdentifierInObjectViews({
|
||||
|
||||
+12
@@ -221,6 +221,18 @@ export class WorkspaceCacheStorageService {
|
||||
);
|
||||
}
|
||||
|
||||
async flushGraphQLOperation({
|
||||
operationName,
|
||||
workspaceId,
|
||||
}: {
|
||||
operationName: string;
|
||||
workspaceId: string;
|
||||
}): Promise<void> {
|
||||
await this.cacheStorageService.flushByPattern(
|
||||
`${WorkspaceCacheKeys.GraphQLOperations}:${operationName}:${workspaceId}:*`,
|
||||
);
|
||||
}
|
||||
|
||||
async flushVersionedMetadata(
|
||||
workspaceId: string,
|
||||
metadataVersion?: number,
|
||||
|
||||
Reference in New Issue
Block a user