Commit 758d1386 by Torkel Ödegaard Committed by GitHub

DashboardSettings: Update to new form styles (#31022)

* DashboardSettings: Update to new form styles

* Improve header margin and fixing issue in permissions tab

* Updated

* Switch to radio

* Remove unused import
parent b8a52ed0
......@@ -37,6 +37,7 @@ const collapsableSectionStyles = (theme: GrafanaTheme) => {
display: flex;
justify-content: space-between;
font-size: ${theme.typography.size.lg};
line-height: ${theme.spacing.base * 5}px;
cursor: pointer;
`,
headerCollapsed: css`
......
......@@ -21,7 +21,7 @@ export interface FieldProps extends HTMLAttributes<HTMLDivElement> {
/** Indicates if field is required */
required?: boolean;
/** Error message to display */
error?: string;
error?: string | null;
/** Indicates horizontal layout of the field */
horizontal?: boolean;
className?: string;
......
......@@ -25,7 +25,7 @@ const getStyles = stylesFactory(({ theme, name }: { theme: GrafanaTheme; name: s
white-space: nowrap;
text-shadow: none;
font-weight: 500;
line-height: 14px;
font-size: ${theme.typography.size.sm};
display: flex;
align-items: center;
`,
......@@ -43,7 +43,7 @@ export const TagItem: FC<Props> = ({ name, onRemove }) => {
return (
<div className={styles.itemStyle}>
<span className={styles.nameStyle}>{name}</span>
<Icon name="times" onClick={() => onRemove(name)} />
<Icon className="pointer" name="times" onClick={() => onRemove(name)} />
</div>
);
};
......@@ -94,17 +94,15 @@ export class DashboardPermissionsUnconnected extends PureComponent<Props, State>
<h5>You have changed folder, please save to view permissions.</h5>
) : (
<div>
<div className="dashboard-settings__header">
<div className="page-action-bar">
<h3 className="d-inline-block">Permissions</h3>
<Tooltip placement="auto" content={<PermissionsInfo />}>
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
</Tooltip>
<div className="page-action-bar__spacer" />
<Button className="pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
Add Permission
</Button>
</div>
<div className="page-action-bar">
<h3 className="page-sub-heading">Permissions</h3>
<Tooltip placement="auto" content={<PermissionsInfo />}>
<Icon className="icon--has-hover page-sub-heading-icon" name="question-circle" />
</Tooltip>
<div className="page-action-bar__spacer" />
<Button className="pull-right" onClick={this.onOpenAddPermissions} disabled={isAdding}>
Add Permission
</Button>
</div>
<SlideDown in={isAdding}>
<AddPermission onAddPermission={this.onAddPermission} onCancel={this.onCancelAddPermission} />
......
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { Input, Tooltip, defaultIntervals } from '@grafana/ui';
import { Input, defaultIntervals, Field } from '@grafana/ui';
import { getTimeSrv } from '../../services/TimeSrv';
......@@ -56,16 +56,19 @@ export const AutoRefreshIntervals: FC<Props> = ({
);
return (
<div className="gf-form">
<label className="gf-form-label width-7">Auto-refresh</label>
{invalidIntervalsMessage ? (
<Tooltip placement="right" content={invalidIntervalsMessage}>
<Input width={60} invalid value={intervalsString} onChange={onIntervalsChange} onBlur={onIntervalsBlur} />
</Tooltip>
) : (
<Input width={60} value={intervalsString} onChange={onIntervalsChange} onBlur={onIntervalsBlur} />
)}
</div>
<Field
label="Auto refresh"
description="Define the auto refresh intervals that should be available in the auto refresh dropdown"
error={invalidIntervalsMessage}
invalid={!!invalidIntervalsMessage}
>
<Input
invalid={!!invalidIntervalsMessage}
value={intervalsString}
onChange={onIntervalsChange}
onBlur={onIntervalsBlur}
/>
</Field>
);
};
......
import React, { useState } from 'react';
import { SelectableValue, TimeZone } from '@grafana/data';
import { Select, InlineSwitch, TagsInput, InlineField, Input } from '@grafana/ui';
import { Select, TagsInput, Input, Field, CollapsableSection, RadioButtonGroup } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
import { DashboardModel } from '../../state/DashboardModel';
......@@ -57,41 +57,50 @@ export const GeneralSettings: React.FC<Props> = ({ dashboard }) => {
dashboard.tags = tags;
};
const onEditableChange = (ev: React.FormEvent<HTMLInputElement>) => {
dashboard.editable = ev.currentTarget.checked;
const onEditableChange = (value: boolean) => {
dashboard.editable = value;
setRenderCounter(renderCounter + 1);
};
const editableOptions = [
{ label: 'Editable', value: true },
{ label: 'Read-only', value: false },
];
return (
<>
<div style={{ maxWidth: '600px' }}>
<h3 className="dashboard-settings__header" aria-label={selectors.pages.Dashboard.Settings.General.title}>
General
</h3>
<div className="gf-form-group">
<InlineField label="Name" labelWidth={14}>
<Input name="title" onBlur={onBlur} defaultValue={dashboard.title} width={60} />
</InlineField>
<InlineField label="Description" labelWidth={14}>
<Input name="description" onBlur={onBlur} defaultValue={dashboard.description} width={60} />
</InlineField>
<InlineField label="Tags" tooltip="Press enter to add a tag" labelWidth={14}>
<Field label="Name">
<Input name="title" onBlur={onBlur} defaultValue={dashboard.title} />
</Field>
<Field label="Description">
<Input name="description" onBlur={onBlur} defaultValue={dashboard.description} />
</Field>
<Field label="Tags" description="Press enter to add a tag">
<TagsInput tags={dashboard.tags} onChange={onTagsChange} />
</InlineField>
<FolderPicker
initialTitle={dashboard.meta.folderTitle}
initialFolderId={dashboard.meta.folderId}
onChange={onFolderChange}
enableCreateNew={true}
dashboardId={dashboard.id}
/>
<InlineField
</Field>
<Field label="Folder">
<FolderPicker
useNewForms={true}
initialTitle={dashboard.meta.folderTitle}
initialFolderId={dashboard.meta.folderId}
onChange={onFolderChange}
enableCreateNew={true}
dashboardId={dashboard.id}
/>
</Field>
<Field
label="Editable"
tooltip="Uncheck, then save and reload to disable all dashboard editing"
labelWidth={14}
description="Set to read-only to disable all editing. Reload the dashboard for changes to take effect"
>
<InlineSwitch value={dashboard.editable} onChange={onEditableChange} />
</InlineField>
<RadioButtonGroup value={dashboard.editable} options={editableOptions} onChange={onEditableChange} />
</Field>
</div>
<TimePickerSettings
onTimeZoneChange={onTimeZoneChange}
onRefreshIntervalChange={onRefreshIntervalChange}
......@@ -103,20 +112,23 @@ export const GeneralSettings: React.FC<Props> = ({ dashboard }) => {
timezone={dashboard.timezone}
/>
<h5 className="section-heading">Panel Options</h5>
<div className="gf-form">
<InlineField label="Graph Tooltip" labelWidth={14}>
<CollapsableSection label="Panel options" isOpen={true}>
<Field
label="Graph tooltip"
description="Controls tooltip and hover highlight behavior across different panels"
>
<Select
onChange={onTooltipChange}
options={GRAPH_TOOLTIP_OPTIONS}
width={40}
value={dashboard.graphTooltip}
/>
</InlineField>
</div>
</Field>
</CollapsableSection>
<div className="gf-form-button-row">
{dashboard.meta.canSave && <DeleteDashboardButton dashboard={dashboard} />}
</div>
</>
</div>
);
};
import React, { PureComponent } from 'react';
import { InlineField, Input, InlineSwitch, TimeZonePicker, Tooltip } from '@grafana/ui';
import { Input, TimeZonePicker, Field, Switch, CollapsableSection } from '@grafana/ui';
import { rangeUtil, TimeZone } from '@grafana/data';
import isEmpty from 'lodash/isEmpty';
import { selectors } from '@grafana/e2e-selectors';
......@@ -52,45 +52,34 @@ export class TimePickerSettings extends PureComponent<Props, State> {
render() {
return (
<div className="editor-row">
<h5 className="section-heading">Time Options</h5>
<div className="gf-form-group">
<div className="gf-form" aria-label={selectors.components.TimeZonePicker.container}>
<label className="gf-form-label width-7">Timezone</label>
<TimeZonePicker
includeInternal={true}
value={this.props.timezone}
onChange={this.onTimeZoneChange}
width={40}
/>
</div>
<AutoRefreshIntervals
refreshIntervals={this.props.refreshIntervals}
onRefreshIntervalChange={this.props.onRefreshIntervalChange}
<CollapsableSection label="Time options" isOpen={true}>
<Field label="Timezone" aria-label={selectors.components.TimeZonePicker.container}>
<TimeZonePicker
includeInternal={true}
value={this.props.timezone}
onChange={this.onTimeZoneChange}
width={40}
/>
<div className="gf-form">
<span className="gf-form-label width-7">Now delay now-</span>
<Tooltip
placement="right"
content={'Enter 1m to ignore the last minute (because it can contain incomplete metrics)'}
>
<Input
width={60}
invalid={!this.state.isNowDelayValid}
placeholder="0m"
onChange={this.onNowDelayChange}
defaultValue={this.props.nowDelay}
/>
</Tooltip>
</div>
<div className="gf-form">
<InlineField labelWidth={14} label="Hide time picker">
<InlineSwitch value={!!this.props.timePickerHidden} onChange={this.onHideTimePickerChange} />
</InlineField>
</div>
</div>
</div>
</Field>
<AutoRefreshIntervals
refreshIntervals={this.props.refreshIntervals}
onRefreshIntervalChange={this.props.onRefreshIntervalChange}
/>
<Field
label="Now delay now"
description="Enter 1m to ignore the last minute (because it can contain incomplete metrics)"
>
<Input
invalid={!this.state.isNowDelayValid}
placeholder="0m"
onChange={this.onNowDelayChange}
defaultValue={this.props.nowDelay}
/>
</Field>
<Field label="Hide time picker">
<Switch value={!!this.props.timePickerHidden} onChange={this.onHideTimePickerChange} />
</Field>
</CollapsableSection>
);
}
}
......@@ -52,8 +52,7 @@
.dashboard-settings__header {
font-size: $font-size-h3;
margin-bottom: $space-xl;
line-height: 36px;
margin-bottom: $space-md;
}
.dashboard-settings__subheader {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment