From 142a03a01c993cca2f209196a1800d394684eb31 Mon Sep 17 00:00:00 2001 From: Remington Breeze Date: Fri, 21 Apr 2023 15:07:13 -0700 Subject: [PATCH] feat(dashboard): Refresh Rollouts dashboard UI (#2723) * feat: Refresh Rollouts dashboard Signed-off-by: Remington Breeze * rearrange individual rollout view Signed-off-by: Remington Breeze * fix letter L bug Signed-off-by: Remington Breeze * fix single namespace display Signed-off-by: Remington Breeze * bug fixes Signed-off-by: Remington Breeze * remove all dependencies on argo-ui/v2 Signed-off-by: Remington Breeze * feat: Refresh Rollouts dashboard Signed-off-by: Remington Breeze * rearrange individual rollout view Signed-off-by: Remington Breeze * fix letter L bug Signed-off-by: Remington Breeze * fix single namespace display Signed-off-by: Remington Breeze * bug fixes Signed-off-by: Remington Breeze * remove all dependencies on argo-ui/v2 Signed-off-by: Remington Breeze * fix: make logo image path relative Signed-off-by: Remington Breeze --------- Signed-off-by: Remington Breeze --- ui/package.json | 8 +- ui/src/app/App.scss | 4 +- ui/src/app/App.tsx | 108 ++- .../confirm-button/confirm-button.tsx | 72 ++ .../ellipsis-middle/ellipsis-middle.tsx | 13 + ui/src/app/components/header/header.scss | 47 +- ui/src/app/components/header/header.tsx | 67 +- .../app/components/info-item/info-item.scss | 80 ++ ui/src/app/components/info-item/info-item.tsx | 61 ++ ui/src/app/components/pods/pods.scss | 5 +- ui/src/app/components/pods/pods.tsx | 209 +++--- .../rollout-actions/rollout-actions.tsx | 52 +- ui/src/app/components/rollout/containers.tsx | 69 +- ui/src/app/components/rollout/revision.tsx | 73 +- ui/src/app/components/rollout/rollout.scss | 87 +-- ui/src/app/components/rollout/rollout.tsx | 214 +++--- .../rollouts-list/rollouts-list.scss | 59 +- .../rollouts-list/rollouts-list.tsx | 180 ++--- .../components/status-icon/status-icon.tsx | 10 +- ui/src/assets/images/argologo.svg | 1 + ui/src/config/theme.ts | 15 + ui/yarn.lock | 683 +++++++++++++++++- 22 files changed, 1521 insertions(+), 596 deletions(-) create mode 100644 ui/src/app/components/confirm-button/confirm-button.tsx create mode 100644 ui/src/app/components/ellipsis-middle/ellipsis-middle.tsx create mode 100644 ui/src/app/components/info-item/info-item.scss create mode 100644 ui/src/app/components/info-item/info-item.tsx create mode 100644 ui/src/assets/images/argologo.svg create mode 100644 ui/src/config/theme.ts diff --git a/ui/package.json b/ui/package.json index aaaf3de4cb..fac0a758f3 100644 --- a/ui/package.json +++ b/ui/package.json @@ -3,6 +3,10 @@ "version": "0.1.0", "private": true, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.4.0", + "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/react-fontawesome": "^0.2.0", + "antd": "^5.4.2", "argo-ui": "git+https://github.com/argoproj/argo-ui.git", "classnames": "2.2.6", "isomorphic-fetch": "^3.0.0", @@ -16,7 +20,7 @@ "react-keyhooks": "^0.2.3", "react-router-dom": "5.2.0", "rxjs": "^6.6.6", - "typescript": "4.3.5", + "typescript": "^5.0.4", "web-vitals": "^1.0.1" }, "scripts": { @@ -69,4 +73,4 @@ "resolutions": { "@types/react": "16.9.3" } -} \ No newline at end of file +} diff --git a/ui/src/app/App.scss b/ui/src/app/App.scss index ac371917d0..0254cb4ac1 100644 --- a/ui/src/app/App.scss +++ b/ui/src/app/App.scss @@ -27,7 +27,7 @@ html { } a { - color: inherit; + color: inherit !important; text-decoration: none; } @@ -38,7 +38,7 @@ a { .rollouts { height: 100%; overflow-y: auto; - font-family: 'Heebo', sans-serif; + font-family: system-ui, sans-serif; background-color: $argo-color-gray-3; &--dark { diff --git a/ui/src/app/App.tsx b/ui/src/app/App.tsx index b1d28fa5d5..60ba5419c6 100644 --- a/ui/src/app/App.tsx +++ b/ui/src/app/App.tsx @@ -1,8 +1,7 @@ -import {ThemeDiv, ThemeProvider} from 'argo-ui/v2'; import {Header} from './components/header/header'; import {createBrowserHistory} from 'history'; import * as React from 'react'; -import {Key, KeybindingContext, KeybindingProvider} from 'react-keyhooks'; +import {KeybindingProvider} from 'react-keyhooks'; import {Route, Router, Switch} from 'react-router-dom'; import './App.scss'; import {NamespaceContext, RolloutAPI} from './shared/context/api'; @@ -10,46 +9,39 @@ import {Modal} from './components/modal/modal'; import {Rollout} from './components/rollout/rollout'; import {RolloutsList} from './components/rollouts-list/rollouts-list'; import {Shortcut, Shortcuts} from './components/shortcuts/shortcuts'; +import {ConfigProvider} from 'antd'; +import {theme} from '../config/theme'; const bases = document.getElementsByTagName('base'); const base = bases.length > 0 ? bases[0].getAttribute('href') || '/' : '/'; export const history = createBrowserHistory({basename: base}); const Page = (props: {path: string; component: React.ReactNode; exact?: boolean; shortcuts?: Shortcut[]; changeNamespace: (val: string) => void}) => { - const {useKeybinding} = React.useContext(KeybindingContext); const [showShortcuts, setShowShortcuts] = React.useState(false); - useKeybinding( - [Key.SHIFT, Key.H], - () => { - if (props.shortcuts) { - setShowShortcuts(!showShortcuts); - } - return false; - }, - true - ); return ( - - {showShortcuts && ( - setShowShortcuts(false)}> - - - )} - - -
{ - if (props.shortcuts) { - setShowShortcuts(true); - } - }} - /> - {props.component} - - - + +
+ {showShortcuts && ( + setShowShortcuts(false)}> + + + )} + + +
{ + if (props.shortcuts) { + setShowShortcuts(true); + } + }} + /> + {props.component} + + +
+
); }; @@ -84,31 +76,29 @@ const App = () => { }; return ( - - {namespace && ( - - - - - } - shortcuts={[ - {key: '/', description: 'Search'}, - {key: 'TAB', description: 'Search, navigate search items'}, - {key: ['fa-arrow-left', 'fa-arrow-right', 'fa-arrow-up', 'fa-arrow-down'], description: 'Navigate rollouts list', icon: true}, - {key: ['SHIFT', 'H'], description: 'Show help menu', combo: true}, - ]} - changeNamespace={changeNamespace} - /> - } changeNamespace={changeNamespace} /> - - - - - )} - + namespace && ( + + + + + } + shortcuts={[ + {key: '/', description: 'Search'}, + {key: 'TAB', description: 'Search, navigate search items'}, + {key: ['fa-arrow-left', 'fa-arrow-right', 'fa-arrow-up', 'fa-arrow-down'], description: 'Navigate rollouts list', icon: true}, + {key: ['SHIFT', 'H'], description: 'Show help menu', combo: true}, + ]} + changeNamespace={changeNamespace} + /> + } changeNamespace={changeNamespace} /> + + + + + ) ); }; diff --git a/ui/src/app/components/confirm-button/confirm-button.tsx b/ui/src/app/components/confirm-button/confirm-button.tsx new file mode 100644 index 0000000000..4dd4f37e7c --- /dev/null +++ b/ui/src/app/components/confirm-button/confirm-button.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; + +import {Button, Popconfirm, Tooltip} from 'antd'; +import {ButtonProps} from 'antd/es/button/button'; +import {useState} from 'react'; +import { TooltipPlacement } from 'antd/es/tooltip'; + +interface ConfirmButtonProps extends ButtonProps { + skipconfirm?: boolean; + tooltip?: string; + placement?: TooltipPlacement; +} + +export const ConfirmButton = (props: ConfirmButtonProps) => { + const [open, setOpen] = useState(false); + const [buttonProps, setButtonProps] = useState(props); + + React.useEffect(() => { + const tmp = {...props}; + delete tmp.skipconfirm; + delete tmp.children; + delete tmp.onClick; + setButtonProps(tmp); + }, [props]); + + const confirm = () => { + setOpen(false); + if (props.onClick) { + props.onClick(null); + } + }; + + const cancel = () => { + setOpen(false); + }; + + const handleOpenChange = (newOpen: boolean) => { + if (!newOpen) { + setOpen(newOpen); + return; + } + if (props.skipconfirm) { + confirm(); // next step + } else { + setOpen(newOpen); + } + }; + + return ( +
{ + e.stopPropagation(); + e.preventDefault(); + }}> + +
+ + + +
+
+
+ ); +}; diff --git a/ui/src/app/components/ellipsis-middle/ellipsis-middle.tsx b/ui/src/app/components/ellipsis-middle/ellipsis-middle.tsx new file mode 100644 index 0000000000..4eba37f8b6 --- /dev/null +++ b/ui/src/app/components/ellipsis-middle/ellipsis-middle.tsx @@ -0,0 +1,13 @@ +import * as React from 'react'; +import {Typography} from 'antd'; + +const {Text} = Typography; +export const EllipsisMiddle: React.FC<{suffixCount: number; children: string; style: React.CSSProperties}> = ({suffixCount, children, style}) => { + const start = children.slice(0, children.length - suffixCount).trim(); + const suffix = children.slice(-suffixCount).trim(); + return ( + + {start} + + ); +}; diff --git a/ui/src/app/components/header/header.scss b/ui/src/app/components/header/header.scss index 395271d8f2..b1f48904a6 100644 --- a/ui/src/app/components/header/header.scss +++ b/ui/src/app/components/header/header.scss @@ -2,13 +2,12 @@ .rollouts-header { display: flex; - background: $slate; + background: #0f2733; color: white; align-items: center; padding: 10px 0; &__brand { - color: $shine; display: flex; align-items: center; text-decoration: none; @@ -16,44 +15,18 @@ -moz-user-select: none; -ms-user-select: none; user-select: none; - } - - &__welcome { - position: absolute; - transform-origin: left; - display: block; - overflow: hidden; - width: 174px; - white-space: nowrap; - transition: transform 1s ease 1s, opacity 1s ease; + margin-left: 10px; } &__title { - position: absolute; - transform: translateX(174px); - transition: transform 500ms ease 750ms; display: flex; align-items: center; - } - - h1 { - position: relative; + color: white !important; + font-weight: 600; font-size: 22px; - font-weight: 400; - margin: 0; - display: flex; - align-items: center; - } - - h2 { - font-size: 18px; - color: $sherbert; - margin: 0; - margin-left: 10px; - flex-grow: 1; - white-space: nowrap; + width: 200px; } - + &__info { margin-left: auto; display: flex; @@ -61,13 +34,11 @@ } &__label { color: $shine; - margin: 0 15px; margin: auto; - padding: 5px; + font-size: 10px; + font-weight: 600; } &__namespace { - color: black; - display: flex; - position: relative; + margin: 0 20px; } } diff --git a/ui/src/app/components/header/header.tsx b/ui/src/app/components/header/header.tsx index 3c3eba392e..e267822108 100644 --- a/ui/src/app/components/header/header.tsx +++ b/ui/src/app/components/header/header.tsx @@ -1,18 +1,19 @@ import * as React from 'react'; -import {ActionButton, Brand, InfoItemRow, ThemeToggle, Tooltip, Header as GenericHeader, Autocomplete, ThemeDiv} from 'argo-ui/v2'; import {useParams} from 'react-router'; import {NamespaceContext, RolloutAPIContext} from '../../shared/context/api'; import './header.scss'; import {Link, useHistory} from 'react-router-dom'; +import {AutoComplete, Button, Input, Tooltip} from 'antd'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faBook, faKeyboard} from '@fortawesome/free-solid-svg-icons'; -const Logo = () => Argo Logo; +const Logo = () => Argo Logo; export const Header = (props: {pageHasShortcuts: boolean; changeNamespace: (val: string) => void; showHelp: () => void}) => { const history = useHistory(); const namespaceInfo = React.useContext(NamespaceContext); - const {name} = useParams<{name: string}>(); const {namespace} = useParams<{namespace: string}>(); const api = React.useContext(RolloutAPIContext); const [version, setVersion] = React.useState('v?'); @@ -25,52 +26,54 @@ export const Header = (props: {pageHasShortcuts: boolean; changeNamespace: (val: getVersion(); }, []); React.useEffect(() => { - if (namespace && namespace != namespaceInfo.namespace) { - props.changeNamespace(namespace); - setNsInput(namespace); - } + if (namespace && namespace != namespaceInfo.namespace) { + props.changeNamespace(namespace); + setNsInput(namespace); + } }, []); return ( - - - } /> +
+ + +
+
+ Argo Text Logo +
+
Rollouts {version}
+
{props.pageHasShortcuts && ( - - + +
- +
); }; diff --git a/ui/src/app/components/info-item/info-item.scss b/ui/src/app/components/info-item/info-item.scss new file mode 100644 index 0000000000..0cd040dde6 --- /dev/null +++ b/ui/src/app/components/info-item/info-item.scss @@ -0,0 +1,80 @@ +@import 'node_modules/argo-ui/v2/styles/colors'; + +.info-item { + background-color: $argo-color-gray-4; + border-radius: 3px; + border: 1px solid $argo-color-gray-5; + padding: 5px 7px; + margin-right: 5px; + color: $argo-color-gray-8; + display: flex; + align-items: center; + min-width: 0; + + &--lightweight { + border: none; + background: none; + font-weight: 500; + padding-left: 0; + padding-right: 0; + } + + &--dark { + background-color: $fog; + border: 1px solid $silver-lining; + color: $dull-shine; + } + + &--colored { + background-color: $sherbert; + border: 1px solid $sherbert; + color: white; + } + + &--dark#{&}--colored { + background-color: $spray-tan; + border: 1px solid $sherbert; + color: white; + } + + &--canary { + background-color: $canary; + border: 1px solid $canary; + color: $space; + } + + &--bluegreen { + background-color: $sea; + border: 1px solid $sea; + color: white; + } + + &--monospace { + font-family: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', + 'Droid Sans Mono', 'Courier New', monospace; + font-size: 14px; + } + + &--row { + display: flex; + align-items: center; + flex-grow: 1; + label { + margin-right: auto; + padding-right: 5px; + } + .info-item { + margin: 0.25em 0; + margin-left: 5px; + } + + &__container { + margin-left: auto; + display: flex; + min-width: 0; + padding-left: 25px; + flex-wrap: wrap; + justify-content: flex-end; + } + } +} diff --git a/ui/src/app/components/info-item/info-item.tsx b/ui/src/app/components/info-item/info-item.tsx new file mode 100644 index 0000000000..7e7bf8e617 --- /dev/null +++ b/ui/src/app/components/info-item/info-item.tsx @@ -0,0 +1,61 @@ +import * as React from 'react'; +import './info-item.scss'; +import { Tooltip } from 'antd'; + +export enum InfoItemKind { + Default = 'default', + Colored = 'colored', + Monospace = 'monospace', + Canary = 'canary', + BlueGreen = 'bluegreen', +} + +export interface InfoItemProps { + content?: string; + icon?: string; + style?: React.CSSProperties; + kind?: InfoItemKind; + truncate?: boolean; + lightweight?: boolean; +} + +/** + * Displays a small piece encapsulated piece of data + */ +export const InfoItem = (props: InfoItemProps) => { + const truncateStyle = props.truncate ? {overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis'} : {}; + const item = ( +
+ {props.icon && ( + + + + )} +
{props.content}
+
+ ); + return props.truncate ? {item} : item; +}; + +/** + * Displays a right justified InfoItem (or multiple InfoItems) and a left justfied label + */ +export const InfoItemRow = (props: {label: string | React.ReactNode; items?: InfoItemProps | InfoItemProps[]; lightweight?: boolean}) => { + let {label, items} = props; + let itemComponents = null; + if (!Array.isArray(items)) { + items = [items]; + } + itemComponents = items.map((c, i) => ); + + return ( +
+ {props.label && ( +
+ +
+ )} + {props.items &&
{itemComponents}
} +
+ ); +}; diff --git a/ui/src/app/components/pods/pods.scss b/ui/src/app/components/pods/pods.scss index ee3121b111..b55f08c9d6 100644 --- a/ui/src/app/components/pods/pods.scss +++ b/ui/src/app/components/pods/pods.scss @@ -7,6 +7,7 @@ $POD_SIZE: 30px; font-size: 16px; font-weight: 500; display: flex; + max-width: 100%; align-items: center; &__tags { margin-left: auto; @@ -25,10 +26,6 @@ $POD_SIZE: 30px; .pod-icon { margin: 3px; } - &--dark { - border-color: $silver-lining; - background-color: $space; - } } } diff --git a/ui/src/app/components/pods/pods.tsx b/ui/src/app/components/pods/pods.tsx index c9be978570..c3e5fecb32 100644 --- a/ui/src/app/components/pods/pods.tsx +++ b/ui/src/app/components/pods/pods.tsx @@ -1,10 +1,14 @@ -import {Menu, ThemeDiv, Tooltip, WaitFor, InfoItem} from 'argo-ui/v2'; import * as React from 'react'; import * as moment from 'moment'; import {Duration, Ticker} from 'argo-ui'; import {RolloutReplicaSetInfo} from '../../../models/rollout/generated'; import {ReplicaSetStatus, ReplicaSetStatusIcon} from '../status-icon/status-icon'; import './pods.scss'; +import {Dropdown, MenuProps, Tooltip} from 'antd'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {IconDefinition, faCheck, faCircleNotch, faClipboard, faExclamationTriangle, faQuestionCircle, faTimes} from '@fortawesome/free-solid-svg-icons'; +import {EllipsisMiddle} from '../ellipsis-middle/ellipsis-middle'; +import {InfoItem} from '../info-item/info-item'; export enum PodStatus { Pending = 'pending', @@ -36,52 +40,6 @@ export const ParsePodStatus = (status: string): PodStatus => { } }; -export const PodIcon = (props: {status: string; customIcon?: string}) => { - const {status, customIcon} = props; - let icon; - let spin = false; - if (status.startsWith('Init:')) { - icon = 'fa-circle-notch'; - spin = true; - } - if (status.startsWith('Signal:') || status.startsWith('ExitCode:')) { - icon = 'fa-times'; - } - if (status.endsWith('Error') || status.startsWith('Err')) { - icon = 'fa-exclamation-triangle'; - } - - const className = ParsePodStatus(status); - - if (customIcon) icon = customIcon; - else - switch (className) { - case PodStatus.Pending: - icon = 'fa-circle-notch'; - spin = true; - break; - case PodStatus.Success: - icon = 'fa-check'; - break; - case PodStatus.Failed: - icon = 'fa-times'; - break; - case PodStatus.Warning: - icon = 'fa-exclamation-triangle'; - break; - default: - spin = false; - icon = 'fa-question-circle'; - break; - } - - return ( - - - - ); -}; - export const ReplicaSets = (props: {replicaSets: RolloutReplicaSetInfo[]; showRevisions?: boolean}) => { const {replicaSets} = props; if (!replicaSets || replicaSets.length < 1) { @@ -106,60 +64,119 @@ export const ReplicaSets = (props: {replicaSets: RolloutReplicaSetInfo[]; showRe export const ReplicaSet = (props: {rs: RolloutReplicaSetInfo; showRevision?: boolean}) => { const rsName = props.rs.objectMeta.name; return ( - +
{rsName && ( - - {rsName} - {props.showRevision &&
Revision {props.rs.revision}
} - {props.rs.scaleDownDeadline && ( -
- - {(now) => { - const time = moment(props.rs.scaleDownDeadline).diff(now.toDate(), 'second'); - return time <= 0 ? null : ( - - Scaledown in - - }> - ) as any} icon='fa fa-clock'> - - ); - }} - -
- )} -
+ +
+ + {rsName} + + + {props.showRevision &&
Revision {props.rs.revision}
} + {props.rs.scaleDownDeadline && ( +
+ + {(now) => { + const time = moment(props.rs.scaleDownDeadline).diff(now.toDate(), 'second'); + return time <= 0 ? null : ( + + Scaledown in + + }> + ) as any} icon='fa fa-clock'> + + ); + }} + +
+ )} +
+
)} {props.rs.pods && props.rs.pods.length > 0 && ( - - - {props.rs.pods.map((pod, i) => ( - -
Status: {pod.status}
-
{pod.objectMeta?.name}
-
- } - /> - ))} - -
+
+ {(props.rs?.pods || []).map((pod, i) => ( + +
Status: {pod.status}
+
{pod.objectMeta?.name}
+
+ } + /> + ))} + )} - + ); }; -export const PodWidget = ({name, status, tooltip, customIcon}: {name: string; status: string; tooltip: React.ReactNode; customIcon?: string}) => ( - navigator.clipboard.writeText(name), icon: 'fa-clipboard'}]}> - - - - -); +const CopyMenu = (name: string): MenuProps['items'] => { + return [ + { + key: 1, + label: ( +
navigator.clipboard.writeText(name)}> + Copy Name +
+ ), + }, + ]; +}; + +export const PodWidget = ({name, status, tooltip, customIcon}: {name: string; status: string; tooltip: React.ReactNode; customIcon?: IconDefinition}) => { + let icon: IconDefinition; + let spin = false; + if (status.startsWith('Init:')) { + icon = faCircleNotch; + spin = true; + } + if (status.startsWith('Signal:') || status.startsWith('ExitCode:')) { + icon = faTimes; + } + if (status.endsWith('Error') || status.startsWith('Err')) { + icon = faExclamationTriangle; + } + + const className = ParsePodStatus(status); + + if (customIcon) { + icon = customIcon; + } else { + switch (className) { + case PodStatus.Pending: + icon = faCircleNotch; + spin = true; + break; + case PodStatus.Success: + icon = faCheck; + break; + case PodStatus.Failed: + icon = faTimes; + break; + case PodStatus.Warning: + icon = faExclamationTriangle; + break; + default: + spin = false; + icon = faQuestionCircle; + break; + } + } + + return ( + + +
+ +
+
+
+ ); +}; diff --git a/ui/src/app/components/rollout-actions/rollout-actions.tsx b/ui/src/app/components/rollout-actions/rollout-actions.tsx index 283af8c4ca..94a4b289f2 100644 --- a/ui/src/app/components/rollout-actions/rollout-actions.tsx +++ b/ui/src/app/components/rollout-actions/rollout-actions.tsx @@ -2,8 +2,11 @@ import * as React from 'react'; import {RolloutInfo} from '../../../models/rollout/rollout'; import {NamespaceContext, RolloutAPIContext} from '../../shared/context/api'; import {formatTimestamp} from '../../shared/utils/utils'; -import {ActionButton, ActionButtonProps} from 'argo-ui/v2'; import {RolloutStatus} from '../status-icon/status-icon'; +import {ConfirmButton} from '../confirm-button/confirm-button'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faArrowCircleUp, faChevronCircleUp, faExclamationCircle, faRedoAlt, faSync} from '@fortawesome/free-solid-svg-icons'; +import {IconProp} from '@fortawesome/fontawesome-svg-core'; export enum RolloutAction { Restart = 'Restart', @@ -13,19 +16,28 @@ export enum RolloutAction { PromoteFull = 'PromoteFull', } +interface ActionData { + label: string; + icon: IconProp; + action: (body: any, namespace: string, name: string) => Promise; + tooltip?: string; + disabled?: boolean; + shouldConfirm?: boolean; +} + export const RolloutActionButton = (props: {action: RolloutAction; rollout: RolloutInfo; callback?: Function; indicateLoading: boolean; disabled?: boolean}) => { const api = React.useContext(RolloutAPIContext); const namespaceCtx = React.useContext(NamespaceContext); const restartedAt = formatTimestamp(props.rollout.restartedAt || ''); - const isDeploying = props.rollout.status === RolloutStatus.Progressing || props.rollout.status === RolloutStatus.Paused + const isDeploying = props.rollout.status === RolloutStatus.Progressing || props.rollout.status === RolloutStatus.Paused; - const actionMap = new Map([ + const actionMap = new Map([ [ RolloutAction.Restart, { label: 'RESTART', - icon: 'fa-sync', + icon: faSync, action: api.rolloutServiceRestartRollout, tooltip: restartedAt === 'Never' ? 'Never restarted' : `Last restarted ${restartedAt}`, shouldConfirm: true, @@ -35,7 +47,7 @@ export const RolloutActionButton = (props: {action: RolloutAction; rollout: Roll RolloutAction.Retry, { label: 'RETRY', - icon: 'fa-redo-alt', + icon: faRedoAlt, action: api.rolloutServiceRetryRollout, disabled: props.rollout.status !== RolloutStatus.Degraded, shouldConfirm: true, @@ -45,7 +57,7 @@ export const RolloutActionButton = (props: {action: RolloutAction; rollout: Roll RolloutAction.Abort, { label: 'ABORT', - icon: 'fa-exclamation-circle', + icon: faExclamationCircle, action: api.rolloutServiceAbortRollout, disabled: !isDeploying, shouldConfirm: true, @@ -55,7 +67,7 @@ export const RolloutActionButton = (props: {action: RolloutAction; rollout: Roll RolloutAction.Promote, { label: 'PROMOTE', - icon: 'fa-chevron-circle-up', + icon: faChevronCircleUp, action: api.rolloutServicePromoteRollout, body: {full: false}, disabled: !isDeploying, @@ -66,7 +78,7 @@ export const RolloutActionButton = (props: {action: RolloutAction; rollout: Roll RolloutAction.PromoteFull, { label: 'PROMOTE-FULL', - icon: 'fa-arrow-circle-up', + icon: faArrowCircleUp, action: api.rolloutServicePromoteRollout, body: {full: true}, disabled: !isDeploying, @@ -77,17 +89,27 @@ export const RolloutActionButton = (props: {action: RolloutAction; rollout: Roll const ap = actionMap.get(props.action); + const [loading, setLoading] = React.useState(false); + return ( - { - ap.action(ap.body || {}, namespaceCtx.namespace, props.rollout.objectMeta?.name || ''); + { + setLoading(true); + await ap.action(ap.body || {}, namespaceCtx.namespace, props.rollout.objectMeta?.name || ''); if (props.callback) { - props.callback(); + await props.callback(); } + setLoading(false); }} - indicateLoading={props.indicateLoading} - /> + disabled={ap.disabled} + loading={loading} + tooltip={ap.tooltip} + icon={}> + {props.action} + ); }; diff --git a/ui/src/app/components/rollout/containers.tsx b/ui/src/app/components/rollout/containers.tsx index 051c8c606c..c69b30658b 100644 --- a/ui/src/app/components/rollout/containers.tsx +++ b/ui/src/app/components/rollout/containers.tsx @@ -1,7 +1,10 @@ -import {ActionButton, Autocomplete, InfoItem, ThemeDiv, useInput} from 'argo-ui/v2'; import * as React from 'react'; import {RolloutContainerInfo} from '../../../models/rollout/generated'; import {ImageInfo, ReactStatePair} from './rollout'; +import {AutoComplete, Button, Input} from 'antd'; +import {ConfirmButton} from '../confirm-button/confirm-button'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faExclamationCircle, faPencilAlt, faSave, faTimes} from '@fortawesome/free-solid-svg-icons'; interface ContainersWidgetProps { containers: RolloutContainerInfo[]; @@ -25,25 +28,28 @@ export const ContainersWidget = (props: ContainersWidgetProps) => { return (
- +
Containers - +
{interactive && (interactive?.editState[0] ? (
- { +
) : ( - setEditing(true)} style={{cursor: 'pointer', marginLeft: 'auto'}} /> + ))}
{containers.map((c, i) => ( @@ -80,12 +87,11 @@ export const ContainersWidget = (props: ContainersWidgetProps) => { /> ))} {containers.length < 2 && ( - +
- Add more containers to fill this space! - +
)}
); @@ -93,16 +99,31 @@ export const ContainersWidget = (props: ContainersWidgetProps) => { const ContainerWidget = (props: {container: RolloutContainerInfo; images: ImageInfo[]; setInput: (image: string) => void; editing: boolean}) => { const {container, editing} = props; - const [, , newImageInput] = useInput(container.image, (val) => props.setInput(val)); + const [input, setInput] = React.useState(container.image); + + const update = (val: string) => { + setInput(val); + props.setInput(val); + }; return ( -
-
{container.name}
-
+
+
{container.name}
+
{!editing ? ( - + ) : ( - img.image)} placeholder='New Image' {...newImageInput} /> + { + return {label: img.image, value: img.image}; + })} + placeholder='New Image' + value={input} + onSelect={update} + onChange={update} + /> )}
diff --git a/ui/src/app/components/rollout/revision.tsx b/ui/src/app/components/rollout/revision.tsx index f61a9229c7..e2fcd11526 100644 --- a/ui/src/app/components/rollout/revision.tsx +++ b/ui/src/app/components/rollout/revision.tsx @@ -1,4 +1,3 @@ -import {ActionButton, EffectDiv, formatTimestamp, InfoItemProps, InfoItemRow, ThemeDiv, Tooltip} from 'argo-ui/v2'; import * as React from 'react'; import {RolloutAnalysisRunInfo, RolloutExperimentInfo, RolloutReplicaSetInfo} from '../../../models/rollout/generated'; import {IconForTag} from '../../shared/utils/utils'; @@ -6,6 +5,21 @@ import {PodWidget, ReplicaSets} from '../pods/pods'; import {ImageInfo, parseImages} from './rollout'; import './rollout.scss'; import '../pods/pods.scss'; +import {ConfirmButton} from '../confirm-button/confirm-button'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faChartBar, faChevronCircleDown, faChevronCircleUp, faUndoAlt} from '@fortawesome/free-solid-svg-icons'; +import {Button, Tooltip} from 'antd'; +import moment = require('moment'); +import {InfoItemProps, InfoItemRow} from '../info-item/info-item'; + +function formatTimestamp(ts: string): string { + const inputFormat = 'YYYY-MM-DD HH:mm:ss Z z'; + const m = moment(ts, inputFormat); + if (!ts || !m.isValid()) { + return 'Never'; + } + return m.format('MMM D YYYY [at] hh:mm:ss'); +} export interface Revision { number: string; @@ -24,7 +38,7 @@ const ImageItems = (props: {images: ImageInfo[]}) => { if (imageItems.length === 0) { imageItems = []; } - return {img.image}} items={imageItems} />; + return {img.image}
} items={imageItems} />; })}
); @@ -41,31 +55,29 @@ interface RevisionWidgetProps { export const RevisionWidget = (props: RevisionWidgetProps) => { const {revision, initCollapsed} = props; const [collapsed, setCollapsed] = React.useState(initCollapsed); - const icon = collapsed ? 'fa-chevron-circle-down' : 'fa-chevron-circle-up'; + const icon = collapsed ? faChevronCircleDown : faChevronCircleUp; const images = parseImages(revision.replicaSets); + const hasPods = (revision.replicaSets || []).some((rs) => rs.pods?.length > 0); return ( - - +
+
Revision {revision.number}
{!props.current && props.rollback && ( - props.rollback(Number(revision.number))} - label='ROLLBACK' - icon='fa-undo-alt' - style={{fontSize: '13px'}} - indicateLoading - shouldConfirm - /> + props.rollback(Number(revision.number))} + type='default' + icon={} + style={{fontSize: '13px', marginRight: '10px'}}> + Rollback + )} - setCollapsed(!collapsed)}> - - + {hasPods && setCollapsed(!collapsed)} />}
- - +
+
- +
{!collapsed && ( @@ -79,7 +91,7 @@ export const RevisionWidget = (props: RevisionWidgetProps) => { )} )} - +
); }; @@ -88,7 +100,7 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => { const [selection, setSelection] = React.useState(null); return ( - +
Analysis Runs
{analysisRuns.map((ar) => { @@ -97,7 +109,7 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => { return (
Name: {ar.objectMeta.name} @@ -116,10 +128,9 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => { className={`analysis__runs-action ${ ar.status === 'Running' ? 'analysis--pending' : ar.status === 'Successful' ? 'analysis--success' : 'analysis--failure' }`}> - (selection?.objectMeta.name === ar.objectMeta.name ? setSelection(null) : setSelection(ar))} - label={`Analysis ${temp[len - 2] + '-' + temp[len - 1]}`} - /> +
); @@ -149,13 +160,13 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => {
MetricName: {job.metricName}
} - customIcon='fa-chart-bar' + customIcon={faChartBar} /> ); })}
metric.name === selection.jobs[0].metricName) .map((metric) => { return ( @@ -212,13 +223,13 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => {
MetricName: {nonJob.metricName}
} - customIcon='fa-chart-bar' + customIcon={faChartBar} /> ); })} metric.name === selection.nonJobInfo[0].metricName) .map((metric) => { return ( @@ -260,6 +271,6 @@ const AnalysisRunWidget = (props: {analysisRuns: RolloutAnalysisRunInfo[]}) => { )} )} -
+ ); }; diff --git a/ui/src/app/components/rollout/rollout.scss b/ui/src/app/components/rollout/rollout.scss index 88819de47b..ad6247c478 100644 --- a/ui/src/app/components/rollout/rollout.scss +++ b/ui/src/app/components/rollout/rollout.scss @@ -1,26 +1,13 @@ -@import 'node_modules/argo-ui/v2/styles/colors'; +@import "node_modules/argo-ui/v2/styles/colors"; .revision { padding: 15px; margin-bottom: 1em; background: none; - &__background { - background: $argo-color-gray-2; - border: 1px solid $argo-color-gray-4; - border-radius: 5px; - } - - &--dark > &__background { - border: none; - background: $slate; - } - - &:hover > &__background { - transform: scale(1.02); - box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.1); - } - + background: $argo-color-gray-1; + border-radius: 5px; + &__header { display: flex; align-items: center; @@ -40,39 +27,36 @@ } .steps { - width: 250px; + width: 300px; flex-shrink: 0; - max-height: 500px; overflow-y: auto; &__step { padding: 15px 18px; - &__background { - border-radius: 10px; - border: 1px solid $argo-color-gray-4; - &--dark { - border: 1px solid $silver-lining; - } + border-radius: 10px; + border: 1px solid $argo-color-gray-4; + &--dark { + border: 1px solid $silver-lining; } - &:hover > &__background { + &:hover { border: 1px solid $sherbert; } - &--complete > &__background { + &--complete { border: 2px solid $argo-success-color; } - &--complete:hover > &__background { + &--complete:hover { border: 2px solid $argo-success-color; } - &--current > &__background { + &--current { border: 2px solid $sherbert; } - &--current:hover > &__background { + &--current:hover { border: 2px solid $sherbert; } @@ -105,6 +89,7 @@ display: flex; align-items: center; justify-content: space-between; + font-weight: 600; } &-title { @@ -112,20 +97,6 @@ padding-bottom: 4px; font-size: 14px; } - - &-value { - font-weight: 600; - padding-bottom: 4px; - border-bottom: 1px solid $argo-color-gray-4; - &:last-child { - padding-bottom: -8px; - border-bottom: none; - } - } - } - - &:hover > &__background { - transform: scale(1.02); } } @@ -163,9 +134,8 @@ } .info { - border: 1px solid $argo-color-gray-4; border-radius: 5px; - padding: 20px; + padding: 15px; background-color: white; height: max-content; box-sizing: border-box; @@ -217,27 +187,23 @@ } .action-button { - font-size: '10px'; + font-size: "10px"; line-height: 1; - border: '1px solid'; - padding: '8px 8px 8px 10px'; - border-radius: '12px'; - color: 'white'; + border: "1px solid"; + padding: "8px 8px 8px 10px"; + border-radius: "12px"; + color: "white"; margin-top: 4px; } &.analysis--success .action-button:hover { - .action-button__background { - background-color: seagreen; - border-color: seagreen; - } + background-color: seagreen; + border-color: seagreen; } &.analysis--failure .action-button:hover { - .action-button__background { - background-color: red; - border-color: red; - } + background-color: red; + border-color: red; } } } @@ -362,6 +328,7 @@ &__toolbar { box-sizing: border-box; font-size: 14px; + font-weight: 600; display: flex; align-items: center; padding: 0 10px; @@ -386,7 +353,7 @@ } &__revisions { - width: 550px; + width: 100%; } &__body { diff --git a/ui/src/app/components/rollout/rollout.tsx b/ui/src/app/components/rollout/rollout.tsx index 77d6607ac4..91b6c0a9d8 100644 --- a/ui/src/app/components/rollout/rollout.tsx +++ b/ui/src/app/components/rollout/rollout.tsx @@ -1,8 +1,6 @@ -import {EffectDiv, InfoItemKind, InfoItemRow, Spinner, ThemeDiv, WaitFor} from 'argo-ui/v2'; import * as React from 'react'; import {Helmet} from 'react-helmet'; -import {Key, KeybindingContext} from 'react-keyhooks'; -import {useHistory, useParams} from 'react-router-dom'; +import {useParams} from 'react-router-dom'; import { GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1CanaryStep, GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1HeaderRoutingMatch, @@ -21,6 +19,9 @@ import {ContainersWidget} from './containers'; import {Revision, RevisionWidget} from './revision'; import './rollout.scss'; import {Fragment} from 'react'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faChevronCircleDown, faChevronCircleUp, faCircleNotch} from '@fortawesome/free-solid-svg-icons'; +import {InfoItemKind, InfoItemRow} from '../info-item/info-item'; const RolloutActions = React.lazy(() => import('../rollout-actions/rollout-actions')); export interface ImageInfo { @@ -104,78 +105,85 @@ export const RolloutWidget = (props: {rollout: RolloutRolloutInfo; interactive?: } return ( - -
- -
Summary
- - - - {rollout.strategy === Strategy.Canary && ( - - - - {' '} - - )} - -
- - { - interactive.api.rolloutServiceSetRolloutImage({}, interactive.namespace, rollout.objectMeta?.name, container, image, tag); - }, - } - : null - } - /> - +
+
+ {(rollout?.strategy || '').toLowerCase() === 'canary' && rollout.steps && rollout.steps.length > 0 && }
-
- {rollout.replicaSets && rollout.replicaSets.length > 0 && ( - -
Revisions
-
- {revisions.map((r, i) => ( - interactive.api.rolloutServiceUndoRollout({}, interactive.namespace, rollout.objectMeta.name, `${r}`) : null} - current={i === 0} - message={rollout.message} - /> - ))} +
+
+
+
Summary
+ + +
+ {rollout.strategy === Strategy.Canary && ( + + + + {' '} + + )}
- - )} - {(rollout?.strategy || '').toLowerCase() === 'canary' && rollout.steps && rollout.steps.length > 0 && ( - - Steps -
- {rollout.steps - .filter((step) => Object.keys(step).length) - .map((step, i, arr) => ( - +
+
+ { + interactive.api.rolloutServiceSetRolloutImage({}, interactive.namespace, rollout.objectMeta?.name, container, image, tag); + }, + } + : null + } + /> +
+
+ +
+ {rollout.replicaSets && rollout.replicaSets.length > 0 && ( +
+
Revisions
+
+ {revisions.map((r, i) => ( + interactive.api.rolloutServiceUndoRollout({}, interactive.namespace, rollout.objectMeta.name, `${r}`) : null} + current={i === 0} + message={rollout.message} + /> ))} +
- - )} + )} +
- +
); }; +const Steps = (props: {rollout: RolloutInfo; curStep: number}) => ( +
+
Steps
+
+ {props.rollout.steps + .filter((step) => Object.keys(step).length) + .map((step, i, arr) => ( + + ))} +
+
+); + export const Rollout = () => { const {name} = useParams<{name: string}>(); @@ -183,39 +191,25 @@ export const Rollout = () => { const api = React.useContext(RolloutAPIContext); const namespaceCtx = React.useContext(NamespaceContext); - const {useKeybinding} = React.useContext(KeybindingContext); const editState = React.useState(false); - const history = useHistory(); - - useKeybinding(Key.L, () => { - if (editState[0]) { - return false; - } - history.push('/rollouts'); - return true; - }); return (
{name} / Argo Rollouts - - +
+
{name}
- +
- }> + }>
- +
- - - - - +
{!loading && }
); }; @@ -328,7 +322,7 @@ const Step = (props: {step: GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1 return ( - +
} {content} {unit} {props.step.setCanaryScale && ( - setOpenCanary(!openCanary)}> +
setOpenCanary(!openCanary)}> - +
)} {props.step.analysis && ( - setOpenAnalysis(!openAnalysis)}> +
setOpenAnalysis(!openAnalysis)}> - +
)} {props.step.setHeaderRoute && props.step.setHeaderRoute.match && ( - setOpenHeader(!openHeader)}> +
setOpenHeader(!openHeader)}> - +
)} {props.step.setMirrorRoute && props.step.setMirrorRoute.match && ( - setOpenMirror(!openMirror)}> +
setOpenMirror(!openMirror)}> - +
)}
{props.step.experiment?.templates && ( @@ -387,8 +381,8 @@ const Step = (props: {step: GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1 {props.step?.setCanaryScale && openCanary && } {props.step?.setHeaderRoute && openHeader && } {props.step?.setMirrorRoute && openMirror && } - - {!props.last && } +
+ {!props.last &&
} ); }; @@ -402,23 +396,21 @@ const ExperimentWidget = ({ opened: boolean; onToggle: (name: string) => void; }) => { - const icon = opened ? 'fa-chevron-circle-up' : 'fa-chevron-circle-down'; + const icon = opened ? faChevronCircleUp : faChevronCircleDown; return ( - - +
+
{template.name} - onToggle(opened ? '' : template.name)}> - - - + onToggle(opened ? '' : template.name)} style={{cursor: 'pointer'}} /> +
{opened && } - +
); }; const WidgetItem = ({values}: {values: Record}) => { return ( - +
{Object.keys(values).map((val) => { if (!values[val]) return null; return ( @@ -428,14 +420,14 @@ const WidgetItem = ({values}: {values: Record}) => { ); })} - +
); }; const WidgetItemSetMirror = ({value}: {value: GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1SetMirrorRoute}) => { if (!value) return null; return ( - +
Name
{value.name}
@@ -493,14 +485,14 @@ const WidgetItemSetMirror = ({value}: {value: GithubComArgoprojArgoRolloutsPkgAp return fragments; })}
- +
); }; const WidgetItemSetHeader = ({values}: {values: GithubComArgoprojArgoRolloutsPkgApisRolloutsV1alpha1HeaderRoutingMatch[]}) => { if (!values) return null; return ( - +
{values.map((record) => { if (!record.headerName) return null; if (!record.headerValue) return null; @@ -528,6 +520,6 @@ const WidgetItemSetHeader = ({values}: {values: GithubComArgoprojArgoRolloutsPkg ); })} - +
); }; diff --git a/ui/src/app/components/rollouts-list/rollouts-list.scss b/ui/src/app/components/rollouts-list/rollouts-list.scss index 3892e8cb9a..f0ec5fdcc7 100644 --- a/ui/src/app/components/rollouts-list/rollouts-list.scss +++ b/ui/src/app/components/rollouts-list/rollouts-list.scss @@ -16,6 +16,11 @@ $colWidth: ($WIDGET_WIDTH + (2 * $widgetPadding)) + $widgetMarginRight; margin: 0 auto; } + &__search { + width: 100%; + font-size: 15px; + } + &__rollouts-container { padding: 20px; display: flex; @@ -89,7 +94,7 @@ $colWidth: ($WIDGET_WIDTH + (2 * $widgetPadding)) + $widgetMarginRight; &__toolbar { width: 100%; - padding-top: 1.5em; + padding: 1em 0; background-color: white; border-bottom: 1px solid white; @@ -111,48 +116,30 @@ $colWidth: ($WIDGET_WIDTH + (2 * $widgetPadding)) + $widgetMarginRight; flex-shrink: 0; margin-bottom: 1.5em; border-radius: 5px; + background-color: white; + box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.05); + border: 1px solid $argo-color-gray-4; + z-index: 0; - &__pods { - margin-bottom: 1em; - } - - &__background { - background-color: white; - box-shadow: 1px 2px 2px rgba(0, 0, 0, 0.05); - border: 1px solid $argo-color-gray-4; - - border-radius: 5px; - &--dark { - border-color: $silver-lining; - box-shadow: 1px 2px 3px 1px $space; - background: none; - } - } - - &:hover > &__background, - &--selected > &__background { - transform: scale(1.01); - border-color: $sherbert; + &:hover, + &--selected { + border-color: $argo-running-color; } - &--dark:hover > &__background, - &--dark#{&}--selected > &__background { - border-color: $spray-tan; + &__pods { + margin-bottom: 1em; } &--dark { color: $dull-shine; - } - - &__container { - position: relative; - display: block; - z-index: 2; + border-color: $silver-lining; + box-shadow: 1px 2px 3px 1px $space; + background: none; } &__refresh { &:hover { - color: $sherbert; + color: $argo-running-color; } } @@ -169,10 +156,8 @@ $colWidth: ($WIDGET_WIDTH + (2 * $widgetPadding)) + $widgetMarginRight; color: $argo-color-gray-8; display: flex; align-items: center; - font-weight: 500; - font-size: 18px; - border-bottom: 1px solid $argo-color-gray-4; - padding-bottom: 1em; + font-weight: 600; + font-size: 20px; margin-bottom: 1em; } @@ -181,9 +166,11 @@ $colWidth: ($WIDGET_WIDTH + (2 * $widgetPadding)) + $widgetMarginRight; border-bottom: 1px solid $silver-lining; } &__actions { + position: relative; display: flex; align-items: center; margin-top: 1.5em; + z-index: 10 !important; } } } diff --git a/ui/src/app/components/rollouts-list/rollouts-list.tsx b/ui/src/app/components/rollouts-list/rollouts-list.tsx index ba7189adb5..e8c9a4dc5f 100644 --- a/ui/src/app/components/rollouts-list/rollouts-list.tsx +++ b/ui/src/app/components/rollouts-list/rollouts-list.tsx @@ -1,4 +1,3 @@ -import {Autocomplete, EffectDiv, InfoItemKind, InfoItemRow, Spinner, ThemeDiv, useAutocomplete, WaitFor} from 'argo-ui/v2'; import * as React from 'react'; import {Key, KeybindingContext, useNav} from 'react-keyhooks'; import {Link, useHistory} from 'react-router-dom'; @@ -10,9 +9,20 @@ import {ParsePodStatus, PodStatus, ReplicaSets} from '../pods/pods'; import {RolloutAction, RolloutActionButton} from '../rollout-actions/rollout-actions'; import {RolloutStatus, StatusIcon} from '../status-icon/status-icon'; import './rollouts-list.scss'; +import {AutoComplete, Tooltip} from 'antd'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faCircleNotch, faRedoAlt} from '@fortawesome/free-solid-svg-icons'; +import {InfoItemKind, InfoItemRow} from '../info-item/info-item'; const useRolloutNames = (rollouts: RolloutInfo[]) => { - const parseNames = (rl: RolloutInfo[]) => (rl || []).map((r) => r.objectMeta?.name || ''); + const parseNames = (rl: RolloutInfo[]) => + (rl || []).map((r) => { + const name = r.objectMeta?.name || ''; + return { + label: name, + value: name, + }; + }); const [rolloutNames, setRolloutNames] = React.useState(parseNames(rollouts)); React.useEffect(() => { @@ -28,26 +38,25 @@ export const RolloutsList = () => { const loading = rolloutsList.loading; const [filteredRollouts, setFilteredRollouts] = React.useState(rollouts); const [pos, nav, reset] = useNav(filteredRollouts.length); - const [searchString, setSearchString, searchInput] = useAutocomplete(''); + const [searchString, setSearchString] = React.useState(''); const searchParam = new URLSearchParams(window.location.search).get('q'); React.useEffect(() => { - if (searchParam && searchParam != searchString) { - setSearchString(searchParam); - } + if (searchParam && searchParam != searchString) { + setSearchString(searchParam); + } }, []); - const {useKeybinding, keybindingState} = React.useContext(KeybindingContext); + const searchRef = React.useRef(null); - // ignore H key when typing - const hGroup = keybindingState.groupForKey[Key.H]; - const showHelpMenu = keybindingState.groups[hGroup][Key.H].action; - keybindingState.groups[hGroup][Key.H].action = () => { - if (searchInput.inputref.current === document.activeElement) { - return false; - } else { - return showHelpMenu(); + React.useEffect(() => { + if (searchRef.current) { + // or, if Input component in your ref, then use input property like: + // searchRef.current.input.focus(); + searchRef.current.focus(); } - }; + }, [searchRef]); + + const {useKeybinding} = React.useContext(KeybindingContext); useKeybinding(Key.RIGHT, () => nav(1)); useKeybinding(Key.LEFT, () => nav(-1)); @@ -66,8 +75,8 @@ export const RolloutsList = () => { useKeybinding(Key.SLASH, () => { if (!searchString) { - if (searchInput.inputref.current) { - searchInput.inputref.current.focus(); + if (searchRef) { + searchRef.current.focus(); } return true; } @@ -88,7 +97,9 @@ export const RolloutsList = () => { setFilteredRollouts(filtered); } if (searchString) { - history.replace(`/${namespaceCtx.namespace}?q=${searchString}`); + history.replace(`/${namespaceCtx.namespace}?q=${searchString}`); + } else { + history.replace(`/${namespaceCtx.namespace}`); } }, [searchString, rollouts]); @@ -96,32 +107,35 @@ export const RolloutsList = () => { return (
- - {(rollouts || []).length > 0 ? ( - - -
- history.push(`/rollout/${namespaceCtx.namespace}/${item}`)} - icon='fa-search' - {...searchInput} - /> -
-
-
- {(filteredRollouts.sort((a, b) => (a.objectMeta.name < b.objectMeta.name ? -1 : 1)) || []).map((rollout, i) => ( - reset()} /> - ))} + {loading ? ( +
+ + Loading... +
+ ) : (rollouts || []).length > 0 ? ( + +
+
+ history.push(`/rollout/${namespaceCtx.namespace}/${val}`)} + options={rolloutNames} + onChange={(val) => setSearchString(val)} + value={searchString} + ref={searchRef} + />
- - ) : ( - - )} - +
+
+ {(filteredRollouts.sort((a, b) => (a.objectMeta.name < b.objectMeta.name ? -1 : 1)) || []).map((rollout, i) => ( + reset()} /> + ))} +
+
+ ) : ( + + )}
); }; @@ -131,7 +145,7 @@ const EmptyMessage = (props: {namespace: string}) => { return
 navigator.clipboard.writeText(props.children)}>{props.children}
