Fix various bugs before 0.2.2 (#3118)
* Fix various bugs before 0.2.2 release * Additional fixes * More fixes * Fixes
This commit is contained in:
@ -28,7 +28,6 @@ export const ActivityBodyEditor = ({
|
|||||||
const [body, setBody] = useState<string | null>(null);
|
const [body, setBody] = useState<string | null>(null);
|
||||||
const { updateOneRecord } = useUpdateOneRecord({
|
const { updateOneRecord } = useUpdateOneRecord({
|
||||||
objectNameSingular: 'activity',
|
objectNameSingular: 'activity',
|
||||||
refetchFindManyQuery: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -82,7 +82,6 @@ export const ActivityEditor = ({
|
|||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { updateOneRecord: updateOneActivity } = useUpdateOneRecord<Activity>({
|
const { updateOneRecord: updateOneActivity } = useUpdateOneRecord<Activity>({
|
||||||
objectNameSingular: 'activity',
|
objectNameSingular: 'activity',
|
||||||
refetchFindManyQuery: true,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const { FieldContextProvider: DueAtFieldContextProvider } = useFieldContext({
|
const { FieldContextProvider: DueAtFieldContextProvider } = useFieldContext({
|
||||||
|
|||||||
@ -24,7 +24,6 @@ export const useOpenCreateActivityDrawer = () => {
|
|||||||
});
|
});
|
||||||
const { createOneRecord: createOneActivity } = useCreateOneRecord<Activity>({
|
const { createOneRecord: createOneActivity } = useCreateOneRecord<Activity>({
|
||||||
objectNameSingular: 'activity',
|
objectNameSingular: 'activity',
|
||||||
refetchFindManyQuery: true,
|
|
||||||
});
|
});
|
||||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import {
|
|||||||
IconCheckbox,
|
IconCheckbox,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
IconSettings,
|
IconSettings,
|
||||||
IconTargetArrow,
|
|
||||||
} from '@/ui/display/icon';
|
} from '@/ui/display/icon';
|
||||||
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
|
||||||
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
|
import { NavigationDrawerSection } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerSection';
|
||||||
@ -70,12 +69,6 @@ export const MainNavigationDrawerItems = () => {
|
|||||||
<NavigationDrawerSection>
|
<NavigationDrawerSection>
|
||||||
<NavigationDrawerSectionTitle label="Workspace" />
|
<NavigationDrawerSectionTitle label="Workspace" />
|
||||||
<ObjectMetadataNavItems />
|
<ObjectMetadataNavItems />
|
||||||
<NavigationDrawerItem
|
|
||||||
label="Opportunities"
|
|
||||||
to="/objects/opportunities"
|
|
||||||
active={location.pathname === '/objects/opportunities'}
|
|
||||||
Icon={IconTargetArrow}
|
|
||||||
/>
|
|
||||||
</NavigationDrawerSection>
|
</NavigationDrawerSection>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -12,20 +12,45 @@ export const ObjectMetadataNavItems = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{activeObjectMetadataItems.map((objectMetadataItem) =>
|
{[
|
||||||
objectMetadataItem.nameSingular === 'opportunity' ? null : (
|
...activeObjectMetadataItems
|
||||||
<NavigationDrawerItem
|
.filter((item) =>
|
||||||
key={objectMetadataItem.id}
|
['person', 'company', 'opportunity'].includes(item.nameSingular),
|
||||||
label={objectMetadataItem.labelPlural}
|
)
|
||||||
to={`/objects/${objectMetadataItem.namePlural}`}
|
.sort((objectMetadataItemA, _) => {
|
||||||
active={currentPath == `/objects/${objectMetadataItem.namePlural}`}
|
if (objectMetadataItemA.nameSingular === 'person') {
|
||||||
Icon={getIcon(objectMetadataItem.icon)}
|
return -1;
|
||||||
onClick={() => {
|
}
|
||||||
navigate(`/objects/${objectMetadataItem.namePlural}`);
|
|
||||||
}}
|
if (objectMetadataItemA.nameSingular === 'opportunity') {
|
||||||
/>
|
return 1;
|
||||||
),
|
}
|
||||||
)}
|
|
||||||
|
return 0;
|
||||||
|
}),
|
||||||
|
...activeObjectMetadataItems
|
||||||
|
.filter(
|
||||||
|
(item) =>
|
||||||
|
!['person', 'company', 'opportunity'].includes(item.nameSingular),
|
||||||
|
)
|
||||||
|
.sort((objectMetadataItemA, objectMetadataItemB) => {
|
||||||
|
return new Date(objectMetadataItemA.createdAt) <
|
||||||
|
new Date(objectMetadataItemB.createdAt)
|
||||||
|
? 1
|
||||||
|
: -1;
|
||||||
|
}),
|
||||||
|
].map((objectMetadataItem) => (
|
||||||
|
<NavigationDrawerItem
|
||||||
|
key={objectMetadataItem.id}
|
||||||
|
label={objectMetadataItem.labelPlural}
|
||||||
|
to={`/objects/${objectMetadataItem.namePlural}`}
|
||||||
|
active={currentPath == `/objects/${objectMetadataItem.namePlural}`}
|
||||||
|
Icon={getIcon(objectMetadataItem.icon)}
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/objects/${objectMetadataItem.namePlural}`);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -38,7 +38,7 @@ const initializeValue = (
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
amount: convertCurrencyMicrosToCurrency(fieldValue.amountMicros),
|
amount: convertCurrencyMicrosToCurrency(fieldValue.amountMicros),
|
||||||
currencyCode: fieldValue.currencyCode,
|
currencyCode: CurrencyCode.USD,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import { capitalize } from '~/utils/string/capitalize';
|
|||||||
|
|
||||||
type useCreateOneRecordProps = {
|
type useCreateOneRecordProps = {
|
||||||
objectNameSingular: string;
|
objectNameSingular: string;
|
||||||
refetchFindManyQuery?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCreateOneRecord = <T>({
|
export const useCreateOneRecord = <T>({
|
||||||
@ -36,6 +35,7 @@ export const useCreateOneRecord = <T>({
|
|||||||
|
|
||||||
const generatedEmptyRecord = generateEmptyRecord<Record<string, unknown>>({
|
const generatedEmptyRecord = generateEmptyRecord<Record<string, unknown>>({
|
||||||
id: recordId,
|
id: recordId,
|
||||||
|
createdAt: new Date().toISOString(),
|
||||||
...input,
|
...input,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export const useCreateOneRecord = <T>({
|
|||||||
},
|
},
|
||||||
optimisticResponse: {
|
optimisticResponse: {
|
||||||
[`create${capitalize(objectMetadataItem.nameSingular)}`]:
|
[`create${capitalize(objectMetadataItem.nameSingular)}`]:
|
||||||
generateEmptyRecord({ id: recordId, ...input }),
|
generatedEmptyRecord,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue';
|
||||||
|
|
||||||
export const useGenerateEmptyRecord = ({
|
export const useGenerateEmptyRecord = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
@ -10,157 +11,14 @@ export const useGenerateEmptyRecord = ({
|
|||||||
// Todo replace this by runtime typing
|
// Todo replace this by runtime typing
|
||||||
const validatedInput = input as { id: string } & { [key: string]: any };
|
const validatedInput = input as { id: string } & { [key: string]: any };
|
||||||
|
|
||||||
if (objectMetadataItem.nameSingular === 'company') {
|
const emptyRecord = {} as Record<string, any>;
|
||||||
return {
|
|
||||||
id: validatedInput.id,
|
|
||||||
domainName: '',
|
|
||||||
accountOwnerId: null,
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
address: '',
|
|
||||||
people: [
|
|
||||||
{
|
|
||||||
edges: [],
|
|
||||||
__typename: 'PersonConnection',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
xLink: {
|
|
||||||
label: '',
|
|
||||||
url: '',
|
|
||||||
__typename: 'Link',
|
|
||||||
},
|
|
||||||
attachments: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'AttachmentConnection',
|
|
||||||
},
|
|
||||||
activityTargets: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'ActivityTargetConnection',
|
|
||||||
},
|
|
||||||
idealCustomerProfile: null,
|
|
||||||
annualRecurringRevenue: {
|
|
||||||
amountMicros: null,
|
|
||||||
currencyCode: null,
|
|
||||||
__typename: 'Currency',
|
|
||||||
},
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
employees: null,
|
|
||||||
accountOwner: null,
|
|
||||||
name: '',
|
|
||||||
linkedinLink: {
|
|
||||||
label: '',
|
|
||||||
url: '',
|
|
||||||
__typename: 'Link',
|
|
||||||
},
|
|
||||||
favorites: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'FavoriteConnection',
|
|
||||||
},
|
|
||||||
opportunities: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'OpportunityConnection',
|
|
||||||
},
|
|
||||||
__typename: 'Company',
|
|
||||||
} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objectMetadataItem.nameSingular === 'person') {
|
for (const fieldMetadataItem of objectMetadataItem.fields) {
|
||||||
return {
|
emptyRecord[fieldMetadataItem.name] =
|
||||||
id: validatedInput.id,
|
validatedInput[fieldMetadataItem.name] ??
|
||||||
activityTargets: {
|
generateEmptyFieldValue(fieldMetadataItem);
|
||||||
edges: [],
|
|
||||||
__typename: 'ActivityTargetConnection',
|
|
||||||
},
|
|
||||||
opportunities: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'OpportunityConnection',
|
|
||||||
},
|
|
||||||
companyId: null,
|
|
||||||
favorites: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'FavoriteConnection',
|
|
||||||
},
|
|
||||||
phone: '',
|
|
||||||
company: null,
|
|
||||||
xLink: {
|
|
||||||
label: '',
|
|
||||||
url: '',
|
|
||||||
__typename: 'Link',
|
|
||||||
},
|
|
||||||
jobTitle: '',
|
|
||||||
pointOfContactForOpportunities: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'OpportunityConnection',
|
|
||||||
},
|
|
||||||
email: '',
|
|
||||||
attachments: {
|
|
||||||
edges: [],
|
|
||||||
__typename: 'AttachmentConnection',
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
firstName: '',
|
|
||||||
lastName: '',
|
|
||||||
__typename: 'FullName',
|
|
||||||
},
|
|
||||||
avatarUrl: '',
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
city: '',
|
|
||||||
linkedinLink: {
|
|
||||||
label: '',
|
|
||||||
url: '',
|
|
||||||
__typename: 'Link',
|
|
||||||
},
|
|
||||||
__typename: 'Person',
|
|
||||||
} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objectMetadataItem.nameSingular === 'opportunity') {
|
|
||||||
return {
|
|
||||||
id: validatedInput.id,
|
|
||||||
pipelineStepId: validatedInput.pipelineStepId,
|
|
||||||
closeDate: null,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
pipelineStep: null,
|
|
||||||
probability: '0',
|
|
||||||
pointOfContactId: null,
|
|
||||||
personId: null,
|
|
||||||
amount: {
|
|
||||||
amountMicros: null,
|
|
||||||
currencyCode: null,
|
|
||||||
__typename: 'Currency',
|
|
||||||
},
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
pointOfContact: null,
|
|
||||||
person: null,
|
|
||||||
company: null,
|
|
||||||
companyId: validatedInput.companyId,
|
|
||||||
__typename: 'Opportunity',
|
|
||||||
} as T;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (objectMetadataItem.nameSingular === 'opportunity') {
|
|
||||||
return {
|
|
||||||
id: validatedInput.id,
|
|
||||||
pipelineStepId: validatedInput.pipelineStepId,
|
|
||||||
closeDate: null,
|
|
||||||
updatedAt: new Date().toISOString(),
|
|
||||||
pipelineStep: null,
|
|
||||||
probability: '0',
|
|
||||||
pointOfContactId: null,
|
|
||||||
personId: null,
|
|
||||||
amount: {
|
|
||||||
amountMicros: null,
|
|
||||||
currencyCode: null,
|
|
||||||
__typename: 'Currency',
|
|
||||||
},
|
|
||||||
createdAt: new Date().toISOString(),
|
|
||||||
pointOfContact: null,
|
|
||||||
person: null,
|
|
||||||
company: null,
|
|
||||||
companyId: validatedInput.companyId,
|
|
||||||
__typename: 'Opportunity',
|
|
||||||
} as T;
|
|
||||||
}
|
}
|
||||||
|
return emptyRecord as T;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { capitalize } from '~/utils/string/capitalize';
|
|||||||
|
|
||||||
type useUpdateOneRecordProps = {
|
type useUpdateOneRecordProps = {
|
||||||
objectNameSingular: string;
|
objectNameSingular: string;
|
||||||
refetchFindManyQuery?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdateOneRecord = <T>({
|
export const useUpdateOneRecord = <T>({
|
||||||
|
|||||||
@ -43,13 +43,11 @@ export const ColumnHead = ({ column }: ColumnHeadProps) => {
|
|||||||
const Icon = getIcon(column.iconName);
|
const Icon = getIcon(column.iconName);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<StyledTitle>
|
||||||
<StyledTitle>
|
<StyledIcon>
|
||||||
<StyledIcon>
|
<Icon size={theme.icon.size.md} />
|
||||||
<Icon size={theme.icon.size.md} />
|
</StyledIcon>
|
||||||
</StyledIcon>
|
<StyledText>{column.label}</StyledText>
|
||||||
<StyledText>{column.label}</StyledText>
|
</StyledTitle>
|
||||||
</StyledTitle>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||||
|
|
||||||
@ -14,6 +16,11 @@ type ColumnHeadWithDropdownProps = {
|
|||||||
primaryColumnKey: string;
|
primaryColumnKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const StyledDropdown = styled(Dropdown)`
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
export const ColumnHeadWithDropdown = ({
|
export const ColumnHeadWithDropdown = ({
|
||||||
column,
|
column,
|
||||||
isFirstColumn,
|
isFirstColumn,
|
||||||
@ -22,7 +29,7 @@ export const ColumnHeadWithDropdown = ({
|
|||||||
}: ColumnHeadWithDropdownProps) => {
|
}: ColumnHeadWithDropdownProps) => {
|
||||||
return (
|
return (
|
||||||
<DropdownScope dropdownScopeId={column.fieldMetadataId + '-header'}>
|
<DropdownScope dropdownScopeId={column.fieldMetadataId + '-header'}>
|
||||||
<Dropdown
|
<StyledDropdown
|
||||||
clickableComponent={<ColumnHead column={column} />}
|
clickableComponent={<ColumnHead column={column} />}
|
||||||
dropdownComponents={
|
dropdownComponents={
|
||||||
<RecordTableColumnDropdownMenu
|
<RecordTableColumnDropdownMenu
|
||||||
|
|||||||
@ -10,15 +10,17 @@ export const RecordTableBody = () => {
|
|||||||
const tableRowIds = useRecoilValue(tableRowIdsState);
|
const tableRowIds = useRecoilValue(tableRowIdsState);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tbody>
|
<>
|
||||||
{tableRowIds.map((rowId, rowIndex) => (
|
<tbody>
|
||||||
<RowIdContext.Provider value={rowId} key={rowId}>
|
{tableRowIds.map((rowId, rowIndex) => (
|
||||||
<RowIndexContext.Provider value={rowIndex}>
|
<RowIdContext.Provider value={rowId} key={rowId}>
|
||||||
<RecordTableRow key={rowId} rowId={rowId} />
|
<RowIndexContext.Provider value={rowIndex}>
|
||||||
</RowIndexContext.Provider>
|
<RecordTableRow key={rowId} rowId={rowId} />
|
||||||
</RowIdContext.Provider>
|
</RowIndexContext.Provider>
|
||||||
))}
|
</RowIdContext.Provider>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
<RecordTableBodyFetchMoreLoader />
|
<RecordTableBodyFetchMoreLoader />
|
||||||
</tbody>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,11 +30,15 @@ export const RecordTableBodyFetchMoreLoader = () => {
|
|||||||
onChange: onLastRowVisible,
|
onChange: onLastRowVisible,
|
||||||
});
|
});
|
||||||
|
|
||||||
return isFetchingMoreObjects ? (
|
return (
|
||||||
<StyledRow ref={tbodyRef} selected={false}>
|
<tbody ref={tbodyRef}>
|
||||||
<td style={{ height: 50 }} colSpan={1000}>
|
{isFetchingMoreObjects ? (
|
||||||
Loading more...
|
<StyledRow selected={false}>
|
||||||
</td>
|
<td style={{ height: 50 }} colSpan={1000}>
|
||||||
</StyledRow>
|
Loading more...
|
||||||
) : null;
|
</td>
|
||||||
|
</StyledRow>
|
||||||
|
) : null}
|
||||||
|
</tbody>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||||
|
import { FieldMetadataType } from '~/generated/graphql';
|
||||||
|
|
||||||
|
export const generateEmptyFieldValue = (
|
||||||
|
fieldMetadataItem: FieldMetadataItem,
|
||||||
|
) => {
|
||||||
|
switch (fieldMetadataItem.type) {
|
||||||
|
case FieldMetadataType.Email:
|
||||||
|
case FieldMetadataType.Phone:
|
||||||
|
case FieldMetadataType.Text: {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Link: {
|
||||||
|
return {
|
||||||
|
label: '',
|
||||||
|
url: '',
|
||||||
|
__typename: 'Link',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case FieldMetadataType.FullName: {
|
||||||
|
return {
|
||||||
|
firstName: '',
|
||||||
|
lastName: '',
|
||||||
|
__typename: 'FullName',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case FieldMetadataType.DateTime: {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Number:
|
||||||
|
case FieldMetadataType.Rating:
|
||||||
|
case FieldMetadataType.Numeric: {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Uuid: {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Boolean: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Relation: {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
case FieldMetadataType.Currency: {
|
||||||
|
return {
|
||||||
|
amountMicros: null,
|
||||||
|
currencyCode: null,
|
||||||
|
__typename: 'Currency',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
case FieldMetadataType.MultiSelect:
|
||||||
|
case FieldMetadataType.Select: {
|
||||||
|
throw new Error('Not implemented yet');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -5,7 +5,9 @@ export const isFieldMetadataItemAvailable = (
|
|||||||
fieldMetadataItem: FieldMetadataItem,
|
fieldMetadataItem: FieldMetadataItem,
|
||||||
) =>
|
) =>
|
||||||
fieldMetadataItem.type !== 'UUID' &&
|
fieldMetadataItem.type !== 'UUID' &&
|
||||||
(fieldMetadataItem.type !== 'RELATION' ||
|
!(
|
||||||
parseFieldRelationType(fieldMetadataItem) === 'TO_ONE_OBJECT') &&
|
fieldMetadataItem.type === 'RELATION' &&
|
||||||
|
parseFieldRelationType(fieldMetadataItem) !== 'TO_ONE_OBJECT'
|
||||||
|
) &&
|
||||||
!fieldMetadataItem.isSystem &&
|
!fieldMetadataItem.isSystem &&
|
||||||
!!fieldMetadataItem.isActive;
|
!!fieldMetadataItem.isActive;
|
||||||
|
|||||||
@ -111,9 +111,9 @@ export const SettingsObjectFieldPreview = ({
|
|||||||
{objectMetadataItem?.labelPlural}
|
{objectMetadataItem?.labelPlural}
|
||||||
</StyledObjectName>
|
</StyledObjectName>
|
||||||
{objectMetadataItem?.isCustom ? (
|
{objectMetadataItem?.isCustom ? (
|
||||||
<Tag color="orange" text="Custom" />
|
<Tag color="orange" text="Custom" weight="medium" />
|
||||||
) : (
|
) : (
|
||||||
<Tag color="blue" text="Standard" />
|
<Tag color="blue" text="Standard" weight="medium" />
|
||||||
)}
|
)}
|
||||||
</StyledObjectSummary>
|
</StyledObjectSummary>
|
||||||
<SettingsObjectFieldPreviewValueEffect
|
<SettingsObjectFieldPreviewValueEffect
|
||||||
|
|||||||
@ -79,9 +79,9 @@ export const SettingsAboutSection = ({
|
|||||||
{name}
|
{name}
|
||||||
</StyledName>
|
</StyledName>
|
||||||
{isCustom ? (
|
{isCustom ? (
|
||||||
<StyledTag color="orange" text="Custom" />
|
<StyledTag color="orange" text="Custom" weight="medium" />
|
||||||
) : (
|
) : (
|
||||||
<StyledTag color="blue" text="Standard" />
|
<StyledTag color="blue" text="Standard" weight="medium" />
|
||||||
)}
|
)}
|
||||||
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
<DropdownScope dropdownScopeId={dropdownScopeId}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
|
|||||||
@ -51,9 +51,9 @@ export const SettingsObjectItemTableRow = ({
|
|||||||
</StyledNameTableCell>
|
</StyledNameTableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{objectItem.isCustom ? (
|
{objectItem.isCustom ? (
|
||||||
<Tag color="orange" text="Custom" />
|
<Tag color="orange" text="Custom" weight="medium" />
|
||||||
) : (
|
) : (
|
||||||
<Tag color="blue" text="Standard" />
|
<Tag color="blue" text="Standard" weight="medium" />
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { themeColorSchema } from '@/ui/theme/utils/themeColorSchema';
|
|||||||
|
|
||||||
const StyledTag = styled.h3<{
|
const StyledTag = styled.h3<{
|
||||||
color: ThemeColor;
|
color: ThemeColor;
|
||||||
|
weight: TagWeight;
|
||||||
}>`
|
}>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background: ${({ color, theme }) => theme.tag.background[color]};
|
background: ${({ color, theme }) => theme.tag.background[color]};
|
||||||
@ -13,7 +14,10 @@ const StyledTag = styled.h3<{
|
|||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
font-size: ${({ theme }) => theme.font.size.md};
|
font-size: ${({ theme }) => theme.font.size.md};
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: ${({ theme }) => theme.font.weight.regular};
|
font-weight: ${({ theme, weight }) =>
|
||||||
|
weight === 'regular'
|
||||||
|
? theme.font.weight.regular
|
||||||
|
: theme.font.weight.medium};
|
||||||
height: ${({ theme }) => theme.spacing(5)};
|
height: ${({ theme }) => theme.spacing(5)};
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -26,18 +30,28 @@ const StyledContent = styled.span`
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
type TagWeight = 'regular' | 'medium';
|
||||||
|
|
||||||
type TagProps = {
|
type TagProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
color: ThemeColor;
|
color: ThemeColor;
|
||||||
text: string;
|
text: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
weight?: TagWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Tag = ({ className, color, text, onClick }: TagProps) => (
|
export const Tag = ({
|
||||||
|
className,
|
||||||
|
color,
|
||||||
|
text,
|
||||||
|
onClick,
|
||||||
|
weight = 'regular',
|
||||||
|
}: TagProps) => (
|
||||||
<StyledTag
|
<StyledTag
|
||||||
className={className}
|
className={className}
|
||||||
color={themeColorSchema.catch('gray').parse(color)}
|
color={themeColorSchema.catch('gray').parse(color)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
weight={weight}
|
||||||
>
|
>
|
||||||
<StyledContent>{text}</StyledContent>
|
<StyledContent>{text}</StyledContent>
|
||||||
</StyledTag>
|
</StyledTag>
|
||||||
|
|||||||
@ -102,7 +102,11 @@ export const Dropdown = ({
|
|||||||
return (
|
return (
|
||||||
<div ref={containerRef} className={className}>
|
<div ref={containerRef} className={className}>
|
||||||
{clickableComponent && (
|
{clickableComponent && (
|
||||||
<div ref={refs.setReference} onClick={toggleDropdown}>
|
<div
|
||||||
|
ref={refs.setReference}
|
||||||
|
onClick={toggleDropdown}
|
||||||
|
className={className}
|
||||||
|
>
|
||||||
{clickableComponent}
|
{clickableComponent}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -18,7 +18,9 @@ const StyledMainContainer = styled.div`
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding: ${({ theme }) => theme.spacing(0, 3)};
|
padding-bottom: ${({ theme }) => theme.spacing(3)};
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: ${({ theme }) => theme.spacing(3)};
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
@media (max-width: ${MOBILE_VIEWPORT}px) {
|
||||||
|
|||||||
@ -94,7 +94,6 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
{
|
{
|
||||||
name: objectMetadata.targetTableName,
|
name: objectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: objectMetadata.dataSource.schema,
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
WorkspaceMigrationColumnActionType.CREATE,
|
WorkspaceMigrationColumnActionType.CREATE,
|
||||||
createdFieldMetadata,
|
createdFieldMetadata,
|
||||||
@ -205,7 +204,6 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
{
|
{
|
||||||
name: objectMetadata.targetTableName,
|
name: objectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: objectMetadata.dataSource.schema,
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
WorkspaceMigrationColumnActionType.ALTER,
|
WorkspaceMigrationColumnActionType.ALTER,
|
||||||
existingFieldMetadata,
|
existingFieldMetadata,
|
||||||
|
|||||||
@ -230,13 +230,11 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
{
|
{
|
||||||
name: createdObjectMetadata.targetTableName,
|
name: createdObjectMetadata.targetTableName,
|
||||||
action: 'create',
|
action: 'create',
|
||||||
schemaName: createdObjectMetadata.dataSource.schema,
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
// Add activity target relation
|
// Add activity target relation
|
||||||
{
|
{
|
||||||
name: activityTargetObjectMetadata.targetTableName,
|
name: activityTargetObjectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: activityTargetObjectMetadata.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
@ -249,7 +247,6 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
{
|
{
|
||||||
name: activityTargetObjectMetadata.targetTableName,
|
name: activityTargetObjectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: activityTargetObjectMetadata.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.RELATION,
|
action: WorkspaceMigrationColumnActionType.RELATION,
|
||||||
@ -263,7 +260,6 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
{
|
{
|
||||||
name: createdObjectMetadata.targetTableName,
|
name: createdObjectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: createdObjectMetadata.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
|||||||
@ -200,9 +200,6 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
|||||||
name: objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
name: objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
||||||
.targetTableName,
|
.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName:
|
|
||||||
objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
|
||||||
.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.CREATE,
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
@ -217,9 +214,6 @@ export class RelationMetadataService extends TypeOrmQueryService<RelationMetadat
|
|||||||
name: objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
name: objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
||||||
.targetTableName,
|
.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName:
|
|
||||||
objectMetadataMap[relationMetadataInput.toObjectMetadataId]
|
|
||||||
.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.RELATION,
|
action: WorkspaceMigrationColumnActionType.RELATION,
|
||||||
|
|||||||
@ -39,7 +39,6 @@ export type WorkspaceMigrationColumnRelation = {
|
|||||||
columnName: string;
|
columnName: string;
|
||||||
referencedTableName: string;
|
referencedTableName: string;
|
||||||
referencedTableColumnName: string;
|
referencedTableColumnName: string;
|
||||||
referencedSchema?: string;
|
|
||||||
isUnique?: boolean;
|
isUnique?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,7 +59,6 @@ export type WorkspaceMigrationColumnAction = {
|
|||||||
export type WorkspaceMigrationTableAction = {
|
export type WorkspaceMigrationTableAction = {
|
||||||
name: string;
|
name: string;
|
||||||
action: 'create' | 'alter';
|
action: 'create' | 'alter';
|
||||||
schemaName: string;
|
|
||||||
columns?: WorkspaceMigrationColumnAction[];
|
columns?: WorkspaceMigrationColumnAction[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -63,11 +63,13 @@ export class WorkspaceMigrationRunnerService {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const queryRunner = workspaceDataSource?.createQueryRunner();
|
const queryRunner = workspaceDataSource?.createQueryRunner();
|
||||||
|
const schemaName =
|
||||||
|
this.workspaceDataSourceService.getSchemaName(workspaceId);
|
||||||
|
|
||||||
// Loop over each migration and create or update the table
|
// Loop over each migration and create or update the table
|
||||||
// TODO: Should be done in a transaction
|
// TODO: Should be done in a transaction
|
||||||
for (const migration of flattenedPendingMigrations) {
|
for (const migration of flattenedPendingMigrations) {
|
||||||
await this.handleTableChanges(queryRunner, migration);
|
await this.handleTableChanges(queryRunner, schemaName, migration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update appliedAt date for each migration
|
// Update appliedAt date for each migration
|
||||||
@ -96,20 +98,17 @@ export class WorkspaceMigrationRunnerService {
|
|||||||
*/
|
*/
|
||||||
private async handleTableChanges(
|
private async handleTableChanges(
|
||||||
queryRunner: QueryRunner,
|
queryRunner: QueryRunner,
|
||||||
|
schemaName: string,
|
||||||
tableMigration: WorkspaceMigrationTableAction,
|
tableMigration: WorkspaceMigrationTableAction,
|
||||||
) {
|
) {
|
||||||
switch (tableMigration.action) {
|
switch (tableMigration.action) {
|
||||||
case 'create':
|
case 'create':
|
||||||
await this.createTable(
|
await this.createTable(queryRunner, schemaName, tableMigration.name);
|
||||||
queryRunner,
|
|
||||||
tableMigration.schemaName,
|
|
||||||
tableMigration.name,
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
case 'alter':
|
case 'alter':
|
||||||
await this.handleColumnChanges(
|
await this.handleColumnChanges(
|
||||||
queryRunner,
|
queryRunner,
|
||||||
tableMigration.schemaName,
|
schemaName,
|
||||||
tableMigration.name,
|
tableMigration.name,
|
||||||
tableMigration?.columns,
|
tableMigration?.columns,
|
||||||
);
|
);
|
||||||
@ -293,7 +292,6 @@ export class WorkspaceMigrationRunnerService {
|
|||||||
new TableForeignKey({
|
new TableForeignKey({
|
||||||
columnNames: [migrationColumn.columnName],
|
columnNames: [migrationColumn.columnName],
|
||||||
referencedColumnNames: [migrationColumn.referencedTableColumnName],
|
referencedColumnNames: [migrationColumn.referencedTableColumnName],
|
||||||
referencedSchema: migrationColumn.referencedSchema,
|
|
||||||
referencedTableName: migrationColumn.referencedTableName,
|
referencedTableName: migrationColumn.referencedTableName,
|
||||||
onDelete: 'CASCADE',
|
onDelete: 'CASCADE',
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -92,8 +92,8 @@ export class CompanyObjectMetadata extends BaseObjectMetadata {
|
|||||||
description:
|
description:
|
||||||
'Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you',
|
'Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you',
|
||||||
icon: 'IconTarget',
|
icon: 'IconTarget',
|
||||||
|
defaultValue: { value: false },
|
||||||
})
|
})
|
||||||
@IsNullable()
|
|
||||||
idealCustomerProfile: boolean;
|
idealCustomerProfile: boolean;
|
||||||
|
|
||||||
// Relations
|
// Relations
|
||||||
|
|||||||
@ -393,7 +393,6 @@ export class WorkspaceSyncMetadataService {
|
|||||||
{
|
{
|
||||||
name: object.targetTableName,
|
name: object.targetTableName,
|
||||||
action: 'create',
|
action: 'create',
|
||||||
schemaName: object.dataSource.schema,
|
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
...Object.values(object.fields)
|
...Object.values(object.fields)
|
||||||
.filter((field) => field.type !== FieldMetadataType.RELATION)
|
.filter((field) => field.type !== FieldMetadataType.RELATION)
|
||||||
@ -402,7 +401,6 @@ export class WorkspaceSyncMetadataService {
|
|||||||
({
|
({
|
||||||
name: object.targetTableName,
|
name: object.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: object.dataSource.schema,
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
WorkspaceMigrationColumnActionType.CREATE,
|
WorkspaceMigrationColumnActionType.CREATE,
|
||||||
field,
|
field,
|
||||||
@ -434,8 +432,6 @@ export class WorkspaceSyncMetadataService {
|
|||||||
{
|
{
|
||||||
name: objectsInDbById[field.objectMetadataId].targetTableName,
|
name: objectsInDbById[field.objectMetadataId].targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName:
|
|
||||||
objectsInDbById[field.objectMetadataId].dataSource.schema,
|
|
||||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||||
WorkspaceMigrationColumnActionType.CREATE,
|
WorkspaceMigrationColumnActionType.CREATE,
|
||||||
field,
|
field,
|
||||||
@ -457,8 +453,6 @@ export class WorkspaceSyncMetadataService {
|
|||||||
{
|
{
|
||||||
name: objectsInDbById[field.objectMetadataId].targetTableName,
|
name: objectsInDbById[field.objectMetadataId].targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName:
|
|
||||||
objectsInDbById[field.objectMetadataId].dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.DROP,
|
action: WorkspaceMigrationColumnActionType.DROP,
|
||||||
@ -524,13 +518,11 @@ export class WorkspaceSyncMetadataService {
|
|||||||
{
|
{
|
||||||
name: toObjectMetadata.targetTableName,
|
name: toObjectMetadata.targetTableName,
|
||||||
action: 'alter',
|
action: 'alter',
|
||||||
schemaName: toObjectMetadata.dataSource.schema,
|
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
action: WorkspaceMigrationColumnActionType.RELATION,
|
action: WorkspaceMigrationColumnActionType.RELATION,
|
||||||
columnName: `${camelCase(toFieldMetadata.name)}Id`,
|
columnName: `${camelCase(toFieldMetadata.name)}Id`,
|
||||||
referencedTableName: fromObjectMetadata.targetTableName,
|
referencedTableName: fromObjectMetadata.targetTableName,
|
||||||
referencedSchema: fromObjectMetadata.dataSource.schema,
|
|
||||||
referencedTableColumnName: 'id',
|
referencedTableColumnName: 'id',
|
||||||
isUnique:
|
isUnique:
|
||||||
relation.relationType === RelationMetadataType.ONE_TO_ONE,
|
relation.relationType === RelationMetadataType.ONE_TO_ONE,
|
||||||
|
|||||||
Reference in New Issue
Block a user