From fc9fef65596c61b3f9bb086ae5fd63eb845f7b61 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 6 Apr 2022 21:47:40 +0900 Subject: [PATCH 1/2] Remove unused components --- ui/src/components/ActivityLogs.tsx | 60 -------------- ui/src/components/ApproversSelect.tsx | 80 ------------------- ui/src/components/RepoList.tsx | 55 ------------- ui/src/components/RepoSettingsForm.tsx | 80 ------------------- ui/src/components/StatusStateIcon.tsx | 103 ------------------------- 5 files changed, 378 deletions(-) delete mode 100644 ui/src/components/ActivityLogs.tsx delete mode 100644 ui/src/components/ApproversSelect.tsx delete mode 100644 ui/src/components/RepoList.tsx delete mode 100644 ui/src/components/RepoSettingsForm.tsx delete mode 100644 ui/src/components/StatusStateIcon.tsx diff --git a/ui/src/components/ActivityLogs.tsx b/ui/src/components/ActivityLogs.tsx deleted file mode 100644 index 5e6f1b50..00000000 --- a/ui/src/components/ActivityLogs.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { Timeline, Typography } from 'antd' -import { SyncOutlined } from '@ant-design/icons' -import moment from "moment" - -import { Deployment, DeploymentStatusEnum } from "../models" -import DeploymentStatusBadge from "./DeploymentStatusBadge" -import UserAvatar from './UserAvatar' -import DeploymentRefCode from './DeploymentRefCode' - -const { Text } = Typography - -interface ActivityLogsProps { - deployments: Deployment[] -} - -export default function ActivityLogs(props: ActivityLogsProps): JSX.Element { - return ( - - {props.deployments.map((d, idx) => { - const dot = (d.status === DeploymentStatusEnum.Running)? - : - null - const avatar = - - return ( - -

- {d.env} • View detail #{d.number} -

-

- Deployed by {avatar} {moment(d.createdAt).fromNow()} -

-
- ) - })} -
- ) -} - -// https://ant.design/components/timeline/#Timeline.Item -const getStatusColor = (status: DeploymentStatusEnum) => { - switch (status) { - case DeploymentStatusEnum.Waiting: - return "gray" - case DeploymentStatusEnum.Created: - return "purple" - case DeploymentStatusEnum.Queued: - return "purple" - case DeploymentStatusEnum.Running: - return "purple" - case DeploymentStatusEnum.Success: - return "green" - case DeploymentStatusEnum.Failure: - return "red" - case DeploymentStatusEnum.Canceled: - return "gray" - default: - return "gray" - } -} \ No newline at end of file diff --git a/ui/src/components/ApproversSelect.tsx b/ui/src/components/ApproversSelect.tsx deleted file mode 100644 index d94d5f04..00000000 --- a/ui/src/components/ApproversSelect.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import React from "react" -import { Select, SelectProps, Avatar, Spin } from "antd" -import debounce from "lodash.debounce" - -import { User } from "../models" - -export interface ApproversSelectProps extends SelectProps{ - candidates: User[] - // The type of parameter have to be string - // because candidates could be dynamically changed with search. - onSelectCandidate(candidate: User): void - onDeselectCandidate(candidate: User): void - onSearchCandidates(login: string): void -} - -export default function ApproversSelect(props: ApproversSelectProps): JSX.Element { - const [ searching, setSearching ] = React.useState(false) - const [ value, setValue ] = React.useState([]) - - // Clone Select props only - // https://stackoverflow.com/questions/34698905/how-can-i-clone-a-javascript-object-except-for-one-key - const {candidates, onSelectCandidate, onDeselectCandidate, onSearchCandidates, ...selectProps} = props // eslint-disable-line - - // debounce search action. - const onSearch = debounce((login: string) => { - setSearching(true) - setTimeout(() => { - setSearching(false) - }, 500); - - props.onSearchCandidates(login) - }, 800) - - const _onSelectCandidate = (id: string) => { - const candidate = props.candidates.find(c => c.id === parseInt(id)) - if (candidate === undefined) { - throw new Error("The candidate is undefined.") - } - - onSelectCandidate(candidate) - - // Save value for the deselect event. - value.push(candidate) - setValue(value) - } - - const _onDeselectCandidate = (id: string) => { - const candidate = value.find(c => c.id.toString() === id) - if (candidate === undefined) { - return - } - - onDeselectCandidate(candidate) - - const candidates = value.filter(c => c.id.toString() !== id) - setValue(candidates) - } - - return ( - - ) -} \ No newline at end of file diff --git a/ui/src/components/RepoList.tsx b/ui/src/components/RepoList.tsx deleted file mode 100644 index 71811486..00000000 --- a/ui/src/components/RepoList.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Component } from "react" -import { List, Typography } from 'antd' -import moment from "moment" - -import { Deployment, Repo } from '../models' -import UserAvatar from './UserAvatar' -import DeploymentStatusBadge from "./DeploymentStatusBadge" -import DeploymentRefCode from "./DeploymentRefCode" - -const { Text, Paragraph } = Typography - -export interface RepoListProps { - repos: Repo[] -} - -export default class RepoList extends Component { - render(): JSX.Element { - return ( - { - // deployments is undeinfed if there is no deployments of the repository. - const deployment = (repo.deployments)? - repo.deployments[0] : - undefined - - return - - {repo.namespace} / {repo.name} - } - description={} - /> - - }} - /> - ) - } -} - -interface DescriptionProps { - deployment?: Deployment -} - -function Description(props: DescriptionProps): JSX.Element { - if (!props.deployment) { - return

