InstallFinished.tsx 17.9 KB
Newer Older
R
Rongfeng Fu 已提交
1 2
import { intl } from '@/utils/intl';
import { useEffect, useState } from 'react';
R
Rongfeng Fu 已提交
3 4 5 6 7 8 9 10 11 12 13 14
import { useModel } from 'umi';
import {
  Space,
  Button,
  Table,
  Alert,
  Result,
  Tooltip,
  message,
  Tag,
  Modal,
  Typography,
R
Rongfeng Fu 已提交
15
  Spin,
R
Rongfeng Fu 已提交
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
} from 'antd';
import {
  CloseCircleFilled,
  CheckCircleFilled,
  CaretRightFilled,
  CaretDownFilled,
  CopyOutlined,
  ExclamationCircleOutlined,
  CheckOutlined,
} from '@ant-design/icons';
import { ProCard } from '@ant-design/pro-components';
import useRequest from '@/utils/useRequest';
import type { ColumnsType } from 'antd/es/table';
import copy from 'copy-to-clipboard';
import {
  queryDeploymentReport,
  queryConnectionInfo,
R
Rongfeng Fu 已提交
33
  queryInstallLog,
R
Rongfeng Fu 已提交
34 35 36 37 38
} from '@/services/ob-deploy-web/Deployments';
import {
  componentsConfig,
  componentVersionTypeToComponent,
} from '../constants';
R
Rongfeng Fu 已提交
39 40 41 42 43 44 45
import { handleQuit, getErrorInfo } from '@/utils';
import { getLocale } from 'umi';
import EnStyles from './indexEn.less';
import ZhStyles from './indexZh.less';

const locale = getLocale();
const styles = locale === 'zh-CN' ? ZhStyles : EnStyles;
R
Rongfeng Fu 已提交
46 47 48 49

const { Paragraph } = Typography;

export default function InstallProcess() {
R
Rongfeng Fu 已提交
50 51 52 53 54 55 56 57 58 59 60
  const {
    configData,
    installStatus,
    setCurrentStep,
    handleQuitProgress,
    setErrorVisible,
    setErrorsList,
    errorsList,
  } = useModel('global');
  const [logs, setLogs] = useState({});
  const [currentExpeandedName, setCurrentExpeandedName] = useState('');
R
Rongfeng Fu 已提交
61 62 63 64

  const name = configData?.components?.oceanbase?.appname;
  const { run: fetchReportInfo, data: reportInfo } = useRequest(
    queryDeploymentReport,
R
Rongfeng Fu 已提交
65 66 67 68 69 70 71
    {
      onError: (e: any) => {
        const errorInfo = getErrorInfo(e);
        setErrorVisible(true);
        setErrorsList([...errorsList, errorInfo]);
      },
    },
R
Rongfeng Fu 已提交
72
  );
R
Rongfeng Fu 已提交
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
  const { run: fetchConnectInfo, data: connectInfo } = useRequest(
    queryConnectionInfo,
    {
      onError: (e: any) => {
        const errorInfo = getErrorInfo(e);
        setErrorVisible(true);
        setErrorsList([...errorsList, errorInfo]);
      },
    },
  );

  const { run: handleInstallLog, loading } = useRequest(queryInstallLog, {
    onSuccess: (
      { success, data }: API.OBResponseInstallLog_,
      [{ component_name }]: [API.queryInstallLogParams],
    ) => {
      if (success) {
        setLogs({ ...logs, [component_name]: data?.log });
        setTimeout(() => {
          const log = document.getElementById(`report-log-${component_name}`);
          if (log) {
            log.scrollTop = log.scrollHeight;
          }
        });
      }
    },
    onError: (e: any) => {
      const errorInfo = getErrorInfo(e);
      setErrorVisible(true);
      setErrorsList([...errorsList, errorInfo]);
    },
  });
R
Rongfeng Fu 已提交
105 106 107

  const handleCopy = (content: string) => {
    copy(content);
R
Rongfeng Fu 已提交
108 109 110 111 112 113
    message.success(
      intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.CopiedSuccessfully',
        defaultMessage: '复制成功',
      }),
    );
R
Rongfeng Fu 已提交
114 115 116 117
  };

  const handleCopyCommand = (command: string) => {
    copy(command);
R
Rongfeng Fu 已提交
118 119 120 121 122 123
    message.success(
      intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.CopiedSuccessfully',
        defaultMessage: '复制成功',
      }),
    );
