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:
martmull
2025-10-15 17:13:29 +02:00
committed by GitHub
parent c0ed246a03
commit b16ab1b7c9
109 changed files with 2464 additions and 1357 deletions
@@ -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,
@@ -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}
/>
}
@@ -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);
@@ -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>
</>
@@ -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}
/>
</>
}
@@ -42,6 +42,7 @@ export const SettingsDataModelFieldTextSettingsFormCard = ({
fieldType={FieldMetadataType.TEXT}
existingFieldMetadataId={existingFieldMetadataId}
objectNameSingular={objectNameSingular}
disabled={disabled}
/>
</>
}
@@ -55,6 +55,7 @@ export const SettingsDataModelFieldDateSettingsFormCard = ({
fieldType={fieldType}
existingFieldMetadataId={existingFieldMetadataId}
objectNameSingular={objectNameSingular}
disabled={disabled}
/>
</>
}
@@ -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}
@@ -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}
/>
}
/>
@@ -42,6 +42,7 @@ export const SettingsDataModelFieldNumberSettingsFormCard = ({
fieldType={FieldMetadataType.NUMBER}
existingFieldMetadataId={existingFieldMetadataId}
objectNameSingular={objectNameSingular}
disabled={disabled}
/>
</>
}
@@ -58,6 +58,7 @@ export const SettingsDataModelFieldPhonesSettingsFormCard = ({
fieldType={FieldMetadataType.PHONES}
existingFieldMetadataId={existingFieldMetadataId}
objectNameSingular={objectNameSingular}
disabled={disabled}
/>
</>
}
@@ -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}
@@ -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}
/>
}
/>
@@ -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>
)}
</>
)}
/>
@@ -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}
/>
}
/>