Merge remote-tracking branch 'grafana/master' into all-data-as-table
* grafana/master: fix(explore/logs) not collapsing whitespace (#15737) Refactoring / fixing password hint PR #15868 chore: Move sidemenu out of context service and use the logic we have in the router already for hiding the sidemenu Fix deduplication results displaying wrong data (#15755) Revert "Fix Datasource Update to no User/Password" fix imageurl in notification test changed all rems to pixels in defaults and template, changed back root font size Make password hint configurable from settings/defaults.ini changed root font to 100%(default 16px), changed font-size from px to rem, updated rem sizes in template and default.ts files, removed display classes and variables since not used, removed lead class and variables since not usedremoved serif font since not used and probably never should be used fix: Update test snapshot fix: Logo goes Home instead of toggling side menu #15482 Fix: #14706 Incorrect index pattern padding in alerting queries Removed commented code Fixed alias in Cloudwatch Expressions
This commit is contained in:
@@ -231,6 +231,7 @@ verify_email_enabled = false
|
||||
|
||||
# Background text for the user field on the login page
|
||||
login_hint = email or username
|
||||
password_hint = password
|
||||
|
||||
# Default UI theme ("dark" or "light")
|
||||
default_theme = dark
|
||||
|
||||
@@ -211,6 +211,7 @@ log_queries =
|
||||
|
||||
# Background text for the user field on the login page
|
||||
;login_hint = email or username
|
||||
;password_hint = password
|
||||
|
||||
# Default UI theme ("dark" or "light")
|
||||
;default_theme = dark
|
||||
|
||||
@@ -162,9 +162,9 @@ executed with working directory set to the installation path.
|
||||
|
||||
### enable_gzip
|
||||
|
||||
Set this option to `true` to enable HTTP compression, this can improve
|
||||
transfer speed and bandwidth utilization. It is recommended that most
|
||||
users set it to `true`. By default it is set to `false` for compatibility
|
||||
Set this option to `true` to enable HTTP compression, this can improve
|
||||
transfer speed and bandwidth utilization. It is recommended that most
|
||||
users set it to `true`. By default it is set to `false` for compatibility
|
||||
reasons.
|
||||
|
||||
### cert_file
|
||||
@@ -342,6 +342,14 @@ options are `Admin` and `Editor`. e.g. :
|
||||
Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard.
|
||||
Defaults to `false`.
|
||||
|
||||
### login_hint
|
||||
|
||||
Text used as placeholder text on login page for login/username input.
|
||||
|
||||
### password_hint
|
||||
|
||||
Text used as placeholder text on login page for password input.
|
||||
|
||||
<hr>
|
||||
|
||||
## [auth]
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
}
|
||||
|
||||
.panel-options-group__title {
|
||||
font-size: 1.1rem;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,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: ${theme.spacing.m} !default;
|
||||
$spacer-x: $spacer !default;
|
||||
$spacer-y: $spacer !default;
|
||||
$spacers: (
|
||||
@@ -46,7 +46,7 @@ $spacers: (
|
||||
),
|
||||
),
|
||||
) !default;
|
||||
$border-width: 1px !default;
|
||||
$border-width: ${theme.border.width.s} !default;
|
||||
|
||||
// Grid breakpoints
|
||||
//
|
||||
@@ -54,11 +54,11 @@ $border-width: 1px !default;
|
||||
// adapting to different screen sizes, for use in media queries.
|
||||
|
||||
$grid-breakpoints: (
|
||||
xs: 0,
|
||||
sm: 544px,
|
||||
md: 768px,
|
||||
lg: 992px,
|
||||
xl: 1200px,
|
||||
xs: ${theme.breakpoints.xs},
|
||||
sm: ${theme.breakpoints.s},
|
||||
md: ${theme.breakpoints.m},
|
||||
lg: ${theme.breakpoints.l},
|
||||
xl: ${theme.breakpoints.xl},
|
||||
) !default;
|
||||
|
||||
// Grid containers
|
||||
@@ -84,46 +84,32 @@ $enable-flex: true;
|
||||
// Typography
|
||||
// -------------------------
|
||||
|
||||
$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-sans-serif: ${theme.typography.fontFamily.sansSerif};
|
||||
$font-family-monospace: ${theme.typography.fontFamily.monospace};
|
||||
$font-family-base: $font-family-sans-serif !default;
|
||||
|
||||
$font-size-root: 14px !default;
|
||||
$font-size-base: 13px !default;
|
||||
$font-size-root: ${theme.typography.size.root} !default;
|
||||
$font-size-base: ${theme.typography.size.base} !default;
|
||||
|
||||
$font-size-lg: 18px !default;
|
||||
$font-size-md: 14px !default;
|
||||
$font-size-sm: 12px !default;
|
||||
$font-size-xs: 10px !default;
|
||||
$font-size-lg: ${theme.typography.size.l} !default;
|
||||
$font-size-md: ${theme.typography.size.m} !default;
|
||||
$font-size-sm: ${theme.typography.size.s} !default;
|
||||
$font-size-xs: ${theme.typography.size.xs} !default;
|
||||
|
||||
$line-height-base: 1.5 !default;
|
||||
$font-weight-semi-bold: 500;
|
||||
$line-height-base: ${theme.typography.lineHeight.l} !default;
|
||||
$font-weight-semi-bold: ${theme.typography.weight.semibold};
|
||||
|
||||
$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: ${theme.typography.heading.h1} !default;
|
||||
$font-size-h2: ${theme.typography.heading.h2} !default;
|
||||
$font-size-h3: ${theme.typography.heading.h3} !default;
|
||||
$font-size-h4: ${theme.typography.heading.h4} !default;
|
||||
$font-size-h5: ${theme.typography.heading.h5} !default;
|
||||
$font-size-h6: ${theme.typography.heading.h6} !default;
|
||||
|
||||
$headings-margin-bottom: ($spacer / 2) !default;
|
||||
$headings-font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
$headings-font-weight: 400 !default;
|
||||
$headings-line-height: 1.1 !default;
|
||||
$headings-font-weight: ${theme.typography.weight.normal} !default;
|
||||
$headings-line-height: ${theme.typography.lineHeight.s} !default;
|
||||
|
||||
$hr-border-width: $border-width !default;
|
||||
$dt-font-weight: bold !default;
|
||||
@@ -141,8 +127,8 @@ $border-radius-sm: 2px !default;
|
||||
|
||||
// Page
|
||||
|
||||
$page-sidebar-width: 11rem;
|
||||
$page-sidebar-margin: 4rem;
|
||||
$page-sidebar-width: 154px;
|
||||
$page-sidebar-margin: 56px;
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@@ -174,7 +160,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;
|
||||
@@ -199,13 +185,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-font-weight: ${theme.typography.weight.semibold} !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;
|
||||
|
||||
@@ -5,10 +5,10 @@ const theme: GrafanaThemeCommons = {
|
||||
typography: {
|
||||
fontFamily: {
|
||||
sansSerif: "'Roboto', Helvetica, Arial, sans-serif",
|
||||
serif: "Georgia, 'Times New Roman', Times, serif",
|
||||
monospace: "Menlo, Monaco, Consolas, 'Courier New', monospace",
|
||||
},
|
||||
size: {
|
||||
root: '14px',
|
||||
base: '13px',
|
||||
xs: '10px',
|
||||
s: '12px',
|
||||
@@ -16,12 +16,12 @@ const theme: GrafanaThemeCommons = {
|
||||
l: '18px',
|
||||
},
|
||||
heading: {
|
||||
h1: '2rem',
|
||||
h2: '1.75rem',
|
||||
h3: '1.5rem',
|
||||
h4: '1.3rem',
|
||||
h5: '1.2rem',
|
||||
h6: '1rem',
|
||||
h1: '28px',
|
||||
h2: '24px',
|
||||
h3: '21px',
|
||||
h4: '18px',
|
||||
h5: '16px',
|
||||
h6: '14px',
|
||||
},
|
||||
weight: {
|
||||
light: 300,
|
||||
@@ -35,7 +35,7 @@ const theme: GrafanaThemeCommons = {
|
||||
l: 1.5,
|
||||
},
|
||||
},
|
||||
brakpoints: {
|
||||
breakpoints: {
|
||||
xs: '0',
|
||||
s: '544px',
|
||||
m: '768px',
|
||||
@@ -44,9 +44,9 @@ const theme: GrafanaThemeCommons = {
|
||||
},
|
||||
spacing: {
|
||||
xs: '0',
|
||||
s: '0.2rem',
|
||||
m: '1rem',
|
||||
l: '1.5rem',
|
||||
s: '3px',
|
||||
m: '14px',
|
||||
l: '21px',
|
||||
gutter: '30px',
|
||||
},
|
||||
border: {
|
||||
@@ -55,6 +55,9 @@ const theme: GrafanaThemeCommons = {
|
||||
s: '3px',
|
||||
m: '5px',
|
||||
},
|
||||
width: {
|
||||
s: '1px',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export enum GrafanaThemeType {
|
||||
export interface GrafanaThemeCommons {
|
||||
name: string;
|
||||
// TODO: not sure if should be a part of theme
|
||||
brakpoints: {
|
||||
breakpoints: {
|
||||
xs: string;
|
||||
s: string;
|
||||
m: string;
|
||||
@@ -16,10 +16,10 @@ export interface GrafanaThemeCommons {
|
||||
typography: {
|
||||
fontFamily: {
|
||||
sansSerif: string;
|
||||
serif: string;
|
||||
monospace: string;
|
||||
};
|
||||
size: {
|
||||
root: string;
|
||||
base: string;
|
||||
xs: string;
|
||||
s: string;
|
||||
@@ -60,6 +60,9 @@ export interface GrafanaThemeCommons {
|
||||
s: string;
|
||||
m: string;
|
||||
};
|
||||
width: {
|
||||
s: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ func (hs *HTTPServer) LoginView(c *m.ReqContext) {
|
||||
viewData.Settings["oauth"] = enabledOAuths
|
||||
viewData.Settings["disableUserSignUp"] = !setting.AllowUserSignUp
|
||||
viewData.Settings["loginHint"] = setting.LoginHint
|
||||
viewData.Settings["passwordHint"] = setting.PasswordHint
|
||||
viewData.Settings["disableLoginForm"] = setting.DisableLoginForm
|
||||
|
||||
if loginError, ok := tryGetEncryptedCookie(c, LoginErrorCookieName); ok {
|
||||
|
||||
@@ -56,7 +56,7 @@ func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {
|
||||
|
||||
ctx := NewEvalContext(context.Background(), testRule)
|
||||
if cmd.Settings.Get("uploadImage").MustBool(true) {
|
||||
ctx.ImagePublicUrl = "http://grafana.org/assets/img/blog/mixed_styles.png"
|
||||
ctx.ImagePublicUrl = "https://grafana.com/assets/img/blog/mixed_styles.png"
|
||||
}
|
||||
ctx.IsTestRun = true
|
||||
ctx.Firing = true
|
||||
|
||||
@@ -174,6 +174,11 @@ func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
|
||||
Version: cmd.Version + 1,
|
||||
}
|
||||
|
||||
sess.UseBool("is_default")
|
||||
sess.UseBool("basic_auth")
|
||||
sess.UseBool("with_credentials")
|
||||
sess.UseBool("read_only")
|
||||
|
||||
var updateSession *xorm.Session
|
||||
if cmd.Version != 0 {
|
||||
// the reason we allow cmd.version > db.version is make it possible for people to force
|
||||
@@ -185,7 +190,7 @@ func UpdateDataSource(cmd *m.UpdateDataSourceCommand) error {
|
||||
updateSession = sess.Where("id=? and org_id=?", ds.Id, ds.OrgId)
|
||||
}
|
||||
|
||||
affected, err := updateSession.AllCols().Omit("created").Update(ds)
|
||||
affected, err := updateSession.Update(ds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -109,6 +109,7 @@ var (
|
||||
AutoAssignOrgRole string
|
||||
VerifyEmailEnabled bool
|
||||
LoginHint string
|
||||
PasswordHint string
|
||||
DefaultTheme string
|
||||
DisableLoginForm bool
|
||||
DisableSignoutMenu bool
|
||||
@@ -656,6 +657,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
||||
AutoAssignOrgRole = users.Key("auto_assign_org_role").In("Editor", []string{"Editor", "Admin", "Viewer"})
|
||||
VerifyEmailEnabled = users.Key("verify_email_enabled").MustBool(false)
|
||||
LoginHint = users.Key("login_hint").String()
|
||||
PasswordHint = users.Key("password_hint").String()
|
||||
DefaultTheme = users.Key("default_theme").String()
|
||||
ExternalUserMngLinkUrl = users.Key("external_manage_link_url").String()
|
||||
ExternalUserMngLinkName = users.Key("external_manage_link_name").String()
|
||||
|
||||
@@ -496,9 +496,6 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) {
|
||||
}
|
||||
|
||||
alias := model.Get("alias").MustString()
|
||||
if alias == "" {
|
||||
alias = "{{metric}}_{{stat}}"
|
||||
}
|
||||
|
||||
returnData := model.Get("returnData").MustBool(false)
|
||||
highResolution := model.Get("highResolution").MustBool(false)
|
||||
@@ -521,7 +518,11 @@ func parseQuery(model *simplejson.Json) (*CloudWatchQuery, error) {
|
||||
|
||||
func formatAlias(query *CloudWatchQuery, stat string, dimensions map[string]string) string {
|
||||
if len(query.Id) > 0 && len(query.Expression) > 0 {
|
||||
return query.Id
|
||||
if len(query.Alias) > 0 {
|
||||
return query.Alias
|
||||
} else {
|
||||
return query.Id
|
||||
}
|
||||
}
|
||||
|
||||
data := map[string]string{}
|
||||
|
||||
@@ -279,7 +279,7 @@ func formatDate(t time.Time, pattern string) string {
|
||||
isoYearShort := fmt.Sprintf("%d", isoYear)[2:4]
|
||||
formatted = strings.Replace(formatted, "<stdIsoYear>", fmt.Sprintf("%d", isoYear), -1)
|
||||
formatted = strings.Replace(formatted, "<stdIsoYearShort>", isoYearShort, -1)
|
||||
formatted = strings.Replace(formatted, "<stdWeekOfYear>", fmt.Sprintf("%d", isoWeek), -1)
|
||||
formatted = strings.Replace(formatted, "<stdWeekOfYear>", fmt.Sprintf("%02d", isoWeek), -1)
|
||||
|
||||
formatted = strings.Replace(formatted, "<stdUnix>", fmt.Sprintf("%d", t.Unix()), -1)
|
||||
|
||||
|
||||
@@ -76,6 +76,15 @@ func TestIndexPattern(t *testing.T) {
|
||||
So(indices, ShouldHaveLength, 1)
|
||||
So(indices[0], ShouldEqual, "2018-data")
|
||||
})
|
||||
|
||||
Convey("Should return 01 week", func() {
|
||||
from = fmt.Sprintf("%d", time.Date(2018, 1, 15, 17, 50, 0, 0, time.UTC).UnixNano()/int64(time.Millisecond))
|
||||
to = fmt.Sprintf("%d", time.Date(2018, 1, 15, 17, 55, 0, 0, time.UTC).UnixNano()/int64(time.Millisecond))
|
||||
indexPatternScenario(intervalWeekly, "[data-]GGGG.WW", tsdb.NewTimeRange(from, to), func(indices []string) {
|
||||
So(indices, ShouldHaveLength, 1)
|
||||
So(indices[0], ShouldEqual, "data-2018.03")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Convey("Hourly interval", t, func() {
|
||||
|
||||
@@ -2,7 +2,6 @@ import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
import { SideMenu } from './SideMenu';
|
||||
import appEvents from '../../app_events';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
|
||||
jest.mock('../../app_events', () => ({
|
||||
emit: jest.fn(),
|
||||
@@ -26,7 +25,6 @@ jest.mock('app/core/services/context_srv', () => ({
|
||||
isGrafanaAdmin: false,
|
||||
isEditor: false,
|
||||
hasEditPermissionFolders: false,
|
||||
toggleSideMenu: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -54,20 +52,6 @@ describe('Render', () => {
|
||||
});
|
||||
|
||||
describe('Functions', () => {
|
||||
describe('toggle side menu', () => {
|
||||
const wrapper = setup();
|
||||
const instance = wrapper.instance() as SideMenu;
|
||||
instance.toggleSideMenu();
|
||||
|
||||
it('should call contextSrv.toggleSideMenu', () => {
|
||||
expect(contextSrv.toggleSideMenu).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should emit toggle sidemenu event', () => {
|
||||
expect(appEvents.emit).toHaveBeenCalledWith('toggle-sidemenu');
|
||||
});
|
||||
});
|
||||
|
||||
describe('toggle side menu on mobile', () => {
|
||||
const wrapper = setup();
|
||||
const instance = wrapper.instance() as SideMenu;
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import appEvents from '../../app_events';
|
||||
import { contextSrv } from 'app/core/services/context_srv';
|
||||
import TopSection from './TopSection';
|
||||
import BottomSection from './BottomSection';
|
||||
import { store } from 'app/store/store';
|
||||
import config from 'app/core/config';
|
||||
|
||||
const homeUrl = config.appSubUrl || '/';
|
||||
|
||||
export class SideMenu extends PureComponent {
|
||||
toggleSideMenu = () => {
|
||||
// ignore if we just made a location change, stops hiding sidemenu on double clicks of back button
|
||||
const timeSinceLocationChanged = new Date().getTime() - store.getState().location.lastUpdated;
|
||||
if (timeSinceLocationChanged < 1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
contextSrv.toggleSideMenu();
|
||||
appEvents.emit('toggle-sidemenu');
|
||||
};
|
||||
|
||||
toggleSideMenuSmallBreakpoint = () => {
|
||||
appEvents.emit('toggle-sidemenu-mobile');
|
||||
};
|
||||
|
||||
render() {
|
||||
return [
|
||||
<div className="sidemenu__logo" onClick={this.toggleSideMenu} key="logo">
|
||||
<a href={homeUrl} className="sidemenu__logo" key="logo">
|
||||
<img src="public/img/grafana_icon.svg" alt="Grafana" />
|
||||
</div>,
|
||||
</a>,
|
||||
<div className="sidemenu__logo_small_breakpoint" onClick={this.toggleSideMenuSmallBreakpoint} key="hamburger">
|
||||
<i className="fa fa-bars" />
|
||||
<span className="sidemenu__close">
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
|
||||
exports[`Render should render component 1`] = `
|
||||
Array [
|
||||
<div
|
||||
<a
|
||||
className="sidemenu__logo"
|
||||
href="/"
|
||||
key="logo"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<img
|
||||
alt="Grafana"
|
||||
src="public/img/grafana_icon.svg"
|
||||
/>
|
||||
</div>,
|
||||
</a>,
|
||||
<div
|
||||
className="sidemenu__logo_small_breakpoint"
|
||||
key="hamburger"
|
||||
|
||||
@@ -34,6 +34,7 @@ export class Settings {
|
||||
oauth: any;
|
||||
disableUserSignUp: boolean;
|
||||
loginHint: any;
|
||||
passwordHint: any;
|
||||
loginError: any;
|
||||
viewersCanEdit: boolean;
|
||||
editorsCanOwn: boolean;
|
||||
|
||||
@@ -25,6 +25,7 @@ export class LoginCtrl {
|
||||
$scope.disableLoginForm = config.disableLoginForm;
|
||||
$scope.disableUserSignUp = config.disableUserSignUp;
|
||||
$scope.loginHint = config.loginHint;
|
||||
$scope.passwordHint = config.passwordHint;
|
||||
|
||||
$scope.loginMode = true;
|
||||
$scope.submitBtnText = 'Log in';
|
||||
|
||||
@@ -245,12 +245,13 @@ export function dedupLogRows(logs: LogsModel, strategy: LogsDedupStrategy): Logs
|
||||
}
|
||||
|
||||
const dedupedRows = logs.rows.reduce((result: LogRowModel[], row: LogRowModel, index, list) => {
|
||||
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;
|
||||
}, []);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()', () => {
|
||||
|
||||
@@ -13,8 +13,19 @@ interface Props {
|
||||
export class LogLabels extends PureComponent<Props> {
|
||||
render() {
|
||||
const { getRows, labels, onClickLabel, plain } = this.props;
|
||||
return Object.keys(labels).map(key => (
|
||||
<LogLabel key={key} getRows={getRows} label={key} value={labels[key]} plain={plain} onClickLabel={onClickLabel} />
|
||||
));
|
||||
return (
|
||||
<span className="logs-labels">
|
||||
{Object.keys(labels).map(key => (
|
||||
<LogLabel
|
||||
key={key}
|
||||
getRows={getRows}
|
||||
label={key}
|
||||
value={labels[key]}
|
||||
plain={plain}
|
||||
onClickLabel={onClickLabel}
|
||||
/>
|
||||
))}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ export class LogRow extends PureComponent<Props, State> {
|
||||
</div>
|
||||
)}
|
||||
{showLocalTime && (
|
||||
<div className="logs-row__time" title={`${row.timestamp} (${row.timeFromNow})`}>
|
||||
<div className="logs-row__localtime" title={`${row.timestamp} (${row.timeFromNow})`}>
|
||||
{row.timeLocal}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<div class="login-form">
|
||||
<input type="password" name="password" class="gf-form-input login-form-input" required ng-model="formModel.password" id="inputPassword"
|
||||
placeholder="password">
|
||||
placeholder="{{passwordHint}}">
|
||||
</div>
|
||||
<div class="login-button-group">
|
||||
<button type="submit" class="btn btn-large p-x-2" ng-if="!loggingIn" ng-click="submit();" ng-class="{'btn-inverse': !loginForm.$valid, 'btn-primary': loginForm.$valid}">
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user