From 8ad290dc851266a5a5cfdd7455f140703c470d4f Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 16:27:11 -0800 Subject: [PATCH 01/17] Create stylesheet for dashboards --- ui/src/dashboards/components/Dashboard.js | 2 +- ui/src/hosts/containers/HostPage.js | 2 +- .../components/KubernetesDashboard.js | 2 +- ui/src/style/chronograf.scss | 1 + ui/src/style/pages/dashboards.scss | 72 +++++++++++++++++++ 5 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 ui/src/style/pages/dashboards.scss diff --git a/ui/src/dashboards/components/Dashboard.js b/ui/src/dashboards/components/Dashboard.js index d2afb9d6c4..a6222bc7bd 100644 --- a/ui/src/dashboards/components/Dashboard.js +++ b/ui/src/dashboards/components/Dashboard.js @@ -17,7 +17,7 @@ const Dashboard = ({ return (
-
+
{isEditMode ? : null} {Dashboard.renderDashboard(dashboard, timeRange, source)}
diff --git a/ui/src/hosts/containers/HostPage.js b/ui/src/hosts/containers/HostPage.js index e2002d99cd..574e102899 100644 --- a/ui/src/hosts/containers/HostPage.js +++ b/ui/src/hosts/containers/HostPage.js @@ -172,7 +172,7 @@ export const HostPage = React.createClass({ 'page-contents': true, 'presentation-mode': inPresentationMode, })}> -
+
{ (layouts.length > 0) ? this.renderLayouts(layouts) : '' }
diff --git a/ui/src/kubernetes/components/KubernetesDashboard.js b/ui/src/kubernetes/components/KubernetesDashboard.js index bda8906823..31d0bb6581 100644 --- a/ui/src/kubernetes/components/KubernetesDashboard.js +++ b/ui/src/kubernetes/components/KubernetesDashboard.js @@ -90,7 +90,7 @@ export const KubernetesDashboard = React.createClass({ 'page-contents': true, 'presentation-mode': inPresentationMode, })}> -
+
{layouts.length ? this.renderLayouts(layouts) : emptyState}
diff --git a/ui/src/style/chronograf.scss b/ui/src/style/chronograf.scss index 901fa020c8..83e08cd7c6 100644 --- a/ui/src/style/chronograf.scss +++ b/ui/src/style/chronograf.scss @@ -45,6 +45,7 @@ @import 'pages/hosts'; @import 'pages/kapacitor'; @import 'pages/data-explorer'; +@import 'pages/dashboards'; // TODO @import 'unsorted'; diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss new file mode 100644 index 0000000000..c675c6dfda --- /dev/null +++ b/ui/src/style/pages/dashboards.scss @@ -0,0 +1,72 @@ +$dashboard-item-heading: 30px; + +.dashboard-view { + .react-grid-item { + background-color: $g3-castle; + border-radius: $radius; + border: 2px solid $g3-castle; + + &.resizing { + border-color: $c-pool; + z-index: 3; + } + &.react-draggable-dragging { + border-color: $c-pool; + } + } + .react-grid-placeholder { + background-color: $c-pool; + border: 0; + opacity: 0.3; + z-index: 2; + } + .graph-empty { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + } + .hosts-graph { + position: absolute; + width: 100%; + height: calc(100% - #{$dashboard-item-heading}); + top: $dashboard-item-heading; + left: 0; + padding: 0; + + & > div:not(.graph-empty) { + position: absolute; + left: 16px; + top: 8px; + width: calc(100% - 32px); + height: calc(100% - 16px); + + & > div, + & > div > div:not(.graph-panel__refreshing) { + position: absolute; + width: 100%; + height: 100%; + } + } + .graph-panel__refreshing { + top: -$dashboard-item-heading !important; + right: 0 !important; + } + + } + .hosts-graph-heading { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: $dashboard-item-heading; + padding: 0 16px; + display: flex; + align-items: center; + } +} + +.react-grid-item > .react-resizable-handle { + +} \ No newline at end of file From 36177b204dc28b2d5aaf1cda04eda0089a925147 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 16:27:40 -0800 Subject: [PATCH 02/17] Remove height prop from line graphs --- ui/src/shared/components/LayoutRenderer.js | 33 +++++----------------- ui/src/shared/components/LineGraph.js | 3 +- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index 5b49a71427..1eea30268e 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -10,9 +10,7 @@ const RefreshingLineGraph = AutoRefresh(LineGraph); const RefreshingSingleStat = AutoRefresh(SingleStat); const { - children, arrayOf, - node, number, shape, string, @@ -114,9 +112,12 @@ export const LayoutRenderer = React.createClass({ } return ( - - - +
+

{cell.name}

+
+ +
+
); }); }, @@ -147,24 +148,4 @@ export const LayoutRenderer = React.createClass({ }, }); -const Wrapper = React.createClass({ - propTypes: { - children: node.isRequired, - }, - render() { - const that = this; - const newChildren = React.Children.map(this.props.children, (child) => { - return React.cloneElement(child, { - height: that.props.style.height, - }) - }) - - return ( -
- {newChildren} -
- ); - } -}); - -export default LayoutRenderer; +export default LayoutRenderer; \ No newline at end of file diff --git a/ui/src/shared/components/LineGraph.js b/ui/src/shared/components/LineGraph.js index cfd38b73f7..18cee048e6 100644 --- a/ui/src/shared/components/LineGraph.js +++ b/ui/src/shared/components/LineGraph.js @@ -25,7 +25,6 @@ export default React.createClass({ y: arrayOf(number), y2: arrayOf(number), }), - height: string, title: string, isFetchingInitially: bool, isRefreshing: bool, @@ -105,7 +104,7 @@ export default React.createClass({
{isRefreshing ? this.renderSpinner() : null} Date: Tue, 21 Feb 2017 16:59:18 -0800 Subject: [PATCH 03/17] Adding default name to dashboard graphs --- ui/src/shared/components/LayoutRenderer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index 1eea30268e..ff97fdf0a6 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -103,8 +103,8 @@ export const LayoutRenderer = React.createClass({ if (cell.type === 'single-stat') { return (
-

{cell.name}

-
+

{cell.name || `Graph`}

+
@@ -113,8 +113,8 @@ export const LayoutRenderer = React.createClass({ return (
-

{cell.name}

-
+

{cell.name || `Graph`}

+
From 626e1966b9e8d9dc8cb4560d59ec8e270fad4bfb Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 16:59:43 -0800 Subject: [PATCH 04/17] Fix vertical marker bug & simplify line graph --- ui/src/shared/components/LineGraph.js | 30 +++++++++++++-------------- ui/src/style/pages/dashboards.scss | 15 +++++++------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/ui/src/shared/components/LineGraph.js b/ui/src/shared/components/LineGraph.js index 18cee048e6..abd5ee0ff4 100644 --- a/ui/src/shared/components/LineGraph.js +++ b/ui/src/shared/components/LineGraph.js @@ -100,22 +100,20 @@ export default React.createClass({ } return ( -
-
- {isRefreshing ? this.renderSpinner() : null} - - {showSingleStat ?
{roundedValue}
: null} -
+
+ {this.renderSpinner()} + + {showSingleStat ?
{roundedValue}
: null}
); }, diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index c675c6dfda..6cad0d63f0 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -37,21 +37,20 @@ $dashboard-item-heading: 30px; & > div:not(.graph-empty) { position: absolute; - left: 16px; - top: 8px; - width: calc(100% - 32px); - height: calc(100% - 16px); + left: 0; + top: 0; + width: 100%; + height: 100%; - & > div, - & > div > div:not(.graph-panel__refreshing) { + & > div:not(.graph-panel__refreshing) { position: absolute; width: 100%; height: 100%; + padding: 8px 16px; } } .graph-panel__refreshing { - top: -$dashboard-item-heading !important; - right: 0 !important; + top: (-$dashboard-item-heading + 5px) !important; } } From 3a995f979cf5c6b3961c855d23bd4c9efa60e4fb Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 17:40:45 -0800 Subject: [PATCH 05/17] Style graph resizer --- ui/src/style/pages/dashboards.scss | 32 ++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 6cad0d63f0..467749a582 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -9,6 +9,12 @@ $dashboard-item-heading: 30px; &.resizing { border-color: $c-pool; z-index: 3; + + & > .react-resizable-handle { + &:before, &:after { + background-color: $c-pool; + } + } } &.react-draggable-dragging { border-color: $c-pool; @@ -67,5 +73,31 @@ $dashboard-item-heading: 30px; } .react-grid-item > .react-resizable-handle { + background-image: none; + cursor: nwse-resize; + &:before, + &:after { + content: ''; + display: block; + position: absolute; + height: 2px; + background-color: $g6-smoke; + transition: background-color 0.25s ease; + top: 50%; + left: 50%; + } + &:before { + width: 20px; + transform: translate(-50%,-50%) rotate(-45deg); + } + &:after { + width: 12px; + transform: translate(-3px,2px) rotate(-45deg); + } + &:hover { + &:before, &:after { + background-color: $c-pool; + } + } } \ No newline at end of file From bddc350b75135a8c5f581cc65c44c3eadbfc9c98 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 17:41:22 -0800 Subject: [PATCH 06/17] Using CSS Transforms for react grid layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit says 6x performance boost, seems like a good idea unless there is something I’m not aware of --- ui/src/shared/components/LayoutRenderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index ff97fdf0a6..df75cd6a80 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -131,7 +131,7 @@ export const LayoutRenderer = React.createClass({ rowHeight={83.5} margin={[layoutMargin, layoutMargin]} containerPadding={[0, 0]} - useCSSTransforms={false} + useCSSTransforms={true} onResize={triggerWindowResize} onLayoutChange={triggerWindowResize} > From a13e81b882f88ac5902382be72cc62b3a785f23e Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 17:41:39 -0800 Subject: [PATCH 07/17] Undo debug mode on graph spinner --- ui/src/shared/components/LineGraph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/shared/components/LineGraph.js b/ui/src/shared/components/LineGraph.js index abd5ee0ff4..591b519f8e 100644 --- a/ui/src/shared/components/LineGraph.js +++ b/ui/src/shared/components/LineGraph.js @@ -101,7 +101,7 @@ export default React.createClass({ return (
- {this.renderSpinner()} + {isRefreshing ? this.renderSpinner() : null} Date: Tue, 21 Feb 2017 18:08:20 -0800 Subject: [PATCH 08/17] Make single stat graphs look more styley --- ui/src/style/pages/hosts.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/src/style/pages/hosts.scss b/ui/src/style/pages/hosts.scss index 89aeb0e402..22730cab4c 100644 --- a/ui/src/style/pages/hosts.scss +++ b/ui/src/style/pages/hosts.scss @@ -25,7 +25,9 @@ padding: 8px 16px; .single-stat { - font-size: 32px; + font-size: 60px; + font-weight: 300; + color: $c-pool; display: flex; justify-content: center; align-items: center; From c1191a620fe4f37ffaeefc3e0fdfdf00c69c4f09 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 18:08:39 -0800 Subject: [PATCH 09/17] Limit dragging handle to just the graph header --- ui/src/shared/components/LayoutRenderer.js | 1 + ui/src/style/pages/dashboards.scss | 31 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ui/src/shared/components/LayoutRenderer.js b/ui/src/shared/components/LayoutRenderer.js index df75cd6a80..459f6b3d0f 100644 --- a/ui/src/shared/components/LayoutRenderer.js +++ b/ui/src/shared/components/LayoutRenderer.js @@ -134,6 +134,7 @@ export const LayoutRenderer = React.createClass({ useCSSTransforms={true} onResize={triggerWindowResize} onLayoutChange={triggerWindowResize} + draggableHandle={'.hosts-graph-heading'} > {this.generateVisualizations()} diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 467749a582..1bb8f30b84 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -5,6 +5,7 @@ $dashboard-item-heading: 30px; background-color: $g3-castle; border-radius: $radius; border: 2px solid $g3-castle; + transition: all 0.2s ease !important; &.resizing { border-color: $c-pool; @@ -18,6 +19,23 @@ $dashboard-item-heading: 30px; } &.react-draggable-dragging { border-color: $c-pool; + cursor: grabbing; + cursor: -moz-grabbing; + cursor: -webkit-grabbing; + &:hover { + cursor: grabbing; + cursor: -moz-grabbing; + cursor: -webkit-grabbing; + } + + & > .hosts-graph-heading, + & > .hosts-graph-heading:hover { + background-color: $g4-onyx; + color: $g18-cloud; + cursor: grabbing; + cursor: -moz-grabbing; + cursor: -webkit-grabbing; + } } } .react-grid-placeholder { @@ -69,6 +87,19 @@ $dashboard-item-heading: 30px; padding: 0 16px; display: flex; align-items: center; + border-radius: $radius; + transition: + color 0.25s ease, + background-color 0.25s ease; + + &:hover { + background-color: $g4-onyx; + color: $g18-cloud; + cursor: move; /* fallback if grab cursor is unsupported */ + cursor: grab; + cursor: -moz-grab; + cursor: -webkit-grab; + } } } From 99febb9af544c07ef99ce982e749289110f8240a Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 18:11:40 -0800 Subject: [PATCH 10/17] Fix transitions in graph dragging state --- ui/src/style/pages/dashboards.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 1bb8f30b84..4723cfc192 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -5,7 +5,11 @@ $dashboard-item-heading: 30px; background-color: $g3-castle; border-radius: $radius; border: 2px solid $g3-castle; - transition: all 0.2s ease !important; + transition-property: left, top, border-color; + + &.cssTransforms { + transition-property: transform, border-color; + } &.resizing { border-color: $c-pool; From 882ce72969c2336190e2d3b017cf0c0ab49b8adf Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 18:47:29 -0800 Subject: [PATCH 11/17] Add more CSS gradient mixins --- ui/src/style/mixins/mixins.scss | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/ui/src/style/mixins/mixins.scss b/ui/src/style/mixins/mixins.scss index 288f115b99..cd3af3cae5 100644 --- a/ui/src/style/mixins/mixins.scss +++ b/ui/src/style/mixins/mixins.scss @@ -13,9 +13,31 @@ background: linear-gradient(to right, $startColor 0%,$endColor 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$startColor', endColorstr='$endColor',GradientType=1 ); } +@mixin gradient-diag-up($startColor, $endColor) { + background: $startColor; + background: -moz-linear-gradient(45deg, $startColor 0%, $endColor 100%); + background: -webkit-linear-gradient(45deg, $startColor 0%,$endColor 100%); + background: linear-gradient(45deg, $startColor 0%,$endColor 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$startColor', endColorstr='$endColor',GradientType=1 ); +} +@mixin gradient-diag-down($startColor, $endColor) { + background: $startColor; + background: -moz-linear-gradient(135deg, $startColor 0%, $endColor 100%); + background: -webkit-linear-gradient(135deg, $startColor 0%,$endColor 100%); + background: linear-gradient(135deg, $startColor 0%,$endColor 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$startColor', endColorstr='$endColor',GradientType=1 ); +} +@mixin gradient-r($startColor, $endColor) { + background: $startColor; + background: -moz-radial-gradient(center, ellipse cover, $startColor 0%, $endColor 100%); + background: -webkit-radial-gradient(center, ellipse cover, $startColor 0%,$endColor 100%); + background: radial-gradient(ellipse at center, $startColor 0%,$endColor 100%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='$startColor', endColorstr='$endColor',GradientType=1 ); +} // Custom Scrollbars (Chrome Only) $scrollbar-width: 16px; +$scrollbar-offset: 3px; @mixin custom-scrollbar($trackColor, $handleColor) { &::-webkit-scrollbar { width: $scrollbar-width; @@ -30,12 +52,12 @@ $scrollbar-width: 16px; } &-track-piece { background-color: $trackColor; - border: 6px solid $trackColor; + border: $scrollbar-offset solid $trackColor; border-radius: ($scrollbar-width / 2); } &-thumb { background-color: $handleColor; - border: 6px solid $trackColor; + border: $scrollbar-offset solid $trackColor; border-radius: ($scrollbar-width / 2); } &-corner { From c284b71c90bb6a188ee1f8fc9511524c8da6530f Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 18:47:46 -0800 Subject: [PATCH 12/17] Make graph dragging placeholder more styley --- ui/src/style/pages/dashboards.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index 4723cfc192..e085aa385b 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -43,7 +43,7 @@ $dashboard-item-heading: 30px; } } .react-grid-placeholder { - background-color: $c-pool; + @include gradient-diag-up($c-pool,$c-comet); border: 0; opacity: 0.3; z-index: 2; From 850baf7aeca7820d3c980fb198910ac2d0faafbc Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 22:46:50 -0800 Subject: [PATCH 13/17] Add gradient borders to drag and resize state of graphs --- ui/src/style/pages/dashboards.scss | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index e085aa385b..f4bd933886 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -13,16 +13,26 @@ $dashboard-item-heading: 30px; &.resizing { border-color: $c-pool; + border-image-slice: 3%; + border-image-repeat: initial; + border-image-outset: 0; + border-image-width: 2px; + border-image-source: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTg0NjVDRkVGMEVFMTFFNkE0QjVFRTJGNEI1ODc0RDMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTg0NjVDRkZGMEVFMTFFNkE0QjVFRTJGNEI1ODc0RDMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxODQ2NUNGQ0YwRUUxMUU2QTRCNUVFMkY0QjU4NzREMyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxODQ2NUNGREYwRUUxMUU2QTRCNUVFMkY0QjU4NzREMyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpeetfIAAAMnSURBVHja7N1PatwwFMfxJ5NlKT1DIfQKWZfSA/Q0hexDL9McoOQAPUKglwhp6dZ9Ho/HfyTZs6l+b/E1GDm27IH5oH9Pyji9//7XfLtNZt88/eT722TzlvrFseXHaXFmypuO8vd5nmW6nyeNefrKfZv7i9f75blU/NzafXvns2dV7tl8zqsnT55+9f3Xjf/xwQ9+evou+xLB+N8Ydi4AX3z/6PnvOj94AEOGMV/rB4P00J2rKTC0GNOTPne0GWEwhv1NB0YYjNPWgREHI00gYMTAOIGAEQdjuKcDIw7GXGWBEQJjrLLACIORrFBlgaHDsG2VBYYWY1VlgaHHSH3WqIOhxLB1ow6GGmPRqIMRAeMMAkYUDFuGTsDQYwxP6MCIg1Hp9oKhwih0e8FQYthuLAuM5hj1WBYYEoxUjGWBIcOwrFEHQ4qxLiFgyDFOvSww4mCM8yFghMEoDgzB0GGk2owhGBoMq5UQMDQYxRIChg4ja0PA0GLYMrgIhh7jUkLAiIExV1lghMA4GBiC0RrjNIULRhyMysAQDBVGYWAIhhJjM6cOhhpjUULAiIAxr1wEIwTGPDAEIwTGWGWBEQajHu0FQ4JRjvaCIcPIo71gSDHW0V4w5Bj5SB0MKUZxoRwYOoxsPgQMLcZqPgQMPUaxUQdDh2HVcQgYEoxUHIeAIcPIqywwpBjrKgsMOcb8f+pghMDIwu9gaDFWI3Uw9Bg2N+pgRMA497LAiIJRXf0OhgajuPodDB3G1dFeMNpgXBXtBaMdxmG0F4y2GLvRXjDaY2wGhmCoMawU7QVDh5G20V4wtBjzwBCMEBiXVx6BEQPjsJcFRluM3V4WGO0xqr0sMDQYVuplgaHDWL1YEgw9hi17WWDoMVJ1ChcMCYYVp3DBkGFUl5KCocGw6deAwIiBYUfBRTDaYmTdXjC0GFYLLoKhwSj+cAAYOgzbBhfB0GKsgotg6DGuWrkIRjuMudsLRgiMsQ0BIwzG5ZVHYMTAmKqsVzBiYPj2Z+j2PoERAmM4/2MoIfe+v4Ahx3jx5H4AefYLd37q0Y9/g9EcY/jOHz11A3v+J8AA9wisahRCWTQAAAAASUVORK5CYII=); z-index: 3; & > .react-resizable-handle { &:before, &:after { - background-color: $c-pool; + background-color: $c-comet; } } } &.react-draggable-dragging { border-color: $c-pool; + border-image-slice: 3%; + border-image-repeat: initial; + border-image-outset: 0; + border-image-width: 2px; + border-image-source: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMDY3IDc5LjE1Nzc0NywgMjAxNS8wMy8zMC0yMzo0MDo0MiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MTg0NjVDRkVGMEVFMTFFNkE0QjVFRTJGNEI1ODc0RDMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MTg0NjVDRkZGMEVFMTFFNkE0QjVFRTJGNEI1ODc0RDMiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxODQ2NUNGQ0YwRUUxMUU2QTRCNUVFMkY0QjU4NzREMyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxODQ2NUNGREYwRUUxMUU2QTRCNUVFMkY0QjU4NzREMyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpeetfIAAAMnSURBVHja7N1PatwwFMfxJ5NlKT1DIfQKWZfSA/Q0hexDL9McoOQAPUKglwhp6dZ9Ho/HfyTZs6l+b/E1GDm27IH5oH9Pyji9//7XfLtNZt88/eT722TzlvrFseXHaXFmypuO8vd5nmW6nyeNefrKfZv7i9f75blU/NzafXvns2dV7tl8zqsnT55+9f3Xjf/xwQ9+evou+xLB+N8Ydi4AX3z/6PnvOj94AEOGMV/rB4P00J2rKTC0GNOTPne0GWEwhv1NB0YYjNPWgREHI00gYMTAOIGAEQdjuKcDIw7GXGWBEQJjrLLACIORrFBlgaHDsG2VBYYWY1VlgaHHSH3WqIOhxLB1ow6GGmPRqIMRAeMMAkYUDFuGTsDQYwxP6MCIg1Hp9oKhwih0e8FQYthuLAuM5hj1WBYYEoxUjGWBIcOwrFEHQ4qxLiFgyDFOvSww4mCM8yFghMEoDgzB0GGk2owhGBoMq5UQMDQYxRIChg4ja0PA0GLYMrgIhh7jUkLAiIExV1lghMA4GBiC0RrjNIULRhyMysAQDBVGYWAIhhJjM6cOhhpjUULAiIAxr1wEIwTGPDAEIwTGWGWBEQajHu0FQ4JRjvaCIcPIo71gSDHW0V4w5Bj5SB0MKUZxoRwYOoxsPgQMLcZqPgQMPUaxUQdDh2HVcQgYEoxUHIeAIcPIqywwpBjrKgsMOcb8f+pghMDIwu9gaDFWI3Uw9Bg2N+pgRMA497LAiIJRXf0OhgajuPodDB3G1dFeMNpgXBXtBaMdxmG0F4y2GLvRXjDaY2wGhmCoMawU7QVDh5G20V4wtBjzwBCMEBiXVx6BEQPjsJcFRluM3V4WGO0xqr0sMDQYVuplgaHDWL1YEgw9hi17WWDoMVJ1ChcMCYYVp3DBkGFUl5KCocGw6deAwIiBYUfBRTDaYmTdXjC0GFYLLoKhwSj+cAAYOgzbBhfB0GKsgotg6DGuWrkIRjuMudsLRgiMsQ0BIwzG5ZVHYMTAmKqsVzBiYPj2Z+j2PoERAmM4/2MoIfe+v4Ahx3jx5H4AefYLd37q0Y9/g9EcY/jOHz11A3v+J8AA9wisahRCWTQAAAAASUVORK5CYII=); cursor: grabbing; cursor: -moz-grabbing; cursor: -webkit-grabbing; @@ -43,7 +53,7 @@ $dashboard-item-heading: 30px; } } .react-grid-placeholder { - @include gradient-diag-up($c-pool,$c-comet); + @include gradient-diag-down($c-pool,$c-comet); border: 0; opacity: 0.3; z-index: 2; @@ -132,7 +142,7 @@ $dashboard-item-heading: 30px; } &:hover { &:before, &:after { - background-color: $c-pool; + background-color: $c-comet; } } } \ No newline at end of file From 5983ce3655a7156581500d303d85859c0d85c333 Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 23:04:39 -0800 Subject: [PATCH 14/17] Fix legend vertical position --- ui/src/shared/components/Dygraph.js | 2 ++ ui/src/style/components/dygraphs.scss | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/src/shared/components/Dygraph.js b/ui/src/shared/components/Dygraph.js index 12895f8624..655734984e 100644 --- a/ui/src/shared/components/Dygraph.js +++ b/ui/src/shared/components/Dygraph.js @@ -109,6 +109,7 @@ export default React.createClass({ const legendMaxLeft = graphWidth - (legendWidth / 2); const trueGraphX = (e.pageX - graphRect.left); let legendLeft = trueGraphX; + let legendTop = graphRect.height + 0 // Enforcing max & min legend offsets if (trueGraphX < (legendWidth / 2)) { legendLeft = legendWidth / 2; @@ -117,6 +118,7 @@ export default React.createClass({ } legendContainerNode.style.left = `${legendLeft}px`; + legendContainerNode.style.top = `${legendTop}px`; setMarker(points); }, unhighlightCallback() { diff --git a/ui/src/style/components/dygraphs.scss b/ui/src/style/components/dygraphs.scss index 991c3a9e67..af6caf3d27 100644 --- a/ui/src/style/components/dygraphs.scss +++ b/ui/src/style/components/dygraphs.scss @@ -15,9 +15,8 @@ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='fade-out($g20-white, 0.71)', endColorstr='fade-out($g20-white, 0.71)',GradientType=0 ); } .container--dygraph-legend { - top: 300px !important; - transform: translate(-50%,-6px); - background-color: $g1-raven; + transform: translateX(-50%); + background-color: $g0-obsidian; display: block; position: absolute; padding: 11px; From 1cee9d9b5d8c95092f11e6549dd442bf1c6c2b3d Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 23:04:59 -0800 Subject: [PATCH 15/17] Shrink padding on Y & Y2 graph labels --- ui/src/style/components/dygraphs.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/style/components/dygraphs.scss b/ui/src/style/components/dygraphs.scss index af6caf3d27..b6653fff93 100644 --- a/ui/src/style/components/dygraphs.scss +++ b/ui/src/style/components/dygraphs.scss @@ -118,9 +118,9 @@ .graph--hasYLabel { .dygraph-axis-label-y { - padding: 0 1px 0 12px !important; + padding: 0 1px 0 10px !important; } .dygraph-axis-label-y2 { - padding: 0 12px 0 1px !important; + padding: 0 10px 0 1px !important; } } From 7a3585f32cd36dfb6323500c33e3de8a777ec23e Mon Sep 17 00:00:00 2001 From: Alex P Date: Tue, 21 Feb 2017 23:05:31 -0800 Subject: [PATCH 16/17] Make graph background colorsemi-transparent during drag --- ui/src/style/pages/dashboards.scss | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ui/src/style/pages/dashboards.scss b/ui/src/style/pages/dashboards.scss index f4bd933886..05ae2adc02 100644 --- a/ui/src/style/pages/dashboards.scss +++ b/ui/src/style/pages/dashboards.scss @@ -5,13 +5,14 @@ $dashboard-item-heading: 30px; background-color: $g3-castle; border-radius: $radius; border: 2px solid $g3-castle; - transition-property: left, top, border-color; + transition-property: left, top, border-color, background-color; &.cssTransforms { - transition-property: transform, border-color; + transition-property: transform, border-color, background-color; } &.resizing { + background-color: fade-out($g3-castle,0.09); border-color: $c-pool; border-image-slice: 3%; border-image-repeat: initial; @@ -27,6 +28,7 @@ $dashboard-item-heading: 30px; } } &.react-draggable-dragging { + background-color: fade-out($g3-castle,0.09); border-color: $c-pool; border-image-slice: 3%; border-image-repeat: initial; @@ -59,6 +61,7 @@ $dashboard-item-heading: 30px; z-index: 2; } .graph-empty { + background-color: transparent; position: absolute; width: 100%; height: 100%; @@ -66,6 +69,7 @@ $dashboard-item-heading: 30px; left: 0; } .hosts-graph { + background-color: transparent; position: absolute; width: 100%; height: calc(100% - #{$dashboard-item-heading}); @@ -93,6 +97,7 @@ $dashboard-item-heading: 30px; } .hosts-graph-heading { + background-color: transparent; position: absolute; top: 0; left: 0; From dc3f0b3ee4e395a1e0e219eb7214bb52f11bd0fe Mon Sep 17 00:00:00 2001 From: Chris Goller Date: Wed, 22 Feb 2017 09:46:16 -0600 Subject: [PATCH 17/17] Add dashboards PATCH for incremental update of name or cells --- server/dashboards.go | 50 ++++++++++++++++++++++++++++++++++++++++++-- server/mux.go | 3 ++- server/swagger.json | 45 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 3 deletions(-) diff --git a/server/dashboards.go b/server/dashboards.go index 9bfaba8fe7..5eef491c92 100644 --- a/server/dashboards.go +++ b/server/dashboards.go @@ -127,8 +127,8 @@ func (s *Service) RemoveDashboard(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) } -// UpdateDashboard replaces a dashboard -func (s *Service) UpdateDashboard(w http.ResponseWriter, r *http.Request) { +// ReplaceDashboard completely replaces a dashboard +func (s *Service) ReplaceDashboard(w http.ResponseWriter, r *http.Request) { ctx := r.Context() idParam, err := strconv.Atoi(httprouter.GetParamFromContext(ctx, "id")) if err != nil { @@ -165,6 +165,52 @@ func (s *Service) UpdateDashboard(w http.ResponseWriter, r *http.Request) { encodeJSON(w, http.StatusOK, res, s.Logger) } +// UpdateDashboard completely updates either the dashboard name or the cells +func (s *Service) UpdateDashboard(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + idParam, err := strconv.Atoi(httprouter.GetParamFromContext(ctx, "id")) + if err != nil { + msg := fmt.Sprintf("Could not parse dashboard ID: %s", err) + Error(w, http.StatusInternalServerError, msg, s.Logger) + } + id := chronograf.DashboardID(idParam) + + orig, err := s.DashboardsStore.Get(ctx, id) + if err != nil { + Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id), s.Logger) + return + } + + var req chronograf.Dashboard + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + invalidJSON(w, s.Logger) + return + } + req.ID = id + + if req.Name != "" { + orig.Name = req.Name + } else if len(req.Cells) > 0 { + if err := ValidDashboardRequest(&req); err != nil { + invalidData(w, err, s.Logger) + return + } + orig.Cells = req.Cells + } else { + invalidData(w, fmt.Errorf("Update must include either name or cells"), s.Logger) + return + } + + if err := s.DashboardsStore.Update(ctx, orig); err != nil { + msg := fmt.Sprintf("Error updating dashboard ID %d: %v", id, err) + Error(w, http.StatusInternalServerError, msg, s.Logger) + return + } + + res := newDashboardResponse(orig) + encodeJSON(w, http.StatusOK, res, s.Logger) +} + // ValidDashboardRequest verifies that the dashboard cells have a query func ValidDashboardRequest(d *chronograf.Dashboard) error { if len(d.Cells) == 0 { diff --git a/server/mux.go b/server/mux.go index 5d818d9f40..6ab6ce4356 100644 --- a/server/mux.go +++ b/server/mux.go @@ -117,7 +117,8 @@ func NewMux(opts MuxOpts, service Service) http.Handler { router.GET("/chronograf/v1/dashboards/:id", service.DashboardID) router.DELETE("/chronograf/v1/dashboards/:id", service.RemoveDashboard) - router.PUT("/chronograf/v1/dashboards/:id", service.UpdateDashboard) + router.PUT("/chronograf/v1/dashboards/:id", service.ReplaceDashboard) + router.PATCH("/chronograf/v1/dashboards/:id", service.UpdateDashboard) /* Authentication */ if opts.UseAuth { diff --git a/server/swagger.json b/server/swagger.json index 9e3d7dfd23..35b3b7e153 100644 --- a/server/swagger.json +++ b/server/swagger.json @@ -1519,6 +1519,51 @@ } } } + }, + "patch": { + "tags": [ + "layouts" + ], + "summary": "Update dashboard information.", + "description": "Update either the dashboard name or the dashboard cells", + "parameters": [ + { + "name": "id", + "in": "path", + "type": "integer", + "description": "ID of a dashboard", + "required": true + }, + { + "name": "config", + "in": "body", + "description": "dashboard configuration update parameters. Must be either name or cells", + "schema": { + "$ref": "#/definitions/Dashboard" + }, + "required": true + } + ], + "responses": { + "200": { + "description": "Dashboard has been updated and the new dashboard is returned.", + "schema": { + "$ref": "#/definitions/Dashboard" + } + }, + "404": { + "description": "Happens when trying to access a non-existent dashboard.", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "default": { + "description": "A processing or an unexpected error.", + "schema": { + "$ref": "#/definitions/Error" + } + } + } } } },