R
Rongfeng Fu 已提交
124 125 126 127 128 129 130 131 132
  };

  useEffect(() => {
    fetchReportInfo({ name });
    fetchConnectInfo({ name });
  }, []);

  const connectColumns: ColumnsType<API.ConnectionInfo> = [
    {
R
Rongfeng Fu 已提交
133 134 135 136
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Component',
        defaultMessage: '组件',
      }),
R
Rongfeng Fu 已提交
137 138 139 140 141 142 143 144 145 146
      dataIndex: 'component',
      width: 200,
      render: (text) => {
        const component = componentVersionTypeToComponent[text]
          ? componentVersionTypeToComponent[text]
          : text;
        return componentsConfig[component]?.showComponentName || '-';
      },
    },
    {
R
Rongfeng Fu 已提交
147 148 149 150
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.AccessAddress',
        defaultMessage: '访问地址',
      }),
R
Rongfeng Fu 已提交
151 152 153 154 155
      dataIndex: 'access_url',
      width: 160,
      render: (text) => text || '-',
    },
    {
R
Rongfeng Fu 已提交
156 157 158 159
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Account',
        defaultMessage: '账号',
      }),
R
Rongfeng Fu 已提交
160 161 162 163
      dataIndex: 'user',
      render: (text) => text || '-',
    },
    {
R
Rongfeng Fu 已提交
164 165 166 167
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Password',
        defaultMessage: '密码',
      }),
R
Rongfeng Fu 已提交
168 169 170 171 172 173 174 175 176 177 178 179
      dataIndex: 'password',
      width: 160,
      render: (text) =>
        text ? (
          <Tooltip title={text}>
            <div className="ellipsis">{text}</div>
          </Tooltip>
        ) : (
          '-'
        ),
    },
    {
R
Rongfeng Fu 已提交
180 181 182 183
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.ConnectionString',
        defaultMessage: '连接串',
      }),
R
Rongfeng Fu 已提交
184 185 186 187 188 189 190 191 192 193
      dataIndex: 'connect_url',
      width: 300,
      render: (text, record) => {
        let content;
        if (/^http/g.test(text)) {
          content = (
            <a
              href={text}
              target="_blank"
              {...(record.component === 'ocp-express'
R
Rongfeng Fu 已提交
194 195 196 197 198 199
                ? {
                    spm: intl.formatMessage({
                      id: 'OBD.pages.components.InstallFinished.DeploymentResultOcpExpressAccess',
                      defaultMessage: '部署结果-OCP Express 访问地址',
                    }),
                  }
R
Rongfeng Fu 已提交
200 201 202 203 204 205 206 207 208 209 210
                : {})}
            >
              {text}
            </a>
          );
        } else {
          content = (
            <div
              {...(record.component === 'oceanbase'
                ? { spm: 'c307514.d317296' /* spm: 部署结果-直连连接串 */ }
                : record.component === 'obproxy'
R
Rongfeng Fu 已提交
211 212 213 214 215 216
                ? {
                    spm: intl.formatMessage({
                      id: 'OBD.pages.components.InstallFinished.DeploymentResultObproxyConnectionString',
                      defaultMessage: '部署结果-OBProxy 连接串',
                    }),
                  }
R
Rongfeng Fu 已提交
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
                : {})}
            >
              {text}
            </div>
          );
        }
        return (
          <div style={{ position: 'relative' }}>
            <Tooltip title={text}>
              <div className="ellipsis" style={{ width: 'calc(100% - 20px)' }}>
                {content}
              </div>
            </Tooltip>
            <a style={{ position: 'absolute', top: '0px', right: '0px' }}>
              <CopyOutlined onClick={() => handleCopy(text)} />
            </a>
          </div>
        );
      },
    },
  ];

  const reportColumns: ColumnsType<API.DeploymentReport> = [
    {
R
Rongfeng Fu 已提交
241 242 243 244
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.ComponentName',
        defaultMessage: '组件名称',
      }),
R
Rongfeng Fu 已提交
245 246 247 248 249 250 251 252 253
      dataIndex: 'name',
      render: (text) => {
        const component = componentVersionTypeToComponent[text]
          ? componentVersionTypeToComponent[text]
          : text;
        return componentsConfig[component]?.showComponentName || '-';
      },
    },
    {
R
Rongfeng Fu 已提交
254 255 256 257
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.ComponentType',
        defaultMessage: '组件类型',
      }),
