Merge branch '15217-panels-without-queries' into move-error-boundry

pull/15424/head
Peter Holmberg 6 years ago
commit f52aa4de4e
  1. 8
      CHANGELOG.md
  2. 3
      devenv/docker/blocks/elastic5/docker-compose.yaml
  3. 2
      package.json
  4. 4
      packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx
  5. 4
      packages/grafana-ui/src/components/PanelOptionsGroup/_PanelOptionsGroup.scss
  6. 6
      packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx
  7. 17
      packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx
  8. 2
      packages/grafana-ui/src/components/ThresholdsEditor/_ThresholdsEditor.scss
  9. 8
      packages/grafana-ui/src/utils/namedColorsPalette.test.ts
  10. 3
      packages/grafana-ui/src/utils/namedColorsPalette.ts
  11. 11
      pkg/metrics/metrics.go
  12. 2
      public/app/core/components/EmptyListCTA/EmptyListCTA.tsx
  13. 2
      public/app/core/components/EmptyListCTA/__snapshots__/EmptyListCTA.test.tsx.snap
  14. 2
      public/app/core/components/OrgActionBar/OrgActionBar.tsx
  15. 2
      public/app/core/components/OrgActionBar/__snapshots__/OrgActionBar.test.tsx.snap
  16. 2
      public/app/core/components/PermissionList/AddPermission.tsx
  17. 2
      public/app/core/components/SharedPreferences/SharedPreferences.tsx
  18. 13
      public/app/core/components/manage_dashboards/manage_dashboards.html
  19. 6
      public/app/core/utils/explore.test.ts
  20. 5
      public/app/core/utils/explore.ts
  21. 2
      public/app/features/admin/partials/edit_org.html
  22. 8
      public/app/features/admin/partials/edit_user.html
  23. 2
      public/app/features/admin/partials/new_user.html
  24. 2
      public/app/features/admin/partials/orgs.html
  25. 2
      public/app/features/admin/partials/users.html
  26. 2
      public/app/features/alerting/partials/notification_edit.html
  27. 3
      public/app/features/alerting/partials/notifications_list.html
  28. 8
      public/app/features/annotations/partials/editor.html
  29. 2
      public/app/features/annotations/partials/event_editor.html
  30. 6
      public/app/features/api-keys/ApiKeysPage.tsx
  31. 2
      public/app/features/api-keys/__snapshots__/ApiKeysPage.test.tsx.snap
  32. 2
      public/app/features/dashboard/components/DashExportModal/template.html
  33. 8
      public/app/features/dashboard/components/DashLinks/editor.html
  34. 4
      public/app/features/dashboard/components/DashboardPermissions/DashboardPermissions.tsx
  35. 6
      public/app/features/dashboard/components/DashboardSettings/template.html
  36. 2
      public/app/features/dashboard/components/ExportDataModal/template.html
  37. 2
      public/app/features/dashboard/components/RowOptions/template.html
  38. 2
      public/app/features/dashboard/components/SaveModals/SaveDashboardAsModalCtrl.ts
  39. 4
      public/app/features/dashboard/components/SaveModals/SaveDashboardModalCtrl.ts
  40. 2
      public/app/features/dashboard/components/SaveModals/SaveProvisionedDashboardModalCtrl.ts
  41. 2
      public/app/features/dashboard/components/ShareModal/template.html
  42. 6
      public/app/features/dashboard/components/TimePicker/template.html
  43. 2
      public/app/features/dashboard/components/UnsavedChangesModal/UnsavedChangesModalCtrl.ts
  44. 2
      public/app/features/dashboard/components/VersionHistory/template.html
  45. 3
      public/app/features/dashboard/dashgrid/DataPanel.tsx
  46. 62
      public/app/features/dashboard/dashgrid/PanelChrome.tsx
  47. 1
      public/app/features/datasources/settings/ButtonRow.test.tsx
  48. 10
      public/app/features/datasources/settings/ButtonRow.tsx
  49. 95
      public/app/features/datasources/settings/DataSourceSettingsPage.tsx
  50. 11
      public/app/features/datasources/settings/__snapshots__/ButtonRow.test.tsx.snap
  51. 4
      public/app/features/datasources/settings/__snapshots__/DataSourceSettingsPage.test.tsx.snap
  52. 2
      public/app/features/explore/GraphContainer.tsx
  53. 27
      public/app/features/explore/Logs.tsx
  54. 30
      public/app/features/explore/LogsContainer.tsx
  55. 2
      public/app/features/explore/TableContainer.tsx
  56. 9
      public/app/features/explore/state/actionTypes.ts
  57. 53
      public/app/features/explore/state/actions.ts
  58. 15
      public/app/features/explore/state/reducers.ts
  59. 12
      public/app/features/folders/FolderPermissions.tsx
  60. 2
      public/app/features/folders/FolderSettingsPage.tsx
  61. 4
      public/app/features/folders/__snapshots__/FolderSettingsPage.test.tsx.snap
  62. 2
      public/app/features/folders/partials/create_folder.html
  63. 2
      public/app/features/manage-dashboards/components/MoveToFolderModal/template.html
  64. 2
      public/app/features/manage-dashboards/components/UploadDashboard/uploadDashboardDirective.ts
  65. 2
      public/app/features/manage-dashboards/partials/dashboard_import.html
  66. 2
      public/app/features/org/OrgProfile.tsx
  67. 2
      public/app/features/org/__snapshots__/OrgProfile.test.tsx.snap
  68. 2
      public/app/features/org/partials/invite.html
  69. 2
      public/app/features/org/partials/newOrg.html
  70. 2
      public/app/features/org/partials/select_org.html
  71. 3
      public/app/features/panel/specs/metrics_panel_ctrl.test.ts
  72. 4
      public/app/features/playlist/partials/playlist.html
  73. 3
      public/app/features/playlist/partials/playlists.html
  74. 4
      public/app/features/plugins/partials/plugin_edit.html
  75. 2
      public/app/features/profile/partials/change_password.html
  76. 2
      public/app/features/profile/partials/profile.html
  77. 6
      public/app/features/teams/TeamGroupSync.tsx
  78. 6
      public/app/features/teams/TeamList.tsx
  79. 4
      public/app/features/teams/TeamMembers.tsx
  80. 2
      public/app/features/teams/TeamPages.tsx
  81. 2
      public/app/features/teams/TeamSettings.tsx
  82. 8
      public/app/features/teams/__snapshots__/TeamGroupSync.test.tsx.snap
  83. 550
      public/app/features/teams/__snapshots__/TeamList.test.tsx.snap
  84. 6
      public/app/features/teams/__snapshots__/TeamMembers.test.tsx.snap
  85. 22
      public/app/features/teams/__snapshots__/TeamPages.test.tsx.snap
  86. 2
      public/app/features/teams/__snapshots__/TeamSettings.test.tsx.snap
  87. 2
      public/app/features/teams/partials/create_team.html
  88. 8
      public/app/features/templating/partials/editor.html
  89. 4
      public/app/features/users/UsersActionBar.tsx
  90. 4
      public/app/features/users/__snapshots__/UsersActionBar.test.tsx.snap
  91. 2
      public/app/partials/confirm_modal.html
  92. 2
      public/app/partials/edit_json.html
  93. 2
      public/app/partials/login.html
  94. 6
      public/app/partials/reset_password.html
  95. 2
      public/app/partials/signup_invited.html
  96. 2
      public/app/partials/signup_step2.html
  97. 8
      public/app/types/explore.ts
  98. 86
      public/sass/_variables.dark.scss
  99. 100
      public/sass/_variables.light.scss
  100. 8
      public/sass/base/_type.scss
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,4 +1,6 @@
# 6.0.0-beta2 (unreleased)
# 6.0.0-beta3 (unreleased)
# 6.0.0-beta2 (2019-02-11)
### New Features
* **AzureMonitor**: Enable alerting by converting Azure Monitor API to Go [#14623](https://github.com/grafana/grafana/issues/14623)
@ -19,6 +21,10 @@
* **AzureMonitor**: improve autocomplete for Log Analytics and App Insights editor [#15131](https://github.com/grafana/grafana/issues/15131)
* **LDAP**: Fix IPA/FreeIPA v4.6.4 does not allow LDAP searches with empty attributes [#14432](https://github.com/grafana/grafana/issues/14432)
### Breaking changes
* **Internal Metrics** Edition has been added to the build_info metric. This will break any Graphite queries using this metric. Edition will be a new label for the Prometheus metric. [#15363](https://github.com/grafana/grafana/pull/15363)
### 6.0.0-beta1 fixes
* **Postgres**: Fix default port not added when port not configured [#15189](https://github.com/grafana/grafana/issues/15189)

@ -1,6 +1,3 @@
# You need to run 'sysctl -w vm.max_map_count=262144' on the host machine
version: '2'
services:
elasticsearch5:
image: elasticsearch:5
command: elasticsearch

@ -5,7 +5,7 @@
"company": "Grafana Labs"
},
"name": "grafana",
"version": "6.0.0-prebeta2",
"version": "6.0.0-pre3",
"repository": {
"type": "git",
"url": "http://github.com/grafana/grafana.git"

@ -69,8 +69,8 @@ export class AxisSelector extends React.PureComponent<AxisSelectorProps, AxisSel
}
render() {
const leftButtonClass = this.state.yaxis === 1 ? 'btn-success' : 'btn-inverse';
const rightButtonClass = this.state.yaxis === 2 ? 'btn-success' : 'btn-inverse';
const leftButtonClass = this.state.yaxis === 1 ? 'btn-primary' : 'btn-inverse';
const rightButtonClass = this.state.yaxis === 2 ? 'btn-primary' : 'btn-inverse';
return (
<div className="p-b-1">

@ -29,14 +29,14 @@
&:hover {
.panel-options-group__add-circle {
background-color: $btn-success-bg;
background-color: $btn-primary-bg;
color: $white;
}
}
}
.panel-options-group__add-circle {
@include gradientBar($btn-success-bg, $btn-success-bg-hl);
@include gradientBar($btn-success-bg, $btn-success-bg-hl, #fff);
border-radius: 50px;
width: 20px;

@ -1,4 +1,4 @@
import React from 'react';
import React, { ChangeEvent } from 'react';
import { shallow } from 'enzyme';
import { ThresholdsEditor, Props } from './ThresholdsEditor';
@ -118,7 +118,7 @@ describe('change threshold value', () => {
];
const instance = setup({ thresholds });
const mockEvent = { target: { value: 12 } };
const mockEvent = ({ target: { value: '12' } } as any) as ChangeEvent<HTMLInputElement>;
instance.onChangeThresholdValue(mockEvent, thresholds[0]);
@ -137,7 +137,7 @@ describe('change threshold value', () => {
thresholds,
};
const mockEvent = { target: { value: 78 } };
const mockEvent = ({ target: { value: '78' } } as any) as ChangeEvent<HTMLInputElement>;
instance.onChangeThresholdValue(mockEvent, thresholds[1]);

@ -1,4 +1,4 @@
import React, { PureComponent } from 'react';
import React, { PureComponent, ChangeEvent } from 'react';
import { Threshold } from '../../types';
import { ColorPicker } from '../ColorPicker/ColorPicker';
import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup';
@ -94,14 +94,15 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
);
};
onChangeThresholdValue = (event: any, threshold: Threshold) => {
onChangeThresholdValue = (event: ChangeEvent<HTMLInputElement>, threshold: Threshold) => {
if (threshold.index === 0) {
return;
}
const { thresholds } = this.state;
const parsedValue = parseInt(event.target.value, 10);
const value = isNaN(parsedValue) ? null : parsedValue;
const cleanValue = event.target.value.replace(/,/g, '.');
const parsedValue = parseFloat(cleanValue);
const value = isNaN(parsedValue) ? '' : parsedValue;
const newThresholds = thresholds.map(t => {
if (t === threshold && t.index !== 0) {
@ -164,16 +165,14 @@ export class ThresholdsEditor extends PureComponent<Props, State> {
<div className="thresholds-row-input-inner-color">
{threshold.color && (
<div className="thresholds-row-input-inner-color-colorpicker">
<ColorPicker
color={threshold.color}
onChange={color => this.onChangeThresholdColor(threshold, color)}
/>
<ColorPicker color={threshold.color} onChange={color => this.onChangeThresholdColor(threshold, color)} />
</div>
)}
</div>
<div className="thresholds-row-input-inner-value">
<input
type="text"
type="number"
step="0.0001"
onChange={event => this.onChangeThresholdValue(event, threshold)}
value={value}
onBlur={this.onBlur}

@ -21,7 +21,7 @@
}
.thresholds-row-add-button {
@include buttonBackground($btn-success-bg, $btn-success-bg-hl);
@include buttonBackground($btn-success-bg, $btn-success-bg-hl, #fff);
align-self: center;
margin-right: 5px;

@ -44,8 +44,8 @@ describe('colors', () => {
});
describe('getColorFromHexRgbOrName', () => {
it('returns undefined for unknown color', () => {
expect(() => getColorFromHexRgbOrName('aruba-sunshine')).toThrow();
it('returns black for unknown color', () => {
expect(getColorFromHexRgbOrName('aruba-sunshine')).toBe("#000000");
});
it('returns dark hex variant for known color if theme not specified', () => {
@ -64,5 +64,9 @@ describe('colors', () => {
expect(getColorFromHexRgbOrName('rgb(0,0,0)')).toBe('rgb(0,0,0)');
expect(getColorFromHexRgbOrName('rgba(0,0,0,1)')).toBe('rgba(0,0,0,1)');
});
it('returns hex for named color that is not a part of named colors palette', () => {
expect(getColorFromHexRgbOrName('lime')).toBe('#00ff00');
});
});
});

@ -1,5 +1,6 @@
import { flatten } from 'lodash';
import { GrafanaThemeType } from '../types';
import tinycolor from 'tinycolor2';
type Hue = 'green' | 'yellow' | 'red' | 'blue' | 'orange' | 'purple';
@ -106,7 +107,7 @@ export const getColorFromHexRgbOrName = (color: string, theme?: GrafanaThemeType
const colorDefinition = getColorByName(color);
if (!colorDefinition) {
throw new Error('Unknown color');
return new tinycolor(color).toHexString();
}
return theme ? colorDefinition.variants[theme] : colorDefinition.variants.dark;

@ -3,6 +3,8 @@ package metrics
import (
"runtime"
"github.com/grafana/grafana/pkg/setting"
"github.com/prometheus/client_golang/prometheus"
)
@ -282,7 +284,7 @@ func init() {
Name: "build_info",
Help: "A metric with a constant '1' value labeled by version, revision, branch, and goversion from which Grafana was built.",
Namespace: exporterName,
}, []string{"version", "revision", "branch", "goversion"})
}, []string{"version", "revision", "branch", "goversion", "edition"})
}
// SetBuildInformation sets the build information for this binary
@ -291,8 +293,13 @@ func SetBuildInformation(version, revision, branch string) {
// Once this have been released for some time we should be able to remote `M_Grafana_Version`
// The reason we added a new one is that its common practice in the prometheus community
// to name this metric `*_build_info` so its easy to do aggregation on all programs.
edition := "oss"
if setting.IsEnterprise {
edition = "enterprise"
}
M_Grafana_Version.WithLabelValues(version).Set(1)
grafanaBuildVersion.WithLabelValues(version, revision, branch, runtime.Version()).Set(1)
grafanaBuildVersion.WithLabelValues(version, revision, branch, runtime.Version(), edition).Set(1)
}
func initMetricVars() {

@ -20,7 +20,7 @@ class EmptyListCTA extends Component<Props, any> {
return (
<div className="empty-list-cta">
<div className="empty-list-cta__title">{title}</div>
<a onClick={onClick} href={buttonLink} className="empty-list-cta__button btn btn-xlarge btn-success">
<a onClick={onClick} href={buttonLink} className="empty-list-cta__button btn btn-xlarge btn-primary">
<i className={buttonIcon} />
{buttonTitle}
</a>

@ -10,7 +10,7 @@ exports[`EmptyListCTA renders correctly 1`] = `
Title
</div>
<a
className="empty-list-cta__button btn btn-xlarge btn-success"
className="empty-list-cta__button btn btn-xlarge btn-primary"
href="http://url/to/destination"
onClick={[MockFunction]}
>

@ -35,7 +35,7 @@ export default class OrgActionBar extends PureComponent<Props> {
<LayoutSelector mode={layoutMode} onLayoutModeChanged={(mode: LayoutMode) => onSetLayoutMode(mode)} />
</div>
<div className="page-action-bar__spacer" />
<a className="btn btn-success" {...linkProps}>
<a className="btn btn-primary" {...linkProps}>
{linkButton.title}
</a>
</div>

@ -29,7 +29,7 @@ exports[`Render should render component 1`] = `
className="page-action-bar__spacer"
/>
<a
className="btn btn-success"
className="btn btn-primary"
href="some/url"
target="_blank"
>

@ -130,7 +130,7 @@ class AddPermissions extends Component<Props, NewDashboardAclItem> {
</div>
<div className="gf-form">
<button data-save-permission className="btn btn-success" type="submit" disabled={!isValid}>
<button data-save-permission className="btn btn-primary" type="submit" disabled={!isValid}>
Save
</button>
</div>

@ -126,7 +126,7 @@ export class SharedPreferences extends PureComponent<Props, State> {
/>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success">
<button type="submit" className="btn btn-primary">
Save
</button>
</div>

@ -5,16 +5,13 @@
<i class="gf-form-input-icon fa fa-search"></i>
</label>
<div class="page-action-bar__spacer"></div>
<a class="btn btn-success" ng-href="{{ctrl.createDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
<i class="fa fa-plus"></i>
Dashboard
<a class="btn btn-primary" ng-href="{{ctrl.createDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
New Dashboard
</a>
<a class="btn btn-success" href="dashboards/folder/new" ng-if="!ctrl.folderId && ctrl.isEditor">
<i class="fa fa-plus"></i>
Folder
<a class="btn btn-inverse" href="dashboards/folder/new" ng-if="!ctrl.folderId && ctrl.isEditor">
New Folder
</a>
<a class="btn btn-success" href="{{ctrl.importDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
<i class="fa fa-plus"></i>
<a class="btn btn-inverse" href="{{ctrl.importDashboardUrl()}}" ng-if="ctrl.hasEditPermissionInFolders || ctrl.canSave">
Import
</a>
</div>

@ -8,6 +8,7 @@ import {
} from './explore';
import { ExploreUrlState } from 'app/types/explore';
import store from 'app/core/store';
import { LogsDedupStrategy } from 'app/core/logs_model';
const DEFAULT_EXPLORE_STATE: ExploreUrlState = {
datasource: null,
@ -17,6 +18,7 @@ const DEFAULT_EXPLORE_STATE: ExploreUrlState = {
showingGraph: true,
showingTable: true,
showingLogs: true,
dedupStrategy: LogsDedupStrategy.none,
}
};
@ -78,7 +80,7 @@ describe('state functions', () => {
expect(serializeStateToUrlParam(state)).toBe(
'{"datasource":"foo","queries":[{"expr":"metric{test=\\"a/b\\"}"},' +
'{"expr":"super{foo=\\"x/z\\"}"}],"range":{"from":"now-5h","to":"now"},' +
'"ui":{"showingGraph":true,"showingTable":true,"showingLogs":true}}'
'"ui":{"showingGraph":true,"showingTable":true,"showingLogs":true,"dedupStrategy":"none"}}'
);
});
@ -100,7 +102,7 @@ describe('state functions', () => {
},
};
expect(serializeStateToUrlParam(state, true)).toBe(
'["now-5h","now","foo",{"expr":"metric{test=\\"a/b\\"}"},{"expr":"super{foo=\\"x/z\\"}"},{"ui":[true,true,true]}]'
'["now-5h","now","foo",{"expr":"metric{test=\\"a/b\\"}"},{"expr":"super{foo=\\"x/z\\"}"},{"ui":[true,true,true,"none"]}]'
);
});
});

@ -21,6 +21,7 @@ import {
QueryIntervals,
QueryOptions,
} from 'app/types/explore';
import { LogsDedupStrategy } from 'app/core/logs_model';
export const DEFAULT_RANGE = {
from: 'now-6h',
@ -31,6 +32,7 @@ export const DEFAULT_UI_STATE = {
showingTable: true,
showingGraph: true,
showingLogs: true,
dedupStrategy: LogsDedupStrategy.none,
};
const MAX_HISTORY_ITEMS = 100;
@ -183,6 +185,7 @@ export function parseUrlState(initial: string | undefined): ExploreUrlState {
showingGraph: segment.ui[0],
showingLogs: segment.ui[1],
showingTable: segment.ui[2],
dedupStrategy: segment.ui[3],
};
}
});
@ -204,7 +207,7 @@ export function serializeStateToUrlParam(urlState: ExploreUrlState, compact?: bo
urlState.range.to,
urlState.datasource,
...urlState.queries,
{ ui: [!!urlState.ui.showingGraph, !!urlState.ui.showingLogs, !!urlState.ui.showingTable] },
{ ui: [!!urlState.ui.showingGraph, !!urlState.ui.showingLogs, !!urlState.ui.showingTable, urlState.ui.dedupStrategy] },
]);
}
return JSON.stringify(urlState);

@ -10,7 +10,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="update()" ng-show="!createMode">Update</button>
<button type="submit" class="btn btn-primary" ng-click="update()" ng-show="!createMode">Update</button>
</div>
</form>

@ -21,7 +21,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="update()" ng-show="!createMode">Update</button>
<button type="submit" class="btn btn-primary" ng-click="update()" ng-show="!createMode">Update</button>
</div>
</form>
@ -34,7 +34,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="setPassword()">Update</button>
<button type="submit" class="btn btn-primary" ng-click="setPassword()">Update</button>
</div>
</form>
@ -46,7 +46,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="updatePermissions()">Update</button>
<button type="submit" class="btn btn-primary" ng-click="updatePermissions()">Update</button>
</div>
</form>
@ -65,7 +65,7 @@
</span>
</div>
<div class="gf-form">
<button class="btn btn-success gf-form-btn" ng-click="addOrgUser()">Add</button>
<button class="btn btn-primary gf-form-btn" ng-click="addOrgUser()">Add</button>
</div>
</div>
</form>

@ -24,7 +24,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="create()">Create</button>
<button type="submit" class="btn btn-primary" ng-click="create()">Create</button>
</div>
</form>
</div>

@ -3,7 +3,7 @@
<div class="page-container page-body">
<div class="page-action-bar">
<div class="page-action-bar__spacer"></div>
<a class="page-header__cta btn btn-success" href="org/new">
<a class="page-header__cta btn btn-primary" href="org/new">
<i class="fa fa-plus"></i>
New Org
</a>

@ -7,7 +7,7 @@
<i class="gf-form-input-icon fa fa-search"></i>
</label>
<div class="page-action-bar__spacer"></div>
<a class="btn btn-success" href="admin/users/create">
<a class="btn btn-primary" href="admin/users/create">
<i class="fa fa-plus"></i>
Add new user
</a>

@ -68,7 +68,7 @@
</div>
<div class="gf-form-group gf-form-button-row">
<button type="submit" ng-click="ctrl.save()" class="btn btn-success width-7">Save</button>
<button type="submit" ng-click="ctrl.save()" class="btn btn-primary width-7">Save</button>
<button type="submit" ng-click="ctrl.testNotification()" class="btn btn-secondary width-7">Send Test</button>
<a href="alerting/notifications" class="btn btn-inverse">Back</a>
</div>

@ -7,8 +7,7 @@
<div class="page-action-bar__spacer">
</div>
<a href="alerting/notification/new" class="btn btn-success">
<i class="fa fa-plus"></i>
<a href="alerting/notification/new" class="btn btn-primary">
New Channel
</a>
</div>

@ -9,7 +9,7 @@
<div ng-if="ctrl.mode === 'list'">
<div class="page-action-bar" ng-if="ctrl.annotations.length > 1">
<div class="page-action-bar__spacer"></div>
<a type="button" class="btn btn-success" ng-click="ctrl.setupNew();"><i class="fa fa-plus" ></i> New</a>
<a type="button" class="btn btn-primary" ng-click="ctrl.setupNew();"><i class="fa fa-plus" ></i> New</a>
</div>
<table class="filter-table filter-table--hover">
@ -48,7 +48,7 @@
<div ng-if="ctrl.annotations.length === 1" class="p-t-2">
<div class="empty-list-cta">
<div class="empty-list-cta__title">There are no custom annotation queries added yet</div>
<a ng-click="ctrl.setupNew()" class="empty-list-cta__button btn btn-xlarge btn-success">
<a ng-click="ctrl.setupNew()" class="empty-list-cta__button btn btn-xlarge btn-primary">
<i class="gicon gicon-add-annotation"></i>
Add Annotation Query
</a>
@ -105,8 +105,8 @@
<div class="gf-form">
<div class="gf-form-button-row p-y-0">
<button ng-show="ctrl.mode === 'new'" type="button" class="btn gf-form-button btn-success" ng-click="ctrl.add()">Add</button>
<button ng-show="ctrl.mode === 'edit'" type="button" class="btn btn-success pull-left" ng-click="ctrl.update()">Update</button>
<button ng-show="ctrl.mode === 'new'" type="button" class="btn gf-form-button btn-primary" ng-click="ctrl.add()">Add</button>
<button ng-show="ctrl.mode === 'edit'" type="button" class="btn btn-primary pull-left" ng-click="ctrl.update()">Update</button>
</div>
</div>
</div>

@ -26,7 +26,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.save()">Save</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.save()">Save</button>
<button ng-if="ctrl.event.id" type="submit" class="btn btn-danger" ng-click="ctrl.delete()">Delete</button>
<a class="btn-text" ng-click="ctrl.close();">Cancel</a>
</div>

@ -169,7 +169,7 @@ export class ApiKeysPage extends PureComponent<Props, any> {
</span>
</div>
<div className="gf-form">
<button className="btn gf-form-btn btn-success">Add</button>
<button className="btn gf-form-btn btn-primary">Add</button>
</div>
</div>
</form>
@ -199,8 +199,8 @@ export class ApiKeysPage extends PureComponent<Props, any> {
</div>
<div className="page-action-bar__spacer" />
<button className="btn btn-success pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
<i className="fa fa-plus" /> Add API Key
<button className="btn btn-primary pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
Add API Key
</button>
</div>

@ -134,7 +134,7 @@ exports[`Render should render CTA if there are no API keys 1`] = `
className="gf-form"
>
<button
className="btn gf-form-btn btn-success"
className="btn gf-form-btn btn-primary"
>
Add
</button>

@ -12,7 +12,7 @@
</gf-form-switch>
<div class="gf-form-button-row">
<button type="button" class="btn gf-form-btn width-10 btn-success" ng-click="ctrl.saveDashboardAsFile()">
<button type="button" class="btn gf-form-btn width-10 btn-primary" ng-click="ctrl.saveDashboardAsFile()">
<i class="fa fa-save"></i> Save to file
</button>
<button type="button" class="btn gf-form-btn width-10 btn-secondary" ng-click="ctrl.viewJson()">

@ -10,7 +10,7 @@
<div class="empty-list-cta__title">
There are no dashboard links added yet
</div>
<a ng-click="ctrl.setupNew()" class="empty-list-cta__button btn btn-xlarge btn-success">
<a ng-click="ctrl.setupNew()" class="empty-list-cta__button btn btn-xlarge btn-primary">
<i class="gicon gicon-add-link"></i>
Add Dashboard Link
</a>
@ -26,7 +26,7 @@
<div ng-if="ctrl.dashboard.links.length > 0">
<div class="page-action-bar">
<div class="page-action-bar__spacer"></div>
<a type="button" class="btn btn-success" ng-click="ctrl.setupNew()">
<a type="button" class="btn btn-primary" ng-click="ctrl.setupNew()">
<i class="fa fa-plus"></i> New</a>
</div>
<table class="filter-table filter-table--hover">
@ -126,10 +126,10 @@
</div>
</div>
</div>
<button class="btn btn-success" ng-if="ctrl.mode == 'new'" ng-click="ctrl.addLink()">
<button class="btn btn-primary" ng-if="ctrl.mode == 'new'" ng-click="ctrl.addLink()">
Add
</button>
<button class="btn btn-success" ng-if="ctrl.mode == 'edit'" ng-click="ctrl.saveLink()">
<button class="btn btn-primary" ng-if="ctrl.mode == 'edit'" ng-click="ctrl.saveLink()">
Update
</button>
</div>

@ -76,9 +76,7 @@ export class DashboardPermissions extends PureComponent<Props, State> {
</div>
</Tooltip>
<div className="page-action-bar__spacer" />
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
<i className="fa fa-plus" /> Add Permission
</button>
<button className="btn btn-primary pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>Add Permission</button>
</div>
</div>
<SlideDown in={isAdding}>

@ -10,7 +10,7 @@
</a>
<div class="dashboard-settings__aside-actions">
<button class="btn btn-success" ng-click="ctrl.saveDashboard()" ng-show="ctrl.canSave">
<button class="btn btn-primary" ng-click="ctrl.saveDashboard()" ng-show="ctrl.canSave">
<i class="fa fa-save"></i> Save
</button>
<button class="btn btn-inverse" ng-click="ctrl.openSaveAsModal()" ng-show="ctrl.canSaveAs">
@ -100,7 +100,7 @@
</div>
<div class="gf-form-button-row">
<button class="btn btn-success" ng-click="ctrl.saveDashboardJson()" ng-show="ctrl.canSave">
<button class="btn btn-primary" ng-click="ctrl.saveDashboardJson()" ng-show="ctrl.canSave">
<i class="fa fa-save"></i> Save Changes
</button>
</div>
@ -128,7 +128,7 @@
<div class="dashboard-settings__content" ng-if="ctrl.viewId === 'make_editable'">
<h3 class="dashboard-settings__header">Make Editable</h3>
<button class="btn btn-success" ng-click="ctrl.makeEditable()">
<button class="btn btn-primary" ng-click="ctrl.makeEditable()">
Make Editable
</button>
</div>

@ -29,7 +29,7 @@
</div>
<div class="gf-form-button-row text-center">
<a class="btn btn-success" ng-click="ctrl.export();">Export</a>
<a class="btn btn-primary" ng-click="ctrl.export();">Export</a>
<a class="btn-text" ng-click="ctrl.dismiss();">Cancel</a>
</div>
</div>

@ -22,7 +22,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.update()">Update</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.update()">Update</button>
<button type="button" class="btn btn-inverse" ng-click="ctrl.dismiss()">Cancel</button>
</div>
</div>

@ -32,7 +32,7 @@ const template = `
</div>
<div class="gf-form-button-row text-center">
<button type="submit" class="btn btn-success" ng-click="ctrl.save()" ng-disabled="!ctrl.isValidFolderSelection">Save</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.save()" ng-disabled="!ctrl.isValidFolderSelection">Save</button>
<a class="btn-text" ng-click="ctrl.dismiss();">Cancel</a>
</div>
</form>

@ -52,8 +52,8 @@ const template = `
<button
id="saveBtn"
type="submit"
class="btn btn-success"
ng-class="{'btn-success--processing': ctrl.isSaving}"
class="btn btn-primary"
ng-class="{'btn-primary--processing': ctrl.isSaving}"
ng-disabled="ctrl.saveForm.$invalid || ctrl.isSaving"
>
<span ng-if="!ctrl.isSaving">Save</span>

@ -26,7 +26,7 @@ const template = `
<code-editor content="ctrl.dashboardJson" data-mode="json" data-max-lines=15></code-editor>
</div>
<div class="gf-form-button-row">
<button class="btn btn-success" clipboard-button="ctrl.getJsonForClipboard()">
<button class="btn btn-primary" clipboard-button="ctrl.getJsonForClipboard()">
<i class="fa fa-clipboard"></i>&nbsp;Copy JSON to Clipboard
</button>
<button class="btn btn-secondary" clipboard-button="ctrl.save()">

@ -163,7 +163,7 @@
</div>
<div ng-if="step === 1" class="gf-form-button-row">
<button class="btn gf-form-btn width-10 btn-success" ng-click="createSnapshot()" ng-disabled="loading">
<button class="btn gf-form-btn width-10 btn-primary" ng-click="createSnapshot()" ng-disabled="loading">
<i class="fa fa-save"></i>
Local Snapshot
</button>

@ -48,7 +48,7 @@
<input type="text" class="gf-form-input input-large" ng-model="ctrl.editTimeRaw.from" input-datetime>
</div>
<div class="gf-form">
<button class="btn gf-form-btn btn-primary" type="button" ng-click="openFromPicker=!openFromPicker">
<button class="btn gf-form-btn btn-secondary" type="button" ng-click="openFromPicker=!openFromPicker">
<i class="fa fa-calendar"></i>
</button>
</div>
@ -65,7 +65,7 @@
<input type="text" class="gf-form-input input-large" ng-model="ctrl.editTimeRaw.to" input-datetime>
</div>
<div class="gf-form">
<button class="btn gf-form-btn btn-primary" type="button" ng-click="openToPicker=!openToPicker">
<button class="btn gf-form-btn btn-secondary" type="button" ng-click="openToPicker=!openToPicker">
<i class="fa fa-calendar"></i>
</button>
</div>
@ -81,7 +81,7 @@
<select ng-model="ctrl.refresh.value" class="gf-form-input input-medium" ng-options="f.value as f.text for f in ctrl.refresh.options"></select>
</div>
<div class="gf-form">
<button type="submit" class="btn gf-form-btn btn-secondary" ng-click="ctrl.applyCustom();" ng-disabled="!timeForm.$valid">Apply</button>
<button type="submit" class="btn gf-form-btn btn-primary" ng-click="ctrl.applyCustom();" ng-disabled="!timeForm.$valid">Apply</button>
</div>
</div>
</form>

@ -20,7 +20,7 @@ const template = `
</div>
<div class="confirm-modal-buttons">
<button type="button" class="btn btn-success" ng-click="ctrl.save()">Save</button>
<button type="button" class="btn btn-primary" ng-click="ctrl.save()">Save</button>
<button type="button" class="btn btn-danger" ng-click="ctrl.discard()">Discard</button>
<button type="button" class="btn btn-inverse" ng-click="ctrl.dismiss()">Cancel</button>
</div>

@ -64,7 +64,7 @@
Show more versions
</button>
<button type="button"
class="btn btn-success"
class="btn btn-primary"
ng-if="ctrl.revisions.length > 1"
ng-disabled="!ctrl.canCompare"
ng-click="ctrl.getDiff(ctrl.diff)"

@ -24,7 +24,7 @@ interface RenderProps {
export interface Props {
datasource: string | null;
queries: any[];
panelId?: number;
panelId: number;
dashboardId?: number;
isVisible?: boolean;
timeRange?: TimeRange;
@ -46,7 +46,6 @@ export interface State {
export class DataPanel extends Component<Props, State> {
static defaultProps = {
isVisible: true,
panelId: 1,
dashboardId: 1,
};

@ -100,6 +100,25 @@ export class PanelChrome extends PureComponent<Props, State> {
return !this.props.dashboard.otherPanelInFullscreen(this.props.panel);
}
get hasPanelSnapshot() {
const { panel } = this.props;
return panel.snapshotData && panel.snapshotData.length;
}
get hasDataPanel() {
return !this.props.plugin.noQueries && !this.hasPanelSnapshot;
}
get getDataForPanel() {
const { panel, plugin } = this.props;
if (plugin.noQueries) {
return null;
}
return this.hasPanelSnapshot ? snapshotDataToPanelData(panel) : null;
}
renderPanelPlugin(loading: LoadingState, panelData: PanelData, width: number, height: number): JSX.Element {
const { panel, plugin } = this.props;
const { timeRange, renderCounter } = this.state;
@ -127,34 +146,29 @@ export class PanelChrome extends PureComponent<Props, State> {
);
}
renderHelper = (width: number, height: number): JSX.Element => {
const { panel, plugin } = this.props;
renderPanelBody = (width: number, height: number): JSX.Element => {
const { panel } = this.props;
const { refreshCounter, timeRange } = this.state;
const { datasource, targets } = panel;
return (
<>
{panel.snapshotData && panel.snapshotData.length > 0 ? (
this.renderPanelPlugin(LoadingState.Done, snapshotDataToPanelData(panel), width, height)
{this.hasDataPanel ? (
<DataPanel
panelId={panel.id}
datasource={datasource}
queries={targets}
timeRange={timeRange}
isVisible={this.isVisible}
widthPixels={width}
refreshCounter={refreshCounter}
onDataResponse={this.onDataResponse}
>
{({ loading, panelData }) => {
return this.renderPanelPlugin(loading, panelData, width, height);
}}
</DataPanel>
) : (
<>
{plugin.noQueries ? (
this.renderPanelPlugin(LoadingState.Done, null, width, height)
) : (
<DataPanel
datasource={datasource}
queries={targets}
timeRange={timeRange}
isVisible={this.isVisible}
widthPixels={width}
refreshCounter={refreshCounter}
onDataResponse={this.onDataResponse}
>
{({ loading, panelData }) => {
return this.renderPanelPlugin(loading, panelData, width, height);
}}
</DataPanel>
)}
</>
this.renderPanelPlugin(LoadingState.Done, this.getDataForPanel, width, height)
)}
</>
);
@ -199,7 +213,7 @@ export class PanelChrome extends PureComponent<Props, State> {
this.onError(error.message || DEFAULT_PLUGIN_ERROR);
return null;
}
return this.renderHelper(width, height);
return this.renderPanelBody(width, height);
}}
</ErrorBoundary>
</div>

@ -7,6 +7,7 @@ const setup = (propOverrides?: object) => {
isReadOnly: true,
onSubmit: jest.fn(),
onDelete: jest.fn(),
onTest: jest.fn(),
};
Object.assign(props, propOverrides);

@ -4,14 +4,20 @@ export interface Props {
isReadOnly: boolean;
onDelete: () => void;
onSubmit: (event) => void;
onTest: (event) => void;
}
const ButtonRow: FC<Props> = ({ isReadOnly, onDelete, onSubmit }) => {
const ButtonRow: FC<Props> = ({ isReadOnly, onDelete, onSubmit, onTest }) => {
return (
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success" disabled={isReadOnly} onClick={event => onSubmit(event)}>
<button type="submit" className="btn btn-primary" disabled={isReadOnly} onClick={event => onSubmit(event)}>
Save &amp; Test
</button>
{isReadOnly && (
<button type="submit" className="btn btn-success" onClick={onTest}>
Test
</button>
)}
<button type="submit" className="btn btn-danger" disabled={isReadOnly} onClick={onDelete}>
Delete
</button>

@ -72,6 +72,12 @@ export class DataSourceSettingsPage extends PureComponent<Props, State> {
this.testDataSource();
};
onTest = async (evt: React.FormEvent<HTMLFormElement>) => {
evt.preventDefault();
this.testDataSource();
};
onDelete = () => {
appEvents.emit('confirm-modal', {
title: 'Delete',
@ -180,52 +186,55 @@ export class DataSourceSettingsPage extends PureComponent<Props, State> {
return (
<Page navModel={navModel}>
<Page.Contents isLoading={!this.hasDataSource}>
{this.hasDataSource && <div className="page-container page-body">
<div>
<form onSubmit={this.onSubmit}>
{this.isReadOnly() && this.renderIsReadOnlyMessage()}
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
<BasicSettings
dataSourceName={dataSource.name}
isDefault={dataSource.isDefault}
onDefaultChange={state => setIsDefault(state)}
onNameChange={name => setDataSourceName(name)}
/>
{dataSourceMeta.module && (
<PluginSettings
dataSource={dataSource}
dataSourceMeta={dataSourceMeta}
onModelChange={this.onModelChange}
{this.hasDataSource && (
<div className="page-container page-body">
<div>
<form onSubmit={this.onSubmit}>
{this.isReadOnly() && this.renderIsReadOnlyMessage()}
{this.shouldRenderInfoBox() && <div className="grafana-info-box">{this.getInfoText()}</div>}
<BasicSettings
dataSourceName={dataSource.name}
isDefault={dataSource.isDefault}
onDefaultChange={state => setIsDefault(state)}
onNameChange={name => setDataSourceName(name)}
/>
)}
<div className="gf-form-group section">
{testingMessage && (
<div className={`alert-${testingStatus} alert`}>
<div className="alert-icon">
{testingStatus === 'error' ? (
<i className="fa fa-exclamation-triangle" />
) : (
<i className="fa fa-check" />
)}
</div>
<div className="alert-body">
<div className="alert-title">{testingMessage}</div>
</div>
</div>
{dataSourceMeta.module && (
<PluginSettings
dataSource={dataSource}
dataSourceMeta={dataSourceMeta}
onModelChange={this.onModelChange}
/>
)}
</div>
<ButtonRow
onSubmit={event => this.onSubmit(event)}
isReadOnly={this.isReadOnly()}
onDelete={this.onDelete}
/>
</form>
<div className="gf-form-group section">
{testingMessage && (
<div className={`alert-${testingStatus} alert`}>
<div className="alert-icon">
{testingStatus === 'error' ? (
<i className="fa fa-exclamation-triangle" />
) : (
<i className="fa fa-check" />
)}
</div>
<div className="alert-body">
<div className="alert-title">{testingMessage}</div>
</div>
</div>
)}
</div>
<ButtonRow
onSubmit={event => this.onSubmit(event)}
isReadOnly={this.isReadOnly()}
onDelete={this.onDelete}
onTest={event => this.onTest(event)}
/>
</form>
</div>
</div>
</div>}
)}
</Page.Contents>
</Page>
);

@ -5,13 +5,20 @@ exports[`Render should render component 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
disabled={true}
onClick={[Function]}
type="submit"
>
Save & Test
</button>
<button
className="btn btn-success"
onClick={[MockFunction]}
type="submit"
>
Test
</button>
<button
className="btn btn-danger"
disabled={true}
@ -34,7 +41,7 @@ exports[`Render should render with buttons enabled 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
disabled={false}
onClick={[Function]}
type="submit"

@ -97,6 +97,7 @@ exports[`Render should render alpha info text 1`] = `
isReadOnly={false}
onDelete={[Function]}
onSubmit={[Function]}
onTest={[Function]}
/>
</form>
</div>
@ -202,6 +203,7 @@ exports[`Render should render beta info text 1`] = `
isReadOnly={false}
onDelete={[Function]}
onSubmit={[Function]}
onTest={[Function]}
/>
</form>
</div>
@ -302,6 +304,7 @@ exports[`Render should render component 1`] = `
isReadOnly={false}
onDelete={[Function]}
onSubmit={[Function]}
onTest={[Function]}
/>
</form>
</div>
@ -407,6 +410,7 @@ exports[`Render should render is ready only message 1`] = `
isReadOnly={true}
onDelete={[Function]}
onSubmit={[Function]}
onTest={[Function]}
/>
</form>
</div>

@ -25,7 +25,7 @@ interface GraphContainerProps {
export class GraphContainer extends PureComponent<GraphContainerProps> {
onClickGraphButton = () => {
this.props.toggleGraph(this.props.exploreId);
this.props.toggleGraph(this.props.exploreId, this.props.showingGraph);
};
onChangeTime = (timeRange: TimeRange) => {

@ -58,14 +58,15 @@ interface Props {
range?: RawTimeRange;
scanning?: boolean;
scanRange?: RawTimeRange;
dedupStrategy: LogsDedupStrategy;
onChangeTime?: (range: RawTimeRange) => void;
onClickLabel?: (label: string, value: string) => void;
onStartScanning?: () => void;
onStopScanning?: () => void;
onDedupStrategyChange: (dedupStrategy: LogsDedupStrategy) => void;
}
interface State {
dedup: LogsDedupStrategy;
deferLogs: boolean;
hiddenLogLevels: Set<LogLevel>;
renderAll: boolean;
@ -79,7 +80,6 @@ export default class Logs extends PureComponent<Props, State> {
renderAllTimer: NodeJS.Timer;
state = {
dedup: LogsDedupStrategy.none,
deferLogs: true,
hiddenLogLevels: new Set(),
renderAll: false,
@ -112,12 +112,11 @@ export default class Logs extends PureComponent<Props, State> {
}
onChangeDedup = (dedup: LogsDedupStrategy) => {
this.setState(prevState => {
if (prevState.dedup === dedup) {
return { dedup: LogsDedupStrategy.none };
}
return { dedup };
});
const { onDedupStrategyChange } = this.props;
if (this.props.dedupStrategy === dedup) {
return onDedupStrategyChange(LogsDedupStrategy.none);
}
return onDedupStrategyChange(dedup);
};
onChangeLabels = (event: React.SyntheticEvent) => {
@ -173,17 +172,19 @@ export default class Logs extends PureComponent<Props, State> {
return null;
}
const { dedup, deferLogs, hiddenLogLevels, renderAll, showLocalTime, showUtc } = this.state;
const { deferLogs, hiddenLogLevels, renderAll, showLocalTime, showUtc, } = this.state;
let { showLabels } = this.state;
const { dedupStrategy } = this.props;
const hasData = data && data.rows && data.rows.length > 0;
const showDuplicates = dedup !== LogsDedupStrategy.none;
const showDuplicates = dedupStrategy !== LogsDedupStrategy.none;
// Filtering
const filteredData = filterLogLevels(data, hiddenLogLevels);
const dedupedData = dedupLogRows(filteredData, dedup);
const dedupedData = dedupLogRows(filteredData, dedupStrategy);
const dedupCount = dedupedData.rows.reduce((sum, row) => sum + row.duplicates, 0);
const meta = [...data.meta];
if (dedup !== LogsDedupStrategy.none) {
if (dedupStrategy !== LogsDedupStrategy.none) {
meta.push({
label: 'Dedup count',
value: dedupCount,
@ -236,7 +237,7 @@ export default class Logs extends PureComponent<Props, State> {
key={i}
value={dedupType}
onChange={this.onChangeDedup}
selected={dedup === dedupType}
selected={dedupStrategy === dedupType}
tooltip={LogsDedupDescription[dedupType]}
>
{dedupType}

@ -4,10 +4,10 @@ import { connect } from 'react-redux';
import { RawTimeRange, TimeRange } from '@grafana/ui';
import { ExploreId, ExploreItemState } from 'app/types/explore';
import { LogsModel } from 'app/core/logs_model';
import { LogsModel, LogsDedupStrategy } from 'app/core/logs_model';
import { StoreState } from 'app/types';
import { toggleLogs } from './state/actions';
import { toggleLogs, changeDedupStrategy } from './state/actions';
import Logs from './Logs';
import Panel from './Panel';
@ -25,12 +25,18 @@ interface LogsContainerProps {
scanRange?: RawTimeRange;
showingLogs: boolean;
toggleLogs: typeof toggleLogs;
changeDedupStrategy: typeof changeDedupStrategy;
dedupStrategy: LogsDedupStrategy;
width: number;
}
export class LogsContainer extends PureComponent<LogsContainerProps> {
onClickLogsButton = () => {
this.props.toggleLogs(this.props.exploreId);
this.props.toggleLogs(this.props.exploreId, this.props.showingLogs);
};
handleDedupStrategyChange = (dedupStrategy: LogsDedupStrategy) => {
this.props.changeDedupStrategy(this.props.exploreId, dedupStrategy);
};
render() {
@ -53,6 +59,7 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
return (
<Panel label="Logs" loading={loading} isOpen={showingLogs} onToggle={this.onClickLogsButton}>
<Logs
dedupStrategy={this.props.dedupStrategy || LogsDedupStrategy.none}
data={logsResult}
exploreId={exploreId}
key={logsResult && logsResult.id}
@ -62,6 +69,7 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
onClickLabel={onClickLabel}
onStartScanning={onStartScanning}
onStopScanning={onStopScanning}
onDedupStrategyChange={this.handleDedupStrategyChange}
range={range}
scanning={scanning}
scanRange={scanRange}
@ -72,11 +80,23 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
}
}
const selectItemUIState = (itemState: ExploreItemState) => {
const { showingGraph, showingLogs, showingTable, showingStartPage, dedupStrategy } = itemState;
return {
showingGraph,
showingLogs,
showingTable,
showingStartPage,
dedupStrategy,
};
};
function mapStateToProps(state: StoreState, { exploreId }) {
const explore = state.explore;
const item: ExploreItemState = explore[exploreId];
const { logsHighlighterExpressions, logsResult, queryTransactions, scanning, scanRange, showingLogs, range } = item;
const { logsHighlighterExpressions, logsResult, queryTransactions, scanning, scanRange, range } = item;
const loading = queryTransactions.some(qt => qt.resultType === 'Logs' && !qt.done);
const {showingLogs, dedupStrategy} = selectItemUIState(item);
return {
loading,
logsHighlighterExpressions,
@ -85,11 +105,13 @@ function mapStateToProps(state: StoreState, { exploreId }) {
scanRange,
showingLogs,
range,
dedupStrategy,
};
}
const mapDispatchToProps = {
toggleLogs,
changeDedupStrategy,
};
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(LogsContainer));

@ -21,7 +21,7 @@ interface TableContainerProps {
export class TableContainer extends PureComponent<TableContainerProps> {
onClickTableButton = () => {
this.props.toggleTable(this.props.exploreId);
this.props.toggleTable(this.props.exploreId, this.props.showingTable);
};
render() {

@ -192,6 +192,10 @@ export interface ToggleLogsPayload {
exploreId: ExploreId;
}
export interface UpdateUIStatePayload extends Partial<ExploreUIState>{
exploreId: ExploreId;
}
export interface UpdateDatasourceInstancePayload {
exploreId: ExploreId;
datasourceInstance: DataSourceApi;
@ -366,6 +370,11 @@ export const splitCloseAction = noPayloadActionCreatorFactory('explore/SPLIT_CLO
export const splitOpenAction = actionCreatorFactory<SplitOpenPayload>('explore/SPLIT_OPEN').create();
export const stateSaveAction = noPayloadActionCreatorFactory('explore/STATE_SAVE').create();
/**
* Update state of Explores UI elements (panels visiblity and deduplication strategy)
*/
export const updateUIStateAction = actionCreatorFactory<UpdateUIStatePayload>('explore/UPDATE_UI_STATE').create();
/**
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
*/

@ -67,14 +67,26 @@ import {
ToggleGraphPayload,
ToggleLogsPayload,
ToggleTablePayload,
updateUIStateAction,
} from './actionTypes';
import { ActionOf, ActionCreator } from 'app/core/redux/actionCreatorFactory';
import { LogsDedupStrategy } from 'app/core/logs_model';
type ThunkResult<R> = ThunkAction<R, StoreState, undefined, Action>;
// /**
// * Adds a query row after the row with the given index.
// */
/**
* Updates UI state and save it to the URL
*/
const updateExploreUIState = (exploreId, uiStateFragment: Partial<ExploreUIState>) => {
return dispatch => {
dispatch(updateUIStateAction({ exploreId, ...uiStateFragment }));
dispatch(stateSave());
};
};
/**
* Adds a query row after the row with the given index.
*/
export function addQueryRow(exploreId: ExploreId, index: number): ActionOf<AddQueryRowPayload> {
const query = generateEmptyQuery(index + 1);
return addQueryRowAction({ exploreId, index, query });
@ -669,6 +681,7 @@ export function stateSave() {
showingGraph: left.showingGraph,
showingLogs: left.showingLogs,
showingTable: left.showingTable,
dedupStrategy: left.dedupStrategy,
},
};
urlStates.left = serializeStateToUrlParam(leftUrlState, true);
@ -677,7 +690,12 @@ export function stateSave() {
datasource: right.datasourceInstance.name,
queries: right.queries.map(clearQueryKeys),
range: right.range,
ui: { showingGraph: right.showingGraph, showingLogs: right.showingLogs, showingTable: right.showingTable },
ui: {
showingGraph: right.showingGraph,
showingLogs: right.showingLogs,
showingTable: right.showingTable,
dedupStrategy: right.dedupStrategy,
},
};
urlStates.right = serializeStateToUrlParam(rightUrlState, true);
@ -696,24 +714,26 @@ const togglePanelActionCreator = (
| ActionCreator<ToggleGraphPayload>
| ActionCreator<ToggleLogsPayload>
| ActionCreator<ToggleTablePayload>
) => (exploreId: ExploreId) => {
return (dispatch, getState) => {
let shouldRunQueries;
dispatch(actionCreator({ exploreId }));
dispatch(stateSave());
) => (exploreId: ExploreId, isPanelVisible: boolean) => {
return dispatch => {
let uiFragmentStateUpdate: Partial<ExploreUIState>;
const shouldRunQueries = !isPanelVisible;
switch (actionCreator.type) {
case toggleGraphAction.type:
shouldRunQueries = getState().explore[exploreId].showingGraph;
uiFragmentStateUpdate = { showingGraph: !isPanelVisible };
break;
case toggleLogsAction.type:
shouldRunQueries = getState().explore[exploreId].showingLogs;
uiFragmentStateUpdate = { showingLogs: !isPanelVisible };
break;
case toggleTableAction.type:
shouldRunQueries = getState().explore[exploreId].showingTable;
uiFragmentStateUpdate = { showingTable: !isPanelVisible };
break;
}
dispatch(actionCreator({ exploreId }));
dispatch(updateExploreUIState(exploreId, uiFragmentStateUpdate));
if (shouldRunQueries) {
dispatch(runQueries(exploreId));
}
@ -734,3 +754,12 @@ export const toggleLogs = togglePanelActionCreator(toggleLogsAction);
* Expand/collapse the table result viewer. When collapsed, table queries won't be run.
*/
export const toggleTable = togglePanelActionCreator(toggleTableAction);
/**
* Change logs deduplication strategy and update URL.
*/
export const changeDedupStrategy = (exploreId, dedupStrategy: LogsDedupStrategy) => {
return dispatch => {
dispatch(updateExploreUIState(exploreId, { dedupStrategy }));
};
};

@ -37,6 +37,7 @@ import {
toggleLogsAction,
toggleTableAction,
queriesImportedAction,
updateUIStateAction,
} from './actionTypes';
export const DEFAULT_RANGE = {
@ -406,6 +407,12 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
};
},
})
.addMapper({
filter: updateUIStateAction,
mapper: (state, action): ExploreItemState => {
return { ...state, ...action.payload };
},
})
.addMapper({
filter: toggleGraphAction,
mapper: (state): ExploreItemState => {
@ -415,7 +422,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
// Discard transactions related to Graph query
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Graph');
}
return { ...state, queryTransactions: nextQueryTransactions, showingGraph };
return { ...state, queryTransactions: nextQueryTransactions };
},
})
.addMapper({
@ -427,7 +434,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
// Discard transactions related to Logs query
nextQueryTransactions = state.queryTransactions.filter(qt => qt.resultType !== 'Logs');
}
return { ...state, queryTransactions: nextQueryTransactions, showingLogs };
return { ...state, queryTransactions: nextQueryTransactions };
},
})
.addMapper({
@ -435,7 +442,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
mapper: (state): ExploreItemState => {
const showingTable = !state.showingTable;
if (showingTable) {
return { ...state, showingTable, queryTransactions: state.queryTransactions };
return { ...state, queryTransactions: state.queryTransactions };
}
// Toggle off needs discarding of table queries and results
@ -446,7 +453,7 @@ export const itemReducer = reducerFactory<ExploreItemState>({} as ExploreItemSta
state.queryIntervals.intervalMs
);
return { ...state, ...results, queryTransactions: nextQueryTransactions, showingTable };
return { ...state, ...results, queryTransactions: nextQueryTransactions };
},
})
.addMapper({

@ -73,7 +73,13 @@ export class FolderPermissions extends PureComponent<Props, State> {
const { isAdding } = this.state;
if (folder.id === 0) {
return <Page navModel={navModel}><Page.Contents isLoading={true}><span></span></Page.Contents></Page>;
return (
<Page navModel={navModel}>
<Page.Contents isLoading={true}>
<span />
</Page.Contents>
</Page>
);
}
const folderInfo = { title: folder.title, url: folder.url, id: folder.id };
@ -89,8 +95,8 @@ export class FolderPermissions extends PureComponent<Props, State> {
</div>
</Tooltip>
<div className="page-action-bar__spacer" />
<button className="btn btn-success pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
<i className="fa fa-plus" /> Add Permission
<button className="btn btn-primary pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
Add Permission
</button>
</div>
<SlideDown in={isAdding}>

@ -82,7 +82,7 @@ export class FolderSettingsPage extends PureComponent<Props, State> {
/>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success" disabled={!folder.canSave || !folder.hasChanged}>
<button type="submit" className="btn btn-primary" disabled={!folder.canSave || !folder.hasChanged}>
<i className="fa fa-save" /> Save
</button>
<button className="btn btn-danger" onClick={this.onDelete} disabled={!folder.canSave}>

@ -41,7 +41,7 @@ exports[`Render should enable save button 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
disabled={false}
type="submit"
>
@ -109,7 +109,7 @@ exports[`Render should render component 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
disabled={true}
type="submit"
>

@ -25,7 +25,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success width-12" ng-disabled="!ctrl.titleTouched || ctrl.hasValidationError">
<button type="submit" class="btn btn-primary width-12" ng-disabled="!ctrl.titleTouched || ctrl.hasValidationError">
<i class="fa fa-save"></i> Create
</button>
</div>

@ -26,7 +26,7 @@
</div>
</div>
<div class="gf-form-button-row text-center">
<button type="submit" class="btn btn-success" ng-disabled="ctrl.saveForm.$invalid || !ctrl.isValidFolderSelection">Move</button>
<button type="submit" class="btn btn-primary" ng-disabled="ctrl.saveForm.$invalid || !ctrl.isValidFolderSelection">Move</button>
<a class="btn-text" ng-click="ctrl.dismiss();">Cancel</a>
</div>
</form>

@ -4,7 +4,7 @@ import angular from 'angular';
const template = `
<input type="file" id="dashupload" name="dashupload" class="hide" onchange="angular.element(this).scope().file_selected"/>
<label class="btn btn-success" for="dashupload">
<label class="btn btn-primary" for="dashupload">
<i class="fa fa-upload"></i>
{{btnText}}
</label>

@ -146,7 +146,7 @@
</div>
<div class="gf-form-button-row">
<button type="button" class="btn btn-success width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists || ctrl.uidExists" ng-disabled="!ctrl.isValid()">
<button type="button" class="btn btn-primary width-12" ng-click="ctrl.saveDashboard()" ng-hide="ctrl.nameExists || ctrl.uidExists" ng-disabled="!ctrl.isValid()">
<i class="fa fa-save"></i> Import
</button>
<button type="button" class="btn btn-danger width-12" ng-click="ctrl.saveDashboard()" ng-show="ctrl.nameExists || ctrl.uidExists" ng-disabled="!ctrl.isValid()">

@ -32,7 +32,7 @@ const OrgProfile: FC<Props> = ({ onSubmit, onOrgNameChange, orgName }) => {
</div>
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success">
<button type="submit" className="btn btn-primary">
Save
</button>
</div>

@ -35,7 +35,7 @@ exports[`Render should render component 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
type="submit"
>
Save

@ -28,7 +28,7 @@
<gf-form-switch class="gf-form" label="Send invite email" checked="ctrl.invite.sendEmail" label-class="width-10"></gf-form-switch>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.sendInvite();">Invite</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.sendInvite();">Invite</button>
<a class="btn btn-inverse" href="org/users">Back</a>
</div>
</form>

@ -15,7 +15,7 @@
</div>
<br>
<div class="gf-form-buttons-row">
<button type="submit" class="btn btn-success" ng-click="createOrg()">Create</button>
<button type="submit" class="btn btn-primary" ng-click="createOrg()">Create</button>
</div>
</div>
</form>

@ -14,7 +14,7 @@
<div style="display: inline-block; width: 400px; margin: 30px 0">
<div ng-repeat="org in orgs">
<a ng-click="setUsingOrg(org)" class="btn btn-success">
<a ng-click="setUsingOrg(org)" class="btn btn-primary">
{{org.name}} ({{org.role}})
</a>
</div>

@ -1,6 +1,9 @@
jest.mock('app/core/core', () => ({}));
jest.mock('app/core/config', () => {
return {
bootData: {
user: {},
},
panels: {
test: {
id: 'test',

@ -95,8 +95,8 @@
<div class="clearfix"></div>
<div class="gf-form-button-row">
<a class="btn btn-success" ng-show="ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create</a>
<a class="btn btn-success" ng-show="!ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
<a class="btn btn-primary" ng-show="ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Create</a>
<a class="btn btn-primary" ng-show="!ctrl.isNew" ng-disabled="ctrl.playlistEditForm.$invalid || ctrl.isPlaylistEmpty()" ng-click="ctrl.savePlaylist(ctrl.playlist, ctrl.playlistItems)">Save</a>
<a class="btn-text" ng-click="ctrl.backToList()">Cancel</a>
</div>
</div>

@ -4,8 +4,7 @@
<div ng-if="ctrl.playlists.length > 0">
<div class="page-action-bar">
<div class="page-action-bar__spacer"></div>
<a class="btn btn-success pull-right" href="playlists/create">
<i class="fa fa-plus"></i>
<a class="btn btn-primary pull-right" href="playlists/create">
New Playlist
</a>
</div>

@ -13,8 +13,8 @@
<plugin-component type="app-config-ctrl"></plugin-component>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.enable()" ng-show="!ctrl.model.enabled">Enable</button>
<button type="submit" class="btn btn-success" ng-click="ctrl.update()" ng-show="ctrl.model.enabled">Update</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.enable()" ng-show="!ctrl.model.enabled">Enable</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.update()" ng-show="ctrl.model.enabled">Update</button>
<button type="submit" class="btn btn-danger" ng-click="ctrl.disable()" ng-show="ctrl.model.enabled">Disable</button>
</div>
</div>

@ -26,7 +26,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="changePassword()">Change Password</button>
<button type="submit" class="btn btn-primary" ng-click="changePassword()">Change Password</button>
<a class="btn-text" href="profile">Cancel</a>
</div>
</form>

@ -20,7 +20,7 @@
<i ng-if="ctrl.readonlyLoginFields" class="fa fa-lock gf-form-icon--right-absolute" bs-tooltip="'Login Details Locked - managed in another system.'"></i>
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="ctrl.update()">Save</button>
<button type="submit" class="btn btn-primary" ng-click="ctrl.update()">Save</button>
</div>
</form>

@ -84,7 +84,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
</Tooltip>
<div className="page-action-bar__spacer" />
{groups.length > 0 && (
<button className="btn btn-success pull-right" onClick={this.onToggleAdding}>
<button className="btn btn-primary pull-right" onClick={this.onToggleAdding}>
<i className="fa fa-plus" /> Add group
</button>
)}
@ -108,7 +108,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
</div>
<div className="gf-form">
<button className="btn btn-success gf-form-btn" type="submit" disabled={!this.isNewGroupValid()}>
<button className="btn btn-primary gf-form-btn" type="submit" disabled={!this.isNewGroupValid()}>
Add group
</button>
</div>
@ -120,7 +120,7 @@ export class TeamGroupSync extends PureComponent<Props, State> {
!isAdding && (
<div className="empty-list-cta">
<div className="empty-list-cta__title">There are no external groups to sync with</div>
<button onClick={this.onToggleAdding} className="empty-list-cta__button btn btn-xlarge btn-success">
<button onClick={this.onToggleAdding} className="empty-list-cta__button btn btn-xlarge btn-primary">
<i className="gicon gicon-add-team" />
Add Group
</button>

@ -86,7 +86,7 @@ export class TeamList extends PureComponent<Props, any> {
const { teams, searchQuery } = this.props;
return (
<div className="page-container page-body">
<>
<div className="page-action-bar">
<div className="gf-form gf-form--grow">
<label className="gf-form--has-input-icon gf-form--grow">
@ -103,7 +103,7 @@ export class TeamList extends PureComponent<Props, any> {
<div className="page-action-bar__spacer" />
<a className="btn btn-success" href="org/teams/new">
<a className="btn btn-primary" href="org/teams/new">
New team
</a>
</div>
@ -122,7 +122,7 @@ export class TeamList extends PureComponent<Props, any> {
<tbody>{teams.map(team => this.renderTeam(team))}</tbody>
</table>
</div>
</div>
</>
);
}

@ -103,7 +103,7 @@ export class TeamMembers extends PureComponent<Props, State> {
<div className="page-action-bar__spacer" />
<button className="btn btn-success pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
<button className="btn btn-primary pull-right" onClick={this.onToggleAdding} disabled={isAdding}>
<i className="fa fa-plus" /> Add a member
</button>
</div>
@ -117,7 +117,7 @@ export class TeamMembers extends PureComponent<Props, State> {
<div className="gf-form-inline">
<UserPicker onSelected={this.onUserSelected} className="min-width-30" />
{this.state.newTeamMember && (
<button className="btn btn-success gf-form-btn" type="submit" onClick={this.onAddUserToTeam}>
<button className="btn btn-primary gf-form-btn" type="submit" onClick={this.onAddUserToTeam}>
Add to team
</button>
)}

@ -84,7 +84,7 @@ export class TeamPages extends PureComponent<Props, State> {
return (
<Page navModel={navModel}>
<Page.Contents isLoading={this.state.isLoading}>
{team && Object.keys(team).length !== 0 && <div className="page-container page-body">{this.renderPage()}</div>}
{team && Object.keys(team).length !== 0 && this.renderPage()}
</Page.Contents>
</Page>
);

@ -75,7 +75,7 @@ export class TeamSettings extends React.Component<Props, State> {
</div>
<div className="gf-form-button-row">
<button type="submit" className="btn btn-success">
<button type="submit" className="btn btn-primary">
Update
</button>
</div>

@ -62,7 +62,7 @@ exports[`Render should render component 1`] = `
className="gf-form"
>
<button
className="btn btn-success gf-form-btn"
className="btn btn-primary gf-form-btn"
disabled={true}
type="submit"
>
@ -81,7 +81,7 @@ exports[`Render should render component 1`] = `
There are no external groups to sync with
</div>
<button
className="empty-list-cta__button btn btn-xlarge btn-success"
className="empty-list-cta__button btn btn-xlarge btn-primary"
onClick={[Function]}
>
<i
@ -135,7 +135,7 @@ exports[`Render should render groups table 1`] = `
className="page-action-bar__spacer"
/>
<button
className="btn btn-success pull-right"
className="btn btn-primary pull-right"
onClick={[Function]}
>
<i
@ -180,7 +180,7 @@ exports[`Render should render groups table 1`] = `
className="gf-form"
>
<button
className="btn btn-success gf-form-btn"
className="btn btn-primary gf-form-btn"
disabled={true}
type="submit"
>

@ -36,320 +36,316 @@ exports[`Render should render teams table 1`] = `
isLoading={false}
>
<div
className="page-container page-body"
className="page-action-bar"
>
<div
className="page-action-bar"
className="gf-form gf-form--grow"
>
<div
className="gf-form gf-form--grow"
<label
className="gf-form--has-input-icon gf-form--grow"
>
<label
className="gf-form--has-input-icon gf-form--grow"
>
<input
className="gf-form-input"
onChange={[Function]}
placeholder="Search teams"
type="text"
value=""
/>
<i
className="gf-form-input-icon fa fa-search"
/>
</label>
</div>
<div
className="page-action-bar__spacer"
/>
<a
className="btn btn-success"
href="org/teams/new"
>
New team
</a>
<input
className="gf-form-input"
onChange={[Function]}
placeholder="Search teams"
type="text"
value=""
/>
<i
className="gf-form-input-icon fa fa-search"
/>
</label>
</div>
<div
className="admin-list-table"
className="page-action-bar__spacer"
/>
<a
className="btn btn-primary"
href="org/teams/new"
>
<table
className="filter-table filter-table--hover form-inline"
>
<thead>
<tr>
<th />
<th>
Name
</th>
<th>
Email
</th>
<th>
Members
</th>
<th
style={
Object {
"width": "1%",
}
New team
</a>
</div>
<div
className="admin-list-table"
>
<table
className="filter-table filter-table--hover form-inline"
>
<thead>
<tr>
<th />
<th>
Name
</th>
<th>
Email
</th>
<th>
Members
</th>
<th
style={
Object {
"width": "1%",
}
/>
</tr>
</thead>
<tbody>
<tr
key="1"
}
/>
</tr>
</thead>
<tbody>
<tr
key="1"
>
<td
className="width-4 text-center link-td"
>
<td
className="width-4 text-center link-td"
<a
href="org/teams/edit/1"
>
<a
href="org/teams/edit/1"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/1"
>
<a
href="org/teams/edit/1"
>
test-1
</a>
</td>
<td
className="link-td"
test-1
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/1"
>
<a
href="org/teams/edit/1"
>
test-1@test.com
</a>
</td>
<td
className="link-td"
test-1@test.com
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/1"
>
<a
href="org/teams/edit/1"
>
1
</a>
</td>
<td
className="text-right"
1
</a>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
<tr
key="2"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/2"
>
<DeleteButton
onConfirm={[Function]}
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
</tr>
<tr
key="2"
</a>
</td>
<td
className="link-td"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/2"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
<a
href="org/teams/edit/2"
>
<a
href="org/teams/edit/2"
>
test-2
</a>
</td>
<td
className="link-td"
test-2
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/2"
>
<a
href="org/teams/edit/2"
>
test-2@test.com
</a>
</td>
<td
className="link-td"
test-2@test.com
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/2"
>
<a
href="org/teams/edit/2"
>
2
</a>
</td>
<td
className="text-right"
2
</a>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
<tr
key="3"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/3"
>
<DeleteButton
onConfirm={[Function]}
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
</tr>
<tr
key="3"
</a>
</td>
<td
className="link-td"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/3"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
<a
href="org/teams/edit/3"
>
<a
href="org/teams/edit/3"
>
test-3
</a>
</td>
<td
className="link-td"
test-3
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/3"
>
<a
href="org/teams/edit/3"
>
test-3@test.com
</a>
</td>
<td
className="link-td"
test-3@test.com
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/3"
>
<a
href="org/teams/edit/3"
>
3
</a>
</td>
<td
className="text-right"
3
</a>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
<tr
key="4"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/4"
>
<DeleteButton
onConfirm={[Function]}
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
</tr>
<tr
key="4"
</a>
</td>
<td
className="link-td"
>
<td
className="width-4 text-center link-td"
<a
href="org/teams/edit/4"
>
<a
href="org/teams/edit/4"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/4"
>
test-4
</a>
</td>
<td
className="link-td"
test-4
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/4"
>
<a
href="org/teams/edit/4"
>
test-4@test.com
</a>
</td>
<td
className="link-td"
test-4@test.com
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/4"
>
<a
href="org/teams/edit/4"
>
4
</a>
</td>
<td
className="text-right"
4
</a>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
<tr
key="5"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/5"
>
<DeleteButton
onConfirm={[Function]}
<img
className="filter-table__avatar"
src="some/url/"
/>
</td>
</tr>
<tr
key="5"
</a>
</td>
<td
className="link-td"
>
<td
className="width-4 text-center link-td"
>
<a
href="org/teams/edit/5"
>
<img
className="filter-table__avatar"
src="some/url/"
/>
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/5"
>
test-5
</a>
</td>
<td
className="link-td"
<a
href="org/teams/edit/5"
>
<a
href="org/teams/edit/5"
>
test-5@test.com
</a>
</td>
<td
className="link-td"
test-5
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/5"
>
<a
href="org/teams/edit/5"
>
5
</a>
</td>
<td
className="text-right"
test-5@test.com
</a>
</td>
<td
className="link-td"
>
<a
href="org/teams/edit/5"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
</tbody>
</table>
</div>
5
</a>
</td>
<td
className="text-right"
>
<DeleteButton
onConfirm={[Function]}
/>
</td>
</tr>
</tbody>
</table>
</div>
</PageContents>
</Page>

@ -27,7 +27,7 @@ exports[`Render should render component 1`] = `
className="page-action-bar__spacer"
/>
<button
className="btn btn-success pull-right"
className="btn btn-primary pull-right"
disabled={false}
onClick={[Function]}
>
@ -121,7 +121,7 @@ exports[`Render should render team members 1`] = `
className="page-action-bar__spacer"
/>
<button
className="btn btn-success pull-right"
className="btn btn-primary pull-right"
disabled={false}
onClick={[Function]}
>
@ -341,7 +341,7 @@ exports[`Render should render team members when sync enabled 1`] = `
className="page-action-bar__spacer"
/>
<button
className="btn btn-success pull-right"
className="btn btn-primary pull-right"
disabled={false}
onClick={[Function]}
>

@ -17,11 +17,7 @@ exports[`Render should render group sync page 1`] = `
<PageContents
isLoading={true}
>
<div
className="page-container page-body"
>
<Connect(TeamGroupSync) />
</div>
<Connect(TeamGroupSync) />
</PageContents>
</Page>
`;
@ -33,13 +29,9 @@ exports[`Render should render member page if team not empty 1`] = `
<PageContents
isLoading={true}
>
<div
className="page-container page-body"
>
<Connect(TeamMembers)
syncEnabled={true}
/>
</div>
<Connect(TeamMembers)
syncEnabled={true}
/>
</PageContents>
</Page>
`;
@ -51,11 +43,7 @@ exports[`Render should render settings and preferences page 1`] = `
<PageContents
isLoading={true}
>
<div
className="page-container page-body"
>
<Connect(TeamSettings) />
</div>
<Connect(TeamSettings) />
</PageContents>
</Page>
`;

@ -46,7 +46,7 @@ exports[`Render should render component 1`] = `
className="gf-form-button-row"
>
<button
className="btn btn-success"
className="btn btn-primary"
type="submit"
>
Update

@ -18,7 +18,7 @@
<input class="gf-form-input max-width-22" type="email" ng-model="ctrl.email" placeholder="email@test.com">
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success width-12">
<button type="submit" class="btn btn-primary width-12">
<i class="fa fa-save"></i> Create
</button>
</div>

@ -11,7 +11,7 @@
<div ng-if="variables.length === 0">
<div class="empty-list-cta">
<div class="empty-list-cta__title">There are no variables added yet</div>
<a ng-click="setMode('new')" class="empty-list-cta__button btn btn-xlarge btn-success">
<a ng-click="setMode('new')" class="empty-list-cta__button btn btn-xlarge btn-primary">
<i class="gicon gicon-add-variable"></i>
Add variable
</a>
@ -34,7 +34,7 @@
<div ng-if="variables.length">
<div class="page-action-bar">
<div class="page-action-bar__spacer"></div>
<a type="button" class="btn btn-success" ng-click="setMode('new');"><i class="fa fa-plus"></i> New</a>
<a type="button" class="btn btn-primary" ng-click="setMode('new');"><i class="fa fa-plus"></i> New</a>
</div>
<table class="filter-table filter-table--hover">
@ -317,8 +317,8 @@
</div>
<div class="gf-form-button-row p-y-0">
<button type="submit" class="btn btn-success" ng-show="mode === 'edit'" ng-click="update();">Update</button>
<button type="submit" class="btn btn-success" ng-show="mode === 'new'" ng-click="add();">Add</button>
<button type="submit" class="btn btn-primary" ng-show="mode === 'edit'" ng-click="update();">Update</button>
<button type="submit" class="btn btn-primary" ng-show="mode === 'new'" ng-click="add();">Add</button>
</div>
</form>

@ -65,12 +65,12 @@ export class UsersActionBar extends PureComponent<Props> {
)}
<div className="page-action-bar__spacer" />
{canInvite && (
<a className="btn btn-success" href="org/users/invite">
<a className="btn btn-primary" href="org/users/invite">
<span>Invite</span>
</a>
)}
{externalUserMngLinkUrl && (
<a className="btn btn-success" href={externalUserMngLinkUrl} target="_blank">
<a className="btn btn-primary" href={externalUserMngLinkUrl} target="_blank">
<i className="fa fa-external-link-square" /> {externalUserMngLinkName}
</a>
)}

@ -105,7 +105,7 @@ exports[`Render should show external user management button 1`] = `
className="page-action-bar__spacer"
/>
<a
className="btn btn-success"
className="btn btn-primary"
href="some/url"
target="_blank"
>
@ -143,7 +143,7 @@ exports[`Render should show invite button 1`] = `
className="page-action-bar__spacer"
/>
<a
className="btn btn-success"
className="btn btn-primary"
href="org/users/invite"
>
<span>

@ -26,7 +26,7 @@
</div>
<div class="confirm-modal-buttons">
<button ng-show="onAltAction" type="button" class="btn btn-success" ng-click="dismiss();onAltAction();">{{altActionText}}</button>
<button ng-show="onAltAction" type="button" class="btn btn-primary" ng-click="dismiss();onAltAction();">{{altActionText}}</button>
<button type="button" class="btn btn-danger" ng-click="onConfirm();dismiss();" ng-disabled="!confirmTextValid" give-focus="true">{{yesText}}</button>
<button type="button" class="btn btn-inverse" ng-click="dismiss()">{{noText}}</button>
</div>

@ -15,7 +15,7 @@
</div>
<div class="gf-form-button-row">
<button type="button" class="btn btn-success" ng-show="canUpdate" ng-click="update(); dismiss();">Update</button>
<button type="button" class="btn btn-primary" ng-show="canUpdate" ng-click="update(); dismiss();">Update</button>
<button class="btn btn-secondary" ng-if="canCopy" clipboard-button="getContentForClipboard()">
<i class="fa fa-clipboard"></i>&nbsp;Copy to Clipboard
</button>

@ -99,7 +99,7 @@
If you skip you will be prompted to change password next time you login.
</info-popover>
</a>
<button type="submit" class="btn btn-large p-x-2" ng-click="changePassword();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-success': loginForm.$valid}">
<button type="submit" class="btn btn-large p-x-2" ng-click="changePassword();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
Save
</button>
</div>

@ -16,7 +16,7 @@
<input type="text" name="username" class="gf-form-input max-width-14" required ng-model='formModel.userOrEmail' placeholder="email or username">
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="sendResetEmail();" ng-disabled="!sendResetForm.$valid">
<button type="submit" class="btn btn-primary" ng-click="sendResetEmail();" ng-disabled="!sendResetForm.$valid">
Reset Password
</button>
<a href="login" class="btn btn-inverse">
@ -29,7 +29,7 @@
An email with a reset link has been sent to the email address. <br>
You should receive it shortly.
<div class="p-t-1">
<a href="login" class="btn btn-success p-t-1">
<a href="login" class="btn btn-primary p-t-1">
Login
</a>
</div>
@ -47,7 +47,7 @@
<password-strength password="formModel.newPassword"></password-strength>
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="submitReset();" ng-disabled="!resetForm.$valid">
<button type="submit" class="btn btn-primary" ng-click="submitReset();" ng-disabled="!resetForm.$valid">
Reset Password
</button>
</div>

@ -30,7 +30,7 @@
</div>
<div class="gf-form-button-row">
<button type="submit" class="btn btn-success" ng-click="submit();" ng-disable="!inviteForm.$valid">
<button type="submit" class="btn btn-primary" ng-click="submit();" ng-disable="!inviteForm.$valid">
Sign Up
</button>
</div>

@ -37,7 +37,7 @@
</div>
<div class="gf-form-button-row p-t-3">
<button type="submit" class="btn btn-success" ng-click="ctrl.submit();" ng-disabled="!signUpForm.$valid">
<button type="submit" class="btn btn-primary" ng-click="ctrl.submit();" ng-disabled="!signUpForm.$valid">
Sign Up
</button>
<a href="login" class="btn btn-inverse">

@ -11,7 +11,7 @@ import {
} from '@grafana/ui';
import { Emitter } from 'app/core/core';
import { LogsModel } from 'app/core/logs_model';
import { LogsModel, LogsDedupStrategy } from 'app/core/logs_model';
import TableModel from 'app/core/table_model';
export interface CompletionItem {
@ -237,12 +237,18 @@ export interface ExploreItemState {
* React keys for rendering of QueryRows
*/
queryKeys: string[];
/**
* Current logs deduplication strategy
*/
dedupStrategy?: LogsDedupStrategy;
}
export interface ExploreUIState {
showingTable: boolean;
showingGraph: boolean;
showingLogs: boolean;
dedupStrategy?: LogsDedupStrategy;
}
export interface ExploreUrlState {

@ -3,6 +3,21 @@
$theme-name: dark;
// New Colors
// -------------------------
$sapphire-faint: #041126;
$sapphire-light: #5794F2;
$sapphire-base: #3274D9;
$sapphire-shade: #1F60C4;
$lobster-base: #E02F44;
$lobster-shade: #C4162A;
$forest-light: #96D98D;
$forest-base: #37872D;
$forest-shade: #19730E;
$green-base: #299C46;
$green-shade: #23843B;
// Grays
// -------------------------
$black: #000;
@ -26,30 +41,29 @@ $white: #fff;
// Accent colors
// -------------------------
$blue: #33b5e5;
$blue-dark: #005f81;
$green: #299c46;
$red: #d44a3a;
$red: $lobster-base;
$yellow: #ecbb13;
$purple: #9933cc;
$variable: #32d1df;
$orange: #eb7b18;
$brand-primary: $orange;
$brand-success: $green;
$brand-success: $green-base;
$brand-warning: $brand-primary;
$brand-danger: $red;
$brand-danger: $lobster-base;
$query-red: #e24d42;
$query-green: #74e680;
$query-red: $lobster-base;
$query-green: $forest-light;
$query-purple: #fe85fc;
$query-keyword: #66d9ef;
$query-orange: $orange;
// Status colors
// -------------------------
$online: #10a345;
$online: $green-base;
$warn: #f79520;
$critical: #ed2e18;
$critical: $lobster-base;
// Scaffolding
// -------------------------
@ -82,7 +96,7 @@ $edit-gradient: linear-gradient(180deg, rgb(22, 23, 25) 50%, #090909);
$link-color: darken($white, 11%);
$link-color-disabled: darken($link-color, 30%);
$link-hover-color: $white;
$external-link-color: $blue;
$external-link-color: $sapphire-light;
// Typography
// -------------------------
@ -144,20 +158,18 @@ $table-bg-hover: $dark-3;
// Buttons
// -------------------------
$btn-primary-bg: #ff6600;
$btn-primary-bg-hl: #bc3e06;
$btn-secondary-bg-hl: lighten($blue-dark, 5%);
$btn-secondary-bg: $blue-dark;
$btn-secondary-bg: $sapphire-base;
$btn-secondary-bg-hl: $sapphire-shade;
$btn-success-bg: $green;
$btn-success-bg-hl: darken($green, 6%);
$btn-primary-bg: $green-base;
$btn-primary-bg-hl: $green-shade;
$btn-warning-bg: $brand-warning;
$btn-warning-bg-hl: lighten($brand-warning, 8%);
$btn-success-bg: $green-base;
$btn-success-bg-hl: $green-shade;
$btn-danger-bg: $red;
$btn-danger-bg-hl: darken($red, 8%);
$btn-danger-bg: $lobster-base;
$btn-danger-bg-hl: $lobster-shade;
$btn-inverse-bg: $dark-3;
$btn-inverse-bg-hl: lighten($dark-3, 4%);
@ -257,13 +269,12 @@ $toolbar-bg: $input-black;
// -------------------------
$warning-text-color: $warn;
$error-text-color: #e84d4d;
$success-text-color: #12d95a;
$info-text-color: $blue-dark;
$success-text-color: $forest-light;
$alert-error-bg: linear-gradient(90deg, #d44939, #e0603d);
$alert-success-bg: linear-gradient(90deg, #3aa655, #47b274);
$alert-warning-bg: linear-gradient(90deg, #d44939, #e0603d);
$alert-info-bg: linear-gradient(100deg, #1a4552, #00374a);
$alert-error-bg: linear-gradient(90deg, $lobster-base, $lobster-shade);
$alert-success-bg: linear-gradient(90deg, $green-base, $green-shade);
$alert-warning-bg: linear-gradient(90deg, $lobster-base, $lobster-shade);
$alert-info-bg: linear-gradient(100deg, $sapphire-base, $sapphire-shade);
// popover
$popover-bg: $page-bg;
@ -292,7 +303,7 @@ $tooltipBackgroundError: $brand-danger;
$checkboxImageUrl: '../img/checkbox.png';
// info box
$info-box-border-color: darken($blue, 12%);
$info-box-border-color: $sapphire-base;
// footer
$footer-link-color: $gray-2;
@ -323,8 +334,8 @@ $diff-arrow-color: $white;
$diff-json-bg: $dark-4;
$diff-json-fg: $gray-5;
$diff-json-added: #457740;
$diff-json-deleted: #a04338;
$diff-json-added: $sapphire-shade;
$diff-json-deleted: $lobster-shade;
$diff-json-old: #a04338;
$diff-json-new: #457740;
@ -335,21 +346,21 @@ $diff-json-changed-num: $text-color;
$diff-json-icon: $gray-7;
//Submenu
$variable-option-bg: $blue-dark;
$variable-option-bg: $dropdownLinkBackgroundHover;
//Switch Slider
// -------------------------
$switch-bg: $input-bg;
$switch-slider-color: $dark-2;
$switch-slider-off-bg: $gray-1;
$switch-slider-on-bg: linear-gradient(90deg, $orange, $red);
$switch-slider-on-bg: linear-gradient(90deg, #eb7b18, #d44a3a);
$switch-slider-shadow: 0 0 3px black;
//Checkbox
// -------------------------
$checkbox-bg: $dark-1;
$checkbox-border: 1px solid $gray-1;
$checkbox-checked-bg: linear-gradient(0deg, $orange, $red);
$checkbox-checked-bg: linear-gradient(0deg, #eb7b18, #d44a3a);
$checkbox-color: $dark-1;
//Panel Edit
@ -358,23 +369,24 @@ $panel-editor-shadow: 0 0 20px black;
$panel-editor-side-menu-shadow: drop-shadow(0 0 10px $black);
$panel-editor-viz-item-shadow: 0 0 8px $dark-5;
$panel-editor-viz-item-border: 1px solid $dark-5;
$panel-editor-viz-item-shadow-hover: 0 0 4px $blue;
$panel-editor-viz-item-border-hover: 1px solid $blue;
$panel-editor-viz-item-shadow-hover: 0 0 4px $sapphire-light;
$panel-editor-viz-item-border-hover: 1px solid $sapphire-light;
$panel-editor-viz-item-bg: $input-black;
$panel-editor-tabs-line-color: #e3e3e3;
$panel-editor-viz-item-bg-hover: darken($blue, 47%);
$panel-editor-viz-item-bg-hover: darken($sapphire-base, 46%);
$panel-options-group-border: none;
$panel-options-group-header-bg: $gray-blue;
$panel-grid-placeholder-bg: darken($blue, 47%);
$panel-grid-placeholder-shadow: 0 0 4px $blue;
$panel-grid-placeholder-bg: $sapphire-faint;
$panel-grid-placeholder-shadow: 0 0 4px $sapphire-shade;
// logs
$logs-color-unkown: $gray-2;
// toggle-group
$button-toggle-group-btn-active-bg: linear-gradient(90deg, $orange, $red);
$button-toggle-group-btn-active-bg: linear-gradient(90deg, #eb7b18, #d44a3a);
$button-toggle-group-btn-active-shadow: inset 0 0 4px $black;
$button-toggle-group-btn-seperator-border: 1px solid $page-bg;

@ -3,6 +3,21 @@
$theme-name: light;
// New Colors
// -------------------------
$sapphire-faint: #F5F9FF;
$sapphire-light: #A8CAFF;
$sapphire-base: #3274D9;
$sapphire-shade: #1F60C4;
$lobster-base: #E02F44;
$lobster-shade: #C4162A;
$green-base: #37872D;
$green-shade: #19730E;
$green-base: #3EB15B;
$green-shade: #369B4F;
$purple-shade: #8F3BB8;
$yellow-base: #F2CC0C;
// Grays
// -------------------------
$black: #000;
@ -25,28 +40,28 @@ $white: #fff;
$blue: #0083b3;
$blue-light: #00a8e6;
$green: #3aa655;
$red: #d44939;
$red: $lobster-base;
$yellow: #ff851b;
$orange: #ff7941;
$purple: #9954bb;
$variable: $blue;
$variable: $purple-shade;
$brand-primary: $orange;
$brand-success: $green;
$brand-warning: $orange;
$brand-danger: $red;
$brand-danger: $lobster-base;
$query-red: $red;
$query-red: $lobster-base;
$query-green: $green;
$query-purple: $purple;
$query-orange: $orange;
$query-keyword: $blue;
$query-keyword: $sapphire-base;
// Status colors
// -------------------------
$online: #01a64f;
$online: $green-shade;
$warn: #f79520;
$critical: #ec2128;
$critical: $lobster-shade;
// Scaffolding
// -------------------------
@ -61,7 +76,6 @@ $text-color-faint: $gray-4;
$text-color-emphasis: $dark-5;
$text-shadow-faint: none;
$textShadow: none;
// gradients
$brand-gradient: linear-gradient(
@ -79,7 +93,7 @@ $edit-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%);
$link-color: $gray-1;
$link-color-disabled: lighten($link-color, 30%);
$link-hover-color: darken($link-color, 20%);
$external-link-color: $blue-light;
$external-link-color: $sapphire-shade;
// Typography
// -------------------------
@ -141,20 +155,17 @@ $table-bg-hover: $gray-5;
// Buttons
// -------------------------
$btn-primary-bg: $brand-primary;
$btn-primary-bg-hl: lighten($brand-primary, 8%);
$btn-primary-bg: $green-base;
$btn-primary-bg-hl: $green-shade;
$btn-secondary-bg: $blue;
$btn-secondary-bg-hl: lighten($blue, 4%);
$btn-secondary-bg: $sapphire-base;
$btn-secondary-bg-hl: $sapphire-shade;
$btn-success-bg: lighten($green, 3%);
$btn-success-bg-hl: darken($green, 3%);
$btn-success-bg: $green-base;
$btn-success-bg-hl: $green-shade;
$btn-warning-bg: lighten($orange, 3%);
$btn-warning-bg-hl: darken($orange, 3%);
$btn-danger-bg: lighten($red, 3%);
$btn-danger-bg-hl: darken($red, 3%);
$btn-danger-bg: $lobster-base;
$btn-danger-bg-hl: $lobster-shade;
$btn-inverse-bg: $gray-6;
$btn-inverse-bg-hl: darken($gray-6, 5%);
@ -178,8 +189,8 @@ $input-bg-disabled: $gray-5;
$input-color: $dark-3;
$input-border-color: $gray-5;
$input-box-shadow: none;
$input-border-focus: $blue !default;
$input-box-shadow-focus: $blue !default;
$input-border-focus: $sapphire-light !default;
$input-box-shadow-focus: $sapphire-light !default;
$input-color-placeholder: $gray-4 !default;
$input-label-bg: $gray-5;
$input-label-border-color: $gray-5;
@ -253,14 +264,13 @@ $toolbar-bg: white;
// Form states and alerts
// -------------------------
$warning-text-color: lighten($orange, 10%);
$error-text-color: lighten($red, 10%);
$error-text-color: $lobster-shade;
$success-text-color: lighten($green, 10%);
$info-text-color: $blue;
$alert-error-bg: linear-gradient(90deg, #d44939, #e04d3d);
$alert-success-bg: linear-gradient(90deg, #3aa655, #47b274);
$alert-warning-bg: linear-gradient(90deg, #d44939, #e04d3d);
$alert-info-bg: $blue;
$alert-error-bg: linear-gradient(90deg, $lobster-base, $lobster-shade);
$alert-success-bg: linear-gradient(90deg, $green-base, $green-shade);
$alert-warning-bg: linear-gradient(90deg, $lobster-base, $lobster-shade);
$alert-info-bg: $sapphire-base;
// popover
$popover-bg: $page-bg;
@ -268,7 +278,7 @@ $popover-color: $text-color;
$popover-border-color: $gray-5;
$popover-shadow: 0 0 20px $white;
$popover-help-bg: $blue;
$popover-help-bg: $sapphire-base;
$popover-help-color: $gray-6;
$popover-error-bg: $btn-danger-bg;
@ -289,7 +299,7 @@ $tooltipBackgroundError: $brand-danger;
$checkboxImageUrl: '../img/checkbox_white.png';
// info box
$info-box-border-color: lighten($blue, 20%);
$info-box-border-color: $sapphire-base;
// footer
$footer-link-color: $gray-3;
@ -298,16 +308,16 @@ $footer-link-hover: $dark-5;
// json explorer
$json-explorer-default-color: black;
$json-explorer-string-color: green;
$json-explorer-number-color: blue;
$json-explorer-boolean-color: red;
$json-explorer-number-color: $sapphire-base;
$json-explorer-boolean-color: $lobster-base;
$json-explorer-null-color: #855a00;
$json-explorer-undefined-color: rgb(202, 11, 105);
$json-explorer-function-color: #ff20ed;
$json-explorer-rotate-time: 100ms;
$json-explorer-toggler-opacity: 0.6;
$json-explorer-bracket-color: blue;
$json-explorer-bracket-color: $sapphire-base;
$json-explorer-key-color: #00008b;
$json-explorer-url-color: blue;
$json-explorer-url-color: $sapphire-base;
// Changelog and diff
// -------------------------
@ -318,35 +328,35 @@ $diff-arrow-color: $dark-3;
$diff-group-bg: $gray-7;
$diff-json-bg: $gray-5;
$diff-json-fg: $gray-2;
$diff-json-fg: $gray-1;
$diff-json-added: lighten(desaturate($green, 30%), 10%);
$diff-json-deleted: desaturate($red, 35%);
$diff-json-added: $sapphire-shade;
$diff-json-deleted: $lobster-shade;
$diff-json-old: #5a372a;
$diff-json-new: #664e33;
$diff-json-changed-fg: $gray-6;
$diff-json-changed-fg: $gray-7;
$diff-json-changed-num: $gray-4;
$diff-json-icon: $gray-4;
//Submenu
$variable-option-bg: $blue-light;
$variable-option-bg: $dropdownLinkBackgroundHover;
//Switch Slider
// -------------------------
$switch-bg: $white;
$switch-slider-color: $gray-7;
$switch-slider-off-bg: $gray-5;
$switch-slider-on-bg: linear-gradient(90deg, $yellow, $red);
$switch-slider-on-bg: linear-gradient(90deg, #FF9830, #E55400);
$switch-slider-shadow: 0 0 3px $dark-5;
//Checkbox
// -------------------------
$checkbox-bg: $gray-6;
$checkbox-border: 1px solid $gray-3;
$checkbox-checked-bg: linear-gradient(0deg, $yellow, $red);
$checkbox-checked-bg: linear-gradient(0deg, #FF9830, #E55400);
$checkbox-color: $gray-7;
//Panel Edit
@ -359,13 +369,11 @@ $panel-editor-viz-item-shadow-hover: 0 0 4px $blue-light;
$panel-editor-viz-item-border-hover: 1px solid $blue-light;
$panel-editor-viz-item-bg: $white;
$panel-editor-tabs-line-color: $dark-5;
$panel-editor-viz-item-bg-hover: lighten($blue, 62%);
$panel-options-group-border: none;
$panel-editor-viz-item-bg-hover: lighten($blue, 62%);$panel-options-group-border: none;
$panel-options-group-header-bg: $gray-5;
$panel-grid-placeholder-bg: lighten($blue, 62%);
$panel-grid-placeholder-shadow: 0 0 4px $blue-light;
$panel-grid-placeholder-bg: $sapphire-faint;
$panel-grid-placeholder-shadow: 0 0 4px $sapphire-light;
// logs
$logs-color-unkown: $gray-5;

@ -59,14 +59,6 @@ a.text-error:focus {
color: darken($error-text-color, 10%);
}
.text-info {
color: $info-text-color;
}
a.text-info:hover,
a.text-info:focus {
color: darken($info-text-color, 10%);
}
.text-success {
color: $success-text-color;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save