diff --git a/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts index 3a2d6db458c..54c00f9237e 100644 --- a/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.dark.scss.tmpl.ts @@ -54,34 +54,34 @@ $orange: ${theme.colors.orange}; $purple: ${theme.colors.purple}; $variable: ${theme.colors.variable}; -$brand-primary: $orange; -$brand-success: $green-base; -$brand-warning: $brand-primary; -$brand-danger: $red-base; +$brand-primary: ${theme.colors.brandPrimary}; +$brand-success: ${theme.colors.brandSuccess}; +$brand-warning: ${theme.colors.brandWarning}; +$brand-danger: ${theme.colors.brandDanger}; -$query-red: $red-base; -$query-green: #74e680; -$query-purple: #fe85fc; -$query-keyword: #66d9ef; -$query-orange: $orange; +$query-red: ${theme.colors.queryRed}; +$query-green: ${theme.colors.queryGreen}; +$query-purple: ${theme.colors.queryPurple}; +$query-orange: ${theme.colors.orange}; +$query-keyword: ${theme.colors.queryKeyword}; // Status colors // ------------------------- -$online: $green-base; -$warn: #f79520; -$critical: $red-base; +$online: ${theme.colors.online}; +$warn: ${theme.colors.warn}; +$critical: ${theme.colors.critical}; // Scaffolding // ------------------------- $body-bg: ${theme.colors.bodyBg}; $page-bg: ${theme.colors.pageBg}; -$body-color: $gray-4; -$text-color: $gray-4; -$text-color-strong: $white; -$text-color-weak: $gray-2; -$text-color-faint: $dark-10; -$text-color-emphasis: $gray-5; +$body-color: ${theme.colors.body}; +$text-color: ${theme.colors.text}; +$text-color-strong: ${theme.colors.textStrong}; +$text-color-weak: ${theme.colors.textWeak}; +$text-color-faint: ${theme.colors.textFaint}; +$text-color-emphasis: ${theme.colors.textEmphasis}; $text-shadow-faint: 1px 1px 4px rgb(45, 45, 45); $textShadow: none; @@ -99,14 +99,14 @@ $edit-gradient: linear-gradient(180deg, $dark-2 50%, $input-black); // Links // ------------------------- -$link-color: darken($white, 11%); -$link-color-disabled: darken($link-color, 30%); -$link-hover-color: $white; -$external-link-color: $blue-light; +$link-color: ${theme.colors.link}; +$link-color-disabled: ${theme.colors.linkDisabled}; +$link-hover-color: ${theme.colors.linkHover}; +$external-link-color: ${theme.colors.linkExternal}; // Typography // ------------------------- -$headings-color: darken($white, 11%); +$headings-color: ${theme.colors.headingColor}; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; diff --git a/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts b/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts index 1b017b7eb0d..e90299f619c 100644 --- a/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts +++ b/packages/grafana-ui/src/themes/_variables.light.scss.tmpl.ts @@ -46,34 +46,34 @@ $orange: ${theme.colors.orange}; $purple: ${theme.colors.purple}; $variable: ${theme.colors.variable}; -$brand-primary: $orange; -$brand-success: $green-base; -$brand-warning: $orange; -$brand-danger: $red-base; +$brand-primary: ${theme.colors.brandPrimary}; +$brand-success: ${theme.colors.brandSuccess}; +$brand-warning: ${theme.colors.brandWarning}; +$brand-danger: ${theme.colors.brandDanger}; -$query-red: $red-base; -$query-green: $green-base; -$query-purple: $purple; -$query-orange: $orange; -$query-keyword: $blue-base; +$query-red: ${theme.colors.queryRed}; +$query-green: ${theme.colors.queryGreen}; +$query-purple: ${theme.colors.queryPurple}; +$query-orange: ${theme.colors.orange}; +$query-keyword: ${theme.colors.queryKeyword}; // Status colors // ------------------------- -$online: $green-shade; -$warn: #f79520; -$critical: $red-shade; +$online: ${theme.colors.online}; +$warn: ${theme.colors.warn}; +$critical: ${theme.colors.critical}; // Scaffolding // ------------------------- $body-bg: ${theme.colors.bodyBg}; $page-bg: ${theme.colors.pageBg}; -$body-color: $gray-1; -$text-color: $gray-1; -$text-color-strong: $dark-1; -$text-color-weak: $gray-2; -$text-color-faint: $gray-4; -$text-color-emphasis: $dark-2; +$body-color: ${theme.colors.body}; +$text-color: ${theme.colors.text}; +$text-color-strong: ${theme.colors.textStrong}; +$text-color-weak: ${theme.colors.textWeak}; +$text-color-faint: ${theme.colors.textFaint}; +$text-color-emphasis: ${theme.colors.textEmphasis}; $text-shadow-faint: none; @@ -85,14 +85,14 @@ $edit-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%); // Links // ------------------------- -$link-color: $gray-1; -$link-color-disabled: lighten($link-color, 30%); -$link-hover-color: darken($link-color, 20%); -$external-link-color: $blue-shade; +$link-color: ${theme.colors.link}; +$link-color-disabled: ${theme.colors.linkDisabled}; +$link-hover-color: ${theme.colors.linkHover}; +$external-link-color: ${theme.colors.linkExternal}; // Typography // ------------------------- -$headings-color: $text-color; +$headings-color: ${theme.colors.headingColor}; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; diff --git a/packages/grafana-ui/src/themes/dark.ts b/packages/grafana-ui/src/themes/dark.ts index 7c3e81a7d35..1e424c97154 100644 --- a/packages/grafana-ui/src/themes/dark.ts +++ b/packages/grafana-ui/src/themes/dark.ts @@ -46,6 +46,10 @@ const darkTheme: GrafanaTheme = { colors: { ...basicColors, inputBlack: '#09090b', + brandPrimary: basicColors.orange, + brandSuccess: basicColors.greenBase, + brandWarning: basicColors.orange, + brandDanger: basicColors.redBase, queryRed: basicColors.redBase, queryGreen: '#74e680', queryPurple: '#fe85fc', @@ -56,16 +60,16 @@ const darkTheme: GrafanaTheme = { critical: basicColors.redBase, bodyBg: basicColors.dark2, pageBg: basicColors.dark2, - bodyColor: basicColors.gray4, - textColor: basicColors.gray4, - textColorStrong: basicColors.white, - textColorWeak: basicColors.gray2, - textColorEmphasis: basicColors.gray5, - textColorFaint: basicColors.dark5, - linkColor: new tinycolor(basicColors.white).darken(11).toString(), - linkColorDisabled: new tinycolor(basicColors.white).darken(11).toString(), - linkColorHover: basicColors.white, - linkColorExternal: basicColors.blue, + body: basicColors.gray4, + text: basicColors.gray4, + textStrong: basicColors.white, + textWeak: basicColors.gray2, + textEmphasis: basicColors.gray5, + textFaint: basicColors.dark5, + link: new tinycolor(basicColors.white).darken(11).toString(), + linkDisabled: new tinycolor(basicColors.white).darken(11).toString(), + linkHover: basicColors.white, + linkExternal: basicColors.blue, headingColor: new tinycolor(basicColors.white).darken(11).toString(), }, background: { diff --git a/packages/grafana-ui/src/themes/light.ts b/packages/grafana-ui/src/themes/light.ts index 7e8f6300d84..a3994fc7458 100644 --- a/packages/grafana-ui/src/themes/light.ts +++ b/packages/grafana-ui/src/themes/light.ts @@ -47,26 +47,30 @@ const lightTheme: GrafanaTheme = { ...basicColors, variable: basicColors.blue, inputBlack: '#09090b', - queryRed: basicColors.red, + brandPrimary: basicColors.orange, + brandSuccess: basicColors.greenBase, + brandWarning: basicColors.orange, + brandDanger: basicColors.redBase, + queryRed: basicColors.redBase, queryGreen: basicColors.greenBase, queryPurple: basicColors.purple, - queryKeyword: basicColors.blue, + queryKeyword: basicColors.blueBase, queryOrange: basicColors.orange, online: basicColors.greenShade, warn: '#f79520', critical: basicColors.redShade, bodyBg: basicColors.gray7, pageBg: basicColors.gray7, - bodyColor: basicColors.gray1, - textColor: basicColors.gray1, - textColorStrong: basicColors.dark2, - textColorWeak: basicColors.gray2, - textColorEmphasis: basicColors.gray5, - textColorFaint: basicColors.dark4, - linkColor: basicColors.gray1, - linkColorDisabled: new tinycolor(basicColors.gray1).lighten(30).toString(), - linkColorHover: new tinycolor(basicColors.gray1).darken(20).toString(), - linkColorExternal: basicColors.blueLight, + body: basicColors.gray1, + text: basicColors.gray1, + textStrong: basicColors.dark2, + textWeak: basicColors.gray2, + textEmphasis: basicColors.gray5, + textFaint: basicColors.dark4, + link: basicColors.gray1, + linkDisabled: new tinycolor(basicColors.gray1).lighten(30).toString(), + linkHover: new tinycolor(basicColors.gray1).darken(20).toString(), + linkExternal: basicColors.blueLight, headingColor: basicColors.gray1, }, background: { diff --git a/packages/grafana-ui/src/types/theme.ts b/packages/grafana-ui/src/types/theme.ts index 01886afe3dc..30f1bf4685b 100644 --- a/packages/grafana-ui/src/types/theme.ts +++ b/packages/grafana-ui/src/types/theme.ts @@ -113,25 +113,33 @@ export interface GrafanaTheme extends GrafanaThemeCommons { queryPurple: string; queryKeyword: string; queryOrange: string; + brandPrimary: string; + brandSuccess: string; + brandWarning: string; + brandDanger: string; // Status colors online: string; warn: string; critical: string; + // Link colors + link: string; + linkDisabled: string; + linkHover: string; + linkExternal: string; + + // Text colors + body: string; + text: string; + textStrong: string; + textWeak: string; + textFaint: string; + textEmphasis: string; + // TODO: move to background section bodyBg: string; pageBg: string; - bodyColor: string; - textColor: string; - textColorStrong: string; - textColorWeak: string; - textColorFaint: string; - textColorEmphasis: string; - linkColor: string; - linkColorDisabled: string; - linkColorHover: string; - linkColorExternal: string; headingColor: string; }; } diff --git a/pkg/services/alerting/notifiers/discord.go b/pkg/services/alerting/notifiers/discord.go index 57d9d438fa2..c7178211f0e 100644 --- a/pkg/services/alerting/notifiers/discord.go +++ b/pkg/services/alerting/notifiers/discord.go @@ -111,57 +111,20 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { json, _ := bodyJSON.MarshalJSON() - content_type := "application/json" - - var body []byte - - if embeddedImage { - - var b bytes.Buffer - - w := multipart.NewWriter(&b) - - f, err := os.Open(evalContext.ImageOnDiskPath) - - if err != nil { - this.log.Error("Can't open graph file", err) - return err - } - - defer f.Close() - - fw, err := w.CreateFormField("payload_json") - if err != nil { - return err - } - - if _, err = fw.Write([]byte(string(json))); err != nil { - return err - } - - fw, err = w.CreateFormFile("file", "graph.png") - if err != nil { - return err - } - - if _, err = io.Copy(fw, f); err != nil { - return err - } - - w.Close() - - body = b.Bytes() - content_type = w.FormDataContentType() - - } else { - body = json - } - cmd := &m.SendWebhookSync{ Url: this.WebhookURL, - Body: string(body), HttpMethod: "POST", - ContentType: content_type, + ContentType: "application/json", + } + + if !embeddedImage { + cmd.Body = string(json) + } else { + err := this.embedImage(cmd, evalContext.ImageOnDiskPath, json) + if err != nil { + this.log.Error("failed to embed image", "error", err) + return err + } } if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil { @@ -171,3 +134,45 @@ func (this *DiscordNotifier) Notify(evalContext *alerting.EvalContext) error { return nil } + +func (this *DiscordNotifier) embedImage(cmd *m.SendWebhookSync, imagePath string, existingJSONBody []byte) error { + f, err := os.Open(imagePath) + defer f.Close() + if err != nil { + if os.IsNotExist(err) { + cmd.Body = string(existingJSONBody) + return nil + } + if !os.IsNotExist(err) { + return err + } + } + + var b bytes.Buffer + w := multipart.NewWriter(&b) + + fw, err := w.CreateFormField("payload_json") + if err != nil { + return err + } + + if _, err = fw.Write([]byte(string(existingJSONBody))); err != nil { + return err + } + + fw, err = w.CreateFormFile("file", "graph.png") + if err != nil { + return err + } + + if _, err = io.Copy(fw, f); err != nil { + return err + } + + w.Close() + + cmd.Body = string(b.Bytes()) + cmd.ContentType = w.FormDataContentType() + + return nil +} diff --git a/public/app/core/components/help/help.ts b/public/app/core/components/help/help.ts index 8e8a5ed45d2..7ef54339f49 100644 --- a/public/app/core/components/help/help.ts +++ b/public/app/core/components/help/help.ts @@ -27,6 +27,7 @@ export class HelpCtrl { { keys: ['d', 'C'], description: 'Collapse all rows' }, { keys: ['d', 'a'], description: 'Toggle auto fit panels (experimental feature)' }, { keys: ['mod+o'], description: 'Toggle shared graph crosshair' }, + { keys: ['d', 'l'], description: 'Toggle all panel legends' }, ], 'Focused Panel': [ { keys: ['e'], description: 'Toggle panel edit view' }, diff --git a/public/app/core/services/keybindingSrv.ts b/public/app/core/services/keybindingSrv.ts index 7dab7cffd6f..da096f261c6 100644 --- a/public/app/core/services/keybindingSrv.ts +++ b/public/app/core/services/keybindingSrv.ts @@ -256,6 +256,11 @@ export class KeybindingSrv { } }); + // toggle all panel legends + this.bind('d l', () => { + dashboard.toggleLegendsForAll(); + }); + // collapse all rows this.bind('d shift+c', () => { dashboard.collapseRows(); diff --git a/public/app/features/dashboard/state/DashboardModel.test.ts b/public/app/features/dashboard/state/DashboardModel.test.ts index cd30fc2ecdc..0d18a3b5d12 100644 --- a/public/app/features/dashboard/state/DashboardModel.test.ts +++ b/public/app/features/dashboard/state/DashboardModel.test.ts @@ -635,4 +635,32 @@ describe('DashboardModel', () => { expect(saveModel.templating.list[0].filters[0].value).toBe('server 1'); }); }); + + describe('Given a dashboard with one panel legend on and two off', () => { + let model; + + beforeEach(() => { + const data = { + panels: [ + { id: 1, type: 'graph', gridPos: { x: 0, y: 0, w: 24, h: 2 }, legend: { show: true } }, + { id: 3, type: 'graph', gridPos: { x: 0, y: 4, w: 12, h: 2 }, legend: { show: false } }, + { id: 4, type: 'graph', gridPos: { x: 12, y: 4, w: 12, h: 2 }, legend: { show: false } }, + ], + }; + model = new DashboardModel(data); + }); + + it('toggleLegendsForAll should toggle all legends on on first execution', () => { + model.toggleLegendsForAll(); + const legendsOn = model.panels.filter(panel => panel.legend.show === true); + expect(legendsOn.length).toBe(3); + }); + + it('toggleLegendsForAll should toggle all legends off on second execution', () => { + model.toggleLegendsForAll(); + model.toggleLegendsForAll(); + const legendsOn = model.panels.filter(panel => panel.legend.show === true); + expect(legendsOn.length).toBe(0); + }); + }); }); diff --git a/public/app/features/dashboard/state/DashboardModel.ts b/public/app/features/dashboard/state/DashboardModel.ts index 2a445c9a58c..cde4227d3ec 100644 --- a/public/app/features/dashboard/state/DashboardModel.ts +++ b/public/app/features/dashboard/state/DashboardModel.ts @@ -917,4 +917,20 @@ export class DashboardModel { } } } + + toggleLegendsForAll() { + const panelsWithLegends = this.panels.filter(panel => { + return panel.legend !== undefined && panel.legend !== null; + }); + + // determine if more panels are displaying legends or not + const onCount = panelsWithLegends.filter(panel => panel.legend.show).length; + const offCount = panelsWithLegends.length - onCount; + const panelLegendsOn = onCount >= offCount; + + for (const panel of panelsWithLegends) { + panel.legend.show = !panelLegendsOn; + panel.render(); + } + } } diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index c0739b6d8bc..0c3ab44d8e8 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -106,6 +106,7 @@ export class PanelModel { events: Emitter; cacheTimeout?: any; cachedPluginOptions?: any; + legend?: { show: boolean }; constructor(model) { this.events = new Emitter(); diff --git a/public/app/features/playlist/playlist_srv.ts b/public/app/features/playlist/playlist_srv.ts index cb2763129ef..97ebfff7320 100644 --- a/public/app/features/playlist/playlist_srv.ts +++ b/public/app/features/playlist/playlist_srv.ts @@ -7,6 +7,7 @@ import coreModule from '../../core/core_module'; import appEvents from 'app/core/app_events'; import locationUtil from 'app/core/utils/location_util'; import kbn from 'app/core/utils/kbn'; +import { store } from 'app/store/store'; export class PlaylistSrv { private cancelPromise: any; @@ -15,6 +16,8 @@ export class PlaylistSrv { private interval: number; private startUrl: string; private numberOfLoops = 0; + private storeUnsub: () => void; + private validPlaylistUrl: string; isPlaying: boolean; /** @ngInject */ @@ -39,15 +42,16 @@ export class PlaylistSrv { const dash = this.dashboards[this.index]; const queryParams = this.$location.search(); const filteredParams = _.pickBy(queryParams, value => value !== null); + const nextDashboardUrl = locationUtil.stripBaseFromUrl(dash.url); // this is done inside timeout to make sure digest happens after // as this can be called from react this.$timeout(() => { - const stripedUrl = locationUtil.stripBaseFromUrl(dash.url); - this.$location.url(stripedUrl + '?' + toUrlParams(filteredParams)); + this.$location.url(nextDashboardUrl + '?' + toUrlParams(filteredParams)); }); this.index++; + this.validPlaylistUrl = nextDashboardUrl; this.cancelPromise = this.$timeout(() => this.next(), this.interval); } @@ -56,6 +60,15 @@ export class PlaylistSrv { this.next(); } + // Detect url changes not caused by playlist srv and stop playlist + storeUpdated() { + const state = store.getState(); + + if (state.location.path !== this.validPlaylistUrl) { + this.stop(); + } + } + start(playlistId) { this.stop(); @@ -63,6 +76,10 @@ export class PlaylistSrv { this.index = 0; this.isPlaying = true; + // setup location tracking + this.storeUnsub = store.subscribe(() => this.storeUpdated()); + this.validPlaylistUrl = this.$location.path(); + appEvents.emit('playlist-started'); return this.backendSrv.get(`/api/playlists/${playlistId}`).then(playlist => { @@ -85,6 +102,10 @@ export class PlaylistSrv { this.index = 0; this.isPlaying = false; + if (this.storeUnsub) { + this.storeUnsub(); + } + if (this.cancelPromise) { this.$timeout.cancel(this.cancelPromise); } diff --git a/public/app/features/playlist/specs/playlist_srv.test.ts b/public/app/features/playlist/specs/playlist_srv.test.ts index bfb1732d9c6..628818fd716 100644 --- a/public/app/features/playlist/specs/playlist_srv.test.ts +++ b/public/app/features/playlist/specs/playlist_srv.test.ts @@ -1,4 +1,14 @@ +import configureMockStore from 'redux-mock-store'; import { PlaylistSrv } from '../playlist_srv'; +import { setStore } from 'app/store/store'; + +const mockStore = configureMockStore(); + +setStore( + mockStore({ + location: {}, + }) +); const dashboards = [{ url: 'dash1' }, { url: 'dash2' }]; @@ -19,6 +29,7 @@ const createPlaylistSrv = (): [PlaylistSrv, { url: jest.MockInstance } const mockLocation = { url: jest.fn(), search: () => ({}), + path: () => '/playlists/1', }; const mockTimeout = jest.fn(); @@ -96,4 +107,32 @@ describe('PlaylistSrv', () => { expect(hrefMock).toHaveBeenCalledTimes(3); expect(hrefMock).toHaveBeenLastCalledWith(initialUrl); }); + + it('storeUpdated should stop playlist when navigating away', async () => { + await srv.start(1); + + srv.storeUpdated(); + + expect(srv.isPlaying).toBe(false); + }); + + it('storeUpdated should not stop playlist when navigating to next dashboard', async () => { + await srv.start(1); + + srv.next(); + + setStore( + mockStore({ + location: { + path: 'dash2', + }, + }) + ); + + expect((srv as any).validPlaylistUrl).toBe('dash2'); + + srv.storeUpdated(); + + expect(srv.isPlaying).toBe(true); + }); }); diff --git a/public/sass/_variables.dark.generated.scss b/public/sass/_variables.dark.generated.scss index 3f1e2e4f314..a86134cf4bd 100644 --- a/public/sass/_variables.dark.generated.scss +++ b/public/sass/_variables.dark.generated.scss @@ -57,34 +57,34 @@ $orange: #eb7b18; $purple: #9933cc; $variable: #32d1df; -$brand-primary: $orange; -$brand-success: $green-base; -$brand-warning: $brand-primary; -$brand-danger: $red-base; +$brand-primary: #eb7b18; +$brand-success: #299c46; +$brand-warning: #eb7b18; +$brand-danger: #e02f44; -$query-red: $red-base; +$query-red: #e02f44; $query-green: #74e680; $query-purple: #fe85fc; +$query-orange: #eb7b18; $query-keyword: #66d9ef; -$query-orange: $orange; // Status colors // ------------------------- -$online: $green-base; +$online: #299c46; $warn: #f79520; -$critical: $red-base; +$critical: #e02f44; // Scaffolding // ------------------------- $body-bg: #161719; $page-bg: #161719; -$body-color: $gray-4; -$text-color: $gray-4; -$text-color-strong: $white; -$text-color-weak: $gray-2; -$text-color-faint: $dark-10; -$text-color-emphasis: $gray-5; +$body-color: #d8d9da; +$text-color: #d8d9da; +$text-color-strong: #ffffff; +$text-color-weak: #8e8e8e; +$text-color-faint: #222426; +$text-color-emphasis: #ececec; $text-shadow-faint: 1px 1px 4px rgb(45, 45, 45); $textShadow: none; @@ -102,14 +102,14 @@ $edit-gradient: linear-gradient(180deg, $dark-2 50%, $input-black); // Links // ------------------------- -$link-color: darken($white, 11%); -$link-color-disabled: darken($link-color, 30%); -$link-hover-color: $white; -$external-link-color: $blue-light; +$link-color: #e3e3e3; +$link-color-disabled: #e3e3e3; +$link-hover-color: #ffffff; +$external-link-color: #33b5e5; // Typography // ------------------------- -$headings-color: darken($white, 11%); +$headings-color: #e3e3e3; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak; diff --git a/public/sass/_variables.light.generated.scss b/public/sass/_variables.light.generated.scss index 4aea0a4f993..4d1dd96bccf 100644 --- a/public/sass/_variables.light.generated.scss +++ b/public/sass/_variables.light.generated.scss @@ -49,34 +49,34 @@ $orange: #ff7941; $purple: #9954bb; $variable: #0083b3; -$brand-primary: $orange; -$brand-success: $green-base; -$brand-warning: $orange; -$brand-danger: $red-base; +$brand-primary: #ff7941; +$brand-success: #3eb15b; +$brand-warning: #ff7941; +$brand-danger: #e02f44; -$query-red: $red-base; -$query-green: $green-base; -$query-purple: $purple; -$query-orange: $orange; -$query-keyword: $blue-base; +$query-red: #e02f44; +$query-green: #3eb15b; +$query-purple: #9954bb; +$query-orange: #ff7941; +$query-keyword: #3274d9; // Status colors // ------------------------- -$online: $green-shade; +$online: #369b4f; $warn: #f79520; -$critical: $red-shade; +$critical: #c4162a; // Scaffolding // ------------------------- $body-bg: #f7f8fa; $page-bg: #f7f8fa; -$body-color: $gray-1; -$text-color: $gray-1; -$text-color-strong: $dark-1; -$text-color-weak: $gray-2; -$text-color-faint: $gray-4; -$text-color-emphasis: $dark-2; +$body-color: #52545c; +$text-color: #52545c; +$text-color-strong: #41444b; +$text-color-weak: #767980; +$text-color-faint: #35373f; +$text-color-emphasis: #dde4ed; $text-shadow-faint: none; @@ -88,14 +88,14 @@ $edit-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%); // Links // ------------------------- -$link-color: $gray-1; -$link-color-disabled: lighten($link-color, 30%); -$link-hover-color: darken($link-color, 20%); -$external-link-color: $blue-shade; +$link-color: #52545c; +$link-color-disabled: #9ea0a9; +$link-hover-color: #222326; +$external-link-color: #5794f2; // Typography // ------------------------- -$headings-color: $text-color; +$headings-color: #52545c; $abbr-border-color: $gray-2 !default; $text-muted: $text-color-weak;