diff --git a/ui/package.json b/ui/package.json index 33bf249..3b3754e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -22,6 +22,7 @@ "flat": "^5.0.0", "history": "^4.10.1", "js-cookie": "^2.2.1", + "node-sass": "^4.13.1", "ping.js": "^0.2.3", "rc-steps": "^3.5.0", "react": "^16.12.0", diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 5987e38..b3eec6e 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import './App.css'; +import './styles/App.css'; import { BrowserRouter as Router } from 'react-router-dom'; import { faReact } from '@fortawesome/free-brands-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; diff --git a/ui/src/components/Ghost.tsx b/ui/src/components/Ghost.tsx new file mode 100644 index 0000000..72de2d4 --- /dev/null +++ b/ui/src/components/Ghost.tsx @@ -0,0 +1,100 @@ +import '../styles/ghost.scss'; +import React from 'react'; + +type polyPoint = number[][]; + +function Polygon(props: { points: polyPoint; scale?: number }) { + const scale = props.scale; + + const s = props.points.map((point: number[]) => { + return point + .map(x => { + if (scale) { + return x / scale; + } + return x; + }) + .join(' '); + }); + + return ; +} + +export default function PacmanGhost() { + return ( +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+ ); +} diff --git a/ui/src/components/deployment/run/RunDeploy.tsx b/ui/src/components/deployment/run/RunDeploy.tsx index a8f7ca6..dbb227f 100644 --- a/ui/src/components/deployment/run/RunDeploy.tsx +++ b/ui/src/components/deployment/run/RunDeploy.tsx @@ -4,6 +4,7 @@ import Steps from 'rc-steps'; import { PacmanLoader } from 'react-spinners'; import { UseGlobalSettings, UseGlobalSession } from '../../Global'; import DeployRequest from './DeployRequest'; +import PacmanGhost from '../../Ghost'; type stepStatus = 'working' | 'error'; @@ -53,7 +54,7 @@ export default function RunDeploy() { DeployRequest(endpoint, 'telegraf', state.Telegraf.toString()) .then(() => addStep('Deploy Telegraf', 'Asking OmegaGraf to create the container')) - .catch(() => setLastStep('Deploy Telegraf', 'Error Exception', 'error')); + .catch(() => setLastStep('Deploy Telegraf', 'Error creating container, please check server logs', 'error')); }; return ( @@ -67,9 +68,11 @@ export default function RunDeploy() { {steps.map((step, i) => { const isError = step.status === 'error'; - const iconColor = isError ? '#f50' : '#007bff'; - const icon = ( - + + const icon = !isError ? ( + + ) : ( + ); return ( .rc-steps-item-container > .rc-steps-item-content { margin-top: -1px; +} + +.rc-steps-item-error > .rc-steps-item-container > .rc-steps-item-content { + margin-top: 2px; + margin-left: 40px; } \ No newline at end of file diff --git a/ui/src/styles/ghost.scss b/ui/src/styles/ghost.scss new file mode 100644 index 0000000..c08f2c2 --- /dev/null +++ b/ui/src/styles/ghost.scss @@ -0,0 +1,207 @@ +$ghost-color: orange; +$ghosts: blinky, pinky, clyde, inky ; +$colors: red, pink, orange, cyan ; +$ghosts-colors: zip($ghosts, $colors); +$duration: 6s; +$scale: 2; + +@keyframes eyes { + 0% { + top: (14px / $scale); + } + 10% { + top: (16px / $scale); + } + 50% { + top: (14px / $scale); + } + 70% { + top: (16px / $scale); + } + 100% { + top: (14px / $scale); + } +} +@keyframes eyesballs { + 0% { + top: 0; + left: (4px / $scale); + } + 10% { + top: (8px / $scale); + left: 0; + } + 20% { + left: (4px / $scale); + top: (12px / $scale); + } + 40% { + top: (8px / $scale); + left: 0; + } + 50% { + top: 0; + left: (4px / $scale); + } + 70% { + top: (8px / $scale); + left: (8px / $scale); + } + 90% { + left: (4px / $scale); + top: (12px / $scale); + } + 100% { + top: 0; + left: (4px / $scale); + } +} + +@keyframes feet { + 0% { + box-shadow: + (4px / $scale) 0 $ghost-color, + (8px / $scale) 0 $ghost-color, + (12px / $scale) 0 $ghost-color, + + (4px / $scale) (4px / $scale) $ghost-color, + (8px / $scale) (4px / $scale) $ghost-color, + + (20px / $scale) 0 $ghost-color, + (24px / $scale) 0 $ghost-color, + (28px / $scale) 0 $ghost-color, + (32px / $scale) 0 $ghost-color, + + (24px / $scale) (4px / $scale) $ghost-color, + (28px / $scale) (4px / $scale) $ghost-color, + + (40px / $scale) 0 $ghost-color, + (44px / $scale) 0 $ghost-color, + (48px / $scale) 0 $ghost-color, + (52px / $scale) 0 $ghost-color, + + (44px / $scale) (4px / $scale) $ghost-color, + (48px / $scale) (4px / $scale) $ghost-color + ; + } + 50% { + box-shadow: + 0 (4px / $scale) $ghost-color, + (4px / $scale) 0 $ghost-color, + + (12px / $scale) 0 $ghost-color, + (16px / $scale) 0 $ghost-color, + (20px / $scale) 0 $ghost-color, + (16px / $scale) (4px / $scale) $ghost-color, + (20px / $scale) (4px / $scale) $ghost-color, + + (32px / $scale) 0 $ghost-color, + (36px / $scale) 0 $ghost-color, + (40px / $scale) 0 $ghost-color, + (32px / $scale) (4px / $scale) $ghost-color, + (36px / $scale) (4px / $scale) $ghost-color, + + (48px / $scale) 0 $ghost-color, + (52px / $scale) 0 $ghost-color, + (52px / $scale) (4px / $scale) $ghost-color + ; + } + 100% { + box-shadow: + (4px / $scale) 0 $ghost-color, + (8px / $scale) 0 $ghost-color, + (12px / $scale) 0 $ghost-color, + + (4px / $scale) (4px / $scale) $ghost-color, + (8px / $scale) (4px / $scale) $ghost-color, + + (20px / $scale) 0 $ghost-color, + (24px / $scale) 0 $ghost-color, + (28px / $scale) 0 $ghost-color, + (32px / $scale) 0 $ghost-color, + + (24px / $scale) (4px / $scale) $ghost-color, + (28px / $scale) (4px / $scale) $ghost-color, + + (40px / $scale) 0 $ghost-color, + (44px / $scale) 0 $ghost-color, + (48px / $scale) 0 $ghost-color, + (52px / $scale) 0 $ghost-color, + + (44px / $scale) (4px / $scale) $ghost-color, + (48px / $scale) (4px / $scale) $ghost-color + ; + } +} + +.ghost { + position: absolute; + top: 0; + left: 0; + width: (56px / $scale); + height: (56px / $scale); + + animation-name: move; + animation-duration: $duration; + animation-timing-function: linear; + animation-fill-mode: forwards; + animation-iteration-count: infinite; +} +.ghost__feet { + animation-name: feet; + animation-duration: .4s; + animation-fill-mode: forwards; + animation-timing-function: steps(1); + animation-iteration-count: infinite; + + background: $ghost-color; + content: ''; + display: block; + position: absolute; + top: (48px / $scale); + left: 0; + width: (4px / $scale); + height: (4px / $scale); + z-index: 1; +} +.ghost__body { + fill: $ghost-color; +} +%ghost__eye { + fill: #fff; + position: absolute; + top: (16px / $scale); + width: (16px / $scale); + height: (20px / $scale); + + animation-name: eyes; + animation-duration: $duration; + animation-fill-mode: forwards; + animation-timing-function: steps(1); + animation-iteration-count: infinite; + + &:after { + background: blue; + content: ''; + display: block; + position: absolute; + top: (8px / $scale); + left: 0; + width: (8px / $scale); + height: (8px / $scale); + + animation-name: eyesballs; + animation-duration: $duration; + animation-fill-mode: forwards; + animation-timing-function: steps(1); + animation-iteration-count: infinite; + } +} +.ghost__eye--left { + @extend %ghost__eye; + left: (8px / $scale); +} +.ghost__eye--right { + @extend %ghost__eye; + right: (8px / $scale); +} \ No newline at end of file