From 4b92b84b584d7cc4ad2b2e048fd02e3cadc335a2 Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 11:57:25 -0700 Subject: [PATCH 1/7] Wrap body builder in fancy scrollbars --- ui/src/flux/components/BodyBuilder.tsx | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/ui/src/flux/components/BodyBuilder.tsx b/ui/src/flux/components/BodyBuilder.tsx index e06965628b..bc2c8f9c95 100644 --- a/ui/src/flux/components/BodyBuilder.tsx +++ b/ui/src/flux/components/BodyBuilder.tsx @@ -1,6 +1,7 @@ import React, {PureComponent} from 'react' import _ from 'lodash' +import FancyScrollbar from 'src/shared/components/FancyScrollbar' import ExpressionNode from 'src/flux/components/ExpressionNode' import VariableName from 'src/flux/components/VariableName' import FuncSelector from 'src/flux/components/FuncSelector' @@ -62,18 +63,20 @@ class BodyBuilder extends PureComponent { }) return ( -
- {_.flatten(bodybuilder)} -
- + +
+ {_.flatten(bodybuilder)} +
+ +
-
+ ) } From 09b44edfe1599b2d8a5252090b58e1d87942da59 Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 11:57:48 -0700 Subject: [PATCH 2/7] Redesign flux builder to stack nodes vertically --- ui/src/flux/components/FuncArgsPreview.tsx | 10 +- ui/src/flux/components/VariableName.tsx | 8 +- .../time-machine/add-func-button.scss | 19 ++-- .../components/time-machine/flux-builder.scss | 101 ++++++++++++------ 4 files changed, 91 insertions(+), 47 deletions(-) diff --git a/ui/src/flux/components/FuncArgsPreview.tsx b/ui/src/flux/components/FuncArgsPreview.tsx index ac8c5a56cc..07b928230b 100644 --- a/ui/src/flux/components/FuncArgsPreview.tsx +++ b/ui/src/flux/components/FuncArgsPreview.tsx @@ -76,19 +76,19 @@ export default class FuncArgsPreview extends PureComponent { case 'period': case 'duration': case 'array': { - return {argument} + return {argument} } case 'bool': { - return {argument} + return {argument} } case 'string': { - return "{argument}" + return "{argument}" } case 'object': { - return {argument} + return {argument} } case 'invalid': { - return {argument} + return {argument} } default: { return {argument} diff --git a/ui/src/flux/components/VariableName.tsx b/ui/src/flux/components/VariableName.tsx index d07f4b3ab9..ca92a73070 100644 --- a/ui/src/flux/components/VariableName.tsx +++ b/ui/src/flux/components/VariableName.tsx @@ -22,7 +22,7 @@ export default class VariableName extends PureComponent { } public render() { - return
{this.nameElement}
+ return
{this.nameElement}
} private get nameElement(): JSX.Element { @@ -32,7 +32,7 @@ export default class VariableName extends PureComponent { return this.colorizeSyntax } - return {name} + return {name} } private get colorizeSyntax(): JSX.Element { @@ -45,11 +45,11 @@ export default class VariableName extends PureComponent { return ( <> - {varName} + {varName} {' = '} {varValue} diff --git a/ui/src/style/components/time-machine/add-func-button.scss b/ui/src/style/components/time-machine/add-func-button.scss index 0be530b189..e0dfaec063 100644 --- a/ui/src/style/components/time-machine/add-func-button.scss +++ b/ui/src/style/components/time-machine/add-func-button.scss @@ -10,25 +10,28 @@ $flux-func-selector--height: 30px; display: flex; align-items: center; position: relative; + flex-direction: column; &.open { z-index: 9999; + height: $flux-func-selector--height + $flux-func-selector--gap; } } .func-selector--connector { - width: $flux-func-selector--gap; - height: $flux-func-selector--height; + width: $flux-node-gap; + height: $flux-func-selector--gap; position: relative; &:after { content: ''; position: absolute; - top: 50%; - width: 100%; - height: 4px; - transform: translateY(-50%); - @include gradient-h($g4-onyx, $c-pool); + top: -130%; + width: $flux-connector-line; + left: 50%; + height: 230%; + transform: translateX(-50%); + @include gradient-v($g4-onyx, $c-pool); } } @@ -51,7 +54,7 @@ $flux-func-selector--height: 30px; top: 0; .func-selector--connector + & { - left: $flux-func-selector--gap; + top: $flux-func-selector--gap; } } diff --git a/ui/src/style/components/time-machine/flux-builder.scss b/ui/src/style/components/time-machine/flux-builder.scss index fa5bade6cf..b5a0c69ec7 100644 --- a/ui/src/style/components/time-machine/flux-builder.scss +++ b/ui/src/style/components/time-machine/flux-builder.scss @@ -1,18 +1,23 @@ +/* + Flux Builder Styles + ------------------------------------------------------------------------------ +*/ + +$flux-builder-min-width: 440px; $flux-node-height: 30px; $flux-node-tooltip-gap: 4px; -$flux-node-gap: 5px; +$flux-connector-line: 2px; +$flux-node-gap: 30px; $flux-node-padding: 10px; $flux-arg-min-width: 120px; + $flux-number-color: $c-neutrino; $flux-object-color: $c-viridian; $flux-string-color: $c-honeydew; $flux-boolean-color: $c-viridian; $flux-invalid-color: $c-viridian; -/* - Shared Node styles - ------------------ -*/ +// Shared Node styles %flux-node { min-height: $flux-node-height; border-radius: $radius; @@ -22,66 +27,81 @@ $flux-invalid-color: $c-viridian; position: relative; background-color: $g4-onyx; transition: background-color 0.25s ease; + margin-bottom: $flux-node-tooltip-gap / 2; + margin-top: $flux-node-tooltip-gap / 2; &:hover { + cursor: pointer; background-color: $g6-smoke; } } -.body-builder { - padding: 30px; - min-width: 440px; - overflow: hidden; - height: 100%; - width: 100%; +.body-builder--container { background-color: $g1-raven; } +.body-builder { + padding: $flux-node-height; + padding-bottom: 0; + min-width: $flux-builder-min-width; + width: 100%; +} .declaration { width: 100%; - margin-bottom: 24px; + margin-bottom: $flux-node-gap; + padding-bottom: $flux-node-gap; + border-bottom: 2px solid $g2-kevlar; display: flex; flex-wrap: nowrap; - align-items: center; + flex-direction: column; + align-items: flex-start; &:last-of-type { margin-bottom: 0; + border: 0; } } -.variable-string { +.variable-node { @extend %flux-node; color: $g11-sidewalk; line-height: $flux-node-height; white-space: nowrap; @include no-user-select(); + margin-top: 0; + + &:hover { + background-color: $g4-onyx; + cursor: default; + } } -.variable-blank { - font-style: italic; -} - -.variable-name { +.variable-node--name { color: $c-pool; } -.variable-value--string { +.variable-node--string, +.func-arg--string { color: $flux-string-color; } -.variable-value--boolean { +.variable-node--boolean, +.func-arg--boolean { color: $flux-boolean-color; } -.variable-value--number { +.variable-node--number, +.func-arg--number { color: $flux-number-color; } -.variable-value--object { +.variable-node--object, +.func-arg--object { color: $flux-object-color; } -.variable-value--invalid { +.variable-node--invalid, +.func-arg--invalid { color: $flux-invalid-color; } @@ -92,21 +112,42 @@ $flux-invalid-color: $c-viridian; margin-left: $flux-node-gap; - // Connection Line + // Connection Lines + &:before, &:after { content: ''; - height: 4px; - width: $flux-node-gap; background-color: $g4-onyx; position: absolute; + } + // Vertical Line + &:before { + width: $flux-connector-line; + height: calc(100% + #{$flux-node-tooltip-gap}); + top: -$flux-node-tooltip-gap / 2; + left: -$flux-node-gap / 2; + transform: translateX(-50%); + } + // Horizontal Line + &:after { + height: $flux-connector-line; + width: $flux-node-gap / 2; top: 50%; left: 0; transform: translate(-100%, -50%); } - - &:first-child:after { - content: none; + + // When there is no variable name for the declaration + &:first-child { margin-left: 0; + + &:before { + left: $flux-node-gap / 2; + top: 100%; + height: $flux-node-tooltip-gap / 2; + } + &:after { + content: none; + } } } From 944c4ed80318d1f693cedda1a4aff14abf35c2f1 Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 14:37:42 -0700 Subject: [PATCH 3/7] Add connector dot to variables when they are assigned to queries --- ui/src/flux/components/BodyBuilder.tsx | 4 +-- ui/src/flux/components/VariableName.tsx | 15 ++++++++--- .../components/time-machine/flux-builder.scss | 27 +++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/ui/src/flux/components/BodyBuilder.tsx b/ui/src/flux/components/BodyBuilder.tsx index bc2c8f9c95..707656f517 100644 --- a/ui/src/flux/components/BodyBuilder.tsx +++ b/ui/src/flux/components/BodyBuilder.tsx @@ -30,7 +30,7 @@ class BodyBuilder extends PureComponent { if (d.funcs) { return (
- + { return (
- +
) }) diff --git a/ui/src/flux/components/VariableName.tsx b/ui/src/flux/components/VariableName.tsx index ca92a73070..f8c150720e 100644 --- a/ui/src/flux/components/VariableName.tsx +++ b/ui/src/flux/components/VariableName.tsx @@ -1,7 +1,8 @@ import React, {PureComponent} from 'react' interface Props { - name?: string + name: string + assignedToQuery: boolean } interface State { @@ -10,7 +11,7 @@ interface State { export default class VariableName extends PureComponent { public static defaultProps: Partial = { - name: '', + assignedToQuery: false, } constructor(props) { @@ -22,7 +23,14 @@ export default class VariableName extends PureComponent { } public render() { - return
{this.nameElement}
+ const {assignedToQuery} = this.props + + return ( +
+ {assignedToQuery &&
} + {this.nameElement} +
+ ) } private get nameElement(): JSX.Element { @@ -42,7 +50,6 @@ export default class VariableName extends PureComponent { const varValue = this.props.name.replace(/^[^=]+=/, '') const valueIsString = varValue.endsWith('"') - return ( <> {varName} diff --git a/ui/src/style/components/time-machine/flux-builder.scss b/ui/src/style/components/time-machine/flux-builder.scss index b5a0c69ec7..aa657ca628 100644 --- a/ui/src/style/components/time-machine/flux-builder.scss +++ b/ui/src/style/components/time-machine/flux-builder.scss @@ -76,8 +76,35 @@ $flux-invalid-color: $c-viridian; } } +.variable-node--connector { + width: 8px; + height: 8px; + border-radius: 50%; + background-color: $c-pool; + position: absolute; + z-index: 2; + top: 50%; + left: $flux-node-gap / 2; + transform: translate(-50%, -50%); + + &:before { + content: ''; + position: absolute; + top: 100%; + left: 50%; + width: $flux-connector-line; + height: $flux-node-gap; + @include gradient-v($c-pool, $g4-onyx); + transform: translateX(-50%); + } +} + .variable-node--name { color: $c-pool; + + .variable-node--connector + & { + margin-left: $flux-node-gap - $flux-node-padding; + } } .variable-node--string, From 278c147089c778d76419c1faa696b4701f3a9cec Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 14:54:37 -0700 Subject: [PATCH 4/7] Add connector line from unassigned FROM to following node --- ui/src/flux/components/FuncNode.tsx | 1 + .../components/time-machine/flux-builder.scss | 45 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/ui/src/flux/components/FuncNode.tsx b/ui/src/flux/components/FuncNode.tsx index 8648425083..7e2fbe5bdf 100644 --- a/ui/src/flux/components/FuncNode.tsx +++ b/ui/src/flux/components/FuncNode.tsx @@ -52,6 +52,7 @@ export default class FuncNode extends PureComponent { onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} > +
{func.name}
{isExpanded && ( diff --git a/ui/src/style/components/time-machine/flux-builder.scss b/ui/src/style/components/time-machine/flux-builder.scss index aa657ca628..df77998c14 100644 --- a/ui/src/style/components/time-machine/flux-builder.scss +++ b/ui/src/style/components/time-machine/flux-builder.scss @@ -136,8 +136,17 @@ $flux-invalid-color: $c-viridian; @extend %flux-node; display: flex; align-items: center; - margin-left: $flux-node-gap; +} + +.func-node--connector { + width: $flux-node-gap; + height: 100%; + position: absolute; + top: 0; + left: 0; + transform: translateX(-100%); + z-index: 0; // Connection Lines &:before, @@ -151,7 +160,7 @@ $flux-invalid-color: $c-viridian; width: $flux-connector-line; height: calc(100% + #{$flux-node-tooltip-gap}); top: -$flux-node-tooltip-gap / 2; - left: -$flux-node-gap / 2; + left: $flux-node-gap / 2; transform: translateX(-50%); } // Horizontal Line @@ -159,21 +168,33 @@ $flux-invalid-color: $c-viridian; height: $flux-connector-line; width: $flux-node-gap / 2; top: 50%; - left: 0; - transform: translate(-100%, -50%); + left: $flux-node-gap / 2; + transform: translateY(-50%); } - - // When there is no variable name for the declaration - &:first-child { - margin-left: 0; +} +// When a query exists unassigned to a variable +.func-node:first-child { + margin-left: 0; + padding-left: $flux-node-gap; + .func-node--connector { + transform: translateX(0); + z-index: 2; + + // Vertical Line &:before { - left: $flux-node-gap / 2; - top: 100%; - height: $flux-node-tooltip-gap / 2; + height: $flux-node-gap; + top: $flux-node-gap / 2; + @include gradient-v($c-comet, $g4-onyx); } + // Dot &:after { - content: none; + width: 8px; + height: 8px; + border-radius: 50%; + background-color: $c-comet; + top: $flux-node-gap / 2; + transform: translate(-50%, -50%); } } } From 5e86a7b5e73cf110c22af1f2d1ee36ba29cacdfe Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 15:08:39 -0700 Subject: [PATCH 5/7] Position node tooltips to the right of the node --- .../components/time-machine/flux-builder.scss | 50 ++++++------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/ui/src/style/components/time-machine/flux-builder.scss b/ui/src/style/components/time-machine/flux-builder.scss index df77998c14..9ded7300e5 100644 --- a/ui/src/style/components/time-machine/flux-builder.scss +++ b/ui/src/style/components/time-machine/flux-builder.scss @@ -228,8 +228,7 @@ $flux-invalid-color: $c-viridian; } } -.func-node--tooltip, -.variable-name--tooltip { +.func-node--tooltip { background-color: $g3-castle; border-radius: $radius; padding: 10px; @@ -237,28 +236,31 @@ $flux-invalid-color: $c-viridian; align-items: stretch; flex-direction: column; position: absolute; - top: calc(100% + #{$flux-node-tooltip-gap}); - left: 0; + top: 0; + left: calc(100% + #{$flux-node-tooltip-gap}); z-index: 9999; - box-shadow: 0 0 10px 2px $g2-kevlar; // Caret + box-shadow: 0 0 10px 2px $g2-kevlar; + + // Caret &:before { content: ''; border-width: 9px; border-style: solid; border-color: transparent; - border-bottom-color: $g3-castle; + border-right-color: $g3-castle; position: absolute; - top: 0; - left: $flux-node-padding + 3px; - transform: translate(-50%, -100%); - } // Invisible block to continue hovering + top: $flux-node-height / 2; + left: 0; + transform: translate(-100%, -50%); + } + // Invisible block to continue hovering &:after { content: ''; - width: 80%; - height: 7px; + height: 50%; + width: $flux-node-tooltip-gap * 3; position: absolute; - top: -7px; - left: 0; + top: 0; + left: -$flux-node-tooltip-gap * 3; } } @@ -301,26 +303,6 @@ $flux-invalid-color: $c-viridian; width: 300px; } -.variable-name--tooltip { - flex-direction: row; - align-items: center; - justify-content: space-between; - flex-wrap: nowrap; -} - -.variable-name--input { - width: 140px; -} - -.variable-name--operator { - width: 20px; - height: 30px; - text-align: center; - line-height: 30px; - font-weight: 600; - @include no-user-select(); -} - /* Filter Preview Styles ------------------------------------------------------------------------------ From a9ab9e0c418c4ef5055ed683b16019f5c6c08696 Mon Sep 17 00:00:00 2001 From: Alex P Date: Thu, 7 Jun 2018 16:22:12 -0700 Subject: [PATCH 6/7] Align func node tooltip contents horizontally --- ui/src/flux/components/FuncArgs.tsx | 52 ++++++++++--------- .../components/time-machine/flux-builder.scss | 17 ++++-- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/ui/src/flux/components/FuncArgs.tsx b/ui/src/flux/components/FuncArgs.tsx index f7bda83c7c..eedc342883 100644 --- a/ui/src/flux/components/FuncArgs.tsx +++ b/ui/src/flux/components/FuncArgs.tsx @@ -34,38 +34,40 @@ export default class FuncArgs extends PureComponent { const {name: funcName, id: funcID} = func return (
- {funcName === funcNames.JOIN ? ( - - ) : ( - func.args.map(({key, value, type}) => ( - + {funcName === funcNames.JOIN ? ( + - )) - )} -
+ ) : ( + func.args.map(({key, value, type}) => ( + + )) + )} +
+
- Delete +
{this.build}
diff --git a/ui/src/style/components/time-machine/flux-builder.scss b/ui/src/style/components/time-machine/flux-builder.scss index 9ded7300e5..5efb3bde62 100644 --- a/ui/src/style/components/time-machine/flux-builder.scss +++ b/ui/src/style/components/time-machine/flux-builder.scss @@ -234,7 +234,6 @@ $flux-invalid-color: $c-viridian; padding: 10px; display: flex; align-items: stretch; - flex-direction: column; position: absolute; top: 0; left: calc(100% + #{$flux-node-tooltip-gap}); @@ -264,22 +263,30 @@ $flux-invalid-color: $c-viridian; } } -.func-node--buttons { +.func-arg--buttons { display: flex; - margin-top: 12px; + flex-direction: column; + justify-content: center; + margin-left: 8px; } -.func-node--delete, .func-node--build { width: 60px; + margin-top: 4px; } -.func-node--sub .func-arg { +.func-args { + display: flex; + flex-direction: column; +} + +.func-arg { min-width: $flux-arg-min-width; display: flex; flex-wrap: nowrap; align-items: center; margin-bottom: 4px; + &:last-of-type { margin-bottom: 0; } From d5654b723ec477ee2231c2dd64e4da220654e586 Mon Sep 17 00:00:00 2001 From: Alex P Date: Fri, 8 Jun 2018 10:10:37 -0700 Subject: [PATCH 7/7] Refactor func args to use getters instead of ternary Cleaning up the render function --- ui/src/flux/components/FuncArgs.tsx | 103 +++++++++++++++++----------- 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/ui/src/flux/components/FuncArgs.tsx b/ui/src/flux/components/FuncArgs.tsx index eedc342883..de16248ef0 100644 --- a/ui/src/flux/components/FuncArgs.tsx +++ b/ui/src/flux/components/FuncArgs.tsx @@ -21,47 +21,11 @@ interface Props { @ErrorHandling export default class FuncArgs extends PureComponent { public render() { - const { - func, - bodyID, - service, - onChangeArg, - onDeleteFunc, - declarationID, - onGenerateScript, - declarationsFromBody, - } = this.props - const {name: funcName, id: funcID} = func + const {onDeleteFunc} = this.props + return (
-
- {funcName === funcNames.JOIN ? ( - - ) : ( - func.args.map(({key, value, type}) => ( - - )) - )} -
+
{this.renderJoinOrArgs}
{ ) } + get renderJoinOrArgs(): JSX.Element | JSX.Element[] { + const {func} = this.props + const {name: funcName} = func + + if (funcName === funcNames.JOIN) { + return this.renderJoin + } + + return this.renderArguments + } + + get renderArguments(): JSX.Element | JSX.Element[] { + const { + func, + bodyID, + service, + onChangeArg, + declarationID, + onGenerateScript, + } = this.props + const {name: funcName, id: funcID} = func + + return func.args.map(({key, value, type}) => ( + + )) + } + + get renderJoin(): JSX.Element { + const { + func, + bodyID, + onChangeArg, + declarationID, + onGenerateScript, + declarationsFromBody, + } = this.props + + return ( + + ) + } + get build(): ReactElement { const {func, onGenerateScript} = this.props if (func.name === funcNames.FILTER) {