1518 extensibility front add an application section in settings (#15056)
Protected by IS_APPLICATION_ENABLED featureFlag Add `Application` section in settings <img width="301" height="137" alt="image" src="https://github.com/user-attachments/assets/ee53bdd2-36f6-45c6-8646-17b1e08abf00" /> A `settings/applications` route listing all installed applications <img width="661" height="428" alt="image" src="https://github.com/user-attachments/assets/69d534c4-4e9e-452a-a3d9-ded0223bb457" /> Introduce a new Tag for application managed items <img width="885" height="759" alt="image" src="https://github.com/user-attachments/assets/19767be5-61e5-4bd2-a51d-54ed9bfb1923" /> A `settings/applications/<application_id>` details setting page listing all objects, serverlessFunctions and agents created by the application: <img width="917" height="778" alt="image" src="https://github.com/user-attachments/assets/7fc056a6-1d73-4242-b2eb-6f8955d8597d" /> A `settings/applications/<application_id>/<serverless_function_id>` <img width="905" height="652" alt="image" src="https://github.com/user-attachments/assets/56ca0021-26bf-42cb-9abf-34879f16050a" /> Add trigger tab in serverless function details (readonly for now) <img width="899" height="724" alt="image" src="https://github.com/user-attachments/assets/5eeefa35-f2a4-4fd8-a640-7b5c5891f226" /> Set object, serverless and agent setting detail pages readonly for managed items <img width="1075" height="859" alt="image" src="https://github.com/user-attachments/assets/57c73d69-4980-47a2-b752-8dc5ab494530" /> <img width="648" height="582" alt="image" src="https://github.com/user-attachments/assets/5ad5f3f7-3bc3-4e40-870a-4981c6492524" /> <img width="982" height="692" alt="image" src="https://github.com/user-attachments/assets/7ad756c4-5d33-4a0a-9eb8-416c040362b9" /> <img width="1077" height="647" alt="image" src="https://github.com/user-attachments/assets/e086b9f5-4062-4d10-82a9-4023de3cad3f" />
This commit is contained in:
+1
@@ -9,6 +9,7 @@ type SettingsDataModelPreviewFormCardProps = {
|
||||
className?: string;
|
||||
preview: ReactNode;
|
||||
form?: ReactNode;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const StyledPreviewContainer = styled(CardContent)`
|
||||
|
||||
+3
@@ -18,9 +18,11 @@ export type SettingsDataModelFieldBooleanFormValues = z.infer<
|
||||
|
||||
type SettingsDataModelFieldBooleanFormProps = {
|
||||
existingFieldMetadataId: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldBooleanForm = ({
|
||||
disabled,
|
||||
existingFieldMetadataId,
|
||||
}: SettingsDataModelFieldBooleanFormProps) => {
|
||||
const { t } = useLingui();
|
||||
@@ -46,6 +48,7 @@ export const SettingsDataModelFieldBooleanForm = ({
|
||||
onChange={onChange}
|
||||
dropdownId="object-field-default-value-select-boolean"
|
||||
dropdownWidth={120}
|
||||
disabled={disabled}
|
||||
needIconCheck={false}
|
||||
options={BOOLEAN_DATA_MODEL_SELECT_OPTIONS.map((option) => ({
|
||||
...option,
|
||||
|
||||
+3
@@ -12,11 +12,13 @@ import { type SettingsDataModelFieldEditFormValues } from '~/pages/settings/data
|
||||
type SettingsDataModelFieldBooleanSettingsFormCardProps = {
|
||||
existingFieldMetadataId: string;
|
||||
objectNameSingular: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldBooleanSettingsFormCard = ({
|
||||
existingFieldMetadataId,
|
||||
objectNameSingular,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldBooleanSettingsFormCardProps) => {
|
||||
const { watch } = useFormContext<
|
||||
SettingsDataModelFieldBooleanFormValues &
|
||||
@@ -38,6 +40,7 @@ export const SettingsDataModelFieldBooleanSettingsFormCard = ({
|
||||
}
|
||||
form={
|
||||
<SettingsDataModelFieldBooleanForm
|
||||
disabled={disabled}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
/>
|
||||
}
|
||||
|
||||
+6
-1
@@ -76,12 +76,14 @@ type SettingsDataModelFieldIconLabelFormProps = {
|
||||
fieldMetadataItem?: FieldMetadataItem;
|
||||
maxLength?: number;
|
||||
isCreationMode?: boolean;
|
||||
readonly?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldIconLabelForm = ({
|
||||
isCreationMode = false,
|
||||
fieldMetadataItem,
|
||||
maxLength,
|
||||
readonly = false,
|
||||
}: SettingsDataModelFieldIconLabelFormProps) => {
|
||||
const {
|
||||
control,
|
||||
@@ -150,6 +152,7 @@ export const SettingsDataModelFieldIconLabelForm = ({
|
||||
selectedIconKey={value ?? 'IconUsers'}
|
||||
onChange={({ iconKey }) => onChange(iconKey)}
|
||||
variant="primary"
|
||||
disabled={readonly}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@@ -162,7 +165,7 @@ export const SettingsDataModelFieldIconLabelForm = ({
|
||||
instanceId={labelTextInputId}
|
||||
placeholder={t`Employees`}
|
||||
value={value}
|
||||
disabled={!isLabelEditEnabled}
|
||||
disabled={!isLabelEditEnabled || readonly}
|
||||
onChange={(value) => {
|
||||
onChange(value);
|
||||
trigger('label');
|
||||
@@ -199,6 +202,7 @@ export const SettingsDataModelFieldIconLabelForm = ({
|
||||
placeholder={t`employees`}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
readOnly={readonly}
|
||||
disabled={!isNameEditEnabled}
|
||||
fullWidth
|
||||
maxLength={DATABASE_IDENTIFIER_MAXIMUM_LENGTH}
|
||||
@@ -245,6 +249,7 @@ export const SettingsDataModelFieldIconLabelForm = ({
|
||||
title={t`Synchronize Field Label and API Name`}
|
||||
description={t`Should changing a field's label also change the API name?`}
|
||||
checked={value ?? true}
|
||||
disabled={readonly}
|
||||
advancedMode
|
||||
onChange={(value) => {
|
||||
onChange(value);
|
||||
|
||||
+3
-1
@@ -18,12 +18,14 @@ type SettingsDataModelFieldIsUniqueFormProps = {
|
||||
objectNameSingular: string;
|
||||
fieldType: FieldMetadataType;
|
||||
existingFieldMetadataId: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldIsUniqueForm = ({
|
||||
fieldType,
|
||||
existingFieldMetadataId,
|
||||
objectNameSingular,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldIsUniqueFormProps) => {
|
||||
const { control } =
|
||||
useFormContext<SettingsDataModelFieldIsUniqueFormValues>();
|
||||
@@ -74,7 +76,7 @@ export const SettingsDataModelFieldIsUniqueForm = ({
|
||||
toggleSize="small"
|
||||
value={isUnique}
|
||||
onChange={(value) => onChange(value)}
|
||||
disabled={hasStandardUniqueIndex}
|
||||
disabled={disabled || hasStandardUniqueIndex}
|
||||
/>
|
||||
</SettingsOptionCardContentSelect>
|
||||
</>
|
||||
|
||||
+14
@@ -160,6 +160,7 @@ type SettingsDataModelFieldSettingsFormCardProps = {
|
||||
existingFieldMetadataId: string;
|
||||
fieldType: FieldMetadataType;
|
||||
objectNameSingular: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const previewableTypes = [
|
||||
@@ -188,6 +189,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
existingFieldMetadataId,
|
||||
fieldType,
|
||||
objectNameSingular,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldSettingsFormCardProps) => {
|
||||
const { watch } = useFormContext<SettingsDataModelFieldEditFormValues>();
|
||||
|
||||
@@ -200,6 +202,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldBooleanSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -209,6 +212,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldCurrencySettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -222,6 +226,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
fieldType={fieldType}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -231,6 +236,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldRelationSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -240,6 +246,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldMorphRelationFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -249,6 +256,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldNumberSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -258,6 +266,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldTextSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -267,6 +276,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldAddressSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -276,6 +286,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldPhonesSettingsFormCard
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -289,6 +300,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
fieldType={fieldType}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -318,6 +330,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
<SettingsDataModelFieldMaxValuesForm
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
fieldType={fieldType}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<Separator />
|
||||
</>
|
||||
@@ -326,6 +339,7 @@ export const SettingsDataModelFieldSettingsFormCard = ({
|
||||
fieldType={fieldType}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ export const SettingsDataModelFieldTextSettingsFormCard = ({
|
||||
fieldType={FieldMetadataType.TEXT}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
+1
@@ -55,6 +55,7 @@ export const SettingsDataModelFieldDateSettingsFormCard = ({
|
||||
fieldType={fieldType}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
+3
-1
@@ -39,10 +39,12 @@ export type SettingsDataModelFieldMorphRelationFormValues = z.infer<
|
||||
|
||||
type SettingsDataModelFieldMorphRelationFormProps = {
|
||||
existingFieldMetadataId: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldMorphRelationForm = ({
|
||||
existingFieldMetadataId,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldMorphRelationFormProps) => {
|
||||
const { t } = useLingui();
|
||||
const { control } =
|
||||
@@ -90,7 +92,7 @@ export const SettingsDataModelFieldMorphRelationForm = ({
|
||||
label={t`Relation type`}
|
||||
dropdownId="relation-type-select"
|
||||
fullWidth
|
||||
disabled={disableRelationEdition}
|
||||
disabled={disabled || disableRelationEdition}
|
||||
value={value}
|
||||
options={RELATION_TYPE_OPTIONS}
|
||||
onChange={onChange}
|
||||
|
||||
+3
@@ -18,11 +18,13 @@ import { type SettingsDataModelFieldEditFormValues } from '~/pages/settings/data
|
||||
type SettingsDataModelFieldMorphRelationFormCardProps = {
|
||||
existingFieldMetadataId: string;
|
||||
objectNameSingular: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldMorphRelationFormCard = ({
|
||||
existingFieldMetadataId,
|
||||
objectNameSingular,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldMorphRelationFormCardProps) => {
|
||||
const { watch } = useFormContext<
|
||||
SettingsDataModelFieldMorphRelationFormValues &
|
||||
@@ -107,6 +109,7 @@ export const SettingsDataModelFieldMorphRelationFormCard = ({
|
||||
form={
|
||||
<SettingsDataModelFieldMorphRelationForm
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
disabled={disabled}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
+1
@@ -42,6 +42,7 @@ export const SettingsDataModelFieldNumberSettingsFormCard = ({
|
||||
fieldType={FieldMetadataType.NUMBER}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ export const SettingsDataModelFieldPhonesSettingsFormCard = ({
|
||||
fieldType={FieldMetadataType.PHONES}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectNameSingular={objectNameSingular}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
|
||||
+6
-4
@@ -47,6 +47,7 @@ export type SettingsDataModelFieldRelationFormValues = z.infer<
|
||||
type SettingsDataModelFieldRelationFormProps = {
|
||||
existingFieldMetadataId: string;
|
||||
objectMetadataItem?: ObjectMetadataItem;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const StyledContainer = styled.div`
|
||||
@@ -84,6 +85,7 @@ export const RELATION_TYPE_OPTIONS = Object.entries(RELATION_TYPES).map(
|
||||
export const SettingsDataModelFieldRelationForm = ({
|
||||
existingFieldMetadataId,
|
||||
objectMetadataItem,
|
||||
disabled,
|
||||
}: SettingsDataModelFieldRelationFormProps) => {
|
||||
const { t } = useLingui();
|
||||
const { control, watch: watchFormValue } =
|
||||
@@ -129,7 +131,7 @@ export const SettingsDataModelFieldRelationForm = ({
|
||||
label={t`Relation type`}
|
||||
dropdownId="relation-type-select"
|
||||
fullWidth
|
||||
disabled={disableRelationEdition}
|
||||
disabled={disabled || disableRelationEdition}
|
||||
value={value}
|
||||
options={RELATION_TYPE_OPTIONS}
|
||||
onChange={onChange}
|
||||
@@ -145,7 +147,7 @@ export const SettingsDataModelFieldRelationForm = ({
|
||||
label={t`Object destination`}
|
||||
dropdownId="object-destination-select"
|
||||
fullWidth
|
||||
disabled={disableRelationEdition}
|
||||
disabled={disabled || disableRelationEdition}
|
||||
value={value}
|
||||
options={activeObjectMetadataItems
|
||||
.filter(isObjectMetadataAvailableForRelation)
|
||||
@@ -175,7 +177,7 @@ export const SettingsDataModelFieldRelationForm = ({
|
||||
defaultValue={initialRelationFieldMetadataItem.icon}
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<IconPicker
|
||||
disabled={disableFieldEdition}
|
||||
disabled={disabled || disableFieldEdition}
|
||||
dropdownId="field-destination-icon-picker"
|
||||
selectedIconKey={value ?? undefined}
|
||||
onChange={({ iconKey }) => onChange(iconKey)}
|
||||
@@ -190,7 +192,7 @@ export const SettingsDataModelFieldRelationForm = ({
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<SettingsTextInput
|
||||
instanceId="relation-field-label"
|
||||
disabled={disableFieldEdition}
|
||||
disabled={disabled || disableFieldEdition}
|
||||
placeholder={t`Field name`}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
|
||||
+3
@@ -18,11 +18,13 @@ import { type SettingsDataModelFieldEditFormValues } from '~/pages/settings/data
|
||||
type SettingsDataModelFieldRelationSettingsFormCardProps = {
|
||||
existingFieldMetadataId: string;
|
||||
objectNameSingular: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldRelationSettingsFormCard = ({
|
||||
existingFieldMetadataId,
|
||||
objectNameSingular,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldRelationSettingsFormCardProps) => {
|
||||
const { watch } = useFormContext<
|
||||
SettingsDataModelFieldRelationFormValues &
|
||||
@@ -95,6 +97,7 @@ export const SettingsDataModelFieldRelationSettingsFormCard = ({
|
||||
<SettingsDataModelFieldRelationForm
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
objectMetadataItem={relationObjectMetadataItem}
|
||||
disabled={disabled}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
+40
-15
@@ -48,6 +48,7 @@ export type SettingsDataModelFieldSelectFormValues = z.infer<
|
||||
type SettingsDataModelFieldSelectFormProps = {
|
||||
fieldType: FieldMetadataType.SELECT | FieldMetadataType.MULTI_SELECT;
|
||||
existingFieldMetadataId: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const StyledContainer = styled(CardContent)`
|
||||
@@ -112,6 +113,7 @@ const StyledButton = styled(LightButton)`
|
||||
export const SettingsDataModelFieldSelectForm = ({
|
||||
existingFieldMetadataId,
|
||||
fieldType,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldSelectFormProps) => {
|
||||
const { initialDefaultValue, initialOptions } =
|
||||
useSelectSettingsFormInitialValues({
|
||||
@@ -281,7 +283,11 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
</StyledOptionsLabel>
|
||||
</StyledLabelContainer>
|
||||
<DraggableList
|
||||
onDragEnd={(result) => handleDragEnd(options, result, onChange)}
|
||||
onDragEnd={(result) =>
|
||||
!disabled
|
||||
? handleDragEnd(options, result, onChange)
|
||||
: undefined
|
||||
}
|
||||
draggableItems={
|
||||
<>
|
||||
{options.map((option, index) => (
|
||||
@@ -297,6 +303,9 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
option={option}
|
||||
isNewRow={index === options.length - 1}
|
||||
onChange={(nextOption) => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
const nextOptions = toSpliced(
|
||||
options,
|
||||
index,
|
||||
@@ -315,6 +324,9 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
}
|
||||
}}
|
||||
onRemove={() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
const nextOptions = toSpliced(
|
||||
options,
|
||||
index,
|
||||
@@ -326,13 +338,24 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
onChange(nextOptions);
|
||||
}}
|
||||
isDefault={isOptionDefaultValue(option.value)}
|
||||
onSetAsDefault={() =>
|
||||
handleSetOptionAsDefault(option.value)
|
||||
}
|
||||
onRemoveAsDefault={() =>
|
||||
handleRemoveOptionAsDefault(option.value)
|
||||
}
|
||||
onInputEnter={handleInputEnter}
|
||||
onSetAsDefault={() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
handleSetOptionAsDefault(option.value);
|
||||
}}
|
||||
onRemoveAsDefault={() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
handleRemoveOptionAsDefault(option.value);
|
||||
}}
|
||||
onInputEnter={() => {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
handleInputEnter();
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
@@ -341,13 +364,15 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
}
|
||||
/>
|
||||
</StyledContainer>
|
||||
<StyledFooter>
|
||||
<StyledButton
|
||||
title={t`Add option`}
|
||||
Icon={IconPlus}
|
||||
onClick={handleAddOption}
|
||||
/>
|
||||
</StyledFooter>
|
||||
{!disabled && (
|
||||
<StyledFooter>
|
||||
<StyledButton
|
||||
title={t`Add option`}
|
||||
Icon={IconPlus}
|
||||
onClick={handleAddOption}
|
||||
/>
|
||||
</StyledFooter>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
|
||||
+3
@@ -20,12 +20,14 @@ type SettingsDataModelFieldSelectSettingsFormCardProps = {
|
||||
objectNameSingular: string;
|
||||
fieldType: FieldMetadataType.SELECT | FieldMetadataType.MULTI_SELECT;
|
||||
existingFieldMetadataId: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsDataModelFieldSelectSettingsFormCard = ({
|
||||
objectNameSingular,
|
||||
fieldType,
|
||||
existingFieldMetadataId,
|
||||
disabled = false,
|
||||
}: SettingsDataModelFieldSelectSettingsFormCardProps) => {
|
||||
const { watch: watchFormValue } = useFormContext<
|
||||
SettingsDataModelFieldSelectOrMultiSelectFormValues &
|
||||
@@ -50,6 +52,7 @@ export const SettingsDataModelFieldSelectSettingsFormCard = ({
|
||||
<SettingsDataModelFieldSelectForm
|
||||
fieldType={fieldType}
|
||||
existingFieldMetadataId={existingFieldMetadataId}
|
||||
disabled={disabled}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
+2
-5
@@ -6,8 +6,6 @@ import { Link } from 'react-router-dom';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { ObjectFieldRow } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewField';
|
||||
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
|
||||
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
import { ObjectFieldRowWithoutRelation } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverviewFieldWithoutRelation';
|
||||
@@ -16,6 +14,7 @@ import { useState } from 'react';
|
||||
import { SettingsPath } from 'twenty-shared/types';
|
||||
import { getSettingsPath } from 'twenty-shared/utils';
|
||||
import { IconChevronDown, IconChevronUp, useIcons } from 'twenty-ui/display';
|
||||
import { SettingsItemTypeTag } from '@/settings/components/SettingsItemTypeTag';
|
||||
|
||||
type SettingsDataModelOverviewObjectNode = Node<ObjectMetadataItem, 'object'>;
|
||||
type SettingsDataModelOverviewObjectProps =
|
||||
@@ -134,9 +133,7 @@ export const SettingsDataModelOverviewObject = ({
|
||||
</StyledObjectLink>
|
||||
<StyledObjectInstanceCount> · {totalCount}</StyledObjectInstanceCount>
|
||||
</StyledObjectName>
|
||||
<SettingsDataModelObjectTypeTag
|
||||
objectTypeLabel={getObjectTypeLabel(objectMetadataItem)}
|
||||
></SettingsDataModelObjectTypeTag>
|
||||
<SettingsItemTypeTag item={objectMetadataItem} />
|
||||
</StyledHeader>
|
||||
|
||||
<StyledInnerCard>
|
||||
|
||||
+5
-3
@@ -20,10 +20,12 @@ type SettingsObjectFieldActiveActionDropdownProps = {
|
||||
onEdit: () => void;
|
||||
onSetAsLabelIdentifier?: () => void;
|
||||
fieldMetadataItemId: string;
|
||||
readonly?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsObjectFieldActiveActionDropdown = ({
|
||||
isCustomField,
|
||||
readonly = false,
|
||||
onDeactivate,
|
||||
onEdit,
|
||||
onSetAsLabelIdentifier,
|
||||
@@ -62,18 +64,18 @@ export const SettingsObjectFieldActiveActionDropdown = ({
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.Narrow}>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
text={isCustomField ? 'Edit' : 'View'}
|
||||
text={isCustomField && !readonly ? 'Edit' : 'View'}
|
||||
LeftIcon={isCustomField ? IconPencil : IconEye}
|
||||
onClick={handleEdit}
|
||||
/>
|
||||
{isDefined(onSetAsLabelIdentifier) && (
|
||||
{isDefined(onSetAsLabelIdentifier) && !readonly && (
|
||||
<MenuItem
|
||||
text="Set as record text"
|
||||
LeftIcon={IconTextSize}
|
||||
onClick={handleSetAsLabelIdentifier}
|
||||
/>
|
||||
)}
|
||||
{isDefined(onDeactivate) && (
|
||||
{isDefined(onDeactivate) && !readonly && (
|
||||
<MenuItem
|
||||
text="Deactivate"
|
||||
LeftIcon={IconArchive}
|
||||
|
||||
+11
-7
@@ -22,10 +22,12 @@ type SettingsObjectFieldInactiveActionDropdownProps = {
|
||||
onEdit: () => void;
|
||||
onDelete: () => void;
|
||||
fieldMetadataItemId: string;
|
||||
readonly?: boolean;
|
||||
};
|
||||
|
||||
export const SettingsObjectFieldInactiveActionDropdown = ({
|
||||
onActivate,
|
||||
readonly = false,
|
||||
fieldMetadataItemId,
|
||||
onDelete,
|
||||
onEdit,
|
||||
@@ -66,16 +68,18 @@ export const SettingsObjectFieldInactiveActionDropdown = ({
|
||||
<DropdownContent widthInPixels={GenericDropdownContentWidth.Narrow}>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
text={isCustomField ? t`Edit` : t`View`}
|
||||
text={isCustomField && !readonly ? t`Edit` : t`View`}
|
||||
LeftIcon={isCustomField ? IconPencil : IconEye}
|
||||
onClick={handleEdit}
|
||||
/>
|
||||
<MenuItem
|
||||
text={t`Activate`}
|
||||
LeftIcon={IconArchiveOff}
|
||||
onClick={handleActivate}
|
||||
/>
|
||||
{isDeletable && (
|
||||
{!readonly && (
|
||||
<MenuItem
|
||||
text={t`Activate`}
|
||||
LeftIcon={IconArchiveOff}
|
||||
onClick={handleActivate}
|
||||
/>
|
||||
)}
|
||||
{isDeletable && !readonly && (
|
||||
<MenuItem
|
||||
text={t`Delete`}
|
||||
accent="danger"
|
||||
|
||||
+16
-1
@@ -30,6 +30,7 @@ import { type SettingsObjectDetailTableItem } from '~/pages/settings/data-model/
|
||||
|
||||
import { RELATION_TYPES } from '../../constants/RelationTypes';
|
||||
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
|
||||
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
|
||||
|
||||
type SettingsObjectFieldItemTableRowProps = {
|
||||
settingsObjectDetailTableItem: SettingsObjectDetailTableItem;
|
||||
@@ -65,6 +66,10 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
const { fieldMetadataItem, identifierType, objectMetadataItem } =
|
||||
settingsObjectDetailTableItem;
|
||||
|
||||
const readonly = isObjectMetadataReadOnly({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const isRemoteObjectField = objectMetadataItem.isRemote;
|
||||
|
||||
const variant = objectMetadataItem.isCustom ? 'identifier' : 'field-type';
|
||||
@@ -118,6 +123,10 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
const handleDisableField = async (
|
||||
activeFieldMetadatItem: FieldMetadataItem,
|
||||
) => {
|
||||
if (readonly) {
|
||||
return;
|
||||
}
|
||||
|
||||
await deactivateMetadataField(
|
||||
activeFieldMetadatItem.id,
|
||||
objectMetadataItem.id,
|
||||
@@ -146,13 +155,17 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
|
||||
const handleSetLabelIdentifierField = (
|
||||
activeFieldMetadatItem: FieldMetadataItem,
|
||||
) =>
|
||||
) => {
|
||||
if (readonly) {
|
||||
return;
|
||||
}
|
||||
updateOneObjectMetadataItem({
|
||||
idToUpdate: objectMetadataItem.id,
|
||||
updatePayload: {
|
||||
labelIdentifierFieldMetadataId: activeFieldMetadatItem.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const [, setActiveSettingsObjectFields] = useRecoilState(
|
||||
settingsObjectFieldsFamilyState({
|
||||
@@ -254,6 +267,7 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
mode === 'view' ? (
|
||||
<SettingsObjectFieldActiveActionDropdown
|
||||
isCustomField={fieldMetadataItem.isCustom === true}
|
||||
readonly={readonly}
|
||||
fieldMetadataItemId={fieldMetadataItem.id}
|
||||
onEdit={() =>
|
||||
navigate(SettingsPath.ObjectFieldEdit, {
|
||||
@@ -284,6 +298,7 @@ export const SettingsObjectFieldItemTableRow = ({
|
||||
) : mode === 'view' ? (
|
||||
<SettingsObjectFieldInactiveActionDropdown
|
||||
isCustomField={fieldMetadataItem.isCustom === true}
|
||||
readonly={readonly}
|
||||
fieldMetadataItemId={fieldMetadataItem.id}
|
||||
onEdit={() =>
|
||||
navigate(SettingsPath.ObjectFieldEdit, {
|
||||
|
||||
+2
-4
@@ -3,11 +3,10 @@ import styled from '@emotion/styled';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
|
||||
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
|
||||
import { TableCell } from '@/ui/layout/table/components/TableCell';
|
||||
import { TableRow } from '@/ui/layout/table/components/TableRow';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { SettingsItemTypeTag } from '@/settings/components/SettingsItemTypeTag';
|
||||
|
||||
export type SettingsObjectMetadataItemTableRowProps = {
|
||||
action: ReactNode;
|
||||
@@ -46,7 +45,6 @@ export const SettingsObjectMetadataItemTableRow = ({
|
||||
|
||||
const { getIcon } = useIcons();
|
||||
const Icon = getIcon(objectMetadataItem.icon);
|
||||
const objectTypeLabel = getObjectTypeLabel(objectMetadataItem);
|
||||
|
||||
return (
|
||||
<StyledObjectTableRow key={objectMetadataItem.namePlural} to={link}>
|
||||
@@ -63,7 +61,7 @@ export const SettingsObjectMetadataItemTableRow = ({
|
||||
</StyledNameLabel>
|
||||
</StyledNameTableCell>
|
||||
<TableCell>
|
||||
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
|
||||
<SettingsItemTypeTag item={objectMetadataItem} />
|
||||
</TableCell>
|
||||
<TableCell align="right">
|
||||
{objectMetadataItem.fields.filter((field) => !field.isSystem).length}
|
||||
|
||||
+15
-5
@@ -14,6 +14,7 @@ import { SettingsPath } from 'twenty-shared/types';
|
||||
import { ZodError } from 'zod';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { updatedObjectNamePluralState } from '~/pages/settings/data-model/states/updatedObjectNamePluralState';
|
||||
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
|
||||
|
||||
type SettingsUpdateDataModelObjectAboutFormProps = {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
@@ -22,6 +23,7 @@ type SettingsUpdateDataModelObjectAboutFormProps = {
|
||||
export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
objectMetadataItem,
|
||||
}: SettingsUpdateDataModelObjectAboutFormProps) => {
|
||||
const readonly = isObjectMetadataReadOnly({ objectMetadataItem });
|
||||
const navigate = useNavigateSettings();
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const setUpdatedObjectNamePlural = useSetRecoilState(
|
||||
@@ -54,6 +56,10 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
const handleSave = async (
|
||||
formValues: SettingsDataModelObjectAboutFormValues,
|
||||
) => {
|
||||
if (readonly) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(Object.keys(formConfig.formState.dirtyFields).length > 0)) {
|
||||
return;
|
||||
}
|
||||
@@ -71,10 +77,10 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
description,
|
||||
icon: icon ?? undefined,
|
||||
isLabelSyncedWithName: formValues.isLabelSyncedWithName,
|
||||
labelPlural: updatedObject.data?.updateOneObject.labelPlural,
|
||||
labelSingular: updatedObject.data?.updateOneObject.labelSingular,
|
||||
namePlural: updatedObject.data?.updateOneObject.namePlural,
|
||||
nameSingular: updatedObject.data?.updateOneObject.nameSingular,
|
||||
labelPlural: updatedObject?.data?.updateOneObject.labelPlural,
|
||||
labelSingular: updatedObject?.data?.updateOneObject.labelSingular,
|
||||
namePlural: updatedObject?.data?.updateOneObject.namePlural,
|
||||
nameSingular: updatedObject?.data?.updateOneObject.nameSingular,
|
||||
});
|
||||
} else {
|
||||
formConfig.reset(undefined, { keepValues: true });
|
||||
@@ -91,6 +97,10 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
const updateObjectMetadata = async (
|
||||
formValues: SettingsDataModelObjectAboutFormValues,
|
||||
) => {
|
||||
if (readonly) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatePayload = { ...formValues };
|
||||
|
||||
if (!objectMetadataItem.isCustom) {
|
||||
@@ -139,7 +149,7 @@ export const SettingsUpdateDataModelObjectAboutForm = ({
|
||||
<FormProvider {...formConfig}>
|
||||
<SettingsDataModelObjectAboutForm
|
||||
onNewDirtyField={() => formConfig.handleSubmit(handleSave)()}
|
||||
disableEdition={!objectMetadataItem.isCustom}
|
||||
disableEdition={!objectMetadataItem.isCustom || readonly}
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
/>
|
||||
</FormProvider>
|
||||
|
||||
+5
-2
@@ -9,6 +9,7 @@ import { H2Title, IconPlus } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { UndecoratedLink } from 'twenty-ui/navigation';
|
||||
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
display: flex;
|
||||
@@ -21,7 +22,9 @@ type ObjectFieldsProps = {
|
||||
};
|
||||
|
||||
export const ObjectFields = ({ objectMetadataItem }: ObjectFieldsProps) => {
|
||||
const shouldDisplayAddFieldButton = !objectMetadataItem.isRemote;
|
||||
const readonly = isObjectMetadataReadOnly({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const { t } = useLingui();
|
||||
const objectLabelSingular = objectMetadataItem.labelSingular;
|
||||
@@ -36,7 +39,7 @@ export const ObjectFields = ({ objectMetadataItem }: ObjectFieldsProps) => {
|
||||
objectMetadataItem={objectMetadataItem}
|
||||
mode="view"
|
||||
/>
|
||||
{shouldDisplayAddFieldButton && (
|
||||
{!readonly && (
|
||||
<StyledDiv>
|
||||
<UndecoratedLink
|
||||
to={getSettingsPath(SettingsPath.ObjectNewFieldSelect, {
|
||||
|
||||
+18
-11
@@ -10,6 +10,7 @@ import { H2Title, IconArchive } from 'twenty-ui/display';
|
||||
import { Button } from 'twenty-ui/input';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
|
||||
|
||||
type ObjectSettingsProps = {
|
||||
objectMetadataItem: ObjectMetadataItem;
|
||||
@@ -27,6 +28,7 @@ const StyledFormSection = styled(Section)`
|
||||
|
||||
export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
||||
const { t } = useLingui();
|
||||
const readonly = isObjectMetadataReadOnly({ objectMetadataItem });
|
||||
const navigate = useNavigateSettings();
|
||||
const { updateOneObjectMetadataItem } = useUpdateOneObjectMetadataItem();
|
||||
const handleDisable = async () => {
|
||||
@@ -59,17 +61,22 @@ export const ObjectSettings = ({ objectMetadataItem }: ObjectSettingsProps) => {
|
||||
/>
|
||||
</Section>
|
||||
</StyledFormSection>
|
||||
<StyledFormSection>
|
||||
<Section>
|
||||
<H2Title title={t`Danger zone`} description={t`Deactivate object`} />
|
||||
<Button
|
||||
Icon={IconArchive}
|
||||
title={t`Deactivate`}
|
||||
size="small"
|
||||
onClick={handleDisable}
|
||||
/>
|
||||
</Section>
|
||||
</StyledFormSection>
|
||||
{!readonly && (
|
||||
<StyledFormSection>
|
||||
<Section>
|
||||
<H2Title
|
||||
title={t`Danger zone`}
|
||||
description={t`Deactivate object`}
|
||||
/>
|
||||
<Button
|
||||
Icon={IconArchive}
|
||||
title={t`Deactivate`}
|
||||
size="small"
|
||||
onClick={handleDisable}
|
||||
/>
|
||||
</Section>
|
||||
</StyledFormSection>
|
||||
)}
|
||||
</StyledContentContainer>
|
||||
);
|
||||
};
|
||||
|
||||
+2
-4
@@ -2,13 +2,12 @@ import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SettingsDataModelObjectTypeTag } from '@/settings/data-model/objects/components/SettingsDataModelObjectTypeTag';
|
||||
import { getObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
|
||||
import {
|
||||
IconBox,
|
||||
OverflowingTextWithTooltip,
|
||||
useIcons,
|
||||
} from 'twenty-ui/display';
|
||||
import { SettingsItemTypeTag } from '@/settings/components/SettingsItemTypeTag';
|
||||
|
||||
export type SettingsDataModelObjectPreviewProps = {
|
||||
className?: string;
|
||||
@@ -69,7 +68,6 @@ const SettingsDataModelObjectPreviewItem = ({
|
||||
const theme = useTheme();
|
||||
const { getIcon } = useIcons();
|
||||
const ObjectIcon = getIcon(objectMetadataItem.icon);
|
||||
const objectTypeLabel = getObjectTypeLabel(objectMetadataItem);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -90,7 +88,7 @@ const SettingsDataModelObjectPreviewItem = ({
|
||||
}
|
||||
/>
|
||||
</StyledObjectName>
|
||||
<SettingsDataModelObjectTypeTag objectTypeLabel={objectTypeLabel} />
|
||||
<SettingsItemTypeTag item={objectMetadataItem} />
|
||||
</StyledObjectPreview>
|
||||
</>
|
||||
);
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
import { type ObjectTypeLabel } from '@/settings/data-model/utils/getObjectTypeLabel';
|
||||
import { Tag } from 'twenty-ui/components';
|
||||
|
||||
type SettingsDataModelObjectTypeTagProps = {
|
||||
objectTypeLabel: ObjectTypeLabel;
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const SettingsDataModelObjectTypeTag = ({
|
||||
className,
|
||||
objectTypeLabel,
|
||||
}: SettingsDataModelObjectTypeTagProps) => {
|
||||
return (
|
||||
<Tag
|
||||
className={className}
|
||||
color={objectTypeLabel.labelColor}
|
||||
text={objectTypeLabel.labelText}
|
||||
weight="medium"
|
||||
/>
|
||||
);
|
||||
};
|
||||
+14
-6
@@ -139,7 +139,11 @@ export const SettingsDataModelObjectAboutForm = ({
|
||||
render={({ field: { onChange, value } }) => (
|
||||
<IconPicker
|
||||
selectedIconKey={value}
|
||||
disabled={disableEdition}
|
||||
onChange={({ iconKey }) => {
|
||||
if (disableEdition) {
|
||||
return;
|
||||
}
|
||||
onChange(iconKey);
|
||||
onNewDirtyField?.();
|
||||
}}
|
||||
@@ -170,9 +174,10 @@ export const SettingsDataModelObjectAboutForm = ({
|
||||
}}
|
||||
onBlur={() => onNewDirtyField?.()}
|
||||
disabled={
|
||||
objectMetadataItem &&
|
||||
!objectMetadataItem?.isCustom &&
|
||||
isLabelSyncedWithName
|
||||
disableEdition ||
|
||||
(objectMetadataItem &&
|
||||
!objectMetadataItem?.isCustom &&
|
||||
isLabelSyncedWithName)
|
||||
}
|
||||
fullWidth
|
||||
maxLength={OBJECT_NAME_MAXIMUM_LENGTH}
|
||||
@@ -201,9 +206,10 @@ export const SettingsDataModelObjectAboutForm = ({
|
||||
}}
|
||||
onBlur={() => onNewDirtyField?.()}
|
||||
disabled={
|
||||
objectMetadataItem &&
|
||||
!objectMetadataItem?.isCustom &&
|
||||
isLabelSyncedWithName
|
||||
disableEdition ||
|
||||
(objectMetadataItem &&
|
||||
!objectMetadataItem?.isCustom &&
|
||||
isLabelSyncedWithName)
|
||||
}
|
||||
fullWidth
|
||||
maxLength={OBJECT_NAME_MAXIMUM_LENGTH}
|
||||
@@ -222,6 +228,7 @@ export const SettingsDataModelObjectAboutForm = ({
|
||||
value={value ?? undefined}
|
||||
onChange={(nextValue) => onChange(nextValue ?? null)}
|
||||
onBlur={() => onNewDirtyField?.()}
|
||||
disabled={disableEdition}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
@@ -326,6 +333,7 @@ export const SettingsDataModelObjectAboutForm = ({
|
||||
description={t`Should changing an object's label also change the API?`}
|
||||
checked={value ?? true}
|
||||
advancedMode
|
||||
disabled={disableEdition}
|
||||
onChange={(value) => {
|
||||
onChange(value);
|
||||
const isCustomObject =
|
||||
|
||||
+3
-1
@@ -16,6 +16,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
import { isLabelIdentifierFieldMetadataTypes } from 'twenty-shared/utils';
|
||||
import { IconCircleOff, IconPlus, useIcons } from 'twenty-ui/display';
|
||||
import { type SelectOption } from 'twenty-ui/input';
|
||||
import { isObjectMetadataReadOnly } from '@/object-record/read-only/utils/isObjectMetadataReadOnly';
|
||||
|
||||
export const settingsDataModelObjectIdentifiersFormSchema =
|
||||
objectMetadataItemSchema.pick({
|
||||
@@ -44,6 +45,7 @@ const StyledContainer = styled.div`
|
||||
export const SettingsDataModelObjectIdentifiersForm = ({
|
||||
objectMetadataItem,
|
||||
}: SettingsDataModelObjectIdentifiersFormProps) => {
|
||||
const readonly = isObjectMetadataReadOnly({ objectMetadataItem });
|
||||
const formConfig = useForm<SettingsDataModelObjectIdentifiersFormValues>({
|
||||
mode: 'onTouched',
|
||||
resolver: zodResolver(settingsDataModelObjectIdentifiersFormSchema),
|
||||
@@ -134,7 +136,7 @@ export const SettingsDataModelObjectIdentifiersForm = ({
|
||||
options={options}
|
||||
value={value}
|
||||
withSearchInput={label === t`Record label`}
|
||||
disabled={!objectMetadataItem.isCustom}
|
||||
disabled={!objectMetadataItem.isCustom || readonly}
|
||||
callToActionButton={
|
||||
label === t`Record label`
|
||||
? {
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export type ItemTagInfo =
|
||||
| StandardItemTagInfo
|
||||
| CustomItemTagInfo
|
||||
| RemoteItemTagInfo
|
||||
| ManagedItemTagInfo;
|
||||
|
||||
type StandardItemTagInfo = {
|
||||
labelText: 'Standard';
|
||||
labelColor: 'blue';
|
||||
};
|
||||
|
||||
type CustomItemTagInfo = {
|
||||
labelText: 'Custom';
|
||||
labelColor: 'orange';
|
||||
};
|
||||
|
||||
type RemoteItemTagInfo = {
|
||||
labelText: 'Remote';
|
||||
labelColor: 'green';
|
||||
};
|
||||
|
||||
type ManagedItemTagInfo = {
|
||||
labelText: 'Managed';
|
||||
labelColor: 'sky';
|
||||
};
|
||||
|
||||
export const getItemTagInfo = ({
|
||||
isCustom,
|
||||
isRemote,
|
||||
applicationId,
|
||||
}: {
|
||||
isCustom?: boolean;
|
||||
isRemote?: boolean;
|
||||
applicationId?: string | null;
|
||||
}): ItemTagInfo => {
|
||||
if (isDefined(applicationId)) {
|
||||
return { labelText: 'Managed', labelColor: 'sky' };
|
||||
}
|
||||
|
||||
if (isCustom!!) {
|
||||
return { labelText: 'Custom', labelColor: 'orange' };
|
||||
}
|
||||
|
||||
if (isRemote!!) {
|
||||
return { labelText: 'Remote', labelColor: 'green' };
|
||||
}
|
||||
|
||||
return { labelText: 'Standard', labelColor: 'blue' };
|
||||
};
|
||||
@@ -1,39 +0,0 @@
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
|
||||
export type ObjectTypeLabel =
|
||||
| StandardObjectTypeLabel
|
||||
| CustomObjectTypeLabel
|
||||
| RemoteObjectTypeLabel;
|
||||
|
||||
type StandardObjectTypeLabel = {
|
||||
labelText: 'Standard';
|
||||
labelColor: 'blue';
|
||||
};
|
||||
|
||||
type CustomObjectTypeLabel = {
|
||||
labelText: 'Custom';
|
||||
labelColor: 'orange';
|
||||
};
|
||||
|
||||
type RemoteObjectTypeLabel = {
|
||||
labelText: 'Remote';
|
||||
labelColor: 'green';
|
||||
};
|
||||
|
||||
export const getObjectTypeLabel = (
|
||||
objectMetadataItem: Pick<ObjectMetadataItem, 'isCustom' | 'isRemote'>,
|
||||
): ObjectTypeLabel =>
|
||||
objectMetadataItem.isCustom
|
||||
? {
|
||||
labelText: 'Custom',
|
||||
labelColor: 'orange',
|
||||
}
|
||||
: objectMetadataItem.isRemote
|
||||
? {
|
||||
labelText: 'Remote',
|
||||
labelColor: 'green',
|
||||
}
|
||||
: {
|
||||
labelText: 'Standard',
|
||||
labelColor: 'blue',
|
||||
};
|
||||
Reference in New Issue
Block a user