Kaynağa Gözat

Merge branch 'panel-edit-in-react' of https://github.com/grafana/grafana into panel-edit-in-react

Erik Sundell 7 yıl önce
ebeveyn
işleme
4f38af12a8

+ 1 - 1
public/app/core/components/manage_dashboards/manage_dashboards.html

@@ -67,7 +67,7 @@
       <gf-form-checkbox
         on-change="ctrl.onSelectAllChanged()"
         checked="ctrl.selectAllChecked"
-        switch-class="gf-form-switch--transparent"
+        switch-class="gf-form-checkbox--transparent"
       />
       <div class="search-results-filter-row__filters">
         <div class="gf-form-select-wrapper" ng-show="!(ctrl.canMove || ctrl.canDelete)">

+ 4 - 4
public/app/core/components/search/search_results.html

@@ -1,11 +1,11 @@
 <div ng-repeat="section in ctrl.results" class="search-section">
   <div class="search-section__header pointer" ng-hide="section.hideHeader" ng-class="{'selected': section.selected}" ng-click="ctrl.toggleFolderExpand(section)">
-    <div ng-click="ctrl.toggleSelection(section, $event)">
+    <div ng-click="ctrl.toggleSelection(section, $event)" class="center-vh">
       <gf-form-checkbox
          ng-show="ctrl.editable"
          on-change="ctrl.selectionChanged($event)"
          checked="section.checked"
-         switch-class="gf-form-switch--transparent gf-form-switch--search-result__section">
+         switch-class="gf-form-checkbox--transparent">
       </gf-form-checkbox>
     </div>
     <i class="search-section__header__icon" ng-class="section.icon"></i>
@@ -21,12 +21,12 @@
 
   <div ng-if="section.expanded">
     <a ng-repeat="item in section.items" class="search-item search-item--indent" ng-class="{'selected': item.selected}" ng-href="{{::item.url}}" >
-      <div ng-click="ctrl.toggleSelection(item, $event)">
+      <div ng-click="ctrl.toggleSelection(item, $event)" class="center-vh">
         <gf-form-checkbox
            ng-show="ctrl.editable"
            on-change="ctrl.selectionChanged()"
            checked="item.checked"
-           switch-class="gf-form-switch--transparent gf-form-switch--search-result__item">
+           switch-class="gf-form-checkbox--transparent">
         </gf-form-checkbox>
       </div>
       <span class="search-item__icon">

+ 0 - 4
public/app/features/dashboard/dashgrid/DataSourcePicker.tsx

@@ -79,10 +79,6 @@ export class DataSourcePicker extends PureComponent<Props, State> {
           />
           <i className="gf-form-input-icon fa fa-search" />
         </label>
-        <div className="p-l-1">
-          <button className="btn toggle-btn gf-form-btn active">All</button>
-          <button className="btn toggle-btn gf-form-btn">Favorites</button>
-        </div>
       </>
     );
   }

+ 16 - 104
public/app/features/dashboard/dashgrid/QueriesTab.tsx

@@ -8,11 +8,7 @@ import { DashboardModel } from '../dashboard_model';
 import './../../panel/metrics_tab';
 import config from 'app/core/config';
 import { QueryInspector } from './QueryInspector';
-import { Switch } from 'app/core/components/Switch/Switch';
-import { Input } from 'app/core/components/Form';
-import { InputStatus, EventsWithValidation } from 'app/core/components/Form/Input';
-import { isValidTimeSpan } from 'app/core/utils/rangeutil';
-import { ValidationEvents } from 'app/types';
+import { TimeRangeOptions } from './TimeRangeOptions';
 
 // Services
 import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
