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:
ryan
2019-03-11 09:06:08 -07:00
35 changed files with 332 additions and 265 deletions
+1
View File
@@ -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
+1
View File
@@ -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
+11 -3
View File
@@ -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;
+14 -11
View File
@@ -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',
},
},
};
+5 -2
View File
@@ -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;
};
};
}
+1
View File
@@ -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 {
+1 -1
View File
@@ -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
+6 -1
View File
@@ -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
}
+2
View File
@@ -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()
+5 -4
View File
@@ -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"
+1
View File
@@ -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';
+3 -2
View File
@@ -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;
}, []);
-9
View File
@@ -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;
}
+28
View File
@@ -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()', () => {
+14 -3
View File
@@ -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>
);
}
}
+1 -1
View File
@@ -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);
});
});
+1 -1
View File
@@ -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}">
+3 -19
View File
@@ -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);
}
}
+14 -28
View File
@@ -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;
-23
View File
@@ -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
//
+2 -8
View File
@@ -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 {
+25 -4
View File
@@ -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 -18
View File
@@ -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 {
+15
View File
@@ -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;
}
-9
View File
@@ -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);
+1 -35
View File
@@ -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;