Skip to content

Commit 7fe74b0

Browse files
committed
feat(FR-1407): add modify and delete action buttons for deployment detail page
1 parent 757944c commit 7fe74b0

29 files changed

+322
-46
lines changed

data/schema.graphql

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3111,7 +3111,7 @@ input ModelRevisionFilter
31113111
}
31123112

31133113
"""Added in 25.13.0"""
3114-
input ModelRevisionOrder
3114+
input ModelRevisionOrderBy
31153115
@join__type(graph: STRAWBERRY)
31163116
{
31173117
field: ModelRevisionOrderField!
@@ -4672,43 +4672,13 @@ type Query
46724672
artifactRevisions(filter: ArtifactRevisionFilter = null, orderBy: [ArtifactRevisionOrderBy!] = null, before: String = null, after: String = null, first: Int = null, last: Int = null, limit: Int = null, offset: Int = null): ArtifactRevisionConnection! @join__field(graph: STRAWBERRY)
46734673

46744674
"""Added in 25.13.0"""
4675-
deployments(
4676-
filter: DeploymentFilter = null
4677-
orderBy: DeploymentOrderBy = null
4678-
4679-
"""Returns the first n items from the list."""
4680-
first: Int = null
4681-
4682-
"""Returns the items in the list that come after the specified cursor."""
4683-
after: String = null
4684-
4685-
"""Returns the items in the list that come before the specified cursor."""
4686-
before: String = null
4687-
4688-
"""Returns the items in the list that come after the specified cursor."""
4689-
last: Int = null
4690-
): ModelDeploymentConnection! @join__field(graph: STRAWBERRY)
4675+
deployments(filter: DeploymentFilter = null, orderBy: [DeploymentOrderBy!] = null, before: String = null, after: String = null, first: Int = null, last: Int = null, limit: Int = null, offset: Int = null): ModelDeploymentConnection! @join__field(graph: STRAWBERRY)
46914676

46924677
"""Added in 25.13.0"""
46934678
deployment(id: ID!): ModelDeployment @join__field(graph: STRAWBERRY)
46944679

46954680
"""Added in 25.13.0"""
4696-
revisions(
4697-
filter: ModelRevisionFilter = null
4698-
order: ModelRevisionOrder = null
4699-
4700-
"""Returns the first n items from the list."""
4701-
first: Int = null
4702-
4703-
"""Returns the items in the list that come after the specified cursor."""
4704-
after: String = null
4705-
4706-
"""Returns the items in the list that come before the specified cursor."""
4707-
before: String = null
4708-
4709-
"""Returns the items in the list that come after the specified cursor."""
4710-
last: Int = null
4711-
): ModelRevisionConnection! @join__field(graph: STRAWBERRY)
4681+
revisions(filter: ModelRevisionFilter = null, orderBy: [ModelRevisionOrderBy!] = null, before: String = null, after: String = null, first: Int = null, last: Int = null, limit: Int = null, offset: Int = null): ModelRevisionConnection! @join__field(graph: STRAWBERRY)
47124682

47134683
"""Added in 25.13.0"""
47144684
revision(id: ID!): ModelRevision @join__field(graph: STRAWBERRY)
@@ -5345,6 +5315,9 @@ input UpdateModelDeploymentInput
53455315
tags: [String!] = null
53465316
defaultDeploymentStrategy: DeploymentStrategyInput = null
53475317
activeRevisionId: ID = null
5318+
desiredReplicaCount: Int = null
5319+
name: String = null
5320+
preferredDomainName: String = null
53485321
}
53495322

53505323
"""Added in 25.13.0"""

