Skip to content

Commit

Permalink
#1275 Auto promotion property form
Browse files Browse the repository at this point in the history
  • Loading branch information
dcoraboeuf committed Jun 2, 2024
1 parent 9d649c8 commit 1d471d0
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 32 deletions.
3 changes: 3 additions & 0 deletions ontrack-web-core/components/common/ExtensionUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function getExtensionShortName(fqcn) {
return fqcn.slice("net.nemerosa.ontrack.extension.".length)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const usePropertyDialog = () => {
return useFormDialog({
init: (form, {entityType, entityId, propertyList, initialProperty}) => {
form.setFieldValue("propertyType", initialProperty?.type?.typeName)
form.setFieldValue("value", initialProperty?.value)
form.setFieldValue("value", initialProperty?.clientValue)
setEntity({entityType, entityId})
setSelectedProperty(initialProperty)
setOptions(
Expand All @@ -46,6 +46,7 @@ export const usePropertyDialog = () => {
options,
selectedProperty,
setSelectedProperty,
entity,
query: gql`
mutation SaveProperty(
$entityType: ProjectEntityType!,
Expand Down Expand Up @@ -128,7 +129,7 @@ export default function PropertyDialog({dialog}) {
}
{
dialog.selectedProperty.editable && <>
<PropertyForm property={dialog.selectedProperty} prefix="value"/>
<PropertyForm property={dialog.selectedProperty} entity={dialog.entity} prefix="value"/>
</>
}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {useGraphQLClient} from "@components/providers/ConnectionContextProvider"
import {gql} from "graphql-request";
import {useEventForRefresh} from "@components/common/EventsContext";
import PropertyTitle from "@components/framework/properties/PropertyTitle";
import {callDynamicFunction} from "@components/common/DynamicFunction";
import {getExtensionShortName} from "@components/common/ExtensionUtils";

export default function PropertiesSection({entityType, entityId}) {

Expand All @@ -17,8 +19,9 @@ export default function PropertiesSection({entityType, entityId}) {
const refreshCount = useEventForRefresh("entity.properties.changed")

useEffect(() => {
if (client) {
client.request(

const fetchPropertyList = async () => {
const data = await client.request(
gql`
query EntityProperties(
$type: ProjectEntityType!,
Expand All @@ -41,9 +44,34 @@ export default function PropertiesSection({entityType, entityId}) {
type: entityType,
id: entityId,
}
).then(data => {
setPropertyList(data.entity.properties)
})
)

const initialProperties = data.entity.properties

const transformedProperties = await Promise.all(
initialProperties.map(async (property) => {
if (property.value) {
const shortName = getExtensionShortName(property.type.typeName)
const newValue = await callDynamicFunction(
`framework/properties/${shortName}/Prepare`,
property.value
) ?? property.value
return {
...property,
clientValue: newValue,
}
} else {
return property
}
})
)

setPropertyList(transformedProperties)
}

if (client) {
// noinspection JSIgnoredPromiseFromCall
fetchPropertyList()
}
}, [client, entityType, entityId, refreshCount])

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Dynamic} from "@components/common/Dynamic";

export default function PropertyForm({prefix, property}) {
export default function PropertyForm({prefix, entity, property}) {
const shortTypeName = property.type.typeName.slice("net.nemerosa.ontrack.extension.".length)
return <Dynamic path={`framework/properties/${shortTypeName}/Form`} props={{prefix, property}}/>
return <Dynamic path={`framework/properties/${shortTypeName}/Form`} props={{prefix, property, entity}}/>
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,54 @@
import {Form, Input} from "antd";
import {prefixedFormName} from "@components/form/formUtils";
import SelectMultipleValidationStampNames from "@components/validationStamps/SelectMultipleValidationStampNames";
import SelectMultiplePromotionLevelNames from "@components/promotionLevels/SelectMultiplePromotionLevelNames";
import SelectValidationStamp from "@components/validationStamps/SelectValidationStamp";
import {useEffect, useState} from "react";
import {useGraphQLClient} from "@components/providers/ConnectionContextProvider";
import {gql} from "graphql-request";
import SelectPromotionLevel from "@components/promotionLevels/SelectPromotionLevel";

export default function PropertyForm({prefix}) {
export default function PropertyForm({prefix, entity}) {

const {entityType, entityId} = entity
if (entityType !== 'PROMOTION_LEVEL') throw new Error(`Expecting a promotion level, got ${entityType}`)

const [promotionLevel, setPromotionLevel] = useState()
const client = useGraphQLClient()

useEffect(() => {
if (client) {
client.request(
gql`
query GetPromotionLevel(
$id: Int!,
) {
promotionLevel(id: $id) {
branch {
id
}
}
}
`,
{
id: entityId
}
).then(data => {
setPromotionLevel(data.promotionLevel)
})
}
}, [client])

return (
<>
<Form.Item
label="Validation stamps"
extra="List of validation stamps which trigger this promotion"
name={prefixedFormName(prefix, 'validationStamps')}
>
<SelectMultipleValidationStampNames/>
</Form.Item>
{
promotionLevel &&
<Form.Item
label="Validation stamps"
extra="List of validation stamps which trigger this promotion"
name={prefixedFormName(prefix, 'validationStamps')}
>
<SelectValidationStamp branch={promotionLevel.branch} multiple={true} useName={false}/>
</Form.Item>
}
<Form.Item
label="Including"
extra="Regular expression to include validation stamps by name"
Expand All @@ -28,13 +63,16 @@ export default function PropertyForm({prefix}) {
>
<Input/>
</Form.Item>
<Form.Item
label="Promotion levels"
extra="List of promotion levels which trigger this promotion"
name={prefixedFormName(prefix, 'promotionLevels')}
>
<SelectMultiplePromotionLevelNames/>
</Form.Item>
{
promotionLevel &&
<Form.Item
label="Promotion levels"
extra="List of promotion levels which trigger this promotion"
name={prefixedFormName(prefix, 'promotionLevels')}
>
<SelectPromotionLevel branch={promotionLevel.branch} multiple={true} useName={false}/>
</Form.Item>
}
</>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function prepare(value) {
return {
...value,
validationStamps: value.validationStamps?.map(vs => vs.id) ?? [],
promotionLevels: value.promotionLevels?.map(pl => pl.id) ?? [],
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default function SelectPromotionLevel({
allowClear = false,
disabled = false,
placeholder = "Promotion level",
multiple = false,
}) {

const client = useGraphQLClient()
Expand Down Expand Up @@ -54,12 +55,10 @@ export default function SelectPromotionLevel({
disabled={disabled}
placeholder={placeholder}
options={options}
style={{
width: '10em',
}}
value={value}
onChange={onChange}
allowClear={allowClear}
mode={multiple ? "multiple" : undefined}
/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import MultipleSelectSearch from "@components/common/MultipleSelectSearch";
import {gql} from "graphql-request";
import {useGraphQLClient} from "@components/providers/ConnectionContextProvider";

export default function SelectMultipleValidationStampNames({value, onChange}) {
export default function SelectMultipleValidationStampsNames({value, onChange}) {

const client = useGraphQLClient()
const fetchValidationNames = async (token) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Button, Form, Input, Space} from "antd";
import {useContext} from "react";
import SelectMultiplePromotionLevelNames from "@components/promotionLevels/SelectMultiplePromotionLevelNames";
import SelectMultipleValidationStampNames from "@components/validationStamps/SelectMultipleValidationStampNames";
import SelectMultipleValidationStampsNames from "@components/validationStamps/SelectMultipleValidationStampsNames";
import {FaPlus, FaTrash} from "react-icons/fa";
import SelectProjectBranch from "@components/branches/SelectProjectBranch";
import SelectInterval from "@components/common/SelectInterval";
Expand Down Expand Up @@ -42,7 +42,7 @@ export default function BranchStatusesWidgetForm({promotions, validations, refre
label="List of validations to display"
initialValue={validations}
>
<SelectMultipleValidationStampNames/>
<SelectMultipleValidationStampsNames/>
</Form.Item>
<Form.List name="branches" initialValue={branches}>
{(fields, {add, remove}) => (
Expand Down

0 comments on commit 1d471d0

Please sign in to comment.