R
Rongfeng Fu 已提交
258 259 260 261 262 263 264 265 266
      dataIndex: 'type',
      render: (_, record) => {
        const component = componentVersionTypeToComponent[record.name]
          ? componentVersionTypeToComponent[record.name]
          : record.name;
        return componentsConfig[component]?.type || '-';
      },
    },
    {
R
Rongfeng Fu 已提交
267 268 269 270
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Version',
        defaultMessage: '版本',
      }),
R
Rongfeng Fu 已提交
271 272 273 274
      dataIndex: 'version',
      render: (text) => text || '-',
    },
    {
R
Rongfeng Fu 已提交
275 276 277 278
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.InstallationResults',
        defaultMessage: '安装结果',
      }),
R
Rongfeng Fu 已提交
279
      dataIndex: 'status',
R
Rongfeng Fu 已提交
280 281 282 283
      width: locale === 'zh-CN' ? 200 : 260,
      render: (text, record) => {
        const statusIcon =
          text === 'SUCCESSFUL' ? (
R
Rongfeng Fu 已提交
284
            <CheckCircleFilled style={{ color: '#4dcca2', marginRight: 6 }} />
R
Rongfeng Fu 已提交
285
          ) : (
R
Rongfeng Fu 已提交
286
            <CloseCircleFilled style={{ color: '#ff4d67', marginRight: 6 }} />
R
Rongfeng Fu 已提交
287
          );
R
Rongfeng Fu 已提交
288

R
Rongfeng Fu 已提交
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
        const status =
          text === 'SUCCESSFUL'
            ? intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.Success',
                defaultMessage: '成功',
              })
            : intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.Failed',
                defaultMessage: '失败',
              });

        const getCommand = (component: string, ip: string) => {
          return `obd tool command ${name} log -c ${component} -s ${ip}`;
        };

        const serversInfo = record.servers?.map((server) => ({
          server,
          command: getCommand(record.name, server),
        }));

        return (
          <>
            {statusIcon}
            {status}
R
Rongfeng Fu 已提交
313 314 315
            <Tooltip
              title={
                <>
R
Rongfeng Fu 已提交
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
                  <div style={{ marginBottom: 12 }}>
                    {intl.formatMessage({
                      id: 'OBD.pages.components.InstallFinished.GoToTheObdConsole',
                      defaultMessage: '请前往 OBD 中控机执行以下命令查看日志',
                    })}
                  </div>
                  {serversInfo.map((item) => (
                    <>
                      <div className="fw-500">
                        {statusIcon}
                        {item.server}
                      </div>
                      <div style={{ position: 'relative' }}>
                        <div
                          style={{
                            width: 'calc(100% - 20px)',
                            fontFamily: 'PingFangSC',
                          }}
                        >
                          {item.command}
                        </div>
                        <a
                          style={{
                            position: 'absolute',
                            top: '0px',
                            right: '0px',
                          }}
                        >
                          <CopyOutlined
                            onClick={() => handleCopyCommand(item.command)}
                          />
                        </a>
                      </div>
                    </>
                  ))}
R
Rongfeng Fu 已提交
351 352
                </>
              }
R
Rongfeng Fu 已提交
353 354
              placement="topRight"
              overlayClassName={styles.reportTooltip}
R
Rongfeng Fu 已提交
355
            >
R
Rongfeng Fu 已提交
356 357 358 359 360 361
              <Tag className="default-tag ml-16">
                {intl.formatMessage({
                  id: 'OBD.pages.components.InstallFinished.ViewDetails',
                  defaultMessage: '查看详情',
                })}
              </Tag>
R
Rongfeng Fu 已提交
362
            </Tooltip>
R
Rongfeng Fu 已提交
363 364
          </>
        );
R
Rongfeng Fu 已提交
365
      },
