diff --git a/config-ui/package-lock.json b/config-ui/package-lock.json index e59c2fdab7f..ee9d0c9682f 100644 --- a/config-ui/package-lock.json +++ b/config-ui/package-lock.json @@ -13,6 +13,7 @@ "@blueprintjs/select": "^3.18.10", "axios": "^0.21.4", "babel-plugin-module-resolver": "^4.1.0", + "dayjs": "^1.10.7", "dotenv": "^10.0.0", "dotenv-webpack": "^7.0.3", "react": "17.0.2", @@ -6655,6 +6656,11 @@ "node": ">=10" } }, + "node_modules/dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + }, "node_modules/debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -26966,6 +26972,11 @@ "whatwg-url": "^8.0.0" } }, + "dayjs": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz", + "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", diff --git a/config-ui/package.json b/config-ui/package.json index 471e267024e..41157bf5cd6 100644 --- a/config-ui/package.json +++ b/config-ui/package.json @@ -15,6 +15,7 @@ "@blueprintjs/select": "^3.18.10", "axios": "^0.21.4", "babel-plugin-module-resolver": "^4.1.0", + "dayjs": "^1.10.7", "dotenv": "^10.0.0", "dotenv-webpack": "^7.0.3", "react": "17.0.2", diff --git a/config-ui/src/App.js b/config-ui/src/App.js index 17b5fca2b2a..15edea9a015 100644 --- a/config-ui/src/App.js +++ b/config-ui/src/App.js @@ -22,7 +22,7 @@ import Offline from '@/pages/offline/index' // #963 Create Pipelines import CreatePipeline from '@/pages/pipelines/create' // #965 Pipeline Activity -// import PipelineActivity from '@/pages/pipelines/activity' +import PipelineActivity from '@/pages/pipelines/activity' function App () { return ( @@ -55,9 +55,12 @@ function App () { {/* #964 */} - {/* #965 + - */} + + + + diff --git a/config-ui/src/components/pipelines/CodeInspector.jsx b/config-ui/src/components/pipelines/CodeInspector.jsx new file mode 100644 index 00000000000..894ea22914d --- /dev/null +++ b/config-ui/src/components/pipelines/CodeInspector.jsx @@ -0,0 +1,61 @@ +import React from 'react' +// import { CSSTransition } from 'react-transition-group' +import { + Classes, + Drawer, + DrawerSize, + Card, + Elevation, + Position, +} from '@blueprintjs/core' + +const CodeInspector = (props) => { + const { activePipeline, isOpen, onClose } = props + + return ( + onClose(false)} + title={`Inspect RUN #${activePipeline.ID}`} + position={Position.RIGHT} + size={DrawerSize.SMALL} + autoFocus + canEscapeKeyClose + canOutsideClickClose + enforceFocus + hasBackdrop + isOpen={isOpen} + usePortal + > +
+
+

+ application/json JSON RESPONSE +

+

+ If you are submitting a + Bug-Report regarding a Pipeline Run, include the output below for better debugging. +

