When exporting a kanban we should export the kanban's main field (#6444)
This PR was created by [GitStart](https://gitstart.com/) to address the requirements from this ticket: [TWNTY-6046](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-6046). This ticket was imported from: [TWNTY-6046](https://github.com/twentyhq/twenty/issues/6046) --- ### Description - We are getting the `kanbanFieldMetadataNameState` , get the column data, and if there is data and the use is on the Kanban view we add the data to the result ### Refs #6046 ### Demo <https://jam.dev/c/96f16211-40e4-4b49-a6f5-88f0692fb47a> Fixes #6046 --------- Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: gitstart-twenty <140154534+gitstart-twenty@users.noreply.github.com> Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
This commit is contained in:
committed by
GitHub
parent
f2cc385710
commit
a2a5ab488c
@ -125,6 +125,7 @@ export const RecordIndexOptionsDropdownContent = ({
|
|||||||
filename: `${objectNameSingular}.csv`,
|
filename: `${objectNameSingular}.csv`,
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
|
viewType,
|
||||||
});
|
});
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|||||||
@ -0,0 +1,379 @@
|
|||||||
|
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
|
||||||
|
import { act, renderHook, waitFor } from '@testing-library/react';
|
||||||
|
import { percentage, sleep, useTableData } from '../useTableData';
|
||||||
|
|
||||||
|
import { useRecordBoard } from '@/object-record/record-board/hooks/useRecordBoard';
|
||||||
|
import { recordBoardKanbanFieldMetadataNameComponentState } from '@/object-record/record-board/states/recordBoardKanbanFieldMetadataNameComponentState';
|
||||||
|
import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard';
|
||||||
|
import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState';
|
||||||
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
|
import { MockedProvider, MockedResponse } from '@apollo/client/testing';
|
||||||
|
import gql from 'graphql-tag';
|
||||||
|
import { ReactNode } from 'react';
|
||||||
|
import { BrowserRouter as Router } from 'react-router-dom';
|
||||||
|
import { RecoilRoot, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
const defaultResponseData = {
|
||||||
|
pageInfo: {
|
||||||
|
hasNextPage: false,
|
||||||
|
hasPreviousPage: false,
|
||||||
|
startCursor: '',
|
||||||
|
endCursor: '',
|
||||||
|
},
|
||||||
|
totalCount: 1,
|
||||||
|
};
|
||||||
|
const mockPerson = {
|
||||||
|
__typename: 'Person',
|
||||||
|
updatedAt: '2021-08-03T19:20:06.000Z',
|
||||||
|
myCustomObjectId: '123',
|
||||||
|
whatsapp: '123',
|
||||||
|
linkedinLink: {
|
||||||
|
primaryLinkUrl: 'https://www.linkedin.com',
|
||||||
|
primaryLinkLabel: 'linkedin',
|
||||||
|
secondaryLinks: ['https://www.linkedin.com'],
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
firstName: 'firstName',
|
||||||
|
lastName: 'lastName',
|
||||||
|
},
|
||||||
|
email: 'email',
|
||||||
|
position: 'position',
|
||||||
|
createdBy: {
|
||||||
|
source: 'source',
|
||||||
|
workspaceMemberId: '1',
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
avatarUrl: 'avatarUrl',
|
||||||
|
jobTitle: 'jobTitle',
|
||||||
|
xLink: {
|
||||||
|
primaryLinkUrl: 'https://www.linkedin.com',
|
||||||
|
primaryLinkLabel: 'linkedin',
|
||||||
|
secondaryLinks: ['https://www.linkedin.com'],
|
||||||
|
},
|
||||||
|
performanceRating: 1,
|
||||||
|
createdAt: '2021-08-03T19:20:06.000Z',
|
||||||
|
phone: 'phone',
|
||||||
|
id: '123',
|
||||||
|
city: 'city',
|
||||||
|
companyId: '1',
|
||||||
|
intro: 'intro',
|
||||||
|
workPrefereance: 'workPrefereance',
|
||||||
|
};
|
||||||
|
const mocks: MockedResponse[] = [
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
query: gql`
|
||||||
|
query FindManyPeople(
|
||||||
|
$filter: PersonFilterInput
|
||||||
|
$orderBy: [PersonOrderByInput]
|
||||||
|
$lastCursor: String
|
||||||
|
$limit: Int
|
||||||
|
) {
|
||||||
|
people(
|
||||||
|
filter: $filter
|
||||||
|
orderBy: $orderBy
|
||||||
|
first: $limit
|
||||||
|
after: $lastCursor
|
||||||
|
) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
__typename
|
||||||
|
updatedAt
|
||||||
|
myCustomObjectId
|
||||||
|
whatsapp
|
||||||
|
linkedinLink {
|
||||||
|
primaryLinkUrl
|
||||||
|
primaryLinkLabel
|
||||||
|
secondaryLinks
|
||||||
|
}
|
||||||
|
name {
|
||||||
|
firstName
|
||||||
|
lastName
|
||||||
|
}
|
||||||
|
email
|
||||||
|
position
|
||||||
|
createdBy {
|
||||||
|
source
|
||||||
|
workspaceMemberId
|
||||||
|
name
|
||||||
|
}
|
||||||
|
avatarUrl
|
||||||
|
jobTitle
|
||||||
|
xLink {
|
||||||
|
primaryLinkUrl
|
||||||
|
primaryLinkLabel
|
||||||
|
secondaryLinks
|
||||||
|
}
|
||||||
|
performanceRating
|
||||||
|
createdAt
|
||||||
|
phone
|
||||||
|
id
|
||||||
|
city
|
||||||
|
companyId
|
||||||
|
intro
|
||||||
|
workPrefereance
|
||||||
|
}
|
||||||
|
cursor
|
||||||
|
}
|
||||||
|
pageInfo {
|
||||||
|
hasNextPage
|
||||||
|
hasPreviousPage
|
||||||
|
startCursor
|
||||||
|
endCursor
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
variables: {
|
||||||
|
filter: undefined,
|
||||||
|
limit: 30,
|
||||||
|
orderBy: [{ position: 'AscNullsFirst' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
people: {
|
||||||
|
...defaultResponseData,
|
||||||
|
edges: [
|
||||||
|
{
|
||||||
|
node: mockPerson,
|
||||||
|
cursor: '1',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: ReactNode }) => (
|
||||||
|
<Router>
|
||||||
|
<RecoilRoot>
|
||||||
|
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||||
|
<MockedProvider addTypename={false} mocks={mocks}>
|
||||||
|
{children}
|
||||||
|
</MockedProvider>
|
||||||
|
</SnackBarProviderScope>
|
||||||
|
</RecoilRoot>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
|
||||||
|
const graphqlEmptyResponse = [
|
||||||
|
{
|
||||||
|
...mocks[0],
|
||||||
|
result: jest.fn(() => ({
|
||||||
|
data: {
|
||||||
|
people: {
|
||||||
|
...defaultResponseData,
|
||||||
|
edges: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const WrapperWithEmptyResponse = ({ children }: { children: ReactNode }) => (
|
||||||
|
<Router>
|
||||||
|
<RecoilRoot>
|
||||||
|
<SnackBarProviderScope snackBarManagerScopeId="snack-bar-manager">
|
||||||
|
<MockedProvider addTypename={false} mocks={graphqlEmptyResponse}>
|
||||||
|
{children}
|
||||||
|
</MockedProvider>
|
||||||
|
</SnackBarProviderScope>
|
||||||
|
</RecoilRoot>
|
||||||
|
</Router>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useTableData', () => {
|
||||||
|
const recordIndexId = 'people';
|
||||||
|
const objectNameSingular = 'person';
|
||||||
|
describe('data fetching', () => {
|
||||||
|
it('should handle no records', async () => {
|
||||||
|
const callback = jest.fn();
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useTableData({
|
||||||
|
recordIndexId,
|
||||||
|
objectNameSingular,
|
||||||
|
callback,
|
||||||
|
|
||||||
|
delayMs: 0,
|
||||||
|
viewType: ViewType.Kanban,
|
||||||
|
}),
|
||||||
|
{ wrapper: WrapperWithEmptyResponse },
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.getTableData();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(callback).toHaveBeenCalledWith([], []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the callback function with fetched data', async () => {
|
||||||
|
const callback = jest.fn();
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useTableData({
|
||||||
|
recordIndexId,
|
||||||
|
objectNameSingular,
|
||||||
|
callback,
|
||||||
|
|
||||||
|
delayMs: 0,
|
||||||
|
}),
|
||||||
|
{ wrapper: Wrapper },
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.getTableData();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(callback).toHaveBeenCalledWith([mockPerson], []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the callback function with kanban field included as column if view type is kanban', async () => {
|
||||||
|
const callback = jest.fn();
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const kanbanFieldNameState = extractComponentState(
|
||||||
|
recordBoardKanbanFieldMetadataNameComponentState,
|
||||||
|
recordIndexId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
tableData: useTableData({
|
||||||
|
recordIndexId,
|
||||||
|
objectNameSingular,
|
||||||
|
callback,
|
||||||
|
pageSize: 30,
|
||||||
|
maximumRequests: 100,
|
||||||
|
delayMs: 0,
|
||||||
|
viewType: ViewType.Kanban,
|
||||||
|
}),
|
||||||
|
setKanbanFieldName: useRecordBoard(recordIndexId),
|
||||||
|
kanbanFieldName: useRecoilValue(kanbanFieldNameState),
|
||||||
|
kanbanData: useRecordIndexOptionsForBoard({
|
||||||
|
objectNameSingular,
|
||||||
|
recordBoardId: recordIndexId,
|
||||||
|
viewBarId: recordIndexId,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.setKanbanFieldName.setKanbanFieldMetadataName(
|
||||||
|
result.current.kanbanData.hiddenBoardFields[0].metadata.fieldName,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.tableData.getTableData();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(callback).toHaveBeenCalledWith(
|
||||||
|
[mockPerson],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
defaultValue: 'now',
|
||||||
|
editButtonIcon: undefined,
|
||||||
|
fieldMetadataId: '102963b7-3e77-4293-a1e6-1ab59a02b663',
|
||||||
|
iconName: 'IconCalendarClock',
|
||||||
|
isFilterable: true,
|
||||||
|
isLabelIdentifier: false,
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: false,
|
||||||
|
label: 'Last update',
|
||||||
|
labelWidth: undefined,
|
||||||
|
metadata: {
|
||||||
|
fieldName: 'updatedAt',
|
||||||
|
isNullable: false,
|
||||||
|
objectMetadataNameSingular: 'person',
|
||||||
|
options: null,
|
||||||
|
placeHolder: 'Last update',
|
||||||
|
relationFieldMetadataId: undefined,
|
||||||
|
relationObjectMetadataNamePlural: '',
|
||||||
|
relationObjectMetadataNameSingular: '',
|
||||||
|
relationType: undefined,
|
||||||
|
targetFieldMetadataName: '',
|
||||||
|
},
|
||||||
|
position: 0,
|
||||||
|
showLabel: undefined,
|
||||||
|
size: 100,
|
||||||
|
type: 'DATE_TIME',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not call the callback function with kanban field included as column if view type is table', async () => {
|
||||||
|
const callback = jest.fn();
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const kanbanFieldNameState = extractComponentState(
|
||||||
|
recordBoardKanbanFieldMetadataNameComponentState,
|
||||||
|
recordIndexId,
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
tableData: useTableData({
|
||||||
|
recordIndexId,
|
||||||
|
objectNameSingular,
|
||||||
|
callback,
|
||||||
|
pageSize: 30,
|
||||||
|
maximumRequests: 100,
|
||||||
|
delayMs: 0,
|
||||||
|
viewType: ViewType.Table,
|
||||||
|
}),
|
||||||
|
setKanbanFieldName: useRecordBoard(recordIndexId),
|
||||||
|
kanbanFieldName: useRecoilValue(kanbanFieldNameState),
|
||||||
|
kanbanData: useRecordIndexOptionsForBoard({
|
||||||
|
objectNameSingular,
|
||||||
|
recordBoardId: recordIndexId,
|
||||||
|
viewBarId: recordIndexId,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.setKanbanFieldName.setKanbanFieldMetadataName(
|
||||||
|
result.current.kanbanData.hiddenBoardFields[0].metadata.fieldName,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
result.current.tableData.getTableData();
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitFor(async () => {
|
||||||
|
expect(callback).toHaveBeenCalledWith([mockPerson], []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('utils', () => {
|
||||||
|
it('should correctly calculate percentage', () => {
|
||||||
|
expect(percentage(50, 200)).toBe(25);
|
||||||
|
expect(percentage(1, 3)).toBe(33);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should resolve sleep after given time', async () => {
|
||||||
|
jest.useFakeTimers();
|
||||||
|
const sleepPromise = sleep(1000);
|
||||||
|
jest.advanceTimersByTime(1000);
|
||||||
|
await expect(sleepPromise).resolves.toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -143,6 +143,7 @@ export const useExportTableData = ({
|
|||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
pageSize = 30,
|
pageSize = 30,
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
|
viewType,
|
||||||
}: UseExportTableDataOptions) => {
|
}: UseExportTableDataOptions) => {
|
||||||
const { processRecordsForCSVExport } =
|
const { processRecordsForCSVExport } =
|
||||||
useProcessRecordsForCSVExport(objectNameSingular);
|
useProcessRecordsForCSVExport(objectNameSingular);
|
||||||
@ -164,6 +165,7 @@ export const useExportTableData = ({
|
|||||||
pageSize,
|
pageSize,
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
callback: downloadCsv,
|
callback: downloadCsv,
|
||||||
|
viewType,
|
||||||
});
|
});
|
||||||
|
|
||||||
return { progress, download };
|
return { progress, download };
|
||||||
|
|||||||
@ -8,6 +8,9 @@ import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefin
|
|||||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
|
|
||||||
|
import { useRecordBoardStates } from '@/object-record/record-board/hooks/internal/useRecordBoardStates';
|
||||||
|
import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard';
|
||||||
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { useFindManyParams } from '../../hooks/useLoadRecordIndexTable';
|
import { useFindManyParams } from '../../hooks/useLoadRecordIndexTable';
|
||||||
|
|
||||||
export const sleep = (ms: number) =>
|
export const sleep = (ms: number) =>
|
||||||
@ -27,6 +30,7 @@ export type UseTableDataOptions = {
|
|||||||
rows: ObjectRecord[],
|
rows: ObjectRecord[],
|
||||||
columns: ColumnDefinition<FieldMetadata>[],
|
columns: ColumnDefinition<FieldMetadata>[],
|
||||||
) => void | Promise<void>;
|
) => void | Promise<void>;
|
||||||
|
viewType?: ViewType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ExportProgress = {
|
type ExportProgress = {
|
||||||
@ -42,6 +46,7 @@ export const useTableData = ({
|
|||||||
pageSize = 30,
|
pageSize = 30,
|
||||||
recordIndexId,
|
recordIndexId,
|
||||||
callback,
|
callback,
|
||||||
|
viewType = ViewType.Table,
|
||||||
}: UseTableDataOptions) => {
|
}: UseTableDataOptions) => {
|
||||||
const [isDownloading, setIsDownloading] = useState(false);
|
const [isDownloading, setIsDownloading] = useState(false);
|
||||||
const [inflight, setInflight] = useState(false);
|
const [inflight, setInflight] = useState(false);
|
||||||
@ -58,6 +63,17 @@ export const useTableData = ({
|
|||||||
hasUserSelectedAllRowsState,
|
hasUserSelectedAllRowsState,
|
||||||
} = useRecordTableStates(recordIndexId);
|
} = useRecordTableStates(recordIndexId);
|
||||||
|
|
||||||
|
const { hiddenBoardFields } = useRecordIndexOptionsForBoard({
|
||||||
|
objectNameSingular,
|
||||||
|
recordBoardId: recordIndexId,
|
||||||
|
viewBarId: recordIndexId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { kanbanFieldMetadataNameState } = useRecordBoardStates(recordIndexId);
|
||||||
|
const kanbanFieldMetadataName = useRecoilValue(kanbanFieldMetadataNameState);
|
||||||
|
const hiddenKanbanFieldColumn = hiddenBoardFields.find(
|
||||||
|
(column) => column.metadata.fieldName === kanbanFieldMetadataName,
|
||||||
|
);
|
||||||
const columns = useRecoilValue(visibleTableColumnsSelector());
|
const columns = useRecoilValue(visibleTableColumnsSelector());
|
||||||
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
|
const selectedRowIds = useRecoilValue(selectedRowIdsSelector());
|
||||||
|
|
||||||
@ -165,7 +181,14 @@ export const useTableData = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const res = callback(records, columns);
|
const finalColumns = [
|
||||||
|
...columns,
|
||||||
|
...(hiddenKanbanFieldColumn && viewType === ViewType.Kanban
|
||||||
|
? [hiddenKanbanFieldColumn]
|
||||||
|
: []),
|
||||||
|
];
|
||||||
|
|
||||||
|
const res = callback(records, finalColumns);
|
||||||
|
|
||||||
if (res instanceof Promise) {
|
if (res instanceof Promise) {
|
||||||
res.then(complete);
|
res.then(complete);
|
||||||
@ -189,6 +212,8 @@ export const useTableData = ({
|
|||||||
loading,
|
loading,
|
||||||
callback,
|
callback,
|
||||||
previousRecordCount,
|
previousRecordCount,
|
||||||
|
hiddenKanbanFieldColumn,
|
||||||
|
viewType,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import { CaptchaDriverType } from '~/generated/graphql';
|
|
||||||
import { ClientConfig } from '~/generated-metadata/graphql';
|
import { ClientConfig } from '~/generated-metadata/graphql';
|
||||||
|
import { CaptchaDriverType } from '~/generated/graphql';
|
||||||
|
|
||||||
export const mockedClientConfig: ClientConfig = {
|
export const mockedClientConfig: ClientConfig = {
|
||||||
signInPrefilled: true,
|
signInPrefilled: true,
|
||||||
signUpDisabled: false,
|
signUpDisabled: false,
|
||||||
|
chromeExtensionId: 'MOCKED_EXTENSION_ID',
|
||||||
debugMode: false,
|
debugMode: false,
|
||||||
authProviders: {
|
authProviders: {
|
||||||
google: true,
|
google: true,
|
||||||
|
|||||||
@ -6,6 +6,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
Workspace,
|
Workspace,
|
||||||
WorkspaceActivationStatus,
|
WorkspaceActivationStatus,
|
||||||
|
WorkspaceMemberDateFormatEnum,
|
||||||
|
WorkspaceMemberTimeFormatEnum,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
type MockedUser = Pick<
|
type MockedUser = Pick<
|
||||||
@ -85,6 +87,9 @@ export const mockedWorkspaceMemberData: WorkspaceMember = {
|
|||||||
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
updatedAt: '2023-04-26T10:23:42.33625+00:00',
|
||||||
userId: '2603c1f9-0172-4ea6-986c-eeaccdf7f4cf',
|
userId: '2603c1f9-0172-4ea6-986c-eeaccdf7f4cf',
|
||||||
userEmail: 'charles@test.com',
|
userEmail: 'charles@test.com',
|
||||||
|
dateFormat: WorkspaceMemberDateFormatEnum.DayFirst,
|
||||||
|
timeFormat: WorkspaceMemberTimeFormatEnum.Hour_24,
|
||||||
|
timeZone: 'America/New_York',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const mockedUserData: MockedUser = {
|
export const mockedUserData: MockedUser = {
|
||||||
|
|||||||
@ -18,9 +18,9 @@ import {
|
|||||||
SaveOptions,
|
SaveOptions,
|
||||||
UpdateResult,
|
UpdateResult,
|
||||||
} from 'typeorm';
|
} from 'typeorm';
|
||||||
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
|
|
||||||
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||||
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
import { UpsertOptions } from 'typeorm/repository/UpsertOptions';
|
||||||
|
import { PickKeysByType } from 'typeorm/common/PickKeysByType';
|
||||||
|
|
||||||
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
import { WorkspaceInternalContext } from 'src/engine/twenty-orm/interfaces/workspace-internal-context.interface';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user