R
Rongfeng Fu 已提交
366 367 368 369 370 371 372 373
    },
  ];

  const onExpand = (expeanded: boolean, record: API.DeploymentReport) => {
    if (expeanded && !logs?.[record.name]) {
      setCurrentExpeandedName(record.name);
      handleInstallLog({ name, component_name: record.name });
    }
R
Rongfeng Fu 已提交
374 375 376 377
  };

  const expandedRowRender = (record: API.DeploymentReport) => {
    return (
R
Rongfeng Fu 已提交
378 379 380 381 382
      <Spin spinning={loading && currentExpeandedName === record.name}>
        <pre className={styles.reportLog} id={`report-log-${record.name}`}>
          {logs?.[record.name]}
        </pre>
      </Spin>
R
Rongfeng Fu 已提交
383 384 385 386 387
    );
  };

  const handleFinished = () => {
    Modal.confirm({
R
Rongfeng Fu 已提交
388 389 390 391 392 393 394 395 396 397 398 399
      title: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.DoYouWantToExit',
        defaultMessage: '是否要退出页面?',
      }),
      okText: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Exit',
        defaultMessage: '退出',
      }),
      cancelText: intl.formatMessage({
        id: 'OBD.pages.components.InstallFinished.Cancel',
        defaultMessage: '取消',
      }),
R
Rongfeng Fu 已提交
400 401 402
      okButtonProps: { type: 'primary', danger: true },
      content: (
        <div>
R
Rongfeng Fu 已提交
403 404 405 406 407
          {intl.formatMessage({
            id: 'OBD.pages.components.InstallFinished.BeforeExitingMakeSureThat',
            defaultMessage: '退出前,请确保已复制访问地址及账密信息',
          })}

R
Rongfeng Fu 已提交
408 409 410 411 412 413 414
          <br />
          <Paragraph
            copyable={{
              tooltips: false,
              icon: [
                <>
                  <CopyOutlined style={{ marginRight: 6 }} />
R
Rongfeng Fu 已提交
415 416 417 418
                  {intl.formatMessage({
                    id: 'OBD.pages.components.InstallFinished.CopyInformation',
                    defaultMessage: '复制信息',
                  })}
R
Rongfeng Fu 已提交
419 420 421
                </>,
                <>
                  <CheckOutlined style={{ marginRight: 6, color: '#4dcca2' }} />
R
Rongfeng Fu 已提交
422 423 424 425
                  {intl.formatMessage({
                    id: 'OBD.pages.components.InstallFinished.CopyInformation',
                    defaultMessage: '复制信息',
                  })}
R
Rongfeng Fu 已提交
426 427
                </>,
              ],
R
Rongfeng Fu 已提交
428 429
              onCopy: () =>
                handleCopy(JSON.stringify(connectInfo?.items, null, '\n')),
R
Rongfeng Fu 已提交
430 431 432 433
            }}
          />
        </div>
      ),
R
Rongfeng Fu 已提交
434

R
Rongfeng Fu 已提交
435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460
      icon: <ExclamationCircleOutlined style={{ color: '#ff4b4b' }} />,
      onOk: () => {
        handleQuit(handleQuitProgress, setCurrentStep, true);
      },
    });
  };

  return (
    <Space className={styles.spaceWidth} direction="vertical" size="middle">
      <Result
        style={{ paddingBottom: 8 }}
        icon={
          <img
            src={
              installStatus === 'SUCCESSFUL'
                ? '/assets/successful.png'
                : '/assets/failed.png'
            }
            alt="resultLogo"
            style={{ width: 160, position: 'relative', right: '-8px' }}
          />
        }
        title={
          installStatus === 'SUCCESSFUL' ? (
            <div
              data-aspm-click="c307514.d317295"
R
Rongfeng Fu 已提交
461 462 463 464
              data-aspm-desc={intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.DeploymentResultDeploymentSuccessful',
                defaultMessage: '部署结果-部署成功',
              })}
R
Rongfeng Fu 已提交
465 466 467
              data-aspm-param={``}
              data-aspm-expo
            >
R
Rongfeng Fu 已提交
468 469 470 471
              {intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.OceanbaseSuccessfullyDeployed',
                defaultMessage: 'OceanBase 部署成功',
              })}
R
Rongfeng Fu 已提交
472 473 474 475
            </div>
          ) : (
            <div
              data-aspm-click="c307514.d317298"
R
Rongfeng Fu 已提交
476 477 478 479
              data-aspm-desc={intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.DeploymentResultDeploymentFailed',
                defaultMessage: '部署结果-部署失败',
              })}
R
Rongfeng Fu 已提交
480 481 482
              data-aspm-param={``}
              data-aspm-expo
            >
R
Rongfeng Fu 已提交
483 484 485 486
              {intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.OceanbaseDeploymentFailed',
                defaultMessage: 'OceanBase 部署失败',
              })}