packages/backend.ai-ui/src/components/Table/BAITable.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,7 @@ const BAITable = <RecordType extends object = any>({
331331
opacity: loading ? 0.7 : 1,
332332
transition: 'opacity 0.3s ease',
333333
}}
334+
scroll={tableProps.scroll || { x: 'max-content' }}
334335
components={
335336
resizable
336337
? _.merge(components || {}, {

react/src/components/ActiveRevisionSettingModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const ActiveRevisionSettingModal: React.FC<ActiveRevisionSettingModalProps> = ({
6868
message.error(error);
6969
}
7070
} else {
71-
message.success(t('maintenance.SuccessfullyUpdated'));
71+
message.success(t('message.SuccessfullyUpdated'));
7272
onRequestClose(true);
7373
}
7474
},
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import BAIModal, { BAIModalProps } from './BAIModal';
2+
import DeploymentMetadataFormItem from './DeploymentMetadataFormItem';
3+
import DeploymentNetworkAccessFormItem from './DeploymentNetworkAccessFormItem';
4+
import DeploymentStrategyFormItem from './DeploymentStrategyFormItem';
5+
import { App, Form, FormInstance } from 'antd';
6+
import { toLocalId } from 'backend.ai-ui';
7+
import { useRef } from 'react';
8+
import { useTranslation } from 'react-i18next';
9+
import { graphql, useFragment, useMutation } from 'react-relay';
10+
import {
11+
DeploymentModifyModalFragment$data,
12+
DeploymentModifyModalFragment$key,
13+
} from 'src/__generated__/DeploymentModifyModalFragment.graphql';
14+
import { DeploymentModifyModalMutation } from 'src/__generated__/DeploymentModifyModalMutation.graphql';
15+
16+
interface DeploymentModifyModalProps extends BAIModalProps {
17+
deploymentFrgmt?: DeploymentModifyModalFragment$key | null;
18+
onRequestClose: (success?: boolean) => void;
19+
}
20+
21+
const DeploymentModifyModal: React.FC<DeploymentModifyModalProps> = ({
22+
onRequestClose,
23+
deploymentFrgmt,
24+
...baiModalProps
25+
}) => {
26+
const { t } = useTranslation();
27+
const { message } = App.useApp();
28+
const formRef =
29+
useRef<FormInstance<DeploymentModifyModalFragment$data>>(null);
30+
31+
const deployment = useFragment(
32+
graphql`
33+
fragment DeploymentModifyModalFragment on ModelDeployment {
34+
id
35+
metadata {
36+
name
37+
tags
38+
}
39+
networkAccess {
40+
openToPublic
41+
preferredDomainName
42+
}
43+
defaultDeploymentStrategy {
44+
type
45+
}
46+
replicaState {
47+
desiredReplicaCount
48+
}
49+
}
50+
`,
51+
deploymentFrgmt,
52+
);
53+
54+
const [commitUpdateDeployment, isInFlightUpdateDeployment] =
55+
useMutation<DeploymentModifyModalMutation>(graphql`
56+
mutation DeploymentModifyModalMutation(
57+
$input: UpdateModelDeploymentInput!
58+
) {
59+
updateModelDeployment(input: $input) {
60+
deployment {
61+
id
62+
metadata {
63+
name
64+
tags
65+
}
66+
networkAccess {
67+
openToPublic
68+
}
69+
defaultDeploymentStrategy {
70+
type
71+
}
72+
}
73+
}
74+
}
75+
`);
76+
77+
const handleOk = () => {
78+
formRef.current?.validateFields().then((values) => {
79+
commitUpdateDeployment({
80+
variables: {
81+
input: {
82+
id: toLocalId(deployment?.id || ''),
83+
name: values.metadata?.name,
84+
tags: values.metadata?.tags,
85+
defaultDeploymentStrategy: values?.defaultDeploymentStrategy,
86+
desiredReplicaCount: values.replicaState?.desiredReplicaCount,
87+
preferredDomainName: values.networkAccess?.preferredDomainName,
88+
openToPublic: values.networkAccess?.openToPublic,
89+
},
90+
},
91+
onCompleted: (res, errors) => {
92+
if (!res?.updateModelDeployment?.deployment?.id) {
93+
message.error(t('message.FailedToUpdate'));
94+
return;
95+
}
96+
if (errors && errors.length > 0) {
97+
const errorMsgList = errors.map((error) => error.message);
98+
for (const error of errorMsgList) {
99+
message.error(error);
100+
}
101+
} else {
102+
message.success(t('message.SuccessfullyUpdated'));
103+
onRequestClose(true);
104+
}
105+
},
106+
onError: (err) => {
107+
message.error(err.message || t('message.FailedToUpdate'));
108+
},
109+
});
110+
});
111+
};
112+
113+
return (
114+
<BAIModal
115+
{...baiModalProps}
116+
destroyOnClose
117+
onOk={handleOk}
118+
onCancel={() => onRequestClose(false)}
119+
okText={t('button.Update')}
120+
confirmLoading={isInFlightUpdateDeployment}
121+
title={t('deployment.ModifyDeployment')}
122+
>
123+
<Form
124+
ref={formRef}
125+
layout="vertical"
126+
initialValues={{
127+
...deployment,
128+
}}
129+
style={{ maxWidth: '100%' }}
130+
>
131+
<DeploymentMetadataFormItem />
132+
<DeploymentStrategyFormItem />
133+
<DeploymentNetworkAccessFormItem />
134+
</Form>
135+
</BAIModal>
136+
);
137+
};
138+
139+
export default DeploymentModifyModal;

react/src/components/DeploymentNetworkAccessFormItem.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ const DeploymentNetworkAccessFormItem: React.FC = () => {
1818
name={['networkAccess', 'preferredDomainName']}
1919
label={t('deployment.launcher.PreferredDomainName')}
2020
>
21-
<Input
22-
placeholder={t('deployment.launcher.PreferredDomainNamePlaceholder')}
23-
/>
21+
<Input placeholder={'my-model.example.com'} />
2422
</Form.Item>
2523

2624
<Form.Item

react/src/components/DeploymentStrategyFormItem.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ const DeploymentStrategyFormItem: React.FC = () => {
103103
}}
104104
</Form.Item>
105105
<Form.Item
106-
name={['desiredReplicaCount']}
106+
name={['replicaState', 'desiredReplicaCount']}
107107
label={t('deployment.NumberOfDesiredReplicas')}
108108
rules={[
109109
{

react/src/components/DeploymentTokenGenerationModal.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ const DeploymentTokenGenerationModal: React.FC<
8181
onCancel={() => onRequestClose(false)}
8282
okText={t('button.Generate')}
8383
confirmLoading={isInFlightCreateAccessToken}
84-
centered
8584
title={t('deployment.GenerateNewToken')}
8685
>
8786
<Form

0 commit comments

Comments
 (0)