diff --git a/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap
index ec2fa845c6d..8d23cdc1565 100644
--- a/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap
+++ b/public/app/core/components/sidemenu/__snapshots__/SideMenu.test.tsx.snap
@@ -2,16 +2,16 @@
exports[`Render should render component 1`] = `
Array [
-
-
,
+ ,
{
+ const rowCopy = { ...row };
const previous = result[result.length - 1];
if (index > 0 && isDuplicateRow(row, previous, strategy)) {
previous.duplicates++;
} else {
- row.duplicates = 0;
- result.push(row);
+ rowCopy.duplicates = 0;
+ result.push(rowCopy);
}
return result;
}, []);
diff --git a/public/app/core/services/context_srv.ts b/public/app/core/services/context_srv.ts
index 7bb753e6f71..e3b10f129d1 100644
--- a/public/app/core/services/context_srv.ts
+++ b/public/app/core/services/context_srv.ts
@@ -1,7 +1,6 @@
import config from 'app/core/config';
import _ from 'lodash';
import coreModule from 'app/core/core_module';
-import store from 'app/core/store';
export class User {
isGrafanaAdmin: any;
@@ -29,13 +28,10 @@ export class ContextSrv {
isSignedIn: any;
isGrafanaAdmin: any;
isEditor: any;
- sidemenu: any;
sidemenuSmallBreakpoint = false;
hasEditPermissionInFolders: boolean;
constructor() {
- this.sidemenu = store.getBool('grafana.sidemenu', true);
-
if (!config.bootData) {
config.bootData = { user: {}, settings: {} };
}
@@ -55,11 +51,6 @@ export class ContextSrv {
return !!(document.visibilityState === undefined || document.visibilityState === 'visible');
}
- toggleSideMenu() {
- this.sidemenu = !this.sidemenu;
- store.set('grafana.sidemenu', this.sidemenu);
- }
-
hasAccessToExplore() {
return (this.isEditor || config.viewersCanEdit) && config.exploreEnabled;
}
diff --git a/public/app/core/specs/logs_model.test.ts b/public/app/core/specs/logs_model.test.ts
index c59d18e8b7d..dcd1e483330 100644
--- a/public/app/core/specs/logs_model.test.ts
+++ b/public/app/core/specs/logs_model.test.ts
@@ -113,6 +113,34 @@ describe('dedupLogRows()', () => {
},
]);
});
+
+ test('should return to non-deduped state on same log result', () => {
+ const logs = {
+ rows: [
+ {
+ entry: 'INFO 123',
+ },
+ {
+ entry: 'WARN 123',
+ },
+ {
+ entry: 'WARN 123',
+ },
+ ],
+ };
+ expect(dedupLogRows(logs as LogsModel, LogsDedupStrategy.exact).rows).toEqual([
+ {
+ duplicates: 0,
+ entry: 'INFO 123',
+ },
+ {
+ duplicates: 1,
+ entry: 'WARN 123',
+ },
+ ]);
+
+ expect(dedupLogRows(logs as LogsModel, LogsDedupStrategy.none).rows).toEqual(logs.rows);
+ });
});
describe('calculateFieldStats()', () => {
diff --git a/public/app/features/explore/LogLabels.tsx b/public/app/features/explore/LogLabels.tsx
index 7105a2a5370..24d6e1ec23c 100644
--- a/public/app/features/explore/LogLabels.tsx
+++ b/public/app/features/explore/LogLabels.tsx
@@ -13,8 +13,19 @@ interface Props {
export class LogLabels extends PureComponent
{
render() {
const { getRows, labels, onClickLabel, plain } = this.props;
- return Object.keys(labels).map(key => (
-
- ));
+ return (
+
+ {Object.keys(labels).map(key => (
+
+ ))}
+
+ );
}
}
diff --git a/public/app/features/explore/LogRow.tsx b/public/app/features/explore/LogRow.tsx
index d7615446b21..e45864f7b54 100644
--- a/public/app/features/explore/LogRow.tsx
+++ b/public/app/features/explore/LogRow.tsx
@@ -150,7 +150,7 @@ export class LogRow extends PureComponent {
)}
{showLocalTime && (
-
+
{row.timeLocal}
)}
diff --git a/public/app/features/explore/state/selectors.test.ts b/public/app/features/explore/state/selectors.test.ts
new file mode 100644
index 00000000000..3a1fa5102ae
--- /dev/null
+++ b/public/app/features/explore/state/selectors.test.ts
@@ -0,0 +1,108 @@
+import { deduplicatedLogsSelector } from './selectors';
+import { LogsDedupStrategy } from 'app/core/logs_model';
+import { ExploreItemState } from 'app/types';
+
+const state = {
+ logsResult: {
+ rows: [
+ {
+ entry: '2019-03-05T11:00:56Z sntpc sntpc[1]: offset=-0.033938, delay=0.000649',
+ },
+ {
+ entry: '2019-03-05T11:00:26Z sntpc sntpc[1]: offset=-0.033730, delay=0.000581',
+ },
+ {
+ entry: '2019-03-05T10:59:56Z sntpc sntpc[1]: offset=-0.034184, delay=0.001089',
+ },
+ {
+ entry: '2019-03-05T10:59:26Z sntpc sntpc[1]: offset=-0.033972, delay=0.000582',
+ },
+ {
+ entry: '2019-03-05T10:58:56Z sntpc sntpc[1]: offset=-0.033955, delay=0.000606',
+ },
+ {
+ entry: '2019-03-05T10:58:26Z sntpc sntpc[1]: offset=-0.034067, delay=0.000616',
+ },
+ {
+ entry: '2019-03-05T10:57:56Z sntpc sntpc[1]: offset=-0.034155, delay=0.001021',
+ },
+ {
+ entry: '2019-03-05T10:57:26Z sntpc sntpc[1]: offset=-0.035797, delay=0.000883',
+ },
+ {
+ entry: '2019-03-05T10:56:56Z sntpc sntpc[1]: offset=-0.046818, delay=0.000605',
+ },
+ {
+ entry: '2019-03-05T10:56:26Z sntpc sntpc[1]: offset=-0.049200, delay=0.000584',
+ },
+ ],
+ },
+ hiddenLogLevels: undefined,
+ dedupStrategy: LogsDedupStrategy.none,
+};
+
+describe('Deduplication selector', () => {
+ it('should correctly deduplicate log rows when changing strategy multiple times', () => {
+ // Simulating sequence of UI actions that was causing a problem with deduplication counter being visible when unnecessary.
+ // The sequence was changing dedup strategy: (none -> exact -> numbers -> signature -> none) *2 -> exact. After that the first
+ // row contained information that was deduped, while it shouldn't be.
+ // Problem was caused by mutating the log results entries in redux state. The memoisation hash for deduplicatedLogsSelector
+ // was changing depending on duplicates information from log row state, while should be dependand on log row only.
+
+ let dedups = deduplicatedLogsSelector(state as ExploreItemState);
+ expect(dedups.rows.length).toBe(10);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.none,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.exact,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.numbers,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.signature,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.none,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.exact,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.numbers,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.signature,
+ } as ExploreItemState);
+
+ deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.none,
+ } as ExploreItemState);
+
+ dedups = deduplicatedLogsSelector({
+ ...state,
+ dedupStrategy: LogsDedupStrategy.exact,
+ } as ExploreItemState);
+
+ // Expecting that no row has duplicates now
+ expect(dedups.rows.reduce((acc, row) => acc + row.duplicates, 0)).toBe(0);
+ });
+});
diff --git a/public/app/partials/login.html b/public/app/partials/login.html
index 674c9581ce5..33872c7d6d5 100644
--- a/public/app/partials/login.html
+++ b/public/app/partials/login.html
@@ -13,7 +13,7 @@
+ placeholder="{{passwordHint}}">
diff --git a/public/app/routes/GrafanaCtrl.ts b/public/app/routes/GrafanaCtrl.ts
index 479c5e77f3d..a37222091d0 100644
--- a/public/app/routes/GrafanaCtrl.ts
+++ b/public/app/routes/GrafanaCtrl.ts
@@ -75,27 +75,22 @@ export class GrafanaCtrl {
}
}
-function setViewModeBodyClass(body: JQuery, mode: KioskUrlValue, sidemenuOpen: boolean) {
+function setViewModeBodyClass(body: JQuery, mode: KioskUrlValue) {
body.removeClass('view-mode--tv');
body.removeClass('view-mode--kiosk');
body.removeClass('view-mode--inactive');
switch (mode) {
case 'tv': {
- body.removeClass('sidemenu-open');
body.addClass('view-mode--tv');
break;
}
// 1 & true for legacy states
case '1':
case true: {
- body.removeClass('sidemenu-open');
body.addClass('view-mode--kiosk');
break;
}
- default: {
- body.toggleClass('sidemenu-open', sidemenuOpen);
- }
}
}
@@ -105,7 +100,6 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
restrict: 'E',
controller: GrafanaCtrl,
link: (scope, elem) => {
- let sidemenuOpen;
const body = $('body');
// see https://github.com/zenorocha/clipboard.js/issues/155
@@ -113,14 +107,6 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
$('.preloader').remove();
- sidemenuOpen = scope.contextSrv.sidemenu;
- body.toggleClass('sidemenu-open', sidemenuOpen);
-
- appEvents.on('toggle-sidemenu', () => {
- sidemenuOpen = scope.contextSrv.sidemenu;
- body.toggleClass('sidemenu-open');
- });
-
appEvents.on('toggle-sidemenu-mobile', () => {
body.toggleClass('sidemenu-open--xs');
});
@@ -163,7 +149,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
$('#tooltip, .tooltip').remove();
// check for kiosk url param
- setViewModeBodyClass(body, data.params.kiosk, sidemenuOpen);
+ setViewModeBodyClass(body, data.params.kiosk);
// close all drops
for (const drop of Drop.drops) {
@@ -198,7 +184,7 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
}
$timeout(() => $location.search(search));
- setViewModeBodyClass(body, search.kiosk, sidemenuOpen);
+ setViewModeBodyClass(body, search.kiosk);
});
// handle in active view state class
@@ -218,7 +204,6 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
if (new Date().getTime() - lastActivity > inActiveTimeLimit) {
activeUser = false;
body.addClass('view-mode--inactive');
- body.removeClass('sidemenu-open');
}
}
@@ -227,7 +212,6 @@ export function grafanaAppDirective(playlistSrv, contextSrv, $timeout, $rootScop
if (!activeUser) {
activeUser = true;
body.removeClass('view-mode--inactive');
- body.toggleClass('sidemenu-open', sidemenuOpen);
}
}
diff --git a/public/sass/_variables.generated.scss b/public/sass/_variables.generated.scss
index 713bfb7a336..9a29f9beba9 100644
--- a/public/sass/_variables.generated.scss
+++ b/public/sass/_variables.generated.scss
@@ -20,7 +20,7 @@ $enable-hover-media-query: false !default;
// Control the default styling of most Bootstrap elements by modifying these
// variables. Mostly focused on spacing.
-$spacer: 1rem !default;
+$spacer: 14px !default;
$spacer-x: $spacer !default;
$spacer-y: $spacer !default;
$spacers: (
@@ -88,7 +88,6 @@ $enable-flex: true;
// -------------------------
$font-family-sans-serif: 'Roboto', Helvetica, Arial, sans-serif;
-$font-family-serif: Georgia, 'Times New Roman', Times, serif;
$font-family-monospace: Menlo, Monaco, Consolas, 'Courier New', monospace;
$font-family-base: $font-family-sans-serif !default;
@@ -103,25 +102,12 @@ $font-size-xs: 10px !default;
$line-height-base: 1.5 !default;
$font-weight-semi-bold: 500;
-$font-size-h1: 2rem !default;
-$font-size-h2: 1.75rem !default;
-$font-size-h3: 1.5rem !default;
-$font-size-h4: 1.3rem !default;
-$font-size-h5: 1.2rem !default;
-$font-size-h6: 1rem !default;
-
-$display1-size: 6rem !default;
-$display2-size: 5.5rem !default;
-$display3-size: 4.5rem !default;
-$display4-size: 3.5rem !default;
-
-$display1-weight: 400 !default;
-$display2-weight: 400 !default;
-$display3-weight: 400 !default;
-$display4-weight: 400 !default;
-
-$lead-font-size: 1.25rem !default;
-$lead-font-weight: 300 !default;
+$font-size-h1: 28px !default;
+$font-size-h2: 24px !default;
+$font-size-h3: 21px !default;
+$font-size-h4: 18px !default;
+$font-size-h5: 16px !default;
+$font-size-h6: 14px !default;
$headings-margin-bottom: ($spacer / 2) !default;
$headings-font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
@@ -144,8 +130,8 @@ $border-radius-sm: 2px !default;
// Page
-$page-sidebar-width: 11rem;
-$page-sidebar-margin: 4rem;
+$page-sidebar-width: 154px;
+$page-sidebar-margin: 56px;
// Links
// -------------------------
@@ -177,7 +163,7 @@ $input-padding-y-lg: 10px !default;
$input-height: 35px !default;
-$gf-form-margin: 0.2rem;
+$gf-form-margin: 3px;
$gf-form-input-height: 35px;
$cursor-disabled: not-allowed !default;
@@ -202,13 +188,13 @@ $zindex-typeahead: 1060;
// Buttons
//
-$btn-padding-x: 1rem !default;
-$btn-padding-y: 0.7rem !default;
+$btn-padding-x: 14px !default;
+$btn-padding-y: 10px !default;
$btn-line-height: 1 !default;
$btn-font-weight: 500 !default;
-$btn-padding-x-sm: 0.5rem !default;
-$btn-padding-y-sm: 0.25rem !default;
+$btn-padding-x-sm: 7px !default;
+$btn-padding-y-sm: 4px !default;
$btn-padding-x-lg: 21px !default;
$btn-padding-y-lg: 11px !default;
diff --git a/public/sass/base/_type.scss b/public/sass/base/_type.scss
index ea24116795a..ab4fbc33a55 100644
--- a/public/sass/base/_type.scss
+++ b/public/sass/base/_type.scss
@@ -141,29 +141,6 @@ h6,
font-size: $font-size-h6;
}
-.lead {
- font-size: $lead-font-size;
- font-weight: $lead-font-weight;
-}
-
-// Type display classes
-.display-1 {
- font-size: $display1-size;
- font-weight: $display1-weight;
-}
-.display-2 {
- font-size: $display2-size;
- font-weight: $display2-weight;
-}
-.display-3 {
- font-size: $display3-size;
- font-weight: $display3-weight;
-}
-.display-4 {
- font-size: $display4-size;
- font-weight: $display4-weight;
-}
-
//
// Horizontal rules
//
diff --git a/public/sass/components/_navbar.scss b/public/sass/components/_navbar.scss
index a86b8c450a0..eef101c98b4 100644
--- a/public/sass/components/_navbar.scss
+++ b/public/sass/components/_navbar.scss
@@ -157,14 +157,8 @@
@include media-breakpoint-up(sm) {
.navbar {
- padding-left: 60px;
- }
-
- .sidemenu-open {
- .navbar {
- padding-left: 25px;
- margin-left: 0;
- }
+ padding-left: 20px;
+ margin-left: 0;
}
.navbar-page-btn {
diff --git a/public/sass/components/_panel_logs.scss b/public/sass/components/_panel_logs.scss
index 5ecfa7259b1..5d35f8fddc0 100644
--- a/public/sass/components/_panel_logs.scss
+++ b/public/sass/components/_panel_logs.scss
@@ -63,6 +63,7 @@ $column-horizontal-spacing: 10px;
font-size: $font-size-sm;
display: table;
table-layout: fixed;
+ width: 100%;
}
.logs-row {
@@ -83,16 +84,22 @@ $column-horizontal-spacing: 10px;
.logs-row__time {
white-space: nowrap;
+ width: 19em;
+}
+
+.logs-row__localtime {
+ white-space: nowrap;
+ width: 12.5em;
}
.logs-row__labels {
- max-width: 20%;
+ width: 20%;
line-height: 1.2;
+ position: relative;
}
.logs-row__message {
word-break: break-all;
- min-width: 80%;
}
.logs-row__match-highlight {
@@ -112,6 +119,7 @@ $column-horizontal-spacing: 10px;
.logs-row__level {
position: relative;
+ width: 10px;
&::after {
content: '';
@@ -165,6 +173,7 @@ $column-horizontal-spacing: 10px;
.logs-row__duplicates {
text-align: right;
+ width: 4.5em;
}
.logs-row__field-highlight {
@@ -193,15 +202,20 @@ $column-horizontal-spacing: 10px;
}
}
+.logs-labels {
+ display: flex;
+ flex-wrap: wrap;
+}
+
.logs-label {
- display: inline-block;
+ display: flex;
padding: 0 2px;
background-color: $btn-inverse-bg;
border-radius: $border-radius;
margin: 0 4px 2px 0;
text-overflow: ellipsis;
white-space: nowrap;
- position: relative;
+ overflow: hidden;
}
.logs-label__icon {
@@ -211,6 +225,13 @@ $column-horizontal-spacing: 10px;
margin-left: 2px;
}
+.logs-label__value {
+ display: inline-block;
+ max-width: 20em;
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
.logs-label__stats {
position: absolute;
top: 1.25em;
diff --git a/public/sass/components/_sidemenu.scss b/public/sass/components/_sidemenu.scss
index f30bdb5c79e..c16e037c2ad 100644
--- a/public/sass/components/_sidemenu.scss
+++ b/public/sass/components/_sidemenu.scss
@@ -16,6 +16,14 @@
.sidemenu__close {
display: none;
}
+
+ @include media-breakpoint-up(sm) {
+ background: $side-menu-bg;
+ height: auto;
+ box-shadow: $side-menu-shadow;
+ position: relative;
+ z-index: $zindex-sidemenu;
+ }
}
// body class that hides sidemenu
@@ -25,32 +33,22 @@
}
}
-@include media-breakpoint-up(sm) {
- .sidemenu-open {
- .sidemenu {
- background: $side-menu-bg;
- height: auto;
- box-shadow: $side-menu-shadow;
- position: relative;
- z-index: $zindex-sidemenu;
- }
-
- .sidemenu__top,
- .sidemenu__bottom {
- display: block;
- }
- }
-}
-
.sidemenu__top {
padding-top: 3rem;
flex-grow: 1;
- display: none;
}
.sidemenu__bottom {
padding-bottom: $spacer;
+}
+
+.sidemenu__top,
+.sidemenu__bottom {
display: none;
+
+ @include media-breakpoint-up(sm) {
+ display: block;
+ }
}
.sidemenu-item {
diff --git a/public/sass/components/_view_states.scss b/public/sass/components/_view_states.scss
index b92bd596193..e1ca3d44f83 100644
--- a/public/sass/components/_view_states.scss
+++ b/public/sass/components/_view_states.scss
@@ -29,6 +29,21 @@
.view-mode--tv {
@extend .view-mode--inactive;
+ .sidemenu {
+ position: fixed;
+ background-color: transparent;
+ box-shadow: none;
+
+ .sidemenu__top,
+ .sidemenu__bottom {
+ display: none;
+ }
+ }
+
+ .navbar {
+ padding-left: $side-menu-width;
+ }
+
.submenu-controls {
display: none;
}
diff --git a/public/sass/mixins/_mixins.scss b/public/sass/mixins/_mixins.scss
index 89285cc2496..298ea0c64ad 100644
--- a/public/sass/mixins/_mixins.scss
+++ b/public/sass/mixins/_mixins.scss
@@ -79,10 +79,6 @@
// FONTS
// --------------------------------------------------
-@mixin font-family-serif() {
- font-family: $font-family-serif;
-}
-
@mixin font-family-sans-serif() {
font-family: $font-family-sans-serif;
}
@@ -97,11 +93,6 @@
line-height: $lineHeight;
}
-@mixin font-serif($size: $font-size-base, $weight: normal, $lineHeight: $line-height-base) {
- @include font-family-serif();
- @include font-shorthand($size, $weight, $lineHeight);
-}
-
@mixin font-sans-serif($size: $font-size-base, $weight: normal, $lineHeight: $line-height-base) {
@include font-family-sans-serif();
@include font-shorthand($size, $weight, $lineHeight);
diff --git a/public/sass/pages/_explore.scss b/public/sass/pages/_explore.scss
index 90579ff67ad..0358adb9787 100644
--- a/public/sass/pages/_explore.scss
+++ b/public/sass/pages/_explore.scss
@@ -25,20 +25,13 @@
}
}
-.sidemenu-open {
- .explore-toolbar-header {
- padding: 0;
- margin-left: 0;
- }
-}
-
.explore-toolbar {
background: inherit;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
height: auto;
- padding: 0px $dashboard-padding 0 25px;
+ padding: 0 $dashboard-padding;
border-bottom: 1px solid #0000;
transition-duration: 0.35s;
transition-timing-function: ease-in-out;
@@ -72,11 +65,6 @@
font-size: 18px;
min-height: 55px;
line-height: 55px;
- justify-content: space-between;
- margin-left: $panel-margin * 3;
-}
-
-.explore-toolbar-header {
justify-content: space-between;
align-items: center;
}
@@ -134,20 +122,6 @@
}
@media only screen and (max-width: 803px) {
- .sidemenu-open {
- .explore-toolbar-header-title {
- .navbar-page-btn {
- margin-left: 0;
- }
- }
- }
-
- .explore-toolbar-header-title {
- .navbar-page-btn {
- margin-left: $dashboard-padding;
- }
- }
-
.btn-title {
display: none;
}
@@ -161,14 +135,6 @@
}
@media only screen and (max-width: 544px) {
- .sidemenu-open {
- .explore-toolbar-header-title {
- .navbar-page-btn {
- margin-left: $dashboard-padding;
- }
- }
- }
-
.explore-toolbar-header-title {
.navbar-page-btn {
margin-left: $dashboard-padding;