+
+ + + +
+                  {JSON.stringify(activePipeline, null, '  ')}
+                
+
+
+
+
+
+
+ + ) +} + +export default CodeInspector diff --git a/config-ui/src/components/pipelines/ProviderSettings.jsx b/config-ui/src/components/pipelines/ProviderSettings.jsx index d126e39ced8..1720610f9af 100644 --- a/config-ui/src/components/pipelines/ProviderSettings.jsx +++ b/config-ui/src/components/pipelines/ProviderSettings.jsx @@ -143,7 +143,7 @@ const ProviderSettings = (props) => { setOwner(e.target.value)} className='input-owner' diff --git a/config-ui/src/components/pipelines/StagePanel.jsx b/config-ui/src/components/pipelines/StagePanel.jsx new file mode 100644 index 00000000000..79460298de3 --- /dev/null +++ b/config-ui/src/components/pipelines/StagePanel.jsx @@ -0,0 +1,217 @@ +import React from 'react' +import { CSSTransition } from 'react-transition-group' +import { + Card, + Button, Icon, + ButtonGroup, + Elevation, + Colors, + Spinner, + Intent + // Alignment, Classes, Spinner +} from '@blueprintjs/core' +import { ReactComponent as PipelineRunningIcon } from '@/images/synchronize.svg' +import { ReactComponent as PipelineFailedIcon } from '@/images/no-synchronize.svg' +import { ReactComponent as PipelineCompleteIcon } from '@/images/check-circle.svg' + +const StagePanel = (props) => { + const { activePipeline, pipelineReady = false, stages, activeStageId = 1, isLoading = false } = props + + return ( + <> + + + + + + {/* @todo: re-activate "stage" ux in a future release */} + {Object.keys(stages).length > 0 && ( + <> + {Object.keys(stages).map((s, sIdx) => ( + // + + ))} + + - + + + + {/*
svg { + + >svg { transition: all 0.3s ease; } } + .provider-name { font-family: 'Montserrat', sans-serif; font-weight: 900; @@ -93,10 +84,12 @@ font-size: 14px; margin-bottom: 3px; transition: all 0.3s ease; + &:hover { color: #007cff; - } + } } + .bp3-popover-wrapper { width: auto; } @@ -107,7 +100,7 @@ padding: 0 20px; align-items: flex-end; display: flex; - + .bp3-form-group { margin-bottom: 0; } @@ -131,9 +124,6 @@ } .btn-pipeline { - // font-family: 'Montserrat', sans-serif; - // text-transform: uppercase; - // letter-spacing: 2px; font-weight: 800; transition: all 0.4s ease; white-space: nowrap; @@ -146,18 +136,20 @@ .bp3-switch { &.provider-toggle-switch { margin-bottom: 0; + &:not(.bp3-align-right) { padding-left: 43px } - + } } .pipeline-action-btn { transition: all 0.4s ease; + &:hover { svg { - fill: #007cff!important + fill: #007cff !important } } } @@ -206,6 +198,32 @@ transition: opacity 300ms, transform 300ms; } +.activity-panel-enter { + transform: scale(1.01); + background-color: #f0f0f0; + opacity: 1; + transition: opacity 300ms, transform 300ms, background-color 800ms; +} + +.activity-panel-enter-done { + transform: scale(1); + background-color: #ffffff; + opacity: 1; + transition: opacity 300ms, transform 300ms, background-color 800ms; +} + +.activity-panel-exit { + background-color: #f7f7f7; + opacity: 1; + transition: opacity 300ms, transform 300ms, background-color 800ms; +} + +.activity-panel-exit-active { + background-color: #eeeeee; + opacity: 1; + transition: opacity 300ms, transform 300ms, background-color 800ms; +} + .bp3-spinner { &.lastrun-spinner { position: absolute; @@ -217,7 +235,6 @@ .bp3-popover { &.popover-lastrun { - // margin-left: -8px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; @@ -231,81 +248,80 @@ } } -.trigger-module-lastrun { - -} +.trigger-module-lastrun {} .bp3-button { - &.btn-cancel-pipeline { + &.btn-cancel-pipeline { transition: all 0.4s ease; background-color: darken(#FFA8A8, 5%); border: 1px solid darken(#FF6D6D, 5%); box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.35); border-radius: 6px; - font-family: 'Montserrat', sans-serif; font-style: normal; font-weight: 900; - font-size: 11px; color: #ffffff; - &:hover { - background-color: darken(#FFA8A8, 10%); - border: 1px solid darken(#FF6D6D, 10%); - box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.40); + &:hover, + :active, + &.bp3-active { + background-color: darken(#FFA8A8, 10%) !important; + border: 1px solid darken(#FF6D6D, 10%) !important; + box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.40) !important; } } &.btn-retry-pipeline { transition: all 0.4s ease; - // background-color: darken(#a8d8ff, 5%); - // border: 1px solid darken(#6dd6ff, 5%); box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.35); border-radius: 6px; - font-family: 'Montserrat', sans-serif; font-style: normal; font-weight: 900; - font-size: 11px; color: #ffffff; - &:hover { - // background-color: darken(#a8d8ff, 15%); - // border: 1px solid darken(#6dd6ff, 15%); + &:hover, + :active, + &.bp3-active { box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.40); } - } + } } .bp3-input-group { .bp3-input { transition: all 0.3s ease; } + &.is-invalid { .bp3-input { background-color: lighten(#FFA8A8, 13%); color: darken(#FF6D6D, 20%); border: 1px solid darken(#FF6D6D, 10%); + &::placeholder { color: lighten(#FF6D6D, 10%); } } - } + } + &.is-valid { .bp3-input { background-color: lighten(#b5ffe0, 11%); color: darken(#00cf8a, 5%); border: 1px solid darken(#6dffce, 15%); - // font-weight: 800; + &::placeholder { color: lighten(#6dffce, 10%); } + &:focus { box-shadow: 0 0 0 1px #1ce878, 0 0 0 3px rgba(28, 232, 188, 0.3), inset 0 1px 1px rgba(16, 26, 23, 0.2) } } - } + } } -.bp3-popover-wrapper, .bp3-popover-target { +.bp3-popover-wrapper, +.bp3-popover-target { width: auto; } @@ -318,12 +334,13 @@ } .bp3-menu { - &.pipeline-presets-menu { + &.pipeline-presets-menu { .bp3-menu-item { - &.bp3-active { + &.bp3-active { background-color: transparent; color: #007cff; font-weight: 800; + &:hover { background-color: rgba(66, 66, 66, 0.08); color: darken(#007cff, 5%); diff --git a/config-ui/src/utils/time.js b/config-ui/src/utils/time.js new file mode 100644 index 00000000000..4b528d34451 --- /dev/null +++ b/config-ui/src/utils/time.js @@ -0,0 +1,27 @@ +import * as dayjs from 'dayjs' +import * as relativeTime from 'dayjs/plugin/relativeTime' +import * as updateLocale from 'dayjs/plugin/updateLocale' + +const localeConfiguration = { + relativeTime: { + future: 'in %s', + past: '%s ago', + s: '< 1min', + m: 'a minute', + mm: '%d minutes', + h: 'an hour', + hh: '%d hours', + d: 'a day', + dd: '%d days', + M: 'a month', + MM: '%d months', + y: 'a year', + yy: '%d years' + } +} + +dayjs.extend(relativeTime) +dayjs.extend(updateLocale) +dayjs.updateLocale('en', localeConfiguration) + +export default dayjs