Skip to content

Commit ab34638

Browse files
[master] feat: add formdata version of creating helm app (#4409)
* feat: add formdata version of creating helm app Signed-off-by: ROOMrepair <twekjz@gmail.com> * fix: change comments to English Signed-off-by: ROOMrepair <twekjz@gmail.com> --------- Signed-off-by: ROOMrepair <twekjz@gmail.com> Co-authored-by: ROOMrepair <twekjz@gmail.com>
1 parent a672c34 commit ab34638

File tree

7 files changed

+279
-13
lines changed

7 files changed

+279
-13
lines changed

packages/shared/src/components/Apps/AppCreate/CreateHelmApp/index.tsx

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Templet } from '@kubed/icons';
88
import { notify } from '@kubed/components';
99
import { useParams } from 'react-router-dom';
1010
import { PackageUpload } from '../../PackageUpload';
11-
import { getCreateAppParams } from '../../../../utils';
11+
import { getCreateAppParams, getCreateAppParamsFormData } from '../../../../utils';
1212
import { openpitrixStore } from '../../../../stores';
1313
import CheckFiles from './CheckFiles';
1414
import CreateInfo from './CreateInfo';
@@ -22,6 +22,13 @@ type FormattedFileInfo = {
2222
icon?: string;
2323
};
2424

