Skip to content

Commit

Permalink
feat: improve route (apache#483)
Browse files Browse the repository at this point in the history
* feat: improve step1

* feat: improve step2

* feat: improve createStep4

* feat: improve transform

* fix: event loop

* feat: clean code

* fix: lost route_group info when enable redirect

* feat: UI improve
  • Loading branch information
LiteSun authored Sep 21, 2020
1 parent 7296a56 commit 234e1ea
Show file tree
Hide file tree
Showing 13 changed files with 431 additions and 380 deletions.
143 changes: 61 additions & 82 deletions src/pages/Route/Create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,7 @@ import { transformer as chartTransformer } from '@api7-dashboard/pluginchart';

import ActionBar from '@/components/ActionBar';

import {
create,
fetchItem,
fetchUpstreamItem,
fetchRouteGroupItem,
update,
checkUniqueName,
checkHostWithSSL
} from './service';
import { create, fetchItem, update, checkUniqueName, checkHostWithSSL } from './service';
import Step1 from './components/Step1';
import Step2 from './components/Step2';
import Step3 from './components/Step3';
Expand Down Expand Up @@ -68,80 +60,63 @@ const Page: React.FC<Props> = (props) => {
formatMessage({ id: 'route.constants.preview' }),
];

const [step1Data, setStep1Data] = useState(DEFAULT_STEP_1_DATA);
const [step2Data, setStep2Data] = useState(DEFAULT_STEP_2_DATA);
const [advancedMatchingRules, setAdvancedMatchingRules] = useState<RouteModule.MatchingRule[]>(
[],
);
const [upstreamHeaderList, setUpstreamHeaderList] = useState<RouteModule.UpstreamHeader[]>([]);
const [step3Data, setStep3Data] = useState(DEFAULT_STEP_3_DATA);

const [redirect, setRedirect] = useState(false);

const [form1] = Form.useForm();
const [form2] = Form.useForm();

const [step, setStep] = useState(1);
const [stepHeader, setStepHeader] = useState(STEP_HEADER_4);

const [chart, setChart] = useState(INIT_CHART);

const routeData = {
step1Data,
step2Data,
step3Data,
};
const setupRoute = (rid: number) =>
fetchItem(rid).then((data) => {
form1.setFieldsValue(data.step1Data);
setStep1Data(data.step1Data as RouteModule.Step1Data);

form2.setFieldsValue(data.step2Data);
setStep2Data(data.step2Data);

form1.setFieldsValue(data.form1Data);
setAdvancedMatchingRules(data.advancedMatchingRules);
form2.setFieldsValue(data.form2Data);
setUpstreamHeaderList(data.upstreamHeaderList);
setStep3Data(data.step3Data);
});

useEffect(() => {
if (props.route.path.indexOf('edit') !== -1) {
setupRoute(props.match.params.rid);
}
}, []);

useEffect(() => {
const { redirectOption } = step1Data;

if (redirectOption === 'customRedirect') {
setRedirect(true);
setStepHeader(STEP_HEADER_2);
return;
}
setRedirect(false);
setStepHeader(STEP_HEADER_4);
}, [step1Data]);

const onReset = () => {
setStep1Data(DEFAULT_STEP_1_DATA);
setStep2Data(DEFAULT_STEP_2_DATA);
setAdvancedMatchingRules([]);
setUpstreamHeaderList([]);
setStep3Data(DEFAULT_STEP_3_DATA);

form1.setFieldsValue(DEFAULT_STEP_1_DATA);
form2.setFieldsValue(DEFAULT_STEP_2_DATA);
setStep(1);
};

useEffect(() => {
if (props.route.path.indexOf('edit') !== -1) {
setupRoute(props.match.params.rid);
} else {
onReset();
}
}, []);

const renderStep = () => {
if (step === 1) {
return (
<Step1
data={routeData}
form={form1}
onChange={(params: RouteModule.Step1Data) => {
if (params.route_group_id) {
fetchRouteGroupItem(params.route_group_id).then((data) => {
form1.setFieldsValue({
...form1.getFieldsValue(),
...data,
});
});
advancedMatchingRules={advancedMatchingRules}
onChange={({ action, data }) => {
if (action === 'redirectOptionChange' && data === 'customRedirect') {
setStepHeader(STEP_HEADER_2);
setRedirect(true);
} else {
setStepHeader(STEP_HEADER_4);
setRedirect(false);
}
if (action === 'advancedMatchingRulesChange') {
setAdvancedMatchingRules(data);
}
setStep1Data({ ...form1.getFieldsValue(), ...step1Data, ...params });
}}
isEdit={props.route.path.indexOf('edit') > 0}
/>
Expand All @@ -151,34 +126,25 @@ const Page: React.FC<Props> = (props) => {
if (step === 2) {
if (redirect) {
return (
<CreateStep4 data={routeData} form1={form1} form2={form2} onChange={() => {}} redirect />
<CreateStep4
advancedMatchingRules={advancedMatchingRules}
upstreamHeaderList={upstreamHeaderList}
form1={form1}
form2={form2}
step3Data={step3Data}
redirect
/>
);
}

return (
<Step2
data={routeData}
upstreamHeaderList={upstreamHeaderList}
form={form2}
onChange={(params: RouteModule.Step2Data) => {
if (params.upstream_id) {
fetchUpstreamItem(params.upstream_id).then((data) => {
form2.setFieldsValue({
...form2.getFieldsValue(),
...data,
});
setStep2Data({
...step2Data,
...form2.getFieldsValue(),
...params,
} as RouteModule.Step2Data);
});
return;
onChange={({ action, data }) => {
if (action === 'upstreamHeaderListChange') {
setUpstreamHeaderList(data);
}
setStep2Data({
...step2Data,
...form2.getFieldsValue(),
...params,
} as RouteModule.Step2Data);
}}
/>
);
Expand All @@ -197,7 +163,15 @@ const Page: React.FC<Props> = (props) => {
}

if (step === 4) {
return <CreateStep4 data={routeData} form1={form1} form2={form2} onChange={() => {}} />;
return (
<CreateStep4
advancedMatchingRules={advancedMatchingRules}
upstreamHeaderList={upstreamHeaderList}
form1={form1}
form2={form2}
step3Data={step3Data}
/>
);
}

if (step === 5) {
Expand All @@ -216,13 +190,20 @@ const Page: React.FC<Props> = (props) => {
};

const onStepChange = (nextStep: number) => {
const routeData = {
form1Data: form1.getFieldsValue(),
form2Data: form2.getFieldsValue(),
step3Data,
upstreamHeaderList,
advancedMatchingRules,
} as RouteModule.RequestData;
const onUpdateOrCreate = () => {
if (props.route.path.indexOf('edit') !== -1) {
update((props as any).match.params.rid, { data: routeData }).then(() => {
update((props as any).match.params.rid, routeData).then(() => {
setStep(5);
});
} else {
create({ data: routeData }).then(() => {
create(routeData).then(() => {
setStep(5);
});
}
Expand All @@ -249,7 +230,6 @@ const Page: React.FC<Props> = (props) => {
redirectOption === 'forceHttps' ? checkHostWithSSL(hosts) : Promise.resolve(),
checkUniqueName(value.name, (props as any).match.params.rid || ''),
]).then(() => {
setStep1Data({ ...step1Data, ...value });
setStep(nextStep);
});
});
Expand All @@ -265,8 +245,7 @@ const Page: React.FC<Props> = (props) => {
onUpdateOrCreate();
return;
}
form2.validateFields().then((value) => {
setStep2Data({ ...step2Data, ...value });
form2.validateFields().then(() => {
setStep(nextStep);
});
return;
Expand Down
24 changes: 14 additions & 10 deletions src/pages/Route/components/CreateStep4/CreateStep4.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,22 @@ import PluginOrchestration from '@api7-dashboard/pluginchart';
import Step1 from '../Step1';
import Step2 from '../Step2';

interface Props extends RouteModule.Data {
type Props = {
form1: FormInstance;
form2: FormInstance;
redirect?: boolean;
}
step3Data: RouteModule.Step3Data;
advancedMatchingRules: RouteModule.MatchingRule[];
upstreamHeaderList: RouteModule.UpstreamHeader[];
};

const style = {
marginTop: '40px',
};

const CreateStep4: React.FC<Props> = ({ form1, form2, redirect, ...rest }) => {
const { formatMessage } = useIntl();
const { plugins = {}, script = {} } = rest.data.step3Data;
const { plugins = {}, script = {} } = rest.step3Data;

return (
<>
Expand All @@ -44,17 +47,18 @@ const CreateStep4: React.FC<Props> = ({ form1, form2, redirect, ...rest }) => {
{!redirect && (
<>
<h2 style={style}>{formatMessage({ id: 'route.create.define.api.backend.server' })}</h2>
<Step2 {...rest} form={form2} disabled />
<Step2
upstreamHeaderList={rest.upstreamHeaderList}
form={form2}
disabled
onChange={() => {}}
/>
<h2 style={style}>{formatMessage({ id: 'route.create.plugin.configuration' })}</h2>
{Boolean(Object.keys(plugins).length !== 0) && (
<PluginPage initialData={rest.data.step3Data.plugins} readonly />
<PluginPage initialData={rest.step3Data.plugins} readonly />
)}
{Boolean(Object.keys(script).length !== 0) && (
<PluginOrchestration
data={rest.data.step3Data.script.chart}
readonly
onChange={() => {}}
/>
<PluginOrchestration data={rest.step3Data.script.chart} readonly onChange={() => {}} />
)}
</>
)}
Expand Down
25 changes: 14 additions & 11 deletions src/pages/Route/components/Step1/MatchingRulesView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ import { Button, Table, Modal, Form, Select, Input, Space } from 'antd';
import { useIntl } from 'umi';
import { PanelSection } from '@api7-dashboard/ui';

interface Props extends RouteModule.Data {}

const MatchingRulesView: React.FC<Props> = ({ data, disabled, onChange }) => {
const { advancedMatchingRules } = data.step1Data;

const MatchingRulesView: React.FC<RouteModule.Step1PassProps> = ({
advancedMatchingRules,
disabled,
onChange = () => {},
}) => {
const [visible, setVisible] = useState(false);
const [mode, setMode] = useState<RouteModule.ModalType>('CREATE');
const [namePlaceholder, setNamePlaceholder] = useState('');
Expand All @@ -38,8 +38,8 @@ const MatchingRulesView: React.FC<Props> = ({ data, disabled, onChange }) => {
if (mode === 'EDIT') {
const key = modalForm.getFieldValue('key');
onChange({
...data.step1Data,
advancedMatchingRules: advancedMatchingRules.map((rule) => {
action: 'advancedMatchingRulesChange',
data: advancedMatchingRules.map((rule) => {
if (rule.key === key) {
return { ...(value as RouteModule.MatchingRule), key };
}
Expand All @@ -51,7 +51,10 @@ const MatchingRulesView: React.FC<Props> = ({ data, disabled, onChange }) => {
...(value as RouteModule.MatchingRule),
key: Math.random().toString(36).slice(2),
};
onChange({ ...data.step1Data, advancedMatchingRules: advancedMatchingRules.concat(rule) });
onChange({
action: 'advancedMatchingRulesChange',
data: advancedMatchingRules.concat(rule),
});
}
modalForm.resetFields();
setVisible(false);
Expand All @@ -66,8 +69,8 @@ const MatchingRulesView: React.FC<Props> = ({ data, disabled, onChange }) => {

const handleRemove = (key: string) => {
onChange({
...data.step1Data,
advancedMatchingRules: advancedMatchingRules.filter((item) => item.key !== key),
action: 'advancedMatchingRulesChange',
data: advancedMatchingRules.filter((item) => item.key !== key),
});
};

Expand Down Expand Up @@ -164,7 +167,7 @@ const MatchingRulesView: React.FC<Props> = ({ data, disabled, onChange }) => {
cancelText={formatMessage({ id: 'route.match.cancel' })}
destroyOnClose
>
<Form form={modalForm} labelCol={{ span: 9 }} wrapperCol={{ span: 15 }}>
<Form form={modalForm} labelCol={{ span: 4 }}>
<Form.Item
label={formatMessage({ id: 'route.match.parameter.position' })}
name="position"
Expand Down
Loading

0 comments on commit 234e1ea

Please sign in to comment.