@@ -43,20 +39,6 @@ interface LoadingPlaceholderProps {
 
 const LoadingPlaceholder: SFC<LoadingPlaceholderProps> = ({ text }) => <h2>{text}</h2>;
 
-const timeRangeValidationEvents: ValidationEvents = {
-  [EventsWithValidation.onBlur]: [
-    {
-      rule: value => {
-        if (!value) {
-          return true;
-        }
-        return isValidTimeSpan(value);
-      },
-      errorMessage: 'Not a valid timespan',
-    },
-  ],
-};
-
 export class QueriesTab extends PureComponent<Props, State> {
   element: any;
   component: AngularComponent;
@@ -220,10 +202,19 @@ export class QueriesTab extends PureComponent<Props, State> {
       },
     };
 
-    return Object.keys(queryOptions).map(key => {
-      const options = allOptions[key];
-      return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
-    });
+    const dsOptions = queryOptions
+      ? Object.keys(queryOptions).map(key => {
+          const options = allOptions[key];
+          return <DataSourceOption key={key} {...options} onChange={onChangeFn(allOptions[key].panelKey || key)} />;
+        })
+      : null;
+
+    return (
+      <>
+        <TimeRangeOptions panel={this.props.panel} />
+        {dsOptions}
+      </>
+    );
   };
 
   renderQueryInspector = () => {
@@ -236,42 +227,9 @@ export class QueriesTab extends PureComponent<Props, State> {
     return isLoading ? <LoadingPlaceholder text="Loading help..." /> : helpHtml;
   };
 
-  emptyToNull = (value: string) => {
-    return value === '' ? null : value;
-  };
-
-  onOverrideTime = (evt, status: InputStatus) => {
-    const { value } = evt.target;
-    const { panel } = this.props;
-    const emptyToNullValue = this.emptyToNull(value);
-    if (status === InputStatus.Valid && panel.timeFrom !== emptyToNullValue) {
-      panel.timeFrom = emptyToNullValue;
-      panel.refresh();
-    }
-  };
-
-  onTimeShift = (evt, status: InputStatus) => {
-    const { value } = evt.target;
-    const { panel } = this.props;
-    const emptyToNullValue = this.emptyToNull(value);
-    if (status === InputStatus.Valid && panel.timeShift !== emptyToNullValue) {
-      panel.timeShift = emptyToNullValue;
-      panel.refresh();
-    }
-  };
-
-  onToggleTimeOverride = () => {
-    const { panel } = this.props;
-    panel.hideTimeOverride = !panel.hideTimeOverride;
-    panel.refresh();
-  };
-
   render() {
     const { currentDatasource } = this.state;
-    const hideTimeOverride = this.props.panel.hideTimeOverride;
-    console.log('hideTimeOverride', hideTimeOverride);
-    const { hasQueryHelp, queryOptions } = currentDatasource.meta;
-    const hasQueryOptions = !!queryOptions;
+    const { hasQueryHelp } = currentDatasource.meta;
     const dsInformation = {
       title: currentDatasource.name,
       imgSrc: currentDatasource.meta.info.logos.small,
@@ -302,7 +260,7 @@ export class QueriesTab extends PureComponent<Props, State> {
     const options = {
       title: '',
       icon: 'fa fa-cog',
-      disabled: !hasQueryOptions,
+      disabled: false,
       render: this.renderOptions,
     };
 
@@ -310,52 +268,6 @@ export class QueriesTab extends PureComponent<Props, State> {
       <EditorTabBody heading="Queries" main={dsInformation} toolbarItems={[options, queryInspector, dsHelp]}>
         <>
           <div ref={element => (this.element = element)} style={{ width: '100%' }} />
-
-          <h5 className="section-heading">Time Range</h5>
-
-          <div className="gf-form-group">
-            <div className="gf-form">
-              <span className="gf-form-label">
-                <i className="fa fa-clock-o" />
-              </span>
-
-              <span className="gf-form-label width-12">Override relative time</span>
-              <span className="gf-form-label width-6">Last</span>
-              <Input
-                type="text"
-                className="gf-form-input max-width-8"
-                placeholder="1h"
-                onBlur={this.onOverrideTime}
-                validationEvents={timeRangeValidationEvents}
-                hideErrorMessage={true}
-              />
-            </div>
-
-            <div className="gf-form">
-              <span className="gf-form-label">
-                <i className="fa fa-clock-o" />
-              </span>
-              <span className="gf-form-label width-12">Add time shift</span>
-              <span className="gf-form-label width-6">Amount</span>
-              <Input
-                type="text"
-                className="gf-form-input max-width-8"
-                placeholder="1h"
-                onBlur={this.onTimeShift}
-                validationEvents={timeRangeValidationEvents}
-                hideErrorMessage={true}
-              />
-            </div>
-
-            <div className="gf-form-inline">
-              <div className="gf-form">
-                <span className="gf-form-label">
-                  <i className="fa fa-clock-o" />
-                </span>
-              </div>
-              <Switch label="Hide time override info" checked={hideTimeOverride} onChange={this.onToggleTimeOverride} />
-            </div>
-          </div>
         </>
       </EditorTabBody>
     );

+ 111 - 0
public/app/features/dashboard/dashgrid/TimeRangeOptions.tsx

@@ -0,0 +1,111 @@
+import React, { PureComponent } from 'react';
+import { Switch } from 'app/core/components/Switch/Switch';
+import { Input } from 'app/core/components/Form';
+import { isValidTimeSpan } from 'app/core/utils/rangeutil';
+import { ValidationEvents } from 'app/types';
+import { EventsWithValidation } from 'app/core/components/Form/Input';
+import { PanelModel } from '../panel_model';
+import { InputStatus } from 'app/core/components/Form/Input';
+
+const timeRangeValidationEvents: ValidationEvents = {
+  [EventsWithValidation.onBlur]: [
+    {
+      rule: value => {
+        if (!value) {
+          return true;
+        }
+        return isValidTimeSpan(value);
+      },
+      errorMessage: 'Not a valid timespan',
+    },
+  ],
+};
+
+const emptyToNull = (value: string) => {
+  return value === '' ? null : value;
+};
+
+interface Props {
+  panel: PanelModel;
+}
+
+export class TimeRangeOptions extends PureComponent<Props> {
+  onOverrideTime = (evt, status: InputStatus) => {
+    const { value } = evt.target;
+    const { panel } = this.props;
+    const emptyToNullValue = emptyToNull(value);
+    if (status === InputStatus.Valid && panel.timeFrom !== emptyToNullValue) {
+      panel.timeFrom = emptyToNullValue;
+      panel.refresh();
+    }
+  };
+
+  onTimeShift = (evt, status: InputStatus) => {
+    const { value } = evt.target;
+    const { panel } = this.props;
+    const emptyToNullValue = emptyToNull(value);
+    if (status === InputStatus.Valid && panel.timeShift !== emptyToNullValue) {
+      panel.timeShift = emptyToNullValue;
+      panel.refresh();
+    }
+  };
+
+  onToggleTimeOverride = () => {
+    const { panel } = this.props;
+    panel.hideTimeOverride = !panel.hideTimeOverride;
+    panel.refresh();
+  };
+
+  render = () => {
+    const hideTimeOverride = this.props.panel.hideTimeOverride;
+    return (
+      <>
+        <h5 className="section-heading">Time Range</h5>
+
+        <div className="gf-form-group">
+          <div className="gf-form">
+            <span className="gf-form-label">
+              <i className="fa fa-clock-o" />
+            </span>
+
+            <span className="gf-form-label width-12">Override relative time</span>
+            <span className="gf-form-label width-6">Last</span>
+            <Input
+              type="text"
+              className="gf-form-input max-width-8"
+              placeholder="1h"
+              onBlur={this.onOverrideTime}
+              validationEvents={timeRangeValidationEvents}
+              hideErrorMessage={true}
+            />
+          </div>
+
+          <div className="gf-form">
+            <span className="gf-form-label">
+              <i className="fa fa-clock-o" />
+            </span>
+            <span className="gf-form-label width-12">Add time shift</span>
+            <span className="gf-form-label width-6">Amount</span>
+            <Input
+              type="text"
+              className="gf-form-input max-width-8"
+              placeholder="1h"
+              onBlur={this.onTimeShift}
+              validationEvents={timeRangeValidationEvents}
+              hideErrorMessage={true}
+            />
+          </div>
+
+          <div className="gf-form-inline">
+            <div className="gf-form">
+              <span className="gf-form-label">
+                <i className="fa fa-clock-o" />
+              </span>
+            </div>
+            <Switch label="Hide time override info" checked={hideTimeOverride} onChange={this.onToggleTimeOverride} />
+          </div>
+        </div>
+      </>
+    );
+  };
+}

+ 7 - 0
public/app/plugins/datasource/testdata/datasource.ts

@@ -84,6 +84,13 @@ class TestDataDatasource {
     }
     return this.$q.when(events);
   }
+
+  testDatasource() {
+    return Promise.resolve({
+      status: 'success',
+      message: 'Data source is working',
+    });
+  }
 }
 
 export { TestDataDatasource };

+ 4 - 1
public/sass/_variables.dark.scss

@@ -79,7 +79,7 @@ $brand-gradient: linear-gradient(
 );
 
 $page-gradient: linear-gradient(180deg, #222426 10px, rgb(22, 23, 25) 100px);
-$edit-gradient: linear-gradient(180deg, rgb(22, 23, 25) 00px, #090909 60%);
+$edit-gradient: linear-gradient(180deg, rgb(22, 23, 25) 50%, #090909);
 
 // Links
 // -------------------------
@@ -383,3 +383,6 @@ $panel-editor-viz-item-bg: $black;
 $panel-editor-tabs-line-color: #e3e3e3;
 $panel-editor-viz-item-bg-hover: darken($blue, 47%);
 $panel-editor-viz-item-bg-hover-active: darken($orange, 45%);
+
+$panel-grid-placeholder-bg: darken($blue, 47%);
+$panel-grid-placeholder-shadow: 0 0 4px $blue;

+ 3 - 0
public/sass/_variables.light.scss

@@ -393,3 +393,6 @@ $panel-editor-viz-item-bg: $white;
 $panel-editor-tabs-line-color: $dark-5;
 $panel-editor-viz-item-bg-hover: lighten($blue, 62%);
 $panel-editor-viz-item-bg-hover-active: lighten($orange, 34%);
+
+$panel-grid-placeholder-bg: lighten($blue, 62%);
+$panel-grid-placeholder-shadow: 0 0 4px $blue-light;

+ 7 - 0
public/sass/components/_dashboard_grid.scss

@@ -57,6 +57,13 @@
   }
 }
 
+.react-grid-item.react-grid-placeholder {
+  box-shadow: $panel-grid-placeholder-shadow;
+  background: $panel-grid-placeholder-bg;
+  z-index: 0;
+  opacity: unset;
+}
+
 .theme-dark {
   .react-grid-item > .react-resizable-handle::after {
     border-right: 2px solid $gray-1;

+ 1 - 0
public/sass/components/_dashboard_list.scss

@@ -12,6 +12,7 @@
   height: 35px;
   display: flex;
   justify-content: space-between;
+  align-items: center;
 
   .gf-form-button-row {
     padding-top: 0;

+ 0 - 13
public/sass/components/_gf-form.scss

@@ -141,19 +141,6 @@ $input-border: 1px solid $input-border-color;
   @include border-radius($label-border-radius-sm);
 }
 
-.gf-form-checkbox {
-  flex-shrink: 0;
-  padding: $input-padding-y $input-padding-x;
-  line-height: $input-line-height;
-
-  .checkbox-label {
-    display: inline;
-    cursor: pointer;
-    padding: $input-padding-y 0.4rem;
-    line-height: $input-line-height;
-  }
-}
-
 .gf-form-textarea {
   max-width: 650px;
 }

+ 1 - 6
public/sass/components/_panel_editor.scss

@@ -159,8 +159,6 @@
   transition: transform 1 ease;
 
   &:hover {
-    //background: $card-background-hover;
-    transform: scale(1.05);
     box-shadow: $panel-editor-viz-item-shadow-hover;
     background: $panel-editor-viz-item-bg-hover;
     border: $panel-editor-viz-item-border-hover;
@@ -171,7 +169,6 @@
     border: 1px solid $orange;
 
     &:hover {
-      transform: scale(1.05);
       box-shadow: 0 0 6px $orange;
       border: 1px solid $orange;
       background: $panel-editor-viz-item-bg-hover-active;
@@ -268,11 +265,9 @@
   height: 44px;
 
   &:hover {
-    background: $card-background-hover;
-    transform: scaleY(1.1);
-    box-shadow: $panel-editor-viz-item-shadow-hover;
     background: $panel-editor-viz-item-bg-hover;
     border: $panel-editor-viz-item-border-hover;
+    box-shadow: $panel-editor-viz-item-shadow-hover;
   }
 
   &--selected {

+ 7 - 18
public/sass/components/_switch.scss

@@ -78,6 +78,9 @@ input:checked + .gf-form-switch__slider::before {
   border: 1px solid $input-border-color;
   border-left: none;
   border-radius: $input-border-radius;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 
   input {
     opacity: 0;
@@ -88,25 +91,14 @@ input:checked + .gf-form-switch__slider::before {
   &--transparent {
     background: transparent;
     border: none;
-  }
-
-  &--search-result__section {
-    width: 3.05rem;
+    width: 20px;
     height: auto;
     position: relative;
-    top: -5px;
-    left: 3px;
-  }
-
-  &--search-result__item {
-    width: 2.7rem;
-    height: auto;
-    position: relative;
-    top: 3px;
+    padding-left: 7px;
   }
 
   &--table-cell {
-    width: 40px;
+    width: 20px;
     background: transparent;
     height: auto;
     border: none;
@@ -116,17 +108,14 @@ input:checked + .gf-form-switch__slider::before {
 }
 
 .gf-form-switch__checkbox {
-  position: absolute;
-  left: 16px;
   height: 16px;
   width: 16px;
   border-radius: 3px;
   border: $checkbox-border;
   background: $checkbox-bg;
-  top: 8px;
   display: flex;
-  justify-content: center;
   align-items: center;
+  justify-content: center;
 }
 
 input:checked + .gf-form-switch__checkbox::before {

+ 1 - 0
public/sass/pages/_dashboard.scss

@@ -25,6 +25,7 @@ div.flot-text {
     bottom: 0;
     right: 0;
     margin: 0;
+
     .panel-container {
       border: none;
       z-index: $zindex-sidemenu + 1;

+ 7 - 0
public/sass/utils/_utils.scss

@@ -82,3 +82,10 @@ button.close {
 .absolute {
   position: absolute;
 }
+
+.center-vh {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  justify-items: center;
+}