25+
type FormattedFileInfoFormData = {
26+
status?: string;
27+
name?: string;
28+
formData?: FormData;
29+
icon?: string;
30+
};
31+
2532
type Props = {
2633
visible: boolean;
2734
title?: ReactNode;
@@ -30,6 +37,7 @@ type Props = {
3037
workspace?: string;
3138
type?: string;
3239
onOk?: (data: Record<string, unknown>) => void;
40+
onOkFormData?: (data: Record<string, unknown>, formData: FormData) => void;
3341
onCancel?: () => void;
3442
};
3543

@@ -42,25 +50,39 @@ export function CreateHelmApp({
4250
description,
4351
onCancel,
4452
onOk,
53+
onOkFormData,
4554
}: Props): JSX.Element {
4655
const { appName = '', workspace = ws } = useParams();
4756
const [appIcon, setIconStr] = useState<string>();
4857
const [canCreate, setCanCreate] = useState<boolean>(false);
4958
const [checkedFileInfo, setCheckedFileInfo] = useState<FormattedFileInfo>();
59+
const [checkedFileInfoFormData, setCheckedFileInfoFormData] =
60+
useState<FormattedFileInfoFormData>();
61+
5062
// const htmlDesc = t('APP_CREATE_GUIDE', { docUrl: getWebsiteUrl() });
5163
const checkedUnSuccess = useMemo(
5264
() => checkedFileInfo?.status !== 'success',
5365
[checkedFileInfo?.status],
5466
);
5567

68+
const checkedUnSuccessFormData = useMemo(
69+
() => checkedFileInfoFormData?.status !== 'success',
70+
[checkedFileInfoFormData?.status],
71+
);
72+
5673
function initCheckedStatus(): void {
5774
setCheckedFileInfo(prevChecked => ({ ...prevChecked, status: 'init' }));
5875
}
5976

77+
function initCheckedStatusFormData(): void {
78+
setCheckedFileInfoFormData(prevChecked => ({ ...prevChecked, status: 'init' }));
79+
}
80+
6081
function handleCancel(): void {
6182
onCancel?.();
6283
setCanCreate(false);
6384
initCheckedStatus();
85+
initCheckedStatusFormData();
6486
}
6587

6688
async function submitData(): Promise<void> {
@@ -74,6 +96,22 @@ export function CreateHelmApp({
7496
await fileStore.uploadPackage('CREATE_APP', data, onOk);
7597
}
7698

99+
async function submitDataFormData(): Promise<void | string> {
100+
if (!checkedFileInfoFormData?.formData) {
101+
return notify.error(t('UPLOAD_PACKAGE_OK_NOTE'));
102+
}
103+
const { formData, ...restInfo } = checkedFileInfoFormData;
104+
105+
const data: Record<string, unknown> = getCreateAppParamsFormData({
106+
appType: 'helm',
107+
workspace,
108+
// package: checkedFileInfo?.base64Str,
109+
...restInfo,
110+
icon: appIcon,
111+
});
112+
await fileStore.uploadPackageFormData('CREATE_APP', data, formData, onOkFormData);
113+
}
114+
77115
async function handleSubmit() {
78116
if (checkedUnSuccess) {
79117
return notify.error(t('UPLOAD_PACKAGE_OK_NOTE'));
@@ -87,16 +125,29 @@ export function CreateHelmApp({
87125
initCheckedStatus();
88126
}
89127

128+
async function handleSubmitFormData() {
129+
if (checkedUnSuccessFormData) {
130+
return notify.error(t('UPLOAD_PACKAGE_OK_NOTE'));
131+
}
132+
if (!canCreate) {
133+
return setCanCreate(!canCreate);
134+
}
135+
136+
await submitDataFormData();
137+
setCanCreate(false);
138+
initCheckedStatusFormData();
139+
}
140+
90141
return (
91142
<StyledModal
92143
width={960}
93144
titleIcon={<Templet size={40} />}
94145
title={title || t('UPLOAD_HELM_TITLE')}
95146
description={description || t('UPLOAD_HELM_CHART_DESC')}
96147
visible={visible}
97-
onOk={handleSubmit}
148+
onOk={onOkFormData ? handleSubmitFormData : handleSubmit}
98149
onCancel={handleCancel}
99-
okButtonProps={{ disabled: checkedUnSuccess }}
150+
okButtonProps={{ disabled: onOkFormData ? checkedUnSuccessFormData : checkedUnSuccess }}
100151
>
101152
<IconHelm size={60} />
102153
<PackageUpload
@@ -105,18 +156,24 @@ export function CreateHelmApp({
105156
canCreate={canCreate}
106157
workspace={workspace}
107158
onCheckStatusChange={setCheckedFileInfo}
159+
initCheckedStatus={initCheckedStatus}
160+
onCheckStatusChangeFormData={onOkFormData ? setCheckedFileInfoFormData : undefined}
161+
initCheckedStatusFormData={initCheckedStatusFormData}
108162
/>
109163
{!canCreate ? (
110164
<>
111-
<CheckFiles unSuccess={checkedUnSuccess} />
165+
<CheckFiles unSuccess={onOkFormData ? checkedUnSuccessFormData : checkedUnSuccess} />
112166
{/*{showOutSiteLink() && (*/}
113167
{/* <div>*/}
114168
{/* 💁‍♂️ <span dangerouslySetInnerHTML={{ __html: htmlDesc }} />*/}
115169
{/* </div>*/}
116170
{/*)}*/}
117171
</>
118172
) : (
119-
<CreateInfo createInfo={checkedFileInfo} onIconChange={setIconStr} />
173+
<CreateInfo
174+
createInfo={onOkFormData ? checkedFileInfoFormData : checkedFileInfo}
175+
onIconChange={setIconStr}
176+
/>
120177
)}
121178
</StyledModal>
122179
);

packages/shared/src/components/Apps/AppCreate/index.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ import { Button, Modal, notify } from '@kubed/components';
99
import Icon from '../../Icon';
1010
import { useV3action } from '../../../hooks';
1111
import { openpitrixStore, workspaceStore } from '../../../stores';
12-
import { getCreateAppParams } from '../../../utils';
12+
import { getCreateAppParams, getCreateAppParamsFormData } from '../../../utils';
1313
import { CreateHelmApp } from './CreateHelmApp';
1414
import { CreateYamlApp } from './CreateYamlApp';
1515
import { Header, HeaderFieldItem, Logo, FieldItem } from './styles';
1616

1717
type Props = {
1818
visible?: boolean;
1919
onOk?: (data: any, params: any) => void;
20+
onOkFormData?: (data: any, formData: FormData, params: any) => void;
2021
onCancel?: () => void;
2122
tableRef?: any;
2223
workspace?: string;
@@ -27,14 +28,15 @@ type Props = {
2728

2829
type ModalType = 'create_helm' | 'create_yaml' | 'create_edge';
2930

30-
const { createApp } = openpitrixStore;
31+
const { createApp, createAppFormData } = openpitrixStore;
3132
const { useFetchWorkspaceQuery } = workspaceStore;
3233

3334
export function CreateApp({
3435
visible,
3536
onCancel,
3637
tableRef,
3738
onOk,
39+
onOkFormData,
3840
workspace = '',
3941
isDetail,
4042
appName,
@@ -104,13 +106,35 @@ export function CreateApp({
104106
onCancel?.();
105107
tableRef?.current?.refetch();
106108
}
109+
110+
// todo When using formData and an external operation function is passed, use onOkFormData
111+
async function handleCreateFormData(fileData: any, formData: FormData): Promise<void> {
112+
fileData.maintainers = [{ name: globals.user.username }];
113+
fileData.workspace = workspace;
114+
if (onOkFormData) {
115+
onOkFormData(getCreateAppParamsFormData(fileData), formData, { workspace });
116+
notify.success(t('UPLOAD_SUCCESSFUL'));
117+
118+
setModalVisible(false);
119+
onCancel?.();
120+
tableRef?.current?.refetch();
121+
return;
122+
}
123+
sessionStorage.removeItem('appType');
124+
await createAppFormData({ workspace }, fileData, formData);
125+
notify.success(t('UPLOAD_SUCCESSFUL'));
126+
setModalVisible(false);
127+
onCancel?.();
128+
tableRef?.current?.refetch();
129+
}
107130
function renderModal() {
108131
if (modalType === 'create_helm') {
109132
return (
110133
<CreateHelmApp
111134
visible={modalVisible}
112135
onCancel={() => setModalVisible(false)}
113136
onOk={handleCreate}
137+
onOkFormData={!onOk || onOkFormData ? handleCreateFormData : undefined}
114138
/>
115139
);
116140
}

packages/shared/src/components/Apps/PackageUpload/index.tsx

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ type Props = {
2929
appName?: string;
3030
type?: string;
3131
onOk?: (data: PackageInfo) => void;
32+
onOkFormData?: (data: any, formData: FormData) => void;
3233
onCheckStatusChange?: (status: any) => void;
34+
onCheckStatusChangeFormData?: (status: any) => void;
35+
initCheckedStatus?: () => void;
36+
initCheckedStatusFormData?: () => void;
3337
hasPackage?: boolean;
3438
canCreate?: boolean;
3539
canEdit?: boolean;
@@ -56,15 +60,28 @@ export function PackageUpload({
5660
versionID,
5761
type = 'CREATE_APP',
5862
onOk,
63+
onOkFormData,
5964
onCheckStatusChange,
65+
onCheckStatusChangeFormData,
66+
initCheckedStatus,
67+
initCheckedStatusFormData,
6068
updateTime = '',
6169
packageName,
6270
className,
6371
workspace: ws,
6472
appType,
6573
disabledUpload,
6674
}: Props): JSX.Element {
67-
const { checkFile, handleFileByBase64Str, validatePackage, uploadPackage } = fileStore;
75+
const {
76+
checkFile,
77+
checkFileFormData,
78+
handleFileByBase64Str,
79+
handleFileFormData,
80+
validatePackage,
81+
validatePackageFormData,
82+
uploadPackage,
83+
uploadPackageFormData,
84+
} = fileStore;
6885
const state: Record<string, any> = {};
6986
const { workspace = ws } = useParams();
7087
const [errorInfo, setErrorInfo] = useState<any>('');
@@ -108,16 +125,58 @@ export function PackageUpload({
108125
}
109126
}
110127

128+
async function packageValidatorFormData(formData: FormData): Promise<any> {
129+
const result = await validatePackageFormData({
130+
formData,
131+
appName,
132+
workspace,
133+
});
134+
const status = result.error ? 'error' : 'success';
135+
setMissFile(result.missFile);
136+
setErrorInfo(result.error);
137+
setUploadStatus(status);
138+
onCheckStatusChangeFormData?.({ status, formData, ...result });
139+
140+
// todo when using formdata
141+
// todo type === MODIFY_VERSION and an external operation function is passed,use onOkFormData
142+
if (type === 'MODIFY_VERSION' && status === 'success') {
143+
const uploadData = {
144+
versionID: versionID || result.versionID,
145+
appName: appName,
146+
workspace,
147+
name: result.versionName,
148+
// package: result.base64Str || base64Str,
149+
};
150+
uploadPackageFormData(type, uploadData, formData, (data: any, form: FormData) => {
151+
onOkFormData?.(data, form);
152+
});
153+
setUploadStatus('init');
154+
}
155+
}
156+
111157
async function checkPackage(file: File): Promise<void> {
158+
initCheckedStatusFormData?.();
159+
initCheckedStatus?.();
160+
112161
setUploadStatus('uploading');
113162
setFileName(file.name);
114163

115-
const result = checkFile?.(file, 'package');
116-
if (!result) {
117-
return handleFileByBase64Str?.(file, packageValidator);
164+
if (onCheckStatusChangeFormData || onOkFormData) {
165+
const result = checkFileFormData?.(file, 'package');
166+
if (!result) {
167+
return handleFileFormData?.(file, packageValidatorFormData);
168+
}
169+
170+
setErrorInfo(result);
171+
} else {
172+
const result = checkFile?.(file, 'package');
173+
if (!result) {
174+
return handleFileByBase64Str?.(file, packageValidator);
175+
}
176+
177+
setErrorInfo(result);
118178
}
119179

120-
setErrorInfo(result);
121180
setUploadStatus('error');
122181
return Promise.reject();
123182
}

packages/shared/src/stores/openpitrix/app.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
request,
1515
addCreateAppUrl,
1616
getCreateAppParams,
17+
getCreateAppParamsFormData,
1718
} from '../../utils';
1819

1920
import { BaseUrlParams, defaultUrl, getBaseUrl, useBaseList } from './base';
@@ -94,6 +95,19 @@ export function createApp({ workspace }: BaseUrlParams, data: any): Promise<any>
9495
return request.post(addCreateAppUrl(url), getCreateAppParams(data));
9596
}
9697

98+
export function createAppFormData({ workspace }: BaseUrlParams, data: any, formData: FormData) {
99+
const url = getBaseUrl({ workspace }, resourceName);
100+
const requestData = getCreateAppParamsFormData(data);
101+
const jsonData = JSON.stringify(requestData);
102+
formData.append('jsonData', jsonData);
103+
104+
return request.post(addCreateAppUrl(url), formData, {
105+
headers: {
106+
'Content-Type': 'multipart/form-data',
107+
},
108+
});
109+
}
110+
97111
export function EditApp({ workspace, appName }: BaseUrlParams, params: any): Promise<any> {
98112
const url = getBaseUrl({ workspace, appName }, resourceName);
99113

0 commit comments

Comments
 (0)