blob: 535004c08ab251c4ee529d39342be8fdda3278f7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { useState } from 'react';
import { Button, Intent } from '@blueprintjs/core';
import { IconButton, Table } from '@/components';
import { getPluginId, TransformationSelect } from '@/plugins';
import * as API from './api';
import * as S from './styled';
interface Props {
connections: MixConnection[];
cancelBtnProps?: {
text?: string;
};
submitBtnProps?: {
text?: string;
loading?: boolean;
};
noFooter?: boolean;
onCancel?: () => void;
onSubmit?: (connections: MixConnection[]) => void;
onNext?: () => void;
}
export const Transformation = ({
connections,
cancelBtnProps,
submitBtnProps,
noFooter,
onCancel,
onSubmit,
onNext,
}: Props) => {
const [selected, setSelected] = useState<Record<string, ID[]>>({});
const [connection, setConnection] = useState<MixConnection>();
const [startStepOption, setStartStepOption] = useState<{ type: 'add' | 'edit'; id?: ID }>();
const handleCancel = () => setConnection(undefined);
const handleSubmit = async (tid: ID, connection: MixConnection, connections: MixConnection[]) => {
const { unique, plugin, connectionId } = connection;
const scopeIds = selected[unique];
const scopes = await Promise.all(
scopeIds.map(async (scopeId) => {
const scope = await API.getDataScope(plugin, connectionId, scopeId);
return await API.updateDataScope(plugin, connectionId, scopeId, {
...scope,
transformationRuleId: tid,
});
}),
);
onSubmit?.(
connections.map((cs) => {
if (cs.unique !== unique) {
return cs;
}
const origin = cs.origin.map((sc) => {
if (!scopeIds.includes(sc[getPluginId(cs.plugin)])) {
return sc;
}
return scopes.find((it) => it[getPluginId(cs.plugin)] === sc[getPluginId(cs.plugin)]);
});
return { ...cs, origin };
}),
);
setSelected({
...selected,
[`${unique}`]: [],
});
handleCancel();
};
return (
<S.List>
{connections.map((cs) => (
<S.Item key={cs.unique}>
{connections.length !== 1 && (
<S.Title>
<img src={cs.icon} alt="" />
<span>{cs.name}</span>
</S.Title>
)}
{cs.transformationType === 'for-connection' && (
<S.Action>
<Button
intent={Intent.PRIMARY}
icon="annotation"
disabled={!selected[cs.unique] || !selected[cs.unique].length}
onClick={() => {
setStartStepOption(undefined);
setConnection(cs);
}}
>
Select Transformation
</Button>
</S.Action>
)}
<Table
columns={[
{ title: 'Data Scope', dataIndex: 'name', key: 'name' },
{
title: 'Transformation',
dataIndex: 'transformationRuleName',
key: 'transformation',
align: 'center',
render: (val, row) => (
<div>
<span>{val ?? 'N/A'}</span>
{cs.transformationType === 'for-connection' && (
<IconButton
icon="annotation"
tooltip="Select Transformation"
onClick={() => {
setSelected({
...selected,
[`${cs.unique}`]: [row[getPluginId(cs.plugin)]],
});
setStartStepOption(undefined);
setConnection(cs);
}}
/>
)}
{cs.transformationType === 'for-scope' &&
(row['transformationRuleId'] ? (
<IconButton
icon="annotation"
tooltip="Edit Transformation"
onClick={() => {
setSelected({
...selected,
[`${cs.unique}`]: [row[getPluginId(cs.plugin)]],
});
setStartStepOption({ type: 'edit', id: row['transformationRuleId'] });
setConnection(cs);
}}
/>
) : (
<IconButton
icon="annotation"
tooltip="Add Transformation"
onClick={() => {
setSelected({
...selected,
[`${cs.unique}`]: [row[getPluginId(cs.plugin)]],
});
setStartStepOption({ type: 'add' });
setConnection(cs);
}}
/>
))}
</div>
),
},
]}
dataSource={cs.origin}
rowSelection={
cs.transformationType === 'for-connection'
? {
rowKey: getPluginId(cs.plugin),
selectedRowKeys: selected[cs.unique],
onChange: (selectedRowKeys) => setSelected({ ...selected, [`${cs.unique}`]: selectedRowKeys }),
}
: undefined
}
/>
</S.Item>
))}
{!noFooter && (
<S.Btns>
<Button outlined intent={Intent.PRIMARY} text="Previous Step" onClick={onCancel} {...cancelBtnProps} />
<Button intent={Intent.PRIMARY} text="Next Step" onClick={onNext} {...submitBtnProps} />
</S.Btns>
)}
{connection && (
<TransformationSelect
plugin={connection.plugin}
startStepOption={startStepOption}
connectionId={connection.connectionId}
scopeId={selected[connection.unique][0]}
onCancel={handleCancel}
onSubmit={(tid) => handleSubmit(tid, connection, connections)}
/>
)}
</S.List>
);
};