- } - - return - deployed to the {props.deployment.env} environment {moment(props.deployment.createdAt).fromNow()} - -} \ No newline at end of file diff --git a/ui/src/components/RepoSettingsForm.tsx b/ui/src/components/RepoSettingsForm.tsx deleted file mode 100644 index a875e4b4..00000000 --- a/ui/src/components/RepoSettingsForm.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Form, Input, Button, Space, Typography } from "antd" -import { Repo } from "../models" - -export interface RepoSettingsFormProps { - repo: Repo - saving: boolean - onClickSave(payload: {configPath: string}): void - onClickDeactivate(): void -} - -export default function RepoSettingForm(props: RepoSettingsFormProps): JSX.Element { - const layout = { - labelCol: { span: 5}, - wrapperCol: { span: 12 }, - }; - - const submitLayout = { - wrapperCol: { offset: 5, span: 12 }, - }; - - const onFinish = (values: any) => { - const payload = { - configPath: values.config - } - props.onClickSave(payload) - } - - const values = { - "config": props.repo.configPath - } - - return ( -
- - - - - - - Link - - - - - - - - - - - - - - - -
- ) -} \ No newline at end of file diff --git a/ui/src/components/StatusStateIcon.tsx b/ui/src/components/StatusStateIcon.tsx deleted file mode 100644 index 34b0481f..00000000 --- a/ui/src/components/StatusStateIcon.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import { Popover, Avatar, Typography, Row, Col, Divider, Space } from "antd" -import { CheckOutlined, CloseOutlined, StopOutlined, ExclamationCircleOutlined, ClockCircleOutlined } from "@ant-design/icons" - -import { Status, StatusState } from "../models" - -const colorSuccess = "#1a7f37" -const colorFailure = "#cf222e" - -const { Text, Link } = Typography - -interface StatusStateIconProps { - statuses: Status[] -} - -export default function StatusStateIcon(props: StatusStateIconProps): JSX.Element { - const states = props.statuses.map((status) => status.state) - const content: JSX.Element = ( -
- {props.statuses.map((status, idx) => { - return ( - - - - {mapStateToIcon(status.state)} - - - {status.context} - - - - - Details - - {(idx !== props.statuses.length - 1)? - : null} - - ) - })} -
- ) - - return ( - - {mapStateToIcon(mergeStatusStates(states))} - - ) -} - -function mapStateToIcon(state: StatusState): JSX.Element { - switch (state) { - case StatusState.Null: - return <> - case StatusState.Pending: - return - case StatusState.Success: - return - case StatusState.Failure: - return - case StatusState.Cancelled: - return - case StatusState.Skipped: - return - default: - return - } -} - -function mergeStatusStates(states: StatusState[]): StatusState { - if (states.length === 0) { - return StatusState.Null - } - - // The state is failure if one of them is failure. - for (let idx = 0; idx < states.length; idx++) { - if (states[idx] === StatusState.Failure - || states[idx] === StatusState.Cancelled) { - return StatusState.Failure - } - } - - for (let idx = 0; idx < states.length; idx++) { - if (states[idx] === StatusState.Pending) { - return StatusState.Pending - } - } - - return StatusState.Success -} \ No newline at end of file From 0e1a457648ff63dd56702e3901ee2580902ed360 Mon Sep 17 00:00:00 2001 From: noah Date: Wed, 6 Apr 2022 21:49:25 +0900 Subject: [PATCH 2/2] Move the component into the view --- ui/src/views/repoDeploy/DeployForm.tsx | 2 +- ui/src/views/repoDeploy/StatusStateIcon.tsx | 103 ++++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 ui/src/views/repoDeploy/StatusStateIcon.tsx diff --git a/ui/src/views/repoDeploy/DeployForm.tsx b/ui/src/views/repoDeploy/DeployForm.tsx index 9cf74a13..27c6341b 100644 --- a/ui/src/views/repoDeploy/DeployForm.tsx +++ b/ui/src/views/repoDeploy/DeployForm.tsx @@ -4,7 +4,7 @@ import { Form, Select, Radio, Button, Typography, Avatar, Tag as AntdTag } from import { Branch, Commit, Tag, Deployment, DeploymentType, Status, Env } from "../../models" import CreatableSelect, {Option as Op} from "../../components/CreatableSelect" -import StatusStateIcon from "../../components/StatusStateIcon" +import StatusStateIcon from "./StatusStateIcon" import moment from "moment" export type Option = Op diff --git a/ui/src/views/repoDeploy/StatusStateIcon.tsx b/ui/src/views/repoDeploy/StatusStateIcon.tsx new file mode 100644 index 00000000..050f5dfa --- /dev/null +++ b/ui/src/views/repoDeploy/StatusStateIcon.tsx @@ -0,0 +1,103 @@ +import { Popover, Avatar, Typography, Row, Col, Divider, Space } from "antd" +import { CheckOutlined, CloseOutlined, StopOutlined, ExclamationCircleOutlined, ClockCircleOutlined } from "@ant-design/icons" + +import { Status, StatusState } from "../../models" + +const colorSuccess = "#1a7f37" +const colorFailure = "#cf222e" + +const { Text, Link } = Typography + +interface StatusStateIconProps { + statuses: Status[] +} + +export default function StatusStateIcon(props: StatusStateIconProps): JSX.Element { + const states = props.statuses.map((status) => status.state) + const content: JSX.Element = ( +
+ {props.statuses.map((status, idx) => { + return ( + + + + {mapStateToIcon(status.state)} + + + {status.context} + + + + + Details + + {(idx !== props.statuses.length - 1)? + : null} + + ) + })} +
+ ) + + return ( + + {mapStateToIcon(mergeStatusStates(states))} + + ) +} + +function mapStateToIcon(state: StatusState): JSX.Element { + switch (state) { + case StatusState.Null: + return <> + case StatusState.Pending: + return + case StatusState.Success: + return + case StatusState.Failure: + return + case StatusState.Cancelled: + return + case StatusState.Skipped: + return + default: + return + } +} + +function mergeStatusStates(states: StatusState[]): StatusState { + if (states.length === 0) { + return StatusState.Null + } + + // The state is failure if one of them is failure. + for (let idx = 0; idx < states.length; idx++) { + if (states[idx] === StatusState.Failure + || states[idx] === StatusState.Cancelled) { + return StatusState.Failure + } + } + + for (let idx = 0; idx < states.length; idx++) { + if (states[idx] === StatusState.Pending) { + return StatusState.Pending + } + } + + return StatusState.Success +} \ No newline at end of file