; }; return ( - +

No Rollouts to display!

Make sure you are running the API server in the correct namespace. Your current namespace is:
@@ -149,7 +163,7 @@ const EmptyMessage = (props: {namespace: string}) => { .
- +
); }; @@ -184,33 +198,33 @@ export const RolloutWidget = (props: {rollout: RolloutInfo; deselect: () => void }, [watching, rollout]); return ( - - - { - subscribe(true); - setTimeout(() => { - subscribe(false); - }, 1000); - }} + + { + subscribe(true); + setTimeout(() => { + subscribe(false); + }, 1000); + }} + /> +
+ - - - {(rollout.strategy || '').toLocaleLowerCase() === 'canary' && } - - }> - - -
- subscribe(true)} indicateLoading /> - subscribe(true)} indicateLoading /> -
- - + {(rollout.strategy || '').toLocaleLowerCase() === 'canary' && } +
+ {(rollout.replicaSets || []).length < 1 && } + +
+ subscribe(true)} indicateLoading /> + subscribe(true)} indicateLoading /> +
+ ); }; @@ -224,15 +238,19 @@ const WidgetHeader = (props: {rollout: RolloutInfo; refresh: () => void}) => {
{rollout.objectMeta?.name} - { - props.refresh(); - setLoading(true); - e.preventDefault(); - }} - /> + + { + props.refresh(); + setLoading(true); + e.preventDefault(); + }} + /> +
diff --git a/ui/src/app/components/status-icon/status-icon.tsx b/ui/src/app/components/status-icon/status-icon.tsx index 7f18813f4b..257dc50567 100644 --- a/ui/src/app/components/status-icon/status-icon.tsx +++ b/ui/src/app/components/status-icon/status-icon.tsx @@ -1,6 +1,6 @@ -import {Tooltip} from 'argo-ui/v2'; import * as React from 'react'; import './status-icon.scss'; +import {Tooltip} from 'antd'; export enum RolloutStatus { Progressing = 'Progressing', @@ -40,7 +40,11 @@ export const StatusIcon = (props: {status: RolloutStatus}): JSX.Element => { className = 'unknown'; } } - return ; + return ( + + + + ); }; export enum ReplicaSetStatus { @@ -84,7 +88,7 @@ export const ReplicaSetStatusIcon = (props: {status: ReplicaSetStatus}) => { } } return ( - + ); diff --git a/ui/src/assets/images/argologo.svg b/ui/src/assets/images/argologo.svg new file mode 100644 index 0000000000..eeeb3fb36d --- /dev/null +++ b/ui/src/assets/images/argologo.svg @@ -0,0 +1 @@ +Asset 3 \ No newline at end of file diff --git a/ui/src/config/theme.ts b/ui/src/config/theme.ts new file mode 100644 index 0000000000..c377896a2e --- /dev/null +++ b/ui/src/config/theme.ts @@ -0,0 +1,15 @@ +import { ThemeConfig } from 'antd/es/config-provider'; + +export const theme: ThemeConfig = { + components: { + Button: { + colorPrimary: '#44505f', + colorPrimaryBgHover: '#626f7e', + colorPrimaryHover: '#626f7e', + colorPrimaryActive: '#626f7e', + borderRadius: 100, + borderRadiusSM: 100, + borderRadiusLG: 100 + } + } +}; diff --git a/ui/yarn.lock b/ui/yarn.lock index dbaded50fa..29f5446d37 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2,6 +2,53 @@ # yarn lockfile v1 +"@ant-design/colors@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@ant-design/colors/-/colors-7.0.0.tgz#eb7eecead124c3533aea05d61254f0a17f2b61b3" + integrity sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg== + dependencies: + "@ctrl/tinycolor" "^3.4.0" + +"@ant-design/cssinjs@^1.7.1": + version "1.8.1" + resolved "https://registry.yarnpkg.com/@ant-design/cssinjs/-/cssinjs-1.8.1.tgz#326682e779f5cd074668391a6698b50342a07d92" + integrity sha512-pOQJV9H9viB6qB9u7hkpKEOIQGx4dd8zjpwzF1v8YNwjffbZTlyUNQYln56gwpFF7SFskpYpnSfgoqTK4sFE/Q== + dependencies: + "@babel/runtime" "^7.11.1" + "@emotion/hash" "^0.8.0" + "@emotion/unitless" "^0.7.5" + classnames "^2.3.1" + csstype "^3.0.10" + rc-util "^5.27.0" + stylis "^4.0.13" + +"@ant-design/icons-svg@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz#8630da8eb4471a4aabdaed7d1ff6a97dcb2cf05a" + integrity sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw== + +"@ant-design/icons@^5.0.0": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@ant-design/icons/-/icons-5.0.1.tgz#febb1fdc5776f58187b2c953ac9a4496069d045b" + integrity sha512-ZyF4ksXCcdtwA/1PLlnFLcF/q8/MhwxXhKHh4oCHDA4Ip+ZzAHoICtyp4wZWfiCVDP0yuz3HsjyvuldHFb3wjA== + dependencies: + "@ant-design/colors" "^7.0.0" + "@ant-design/icons-svg" "^4.2.1" + "@babel/runtime" "^7.11.2" + classnames "^2.2.6" + rc-util "^5.9.4" + +"@ant-design/react-slick@~1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ant-design/react-slick/-/react-slick-1.0.0.tgz#4696eecaa2dea0429e47ae24c267015cfd6df35c" + integrity sha512-OKxZsn8TAf8fYxP79rDXgLs9zvKMTslK6dJ4iLhDXOujUqC5zJPBRszyrcEHXcMPOm1Sgk40JgyF3yiL/Swd7w== + dependencies: + "@babel/runtime" "^7.10.4" + classnames "^2.2.5" + json2mq "^0.2.0" + resize-observer-polyfill "^1.5.1" + throttle-debounce "^5.0.0" + "@babel/code-frame@7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" @@ -1164,6 +1211,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.10.1", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.1", "@babel/runtime@^7.16.7", "@babel/runtime@^7.18.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + "@babel/runtime@^7.12.1": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" @@ -1232,11 +1286,26 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-10.1.0.tgz#f0950bba18819512d42f7197e56c518aa491cf18" integrity sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg== +"@ctrl/tinycolor@^3.4.0", "@ctrl/tinycolor@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.6.0.tgz#53fa5fe9c34faee89469e48f91d51a3766108bc8" + integrity sha512-/Z3l6pXthq0JvMYdUFyX9j0MaCltlIn6mfh9jLyQwg5aPKxkyNa0PTHtU1AlFXLNk55ZuAeJRcpvq+tmLfKmaQ== + "@discoveryjs/json-ext@^0.5.0": version "0.5.2" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz#8f03a22a04de437254e8ce8cc84ba39689288752" integrity sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg== +"@emotion/hash@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/unitless@^0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + "@eslint/eslintrc@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.1.tgz#442763b88cecbe3ee0ec7ca6d6dd6168550cbf14" @@ -1252,11 +1321,37 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@fortawesome/fontawesome-common-types@6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz#88da2b70d6ca18aaa6ed3687832e11f39e80624b" + integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ== + "@fortawesome/fontawesome-free@^5.8.1": version "5.15.4" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== +"@fortawesome/fontawesome-svg-core@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz#3727552eff9179506e9203d72feb5b1063c11a21" + integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/free-solid-svg-icons@^6.4.0": + version "6.4.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz#48c0e790847fa56299e2f26b82b39663b8ad7119" + integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ== + dependencies: + "@fortawesome/fontawesome-common-types" "6.4.0" + +"@fortawesome/react-fontawesome@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" + integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== + dependencies: + prop-types "^15.8.1" + "@hapi/address@2.x.x": version "2.1.4" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" @@ -1522,6 +1617,63 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.12.tgz#431ec342a7195622f86688bbda82e3166ce8cb28" integrity sha512-6RglhutqrGFMO1MNUXp95RBuYIuc8wTnMAV5MUhLmjTOy78ncwOw7RgeQ/HeymkKXRhZd0s2DNrM1rL7unk3MQ== +"@rc-component/context@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@rc-component/context/-/context-1.3.0.tgz#608ccf0abcbec9406751b17a4b35db08e481c110" + integrity sha512-6QdaCJ7Wn5UZLJs15IEfqy4Ru3OaL5ctqpQYWd5rlfV9wwzrzdt6+kgAQZV/qdB0MUPN4nhyBfRembQCIvBf+w== + dependencies: + "@babel/runtime" "^7.10.1" + rc-util "^5.27.0" + +"@rc-component/mini-decimal@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@rc-component/mini-decimal/-/mini-decimal-1.0.1.tgz#e5dbc20a6a5b0e234d279bc71ce730ab865d3910" + integrity sha512-9N8nRk0oKj1qJzANKl+n9eNSMUGsZtjwNuDCiZ/KA+dt1fE3zq5x2XxclRcAbOIXnZcJ53ozP2Pa60gyELXagA== + dependencies: + "@babel/runtime" "^7.18.0" + +"@rc-component/mutate-observer@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@rc-component/mutate-observer/-/mutate-observer-1.0.0.tgz#ce99af3239ed9c74ee3e7302f1c67098de920b46" + integrity sha512-okqRJSfNisXdI6CUeOLZC5ukBW/8kir2Ii4PJiKpUt+3+uS7dxwJUMxsUZquxA1rQuL8YcEmKVp/TCnR+yUdZA== + dependencies: + "@babel/runtime" "^7.18.0" + classnames "^2.3.2" + rc-util "^5.24.4" + +"@rc-component/portal@^1.0.0-6", "@rc-component/portal@^1.0.0-8", "@rc-component/portal@^1.0.0-9", "@rc-component/portal@^1.0.2", "@rc-component/portal@^1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@rc-component/portal/-/portal-1.1.1.tgz#1a30ffe51c240b54360cba8e8bfc5d1f559325c4" + integrity sha512-m8w3dFXX0H6UkJ4wtfrSwhe2/6M08uz24HHrF8pWfAXPwA9hwCuTE5per/C86KwNLouRpwFGcr7LfpHaa1F38g== + dependencies: + "@babel/runtime" "^7.18.0" + classnames "^2.3.2" + rc-util "^5.24.4" + +"@rc-component/tour@~1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@rc-component/tour/-/tour-1.8.0.tgz#fda8b533e36db1d4254e3ffbcefe3395c346eb1c" + integrity sha512-rrRGioHTLQlGca27G2+lw7QpRb3uuMYCUIJjj31/B44VCJS0P2tqYhOgtzvWQmaLMlWH3ZlpzotkKX13NT4XEA== + dependencies: + "@babel/runtime" "^7.18.0" + "@rc-component/portal" "^1.0.0-9" + "@rc-component/trigger" "^1.3.6" + classnames "^2.3.2" + rc-util "^5.24.4" + +"@rc-component/trigger@^1.0.4", "@rc-component/trigger@^1.3.6", "@rc-component/trigger@^1.5.0", "@rc-component/trigger@^1.7.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@rc-component/trigger/-/trigger-1.8.0.tgz#9eb26ecdd29971d7e6d30e83716d40f27b8bb596" + integrity sha512-O9d4Tlg/FiCUlkQ+aAUUO5KmrBbj4XYq6qYfZE/hvNHzIepHqwLGx8H/d+1fG13dVPq70nGDf5ha9PQ96YRMVg== + dependencies: + "@babel/runtime" "^7.18.3" + "@rc-component/portal" "^1.1.0" + classnames "^2.3.2" + rc-align "^4.0.0" + rc-motion "^2.0.0" + rc-resize-observer "^1.3.1" + rc-util "^5.29.2" + "@rollup/plugin-node-resolve@^7.1.1": version "7.1.3" resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz#80de384edfbd7bfc9101164910f86078151a3eca" @@ -2458,6 +2610,60 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +antd@^5.4.2: + version "5.4.2" + resolved "https://registry.yarnpkg.com/antd/-/antd-5.4.2.tgz#3923b96da76fc7276992e9fc0286ebb3a638e016" + integrity sha512-OxXZ7joFf6Um4zeXm07tyJ9WV6eMwUw1KUmewfM/BDceUFVtJVf7YbBTBfX3JTl+jOuSpMSb4naFhOCgVwtyFw== + dependencies: + "@ant-design/colors" "^7.0.0" + "@ant-design/cssinjs" "^1.7.1" + "@ant-design/icons" "^5.0.0" + "@ant-design/react-slick" "~1.0.0" + "@babel/runtime" "^7.18.3" + "@ctrl/tinycolor" "^3.6.0" + "@rc-component/mutate-observer" "^1.0.0" + "@rc-component/tour" "~1.8.0" + "@rc-component/trigger" "^1.7.0" + classnames "^2.2.6" + copy-to-clipboard "^3.2.0" + dayjs "^1.11.1" + qrcode.react "^3.1.0" + rc-cascader "~3.10.0" + rc-checkbox "~3.0.0" + rc-collapse "~3.5.2" + rc-dialog "~9.1.0" + rc-drawer "~6.1.1" + rc-dropdown "~4.0.0" + rc-field-form "~1.29.0" + rc-image "~5.16.0" + rc-input "~1.0.4" + rc-input-number "~7.4.0" + rc-mentions "~2.2.0" + rc-menu "~9.8.3" + rc-motion "^2.6.1" + rc-notification "~5.0.0" + rc-pagination "~3.3.1" + rc-picker "~3.6.1" + rc-progress "~3.4.1" + rc-rate "~2.10.0" + rc-resize-observer "^1.2.0" + rc-segmented "~2.1.2" + rc-select "~14.4.3" + rc-slider "~10.1.0" + rc-steps "~6.0.0" + rc-switch "~4.0.0" + rc-table "~7.31.0" + rc-tabs "~12.5.6" + rc-textarea "~1.2.2" + rc-tooltip "~6.0.0" + rc-tree "~5.7.0" + rc-tree-select "~5.8.0" + rc-trigger "^5.3.4" + rc-upload "~4.3.0" + rc-util "^5.27.0" + scroll-into-view-if-needed "^3.0.3" + throttle-debounce "^5.0.0" + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2558,6 +2764,11 @@ array-includes@^3.1.1, array-includes@^3.1.2, array-includes@^3.1.3: get-intrinsic "^1.1.1" is-string "^1.0.5" +array-tree-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz#873ac00fec83749f255ac8dd083814b4f6329190" + integrity sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw== + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -2664,6 +2875,11 @@ async-limiter@~1.0.0: resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +async-validator@^4.1.0: + version "4.2.5" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339" + integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg== + async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -3459,6 +3675,11 @@ classnames@2.2.6, classnames@^2.2.5, classnames@^2.2.6: resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== +classnames@2.x, classnames@^2.2.1, classnames@^2.2.3, classnames@^2.3.1, classnames@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + clean-css@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" @@ -3639,6 +3860,11 @@ compression@^1.7.4: safe-buffer "5.1.2" vary "~1.1.2" +compute-scroll-into-view@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.0.3.tgz#c418900a5c56e2b04b885b54995df164535962b1" + integrity sha512-nadqwNxghAGTamwIqQSG433W6OADZx2vCo3UXHNrzTRHK/htu+7+L0zhjEoaeaQVNAi3YgqWDv8+tzf0hRfR+A== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -3730,6 +3956,13 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-to-clipboard@^3.2.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + copy-webpack-plugin@^6.3.2: version "6.4.1" resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz#138cd9b436dbca0a6d071720d5414848992ec47e" @@ -4105,6 +4338,11 @@ csstype@^2.2.0: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e" integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A== +csstype@^3.0.10: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + csstype@^3.0.2: version "3.0.8" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" @@ -4144,6 +4382,11 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" +dayjs@^1.11.1: + version "1.11.7" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" + integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4371,6 +4614,11 @@ dom-accessibility-api@^0.5.4: resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz#b06d059cdd4a4ad9a79275f9d414a5c126241166" integrity sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ== +dom-align@^1.7.0: + version "1.12.4" + resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.4.tgz#3503992eb2a7cfcb2ed3b2a6d21e0b9c00d54511" + integrity sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw== + dom-converter@^0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -7114,6 +7362,13 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json2mq@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/json2mq/-/json2mq-0.2.0.tgz#b637bd3ba9eabe122c83e9720483aeb10d2c904a" + integrity sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA== + dependencies: + string-convert "^0.2.0" + json3@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" @@ -9291,6 +9546,15 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.1, object-assign "^4.1.1" react-is "^16.8.1" +prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -9366,6 +9630,11 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= +qrcode.react@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-3.1.0.tgz#5c91ddc0340f768316fbdb8fff2765134c2aecd8" + integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q== + qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" @@ -9454,6 +9723,374 @@ raw-loader@^4.0.2: loader-utils "^2.0.0" schema-utils "^3.0.0" +rc-align@^4.0.0: + version "4.0.15" + resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.15.tgz#2bbd665cf85dfd0b0244c5a752b07565e9098577" + integrity sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + dom-align "^1.7.0" + rc-util "^5.26.0" + resize-observer-polyfill "^1.5.1" + +rc-cascader@~3.10.0: + version "3.10.1" + resolved "https://registry.yarnpkg.com/rc-cascader/-/rc-cascader-3.10.1.tgz#bee2732c4ef86dcca06de83d065b1b0d612ff057" + integrity sha512-tImBYEAqLlIZ+jnRmfQQEm5gOXa09N9aGV9AKxriXlCvsNEfdZMIRyY0p74sEZIUn0ycXHo8VcOlqsgLcgFknQ== + dependencies: + "@babel/runtime" "^7.12.5" + array-tree-filter "^2.1.0" + classnames "^2.3.1" + rc-select "~14.4.0" + rc-tree "~5.7.0" + rc-util "^5.6.1" + +rc-checkbox@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rc-checkbox/-/rc-checkbox-3.0.0.tgz#6b426d16c7d2ed9fee219a1dfb14d2c504a45300" + integrity sha512-tOEs1+wWDUei7DuP2EsJCZfam5vxMjKTCGcZdXVgsiOcNszc41Esycbo31P0/jFwUAPmd5oPYFWkcnFUCTLZxA== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.3.2" + rc-util "^5.25.2" + +rc-collapse@~3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/rc-collapse/-/rc-collapse-3.5.2.tgz#abb7d144ad55bd9cbd201fa95bc5b271da2aa7c3" + integrity sha512-/TNiT3DW1t3sUCiVD/DPUYooJZ3BLA93/2rZsB3eM2bGJCCla2X9D2E4tgm7LGMQGy5Atb2lMUn2FQuvQNvavQ== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + rc-motion "^2.3.4" + rc-util "^5.27.0" + +rc-dialog@~9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/rc-dialog/-/rc-dialog-9.1.0.tgz#6bf6fcc0453503b7643e54a5a445e835e3850649" + integrity sha512-5ry+JABAWEbaKyYsmITtrJbZbJys8CtMyzV8Xn4LYuXMeUx5XVHNyJRoqLFE4AzBuXXzOWeaC49cg+XkxK6kHA== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/portal" "^1.0.0-8" + classnames "^2.2.6" + rc-motion "^2.3.0" + rc-util "^5.21.0" + +rc-drawer@~6.1.1: + version "6.1.5" + resolved "https://registry.yarnpkg.com/rc-drawer/-/rc-drawer-6.1.5.tgz#c4137b944c16b7c179d0dba6f06ebe54f9311ec8" + integrity sha512-MDRomQXFi+tvDuwsRAddJ2Oy2ayLCZ29weMzp3rJFO9UNEVLEVV7nuyx5lEgNJIdM//tE6wWQV95cTUiMVqD6w== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/portal" "^1.0.0-6" + classnames "^2.2.6" + rc-motion "^2.6.1" + rc-util "^5.21.2" + +rc-dropdown@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-4.0.1.tgz#f65d9d3d89750241057db59d5a75e43cd4576b68" + integrity sha512-OdpXuOcme1rm45cR0Jzgfl1otzmU4vuBVb+etXM8vcaULGokAKVpKlw8p6xzspG7jGd/XxShvq+N3VNEfk/l5g== + dependencies: + "@babel/runtime" "^7.18.3" + classnames "^2.2.6" + rc-trigger "^5.3.1" + rc-util "^5.17.0" + +rc-field-form@~1.29.0: + version "1.29.2" + resolved "https://registry.yarnpkg.com/rc-field-form/-/rc-field-form-1.29.2.tgz#1c07f29eb88c13e2987fd0bd1e977dfea9e789a7" + integrity sha512-gXNkthHMUjJ7gDKYmD/lJWJrpMqAjiEPQE4QmlOuZoiHF51LybCL/y+iAmLXpdEjPfJ41WtZBH5hZMUEnEnHXA== + dependencies: + "@babel/runtime" "^7.18.0" + async-validator "^4.1.0" + rc-util "^5.8.0" + +rc-image@~5.16.0: + version "5.16.0" + resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.16.0.tgz#79d5864bc1c5d66c4620176cc131d34cd4f4bea8" + integrity sha512-11DOye57IgTXh2yTsmxFNynZJG3tdx8RZnnaqb38eYWrBPPyhVHIuURxyiSZ8B68lEUAggR7SBA0Zb95KP/CyQ== + dependencies: + "@babel/runtime" "^7.11.2" + "@rc-component/portal" "^1.0.2" + classnames "^2.2.6" + rc-dialog "~9.1.0" + rc-motion "^2.6.2" + rc-util "^5.0.6" + +rc-input-number@~7.4.0: + version "7.4.2" + resolved "https://registry.yarnpkg.com/rc-input-number/-/rc-input-number-7.4.2.tgz#7c52d26b986461aa16e486d469dc0476d97c6ea3" + integrity sha512-yGturTw7WGP+M1GbJ+UTAO7L4buxeW6oilhL9Sq3DezsRS8/9qec4UiXUbeoiX9bzvRXH11JvgskBtxSp4YSNg== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/mini-decimal" "^1.0.1" + classnames "^2.2.5" + rc-util "^5.28.0" + +rc-input@~1.0.0, rc-input@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/rc-input/-/rc-input-1.0.4.tgz#2f2c73c884f41e80685bb2eb7b9d5533e8540a77" + integrity sha512-clY4oneVHRtKHYf/HCxT/MO+4BGzCIywSNLosXWOm7fcQAS0jQW7n0an8Raa8JMB8kpxc8m28p7SNwFZmlMj6g== + dependencies: + "@babel/runtime" "^7.11.1" + classnames "^2.2.1" + rc-util "^5.18.1" + +rc-mentions@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/rc-mentions/-/rc-mentions-2.2.0.tgz#27900ec04d067c58205309897efd190f5d8f4ac8" + integrity sha512-R7ncCldr02uKgJBBPlXdtnOGQIjZ9C3uoIMi4fabU3CPFdmefYlNF6QM4u2AzgcGt8V0KkoHTN5T6HPdUpet8g== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/trigger" "^1.5.0" + classnames "^2.2.6" + rc-input "~1.0.0" + rc-menu "~9.8.0" + rc-textarea "~1.2.0" + rc-util "^5.22.5" + +rc-menu@~9.8.0, rc-menu@~9.8.3: + version "9.8.4" + resolved "https://registry.yarnpkg.com/rc-menu/-/rc-menu-9.8.4.tgz#58bf19d471e3c74ff4bcfdb0f02a3826ebe2553b" + integrity sha512-lmw2j8I2fhdIzHmC9ajfImfckt0WDb2KVJJBBRIsxPEw2kGkEfjLMUoB1NgiNT/Q5cC8PdjGOGQjHJIJMwyNMw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + rc-motion "^2.4.3" + rc-overflow "^1.2.8" + rc-trigger "^5.1.2" + rc-util "^5.27.0" + +rc-motion@^2.0.0, rc-motion@^2.0.1, rc-motion@^2.3.0, rc-motion@^2.3.4, rc-motion@^2.4.3, rc-motion@^2.4.4, rc-motion@^2.6.0, rc-motion@^2.6.1, rc-motion@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rc-motion/-/rc-motion-2.6.3.tgz#e6d8ca06591c2c1bcd3391a8e7a822ebc4d94e9c" + integrity sha512-xFLkes3/7VL/J+ah9jJruEW/Akbx5F6jVa2wG5o/ApGKQKSOd5FR3rseHLL9+xtJg4PmCwo6/1tqhDO/T+jFHA== + dependencies: + "@babel/runtime" "^7.11.1" + classnames "^2.2.1" + rc-util "^5.21.0" + +rc-notification@~5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/rc-notification/-/rc-notification-5.0.3.tgz#2566d4a6b2334c171bad0cb9a8b80cb1a24b29e6" + integrity sha512-+wHbHu6RiTNtsZYx42WxWA+tC5m0qyKvJAauO4/6LIEyJspK8fRlFQz+OCFgFwGuNs3cOdo9tLs+cPfztSZwbQ== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + rc-motion "^2.6.0" + rc-util "^5.20.1" + +rc-overflow@^1.0.0, rc-overflow@^1.2.8: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.3.0.tgz#964f7db14aab611c3047788d3b8ee472732fee09" + integrity sha512-p2Qt4SWPTHAYl4oAao1THy669Fm5q8pYBDBHRaFOekCvcdcrgIx0ByXQMEkyPm8wUDX4BK6aARWecvCRc/7CTA== + dependencies: + "@babel/runtime" "^7.11.1" + classnames "^2.2.1" + rc-resize-observer "^1.0.0" + rc-util "^5.19.2" + +rc-pagination@~3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.3.1.tgz#38e364674adf2a753a4fa26e0d9d88ebe523ed0f" + integrity sha512-eI4dSeB3OrFxll7KzWa3ZH63LV2tHxt0AUmZmDwuI6vc3CK5lZhaKUYq0fRowb5586hN+L26j5WZoSz9cwEfjg== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.1" + +rc-picker@~3.6.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-3.6.2.tgz#68d13af7d240e792769a306ed6447e66e47040aa" + integrity sha512-acLNCi2WTNAuvTtcEzKp72mU15ni0sqrIKVlEcj04KgLZxhlVPMabCS+Sc8VuOCPJbOcW0XeOydbNnJbWTvzxg== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/trigger" "^1.5.0" + classnames "^2.2.1" + rc-util "^5.27.0" + +rc-progress@~3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-3.4.1.tgz#a9ffe099e88a4fc03afb09d8603162bf0760d743" + integrity sha512-eAFDHXlk8aWpoXl0llrenPMt9qKHQXphxcVsnKs0FHC6eCSk1ebJtyaVjJUzKe0233ogiLDeEFK1Uihz3s67hw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.6" + rc-util "^5.16.1" + +rc-rate@~2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/rc-rate/-/rc-rate-2.10.0.tgz#b16fd906c13bfc26b4776e27a14d13d06d50c635" + integrity sha512-TCjEpKPeN1m0EnGDDbb1KyxjNTJRzoReiPdtbrBJEey4Ryf/UGOQ6vqmz2yC6DJdYVDVUoZPdoz043ryh0t/nQ== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.5" + rc-util "^5.0.1" + +rc-resize-observer@^1.0.0, rc-resize-observer@^1.1.0, rc-resize-observer@^1.2.0, rc-resize-observer@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/rc-resize-observer/-/rc-resize-observer-1.3.1.tgz#b61b9f27048001243617b81f95e53d7d7d7a6a3d" + integrity sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg== + dependencies: + "@babel/runtime" "^7.20.7" + classnames "^2.2.1" + rc-util "^5.27.0" + resize-observer-polyfill "^1.5.1" + +rc-segmented@~2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/rc-segmented/-/rc-segmented-2.1.2.tgz#14c9077a1dae9c2ccb2ef5fbc5662c1c48c7ce8e" + integrity sha512-qGo1bCr83ESXpXVOCXjFe1QJlCAQXyi9KCiy8eX3rIMYlTeJr/ftySIaTnYsitL18SvWf5ZEHsfqIWoX0EMfFQ== + dependencies: + "@babel/runtime" "^7.11.1" + classnames "^2.2.1" + rc-motion "^2.4.4" + rc-util "^5.17.0" + +rc-select@~14.4.0, rc-select@~14.4.3: + version "14.4.3" + resolved "https://registry.yarnpkg.com/rc-select/-/rc-select-14.4.3.tgz#68d7f1b6bcb41543f69901951facd5e097fb835d" + integrity sha512-qoz4gNqm3SN+4dYKSCRiRkxKSEEdbS3jC6gdFYoYwEjDZ9sdQFo5jHlfQbF+hhai01HOoj1Hf8Gq6tpUvU+Gmw== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/trigger" "^1.5.0" + classnames "2.x" + rc-motion "^2.0.1" + rc-overflow "^1.0.0" + rc-util "^5.16.1" + rc-virtual-list "^3.4.13" + +rc-slider@~10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/rc-slider/-/rc-slider-10.1.1.tgz#5e82036e60b61021aba3ea0e353744dd7c74e104" + integrity sha512-gn8oXazZISEhnmRinI89Z/JD/joAaM35jp+gDtIVSTD/JJMCCBqThqLk1SVJmvtfeiEF/kKaFY0+qt4SDHFUDw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.5" + rc-util "^5.27.0" + +rc-steps@~6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rc-steps/-/rc-steps-6.0.0.tgz#f7148f8097d5d135f19b96c1b4f4b50ad6093753" + integrity sha512-+KfMZIty40mYCQSDvYbZ1jwnuObLauTiIskT1hL4FFOBHP6ZOr8LK0m143yD3kEN5XKHSEX1DIwCj3AYZpoeNQ== + dependencies: + "@babel/runtime" "^7.16.7" + classnames "^2.2.3" + rc-util "^5.16.1" + +rc-switch@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/rc-switch/-/rc-switch-4.0.0.tgz#55fbf99fc2d680791175037d379e170ba51fbe78" + integrity sha512-IfrYC99vN0gKaTyjQdqYuADU0eH00SAFHg3jOp8HrmUpJruhV1SohJzrCbPqPraZeX/6X/QKkdLfkdnUub05WA== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.1" + rc-util "^5.0.1" + +rc-table@~7.31.0: + version "7.31.1" + resolved "https://registry.yarnpkg.com/rc-table/-/rc-table-7.31.1.tgz#85487b25d98559d6e684b3348e893da1d1f48232" + integrity sha512-KZPi35aGpv2VaL1Jbc58FBJo063HtKyVjhOFWX4AkBV7tjHHQokMdUoua5E+GPJh6QZUpK/a8PjKa9IZzPLIEA== + dependencies: + "@babel/runtime" "^7.10.1" + "@rc-component/context" "^1.3.0" + classnames "^2.2.5" + rc-resize-observer "^1.1.0" + rc-util "^5.27.1" + +rc-tabs@~12.5.6: + version "12.5.10" + resolved "https://registry.yarnpkg.com/rc-tabs/-/rc-tabs-12.5.10.tgz#0e41c723fac66c4f0bcad3271429fff6653b0721" + integrity sha512-Ay0l0jtd4eXepFH9vWBvinBjqOpqzcsJTerBGwJy435P2S90Uu38q8U/mvc1sxUEVOXX5ZCFbxcWPnfG3dH+tQ== + dependencies: + "@babel/runtime" "^7.11.2" + classnames "2.x" + rc-dropdown "~4.0.0" + rc-menu "~9.8.0" + rc-motion "^2.6.2" + rc-resize-observer "^1.0.0" + rc-util "^5.16.0" + +rc-textarea@~1.2.0, rc-textarea@~1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/rc-textarea/-/rc-textarea-1.2.2.tgz#111fa90fcedba6d244bc94615b7971b8d8f68815" + integrity sha512-S9fkiek5VezfwJe2McEs/NH63xgnnZ4iDh6a8n01mIfzyNJj0HkS0Uz6boyR3/eONYjmKaqhrpuJJuEClRDEBw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.2.1" + rc-input "~1.0.4" + rc-resize-observer "^1.0.0" + rc-util "^5.27.0" + +rc-tooltip@~6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rc-tooltip/-/rc-tooltip-6.0.1.tgz#6a5e33bd6c3f6afe8851ea90e7af43e5c26b3cc6" + integrity sha512-MdvPlsD1fDSxKp9+HjXrc/CxLmA/s11QYIh1R7aExxfodKP7CZA++DG1AjrW80F8IUdHYcR43HAm0Y2BYPelHA== + dependencies: + "@babel/runtime" "^7.11.2" + "@rc-component/trigger" "^1.0.4" + classnames "^2.3.1" + +rc-tree-select@~5.8.0: + version "5.8.0" + resolved "https://registry.yarnpkg.com/rc-tree-select/-/rc-tree-select-5.8.0.tgz#b3d861b7b2111d3a96b56040b851d5e280d71c95" + integrity sha512-NozrkVLR8k3cpx8R5/YFmJMptgOacR5zEQHZGMQg31bD6jEgGiJeOn2cGRI6x0Xdyvi1CSqCbUsIoqiej74wzw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + rc-select "~14.4.0" + rc-tree "~5.7.0" + rc-util "^5.16.1" + +rc-tree@~5.7.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/rc-tree/-/rc-tree-5.7.3.tgz#5da576ba87039486d59092eb4490831690b8b3b5" + integrity sha512-Oql2S9+ZmT+mfTp5SNo1XM0QvkENjc0mPRFsHWRFSPuKird0OYMZZKmLznUJ+0aGDeFFWN42wiUZJtMFhrLgLw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "2.x" + rc-motion "^2.0.1" + rc-util "^5.16.1" + rc-virtual-list "^3.4.8" + +rc-trigger@^5.1.2, rc-trigger@^5.3.1, rc-trigger@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.3.4.tgz#6b4b26e32825677c837d1eb4d7085035eecf9a61" + integrity sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw== + dependencies: + "@babel/runtime" "^7.18.3" + classnames "^2.2.6" + rc-align "^4.0.0" + rc-motion "^2.0.0" + rc-util "^5.19.2" + +rc-upload@~4.3.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/rc-upload/-/rc-upload-4.3.4.tgz#83ff7d3867631c37adbfd72ea3d1fd7e97ca84af" + integrity sha512-uVbtHFGNjHG/RyAfm9fluXB6pvArAGyAx8z7XzXXyorEgVIWj6mOlriuDm0XowDHYz4ycNK0nE0oP3cbFnzxiQ== + dependencies: + "@babel/runtime" "^7.18.3" + classnames "^2.2.5" + rc-util "^5.2.0" + +rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.15.0, rc-util@^5.16.0, rc-util@^5.16.1, rc-util@^5.17.0, rc-util@^5.18.1, rc-util@^5.19.2, rc-util@^5.2.0, rc-util@^5.20.1, rc-util@^5.21.0, rc-util@^5.21.2, rc-util@^5.22.5, rc-util@^5.24.4, rc-util@^5.25.2, rc-util@^5.26.0, rc-util@^5.27.0, rc-util@^5.27.1, rc-util@^5.28.0, rc-util@^5.29.2, rc-util@^5.6.1, rc-util@^5.8.0, rc-util@^5.9.4: + version "5.29.3" + resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.29.3.tgz#dc02b7b2103468e9fdf14e0daa58584f47898e37" + integrity sha512-wX6ZwQTzY2v7phJBquN4mSEIFR0E0qumlENx0zjENtDvoVSq2s7cR95UidKRO1hOHfDsecsfM9D1gO4Kebs7fA== + dependencies: + "@babel/runtime" "^7.18.3" + react-is "^16.12.0" + +rc-virtual-list@^3.4.13, rc-virtual-list@^3.4.8: + version "3.4.13" + resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.13.tgz#20acc934b263abcf7b7c161f50ef82281b2f7e8d" + integrity sha512-cPOVDmcNM7rH6ANotanMDilW/55XnFPw0Jh/GQYtrzZSy3AmWvCnqVNyNC/pgg3lfVmX2994dlzAhuUrd4jG7w== + dependencies: + "@babel/runtime" "^7.20.0" + classnames "^2.2.6" + rc-resize-observer "^1.0.0" + rc-util "^5.15.0" + react-app-polyfill@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-2.0.0.tgz#a0bea50f078b8a082970a9d853dc34b6dcc6a3cf" @@ -9563,7 +10200,7 @@ react-hot-loader@^3.1.3: redbox-react "^1.3.6" source-map "^0.6.1" -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: +react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -9918,6 +10555,11 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -10073,6 +10715,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -10380,6 +11027,13 @@ schema-utils@^3.0.0: ajv "^6.12.5" ajv-keywords "^3.5.2" +scroll-into-view-if-needed@^3.0.3: + version "3.0.10" + resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.0.10.tgz#38fbfe770d490baff0fb2ba34ae3539f6ec44e13" + integrity sha512-t44QCeDKAPf1mtQH3fYpWz8IM/DyvHLjs8wUvvwMYxk5moOqCzrMSxK6HQVD0QVmVjXFavoFIPRVrMuJPKAvtg== + dependencies: + compute-scroll-into-view "^3.0.2" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -10897,6 +11551,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +string-convert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-convert/-/string-convert-0.2.1.tgz#6982cc3049fbb4cd85f8b24568b9d9bf39eeff97" + integrity sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A== + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -11058,6 +11717,11 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" +stylis@^4.0.13: + version "4.1.3" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.3.tgz#fd2fbe79f5fed17c55269e16ed8da14c84d069f7" + integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -11239,6 +11903,11 @@ throat@^5.0.0: resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throttle-debounce@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz#a17a4039e82a2ed38a5e7268e4132d6960d41933" + integrity sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg== + through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -11328,6 +11997,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" @@ -11506,11 +12180,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@4.3.5, typescript@^4.0.3: +typescript@^4.0.3: version "4.3.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +typescript@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" + integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== + unbox-primitive@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"