R
Rongfeng Fu 已提交
487 488 489 490
            </div>
          )
        }
      />
R
Rongfeng Fu 已提交
491

R
Rongfeng Fu 已提交
492
      {connectInfo?.items?.length ? (
R
Rongfeng Fu 已提交
493 494 495 496 497 498
        <ProCard
          title={intl.formatMessage({
            id: 'OBD.pages.components.InstallFinished.AccessAddressAndAccountSecret',
            defaultMessage: '访问地址及账密信息',
          })}
        >
R
Rongfeng Fu 已提交
499
          <Alert
R
Rongfeng Fu 已提交
500 501 502 503 504
            message={intl.formatMessage({
              id: 'OBD.pages.components.InstallFinished.PleaseKeepTheFollowingAccess',
              defaultMessage:
                '请妥善保存以下访问地址及账密信息,OceanBase 未保存账密信息,丢失后无法找回',
            })}
R
Rongfeng Fu 已提交
505 506 507 508 509
            type="info"
            showIcon
            action={
              <Button
                type="primary"
R
Rongfeng Fu 已提交
510 511 512
                onClick={() =>
                  handleCopy(JSON.stringify(connectInfo?.items, null, '\n'))
                }
R
Rongfeng Fu 已提交
513
                data-aspm-click="c307514.d317299"
R
Rongfeng Fu 已提交
514 515 516 517
                data-aspm-desc={intl.formatMessage({
                  id: 'OBD.pages.components.InstallFinished.DeploymentResultCopyInformation',
                  defaultMessage: '部署结果-复制信息',
                })}
R
Rongfeng Fu 已提交
518 519 520
                data-aspm-param={``}
                data-aspm-expo
              >
R
Rongfeng Fu 已提交
521 522 523 524
                {intl.formatMessage({
                  id: 'OBD.pages.components.InstallFinished.OneClickCopy',
                  defaultMessage: '一键复制',
                })}
R
Rongfeng Fu 已提交
525 526 527
              </Button>
            }
          />
R
Rongfeng Fu 已提交
528

R
Rongfeng Fu 已提交
529 530 531 532 533 534 535 536 537 538
          <Table
            className={`${styles.connectTable} ob-table`}
            columns={connectColumns}
            dataSource={connectInfo?.items || []}
            rowKey="component"
            pagination={false}
          />
        </ProCard>
      ) : null}
      <ProCard
R
Rongfeng Fu 已提交
539 540 541 542
        title={intl.formatMessage({
          id: 'OBD.pages.components.InstallFinished.DeploymentReport',
          defaultMessage: '部署报告',
        })}
R
Rongfeng Fu 已提交
543 544 545 546 547 548 549 550 551 552 553 554 555
        className={styles.collapsibleCard}
        collapsible
        defaultCollapsed={installStatus !== 'FAILED'}
        collapsibleIconRender={({ collapsed }) =>
          collapsed ? <CaretRightFilled /> : <CaretDownFilled />
        }
        bodyStyle={{ paddingLeft: '0px', paddingRight: '0px' }}
      >
        <Table
          className="ob-table ob-table-expandable"
          columns={reportColumns}
          dataSource={reportInfo?.items || []}
          rowKey="name"
R
Rongfeng Fu 已提交
556
          expandable={{ onExpand, expandedRowRender }}
R
Rongfeng Fu 已提交
557 558 559 560 561 562 563 564 565 566
          pagination={false}
        />
      </ProCard>
      <footer className={styles.pageFooterContainer}>
        <div className={styles.pageFooter}>
          <Space className={styles.foolterAction}>
            <Button
              type="primary"
              onClick={handleFinished}
              data-aspm-click="c307514.d317297"
R
Rongfeng Fu 已提交
567 568 569 570
              data-aspm-desc={intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.DeploymentResultDeploymentCompleted',
                defaultMessage: '部署结果-部署完成',
              })}
R
Rongfeng Fu 已提交
571 572 573
              data-aspm-param={``}
              data-aspm-expo
            >
R
Rongfeng Fu 已提交
574 575 576 577
              {intl.formatMessage({
                id: 'OBD.pages.components.InstallFinished.Complete',
                defaultMessage: '完成',
              })}
R
Rongfeng Fu 已提交
578 579 580 581 582 583 584
            </Button>
          </Space>
        </div>
      </footer>
    </Space>
  );
}