Merge branch 'panel-edit-in-react' of https://github.com/grafana/grafana into panel-edit-in-react
@@ -78,8 +78,8 @@ disable_login_form = true
|
||||
|
||||
### Automatic OAuth login
|
||||
|
||||
Set to true to attempt login with OAuth automatically, skipping the login screen.
|
||||
This setting is ignored if multiple OAuth providers are configured.
|
||||
Set to true to attempt login with OAuth automatically, skipping the login screen.
|
||||
This setting is ignored if multiple OAuth providers are configured.
|
||||
Defaults to `false`.
|
||||
|
||||
```bash
|
||||
@@ -95,3 +95,12 @@ Set to the option detailed below to true to hide sign-out menu link. Useful if y
|
||||
[auth]
|
||||
disable_signout_menu = true
|
||||
```
|
||||
|
||||
### URL redirect after signing out
|
||||
|
||||
URL to redirect the user to after signing out from Grafana. This can for example be used to enable signout from oauth provider.
|
||||
|
||||
```bash
|
||||
[auth]
|
||||
signout_redirect_url =
|
||||
```
|
||||
|
||||
@@ -584,8 +584,8 @@ kbn.valueFormats.flowcms = kbn.formatBuilders.fixedUnit('cms');
|
||||
kbn.valueFormats.flowcfs = kbn.formatBuilders.fixedUnit('cfs');
|
||||
kbn.valueFormats.flowcfm = kbn.formatBuilders.fixedUnit('cfm');
|
||||
kbn.valueFormats.litreh = kbn.formatBuilders.fixedUnit('l/h');
|
||||
kbn.valueFormats.flowlpm = kbn.formatBuilders.decimalSIPrefix('L');
|
||||
kbn.valueFormats.flowmlpm = kbn.formatBuilders.decimalSIPrefix('L', -1);
|
||||
kbn.valueFormats.flowlpm = kbn.formatBuilders.decimalSIPrefix('l/min');
|
||||
kbn.valueFormats.flowmlpm = kbn.formatBuilders.decimalSIPrefix('mL/min', -1);
|
||||
|
||||
// Angle
|
||||
kbn.valueFormats.degree = kbn.formatBuilders.fixedUnit('°');
|
||||
|
||||
@@ -64,7 +64,7 @@ export class AlertTab extends PureComponent<Props> {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<EditorTabBody toolbarItems={[]}>
|
||||
<EditorTabBody heading="Alert" toolbarItems={[]}>
|
||||
<div ref={element => (this.element = element)} />
|
||||
</EditorTabBody>
|
||||
);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { FadeIn } from 'app/core/components/Animations/FadeIn';
|
||||
|
||||
interface Props {
|
||||
children: JSX.Element;
|
||||
heading: string;
|
||||
main?: EditorToolBarView;
|
||||
toolbarItems: EditorToolBarView[];
|
||||
}
|
||||
@@ -19,6 +20,7 @@ export interface EditorToolBarView {
|
||||
|
||||
interface State {
|
||||
openView?: EditorToolBarView;
|
||||
fadeIn: boolean;
|
||||
}
|
||||
|
||||
export class EditorTabBody extends PureComponent<Props, State> {
|
||||
@@ -27,9 +29,14 @@ export class EditorTabBody extends PureComponent<Props, State> {
|
||||
|
||||
this.state = {
|
||||
openView: null,
|
||||
fadeIn: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({ fadeIn: true });
|
||||
}
|
||||
|
||||
onToggleToolBarView = (item: EditorToolBarView) => {
|
||||
this.setState({
|
||||
openView: item === this.state.openView ? null : item,
|
||||
@@ -94,24 +101,26 @@ export class EditorTabBody extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { children, toolbarItems, main } = this.props;
|
||||
const { openView } = this.state;
|
||||
const { children, toolbarItems, main, heading } = this.props;
|
||||
const { openView, fadeIn } = this.state;
|
||||
|
||||
return (
|
||||
<>
|
||||
{main && (
|
||||
<div className="toolbar">
|
||||
{this.renderMainSelection(main)}
|
||||
<div className="gf-form--grow" />
|
||||
{toolbarItems.map(item => this.renderButton(item))}
|
||||
</div>
|
||||
)}
|
||||
<div className="toolbar">
|
||||
<div className="toolbar__heading">{heading}</div>
|
||||
{main && this.renderMainSelection(main)}
|
||||
<div className="gf-form--grow" />
|
||||
{toolbarItems.map(item => this.renderButton(item))}
|
||||
</div>
|
||||
<div className="panel-editor__scroll">
|
||||
<CustomScrollbar autoHide={false}>
|
||||
<FadeIn in={openView !== null} duration={200}>
|
||||
<div className="panel-editor__toolbar-view">{openView && this.renderOpenView(openView)}</div>
|
||||
</FadeIn>
|
||||
<div className="panel-editor__content">
|
||||
<FadeIn in={openView !== null} duration={200}>
|
||||
{openView && this.renderOpenView(openView)}
|
||||
<FadeIn in={fadeIn} duration={50}>
|
||||
{children}
|
||||
</FadeIn>
|
||||
{children}
|
||||
</div>
|
||||
</CustomScrollbar>
|
||||
</div>
|
||||
|
||||
@@ -43,14 +43,8 @@ export class GeneralTab extends PureComponent<Props> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const currentDataSource = {
|
||||
title: 'ProductionDB',
|
||||
imgSrc: 'public/app/plugins/datasource/prometheus/img/prometheus_logo.svg',
|
||||
render: () => <h2>hello</h2>,
|
||||
};
|
||||
|
||||
return (
|
||||
<EditorTabBody main={currentDataSource} toolbarItems={[]}>
|
||||
<EditorTabBody heading="Basic Panel Options" toolbarItems={[]}>
|
||||
<div ref={element => (this.element = element)} />
|
||||
</EditorTabBody>
|
||||
);
|
||||
|
||||
@@ -26,7 +26,6 @@ interface PanelEditorProps {
|
||||
interface PanelEditorTab {
|
||||
id: string;
|
||||
text: string;
|
||||
icon: string;
|
||||
}
|
||||
|
||||
export class PanelEditor extends PureComponent<PanelEditorProps> {
|
||||
@@ -74,35 +73,37 @@ export class PanelEditor extends PureComponent<PanelEditorProps> {
|
||||
const activeTab = store.getState().location.query.tab || 'queries';
|
||||
|
||||
const tabs = [
|
||||
{ id: 'general', text: 'General', icon: 'gicon gicon-preferences' },
|
||||
{ id: 'queries', text: 'Queries', icon: 'fa fa-database' },
|
||||
{ id: 'visualization', text: 'Visualization', icon: 'fa fa-line-chart' },
|
||||
{ id: 'queries', text: 'Queries' },
|
||||
{ id: 'visualization', text: 'Visualization' },
|
||||
{ id: 'general', text: 'General' },
|
||||
];
|
||||
|
||||
if (config.alertingEnabled && plugin.id === 'graph') {
|
||||
tabs.push({
|
||||
id: 'alert',
|
||||
text: 'Alert',
|
||||
icon: 'gicon gicon-alert',
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="panel-editor-container__editor">
|
||||
<div className="panel-editor-resizer">
|
||||
<div className="panel-editor-resizer__handle">
|
||||
<div className="panel-editor-resizer__handle-dots" />
|
||||
</div>
|
||||
<div className="panel-editor__close">
|
||||
<i className="fa fa-arrow-left" />
|
||||
</div>
|
||||
{
|
||||
// <div className="panel-editor-resizer">
|
||||
// <div className="panel-editor-resizer__handle">
|
||||
// <div className="panel-editor-resizer__handle-dots" />
|
||||
// </div>
|
||||
// </div>
|
||||
}
|
||||
|
||||
<div className="panel-editor-tabs">
|
||||
<ul className="gf-tabs">
|
||||
{tabs.map(tab => {
|
||||
return <TabItem tab={tab} activeTab={activeTab} onClick={this.onChangeTab} key={tab.id} />;
|
||||
})}
|
||||
</ul>
|
||||
{tabs.map(tab => {
|
||||
return <TabItem tab={tab} activeTab={activeTab} onClick={this.onChangeTab} key={tab.id} />;
|
||||
})}
|
||||
</div>
|
||||
{this.renderCurrentTab(activeTab)}
|
||||
<div className="panel-editor__right">{this.renderCurrentTab(activeTab)}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -116,15 +117,15 @@ interface TabItemParams {
|
||||
|
||||
function TabItem({ tab, activeTab, onClick }: TabItemParams) {
|
||||
const tabClasses = classNames({
|
||||
'gf-tabs-link': true,
|
||||
'panel-editor-tabs__link': true,
|
||||
active: activeTab === tab.id,
|
||||
});
|
||||
|
||||
return (
|
||||
<li className="gf-tabs-item" onClick={() => onClick(tab)}>
|
||||
<div className="panel-editor-tabs__item" onClick={() => onClick(tab)}>
|
||||
<a className={tabClasses}>
|
||||
<i className={tab.icon} /> {tab.text}
|
||||
<img src={`public/img/panel-tabs/${tab.id}${activeTab === tab.id ? '-selected' : ''}.svg`} />
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -238,7 +238,7 @@ export class QueriesTab extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
return (
|
||||
<EditorTabBody main={dsInformation} toolbarItems={[queryInspector, dsHelp, options]}>
|
||||
<EditorTabBody heading="Queries" main={dsInformation} toolbarItems={[options, queryInspector, dsHelp]}>
|
||||
<div ref={element => (this.element = element)} style={{ width: '100%' }} />
|
||||
</EditorTabBody>
|
||||
);
|
||||
|
||||
@@ -126,8 +126,14 @@ export class VisualizationTab extends PureComponent<Props> {
|
||||
},
|
||||
};
|
||||
|
||||
const panelHelp = {
|
||||
title: '',
|
||||
icon: 'fa fa-question',
|
||||
render: () => <h2>Help</h2>,
|
||||
};
|
||||
|
||||
return (
|
||||
<EditorTabBody main={panelSelection} toolbarItems={[]}>
|
||||
<EditorTabBody heading="Visualization" main={panelSelection} toolbarItems={[panelHelp]}>
|
||||
{this.renderPanelOptions()}
|
||||
</EditorTabBody>
|
||||
);
|
||||
|
||||
@@ -67,10 +67,6 @@ export class VizTypePicker extends PureComponent<Props, State> {
|
||||
/>
|
||||
<i className="gf-form-input-icon fa fa-search" />
|
||||
</label>
|
||||
<div className="p-l-1">
|
||||
<button className="btn toggle-btn gf-form-btn active">Basic Types</button>
|
||||
<button className="btn toggle-btn gf-form-btn">Master Types</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class TypeaheadItem extends React.PureComponent<TypeaheadItemProps> {
|
||||
render() {
|
||||
const { isSelected, item, prefix } = this.props;
|
||||
const className = isSelected ? 'typeahead-item typeahead-item__selected' : 'typeahead-item';
|
||||
const { label } = item;
|
||||
const label = item.label || '';
|
||||
return (
|
||||
<li ref={this.getRef} className={className} onClick={this.onClick}>
|
||||
<Highlighter textToHighlight={label} searchWords={[prefix]} highlightClassName="typeahead-match" />
|
||||
|
||||
@@ -1,73 +1,3 @@
|
||||
<div class="gf-form-group">
|
||||
<div class="gf-form-inline">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label">Data Source</label>
|
||||
<gf-form-dropdown model="ctrl.panelDsValue" css-class="gf-size-auto"
|
||||
lookup-text="true"
|
||||
get-options="ctrl.getOptions(true)"
|
||||
on-change="ctrl.datasourceChanged($option)">
|
||||
</gf-form-dropdown>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow">
|
||||
<label class="gf-form-label gf-form-label--grow"></label>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.queryOptions">
|
||||
<a class="gf-form-label" ng-click="ctrl.toggleOptions()">
|
||||
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.optionsOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.optionsOpen"></i>Options
|
||||
</a>
|
||||
</div>
|
||||
<div class="gf-form" ng-if="ctrl.hasQueryHelp">
|
||||
<button class="gf-form-label" ng-click="ctrl.toggleHelp()">
|
||||
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.helpOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.helpOpen"></i>Help
|
||||
</button>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<button class="gf-form-label" ng-click="ctrl.toggleQueryTroubleshooter()" bs-tooltip="'Display query request & response'">
|
||||
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.queryTroubleshooterOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.queryTroubleshooterOpen"></i>Query Inspector
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div ng-if="ctrl.optionsOpen">
|
||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.minInterval">
|
||||
<label class="gf-form-label">Min time interval</label>
|
||||
<input type="text" class="gf-form-input width-6" placeholder="{{ctrl.panelCtrl.interval}}" ng-model="ctrl.panel.interval" spellcheck="false" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" />
|
||||
<info-popover mode="right-absolute">
|
||||
A lower limit for the auto group by time interval. Recommended to be set to write frequency,
|
||||
for example <code>1m</code> if your data is written every minute. Access auto interval via variable <code>$__interval</code> for time range
|
||||
string and <code>$__interval_ms</code> for numeric variable that can be used in math expressions.
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.cacheTimeout">
|
||||
<label class="gf-form-label width-9">Cache timeout</label>
|
||||
<input type="text" class="gf-form-input width-6" placeholder="60" ng-model="ctrl.panel.cacheTimeout" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" spellcheck="false" />
|
||||
<info-popover mode="right-absolute">
|
||||
If your time series store has a query cache this option can override the default
|
||||
cache timeout. Specify a numeric value in seconds.
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.maxDataPoints">
|
||||
<label class="gf-form-label width-9">Max data points</label>
|
||||
<input type="text" class="gf-form-input width-6" placeholder="auto" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" ng-model="ctrl.panel.maxDataPoints" spellcheck="false" />
|
||||
<info-popover mode="right-absolute">
|
||||
The maximum data points the query should return. For graphs this
|
||||
is automatically set to one data point per pixel.
|
||||
</info-popover>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grafana-info-box" ng-if="ctrl.helpOpen">
|
||||
<div class="markdown-html" ng-bind-html="ctrl.helpHtml"></div>
|
||||
<a class="grafana-info-box__close" ng-click="ctrl.toggleHelp()">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<query-troubleshooter panel-ctrl="ctrl.panelCtrl" is-open="ctrl.queryTroubleshooterOpen"></query-troubleshooter>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="query-editor-rows gf-form-group" ng-if="ctrl.datasourceInstance">
|
||||
<div ng-repeat="target in ctrl.panel.targets" ng-class="{'gf-form-disabled': target.hide}">
|
||||
|
||||
@@ -95,5 +95,14 @@ describe('Query imports', () => {
|
||||
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
|
||||
expect(result).toEqual('{foo="bar"}');
|
||||
});
|
||||
|
||||
it('returns selector query from selector query with all labels if logging label list is empty', async () => {
|
||||
const datasourceWithLabels = {
|
||||
metadataRequest: url => (url === '/api/prom/label' ? { data: { data: [] } } : { data: { data: [] } }),
|
||||
};
|
||||
const instance = new LanguageProvider(datasourceWithLabels);
|
||||
const result = await instance.importPrometheusQuery('metric{foo="bar",baz="42"}');
|
||||
expect(result).toEqual('{baz="42",foo="bar"}');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -97,9 +97,10 @@ export default class LoggingLanguageProvider extends LanguageProvider {
|
||||
|
||||
if (history && history.length > 0) {
|
||||
const historyItems = _.chain(history)
|
||||
.uniqBy('query.expr')
|
||||
.take(HISTORY_ITEM_COUNT)
|
||||
.map(h => h.query.expr)
|
||||
.filter()
|
||||
.uniq()
|
||||
.take(HISTORY_ITEM_COUNT)
|
||||
.map(wrapLabel)
|
||||
.map(item => addHistoryMetadata(item, history))
|
||||
.value();
|
||||
@@ -194,17 +195,24 @@ export default class LoggingLanguageProvider extends LanguageProvider {
|
||||
|
||||
// Keep only labels that exist on origin and target datasource
|
||||
await this.start(); // fetches all existing label keys
|
||||
const commonLabels = {};
|
||||
for (const key in labels) {
|
||||
const existingKeys = this.labelKeys[EMPTY_SELECTOR];
|
||||
if (existingKeys && existingKeys.indexOf(key) > -1) {
|
||||
// Should we check for label value equality here?
|
||||
commonLabels[key] = labels[key];
|
||||
const existingKeys = this.labelKeys[EMPTY_SELECTOR];
|
||||
let labelsToKeep = {};
|
||||
if (existingKeys && existingKeys.length > 0) {
|
||||
// Check for common labels
|
||||
for (const key in labels) {
|
||||
if (existingKeys && existingKeys.indexOf(key) > -1) {
|
||||
// Should we check for label value equality here?
|
||||
labelsToKeep[key] = labels[key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Keep all labels by default
|
||||
labelsToKeep = labels;
|
||||
}
|
||||
const labelKeys = Object.keys(commonLabels).sort();
|
||||
|
||||
const labelKeys = Object.keys(labelsToKeep).sort();
|
||||
const cleanSelector = labelKeys
|
||||
.map(key => `${key}${commonLabels[key].operator}${commonLabels[key].value}`)
|
||||
.map(key => `${key}${labelsToKeep[key].operator}${labelsToKeep[key].value}`)
|
||||
.join(',');
|
||||
|
||||
return ['{', cleanSelector, '}'].join('');
|
||||
|
||||
@@ -125,9 +125,10 @@ export default class PromQlLanguageProvider extends LanguageProvider {
|
||||
|
||||
if (history && history.length > 0) {
|
||||
const historyItems = _.chain(history)
|
||||
.uniqBy('query.expr')
|
||||
.take(HISTORY_ITEM_COUNT)
|
||||
.map(h => h.query.expr)
|
||||
.filter()
|
||||
.uniq()
|
||||
.take(HISTORY_ITEM_COUNT)
|
||||
.map(wrapLabel)
|
||||
.map(item => addHistoryMetadata(item, history))
|
||||
.value();
|
||||
|
||||
9
public/img/panel-tabs/alert-selected.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22" cy="22" r="20" fill="#09090B" stroke="#8E8E8E" stroke-width="4"/>
|
||||
<line x1="12.5925" y1="28.1482" x2="31.4073" y2="28.1482" stroke="#8E8E8E" stroke-width="4" stroke-linecap="round"/>
|
||||
<ellipse cx="22.0001" cy="20.3704" rx="8.96296" ry="9.77778" fill="#8E8E8E"/>
|
||||
<circle cx="22.0001" cy="30.1482" r="2.44444" fill="#8E8E8E"/>
|
||||
<line x1="18.7407" y1="30.463" x2="25.2592" y2="30.463" stroke="#09090B"/>
|
||||
<rect x="13.0371" y="20.3704" width="17.9259" height="6.51852" fill="#8E8E8E"/>
|
||||
<ellipse cx="22.0001" cy="11.0001" rx="0.814815" ry="1.22222" fill="#8E8E8E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 677 B |
9
public/img/panel-tabs/alert.svg
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22" cy="22" r="20" fill="#09090B" stroke="#8E8E8E" stroke-width="4"/>
|
||||
<line x1="12.5925" y1="28.1482" x2="31.4073" y2="28.1482" stroke="#8E8E8E" stroke-width="4" stroke-linecap="round"/>
|
||||
<ellipse cx="22.0001" cy="20.3704" rx="8.96296" ry="9.77778" fill="#8E8E8E"/>
|
||||
<circle cx="22.0001" cy="30.1482" r="2.44444" fill="#8E8E8E"/>
|
||||
<line x1="18.7407" y1="30.463" x2="25.2592" y2="30.463" stroke="#09090B"/>
|
||||
<rect x="13.0371" y="20.3704" width="17.9259" height="6.51852" fill="#8E8E8E"/>
|
||||
<ellipse cx="22.0001" cy="11.0001" rx="0.814815" ry="1.22222" fill="#8E8E8E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 677 B |
31
public/img/panel-tabs/general-selected.svg
Normal file
@@ -0,0 +1,31 @@
|
||||
<svg width="65" height="54" viewBox="0 0 65 54" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="27" cy="27" r="25" fill="#09090B" stroke="url(#paint0_linear)" stroke-width="4"/>
|
||||
<ellipse cx="27" cy="33" rx="14" ry="6" fill="url(#paint1_linear)"/>
|
||||
<ellipse cx="27" cy="30" rx="14" ry="6" fill="#09090B"/>
|
||||
<ellipse cx="27" cy="27" rx="14" ry="6" fill="url(#paint2_linear)"/>
|
||||
<ellipse cx="27" cy="24" rx="14" ry="6" fill="#09090B"/>
|
||||
<ellipse cx="27" cy="21" rx="14" ry="6" fill="url(#paint3_linear)"/>
|
||||
<path d="M52 37L65 26.9999L52 17L52 37Z" fill="url(#paint4_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="27" y1="0" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="27" y1="2.01165e-07" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="27" y1="1.40816e-06" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="27" y1="-6.03497e-07" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="57" y1="54" x2="57" y2="7.55191e-06" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EB7B18"/>
|
||||
<stop offset="1" stop-color="#D44A3A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
8
public/img/panel-tabs/general.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22" cy="22" r="20" fill="#09090B" stroke="#8E8E8E" stroke-width="4"/>
|
||||
<ellipse cx="21.9999" cy="26.8889" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
<ellipse cx="21.9999" cy="24.4444" rx="11.4074" ry="4.88889" fill="#09090B"/>
|
||||
<ellipse cx="21.9999" cy="22" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
<ellipse cx="21.9999" cy="19.5555" rx="11.4074" ry="4.88889" fill="#09090B"/>
|
||||
<ellipse cx="21.9999" cy="17.1111" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 570 B |
31
public/img/panel-tabs/queries-selected.svg
Normal file
@@ -0,0 +1,31 @@
|
||||
<svg width="65" height="54" viewBox="0 0 65 54" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="27" cy="27" r="25" fill="#09090B" stroke="url(#paint0_linear)" stroke-width="4"/>
|
||||
<ellipse cx="27" cy="33" rx="14" ry="6" fill="url(#paint1_linear)"/>
|
||||
<ellipse cx="27" cy="30" rx="14" ry="6" fill="#09090B"/>
|
||||
<ellipse cx="27" cy="27" rx="14" ry="6" fill="url(#paint2_linear)"/>
|
||||
<ellipse cx="27" cy="24" rx="14" ry="6" fill="#09090B"/>
|
||||
<ellipse cx="27" cy="21" rx="14" ry="6" fill="url(#paint3_linear)"/>
|
||||
<path d="M52 37L65 26.9999L52 17L52 37Z" fill="url(#paint4_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="27" y1="0" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="27" y1="2.01165e-07" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="27" y1="1.40816e-06" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="27" y1="-6.03497e-07" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#FEBC11"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="57" y1="54" x2="57" y2="7.55191e-06" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EB7B18"/>
|
||||
<stop offset="1" stop-color="#D44A3A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
8
public/img/panel-tabs/queries.svg
Normal file
@@ -0,0 +1,8 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22" cy="22" r="20" fill="#09090B" stroke="#8E8E8E" stroke-width="4"/>
|
||||
<ellipse cx="21.9999" cy="26.8889" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
<ellipse cx="21.9999" cy="24.4444" rx="11.4074" ry="4.88889" fill="#09090B"/>
|
||||
<ellipse cx="21.9999" cy="22" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
<ellipse cx="21.9999" cy="19.5555" rx="11.4074" ry="4.88889" fill="#09090B"/>
|
||||
<ellipse cx="21.9999" cy="17.1111" rx="11.4074" ry="4.88889" fill="#8E8E8E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 570 B |
34
public/img/panel-tabs/visualization-selected.svg
Normal file
@@ -0,0 +1,34 @@
|
||||
<svg width="65" height="54" viewBox="0 0 65 54" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="27" cy="27" r="25" fill="#09090B" stroke="url(#paint0_linear)" stroke-width="4"/>
|
||||
<path d="M39 21L35 17H39V21Z" fill="url(#paint1_linear)"/>
|
||||
<line x1="14" y1="15" x2="14" y2="39" stroke="url(#paint2_linear)" stroke-width="2"/>
|
||||
<line x1="41" y1="38" x2="14" y2="38" stroke="url(#paint3_linear)" stroke-width="2"/>
|
||||
<path d="M37 19L28 27L25 24L16 33" stroke="url(#paint4_linear)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M52 37L65 26.9999L52 17L52 37Z" fill="url(#paint5_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="27" y1="0" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear" x1="37" y1="-9.62518e-07" x2="37" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear" x1="13" y1="53.5" x2="13" y2="1.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EB7B18"/>
|
||||
<stop offset="1" stop-color="#D44A3A"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear" x1="27" y1="7.21113e-07" x2="27.5" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear" x1="27" y1="-4.4462e-08" x2="27" y2="54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#D44A3A"/>
|
||||
<stop offset="1" stop-color="#EB7B18"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear" x1="57" y1="54" x2="57" y2="7.55191e-06" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#EB7B18"/>
|
||||
<stop offset="1" stop-color="#D44A3A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
7
public/img/panel-tabs/visualization.svg
Normal file
@@ -0,0 +1,7 @@
|
||||
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="22" cy="22" r="20" fill="#09090B" stroke="#8E8E8E" stroke-width="4"/>
|
||||
<path d="M31.7778 17.1111L28.5186 13.8518H31.7778V17.1111Z" fill="#8E8E8E"/>
|
||||
<line x1="11" y1="12" x2="11" y2="32" stroke="#8E8E8E" stroke-width="2"/>
|
||||
<line x1="33" y1="31" x2="11" y2="31" stroke="#8E8E8E" stroke-width="2"/>
|
||||
<path d="M30.1482 15.4814L22.8149 22L20.3704 19.5555L13.0371 26.8889" stroke="#8E8E8E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 563 B |
@@ -79,6 +79,7 @@ $brand-gradient: linear-gradient(
|
||||
);
|
||||
|
||||
$page-gradient: linear-gradient(180deg, #222426 10px, rgb(22, 23, 25) 100px);
|
||||
$edit-gradient: linear-gradient(180deg, rgb(22, 23, 25) 00px, #090909 60%);
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@@ -268,9 +269,7 @@ $menu-dropdown-shadow: 5px 5px 20px -5px $black;
|
||||
$tab-border-color: $dark-4;
|
||||
|
||||
// Toolbar
|
||||
$toolbar-bg: $page-header-bg;
|
||||
$toolbar-shadow: 0 0 20px black;
|
||||
$toolbar-tab-bg: $gray-blue;
|
||||
$toolbar-bg: $black;
|
||||
|
||||
// Pagination
|
||||
// -------------------------
|
||||
@@ -367,6 +366,6 @@ $switch-slider-shadow: 0 0 3px black;
|
||||
//Checkbox
|
||||
// -------------------------
|
||||
$checkbox-bg: $dark-1;
|
||||
$checkbox-border: 1px solid $gray-2;
|
||||
$checkbox-border: 1px solid $gray-1;
|
||||
$checkbox-checked-bg: linear-gradient(0deg, $orange, $red);
|
||||
$checkbox-color: $dark-1;
|
||||
|
||||
@@ -76,6 +76,7 @@ $textShadow: none;
|
||||
// gradients
|
||||
$brand-gradient: linear-gradient(to right, rgba(255, 213, 0, 1) 0%, rgba(255, 68, 0, 1) 99%, rgba(255, 68, 0, 1) 100%);
|
||||
$page-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%);
|
||||
$edit-gradient: linear-gradient(-60deg, $gray-7, #f5f6f9 70%, $gray-7 98%);
|
||||
|
||||
// Links
|
||||
// -------------------------
|
||||
@@ -215,9 +216,7 @@ $menu-dropdown-shadow: 5px 5px 10px -5px $gray-1;
|
||||
$tab-border-color: $gray-5;
|
||||
|
||||
// Toolbar
|
||||
$toolbar-bg: linear-gradient(90deg, #ffffff, #e6eef9);
|
||||
$toolbar-shadow: 1px 1px 3px #c7d0d8;
|
||||
$toolbar-tab-bg: $white;
|
||||
$toolbar-bg: white;
|
||||
|
||||
// search
|
||||
$search-shadow: 0 5px 30px 0 $gray-4;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
.footer {
|
||||
color: $footer-link-color;
|
||||
padding: 5rem 0 1rem 0;
|
||||
padding: 1rem 0 1rem 0;
|
||||
font-size: $font-size-sm;
|
||||
position: relative;
|
||||
width: 98%; /* was causing horiz scrollbars - need to examine */
|
||||
@@ -38,6 +38,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Keeping footer inside the graphic on Login screen
|
||||
.login-page {
|
||||
.footer {
|
||||
bottom: $spacer;
|
||||
|
||||
@@ -82,7 +82,7 @@ $input-border: 1px solid $input-border-color;
|
||||
align-content: flex-start;
|
||||
|
||||
.gf-form + .gf-form {
|
||||
margin-right: $gf-form-margin;
|
||||
margin-left: $gf-form-margin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,6 @@ $input-border: 1px solid $input-border-color;
|
||||
width: 100%;
|
||||
height: $gf-form-input-height;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin-right: $gf-form-margin;
|
||||
font-size: $font-size-md;
|
||||
line-height: $input-line-height;
|
||||
color: $input-color;
|
||||
@@ -181,6 +180,7 @@ $input-border: 1px solid $input-border-color;
|
||||
@at-root textarea#{&} {
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// Unstyle the caret on `<select>`s in IE10+.
|
||||
|
||||
@@ -24,11 +24,40 @@
|
||||
.panel-editor-container__editor {
|
||||
margin-top: $panel-margin*2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 65%;
|
||||
flex-direction: row;
|
||||
height: 60%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-editor__right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
background: $page-bg;
|
||||
margin: 0 62px;
|
||||
border-left: 2px solid #ac5224;
|
||||
border-radius: 3px;
|
||||
box-shadow: $popover-shadow;
|
||||
}
|
||||
|
||||
.panel-editor__close {
|
||||
@include buttonBackground($btn-inverse-bg, $btn-inverse-bg-hl);
|
||||
position: absolute;
|
||||
left: 11px;
|
||||
top: 5px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
flex-grow: 1;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-editor__scroll {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
@@ -39,6 +68,11 @@
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.panel-editor__toolbar-view {
|
||||
background: $black;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.panel-in-fullscreen {
|
||||
.sidemenu {
|
||||
display: none;
|
||||
@@ -106,9 +140,8 @@
|
||||
}
|
||||
|
||||
.viz-picker__item {
|
||||
background: $card-background;
|
||||
box-shadow: $card-shadow;
|
||||
|
||||
background: $panel-bg;
|
||||
border: $panel-border;
|
||||
border-radius: 3px;
|
||||
height: 90px;
|
||||
width: 150px;
|
||||
@@ -149,22 +182,46 @@
|
||||
.panel-editor-tabs {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
box-shadow: $page-header-shadow;
|
||||
border-bottom: 1px solid $page-header-border-color;
|
||||
padding: 0 $dashboard-padding;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
top: 79px;
|
||||
left: 9px;
|
||||
align-items: flex-start;
|
||||
|
||||
@include clearfix();
|
||||
|
||||
.active.gf-tabs-link {
|
||||
background: $toolbar-tab-bg;
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 21px;
|
||||
width: 2px;
|
||||
background: #8e8e8e;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-editor-tabs__close {
|
||||
padding: 5px 9px;
|
||||
border-radius: $border-radius;
|
||||
float: right;
|
||||
@include buttonBackground($btn-primary-bg, $btn-primary-bg-hl);
|
||||
.panel-editor-tabs__item {
|
||||
margin-bottom: 25px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
text-align: center;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.panel-editor-tabs__link {
|
||||
display: inline-block;
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
.ds-picker-list {
|
||||
@@ -175,9 +232,8 @@
|
||||
}
|
||||
|
||||
.ds-picker-list__item {
|
||||
background: $card-background;
|
||||
box-shadow: $card-shadow;
|
||||
|
||||
background: $panel-bg;
|
||||
border: $panel-border;
|
||||
border-radius: 3px;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
}
|
||||
|
||||
.gf-form + .gf-form {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,18 @@
|
||||
display: flex;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
background: $toolbar-bg;
|
||||
box-shadow: $toolbar-shadow;
|
||||
padding: 7px 20px 7px 20px;
|
||||
padding: 3px 20px 3px 20px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 0 0 auto;
|
||||
background: $toolbar-bg;
|
||||
border-radius: 3px;
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.toolbar__heading {
|
||||
font-size: $font-size-lg;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.toolbar__main {
|
||||
@@ -36,20 +42,12 @@
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.toolbar-subview {
|
||||
position: relative;
|
||||
padding: 20px 20px;
|
||||
background-color: $empty-list-cta-bg;
|
||||
top: -45px;
|
||||
margin: 0 30px 20px 0px;
|
||||
}
|
||||
|
||||
.toolbar-subview__close {
|
||||
background: transparent;
|
||||
padding: 4px 8px 4px 9px;
|
||||
border: none;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
right: 25px;
|
||||
top: 20px;
|
||||
font-size: $font-size-md;
|
||||
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
background: $page-gradient;
|
||||
}
|
||||
|
||||
.panel-in-fullscreen {
|
||||
.main-view {
|
||||
background: $edit-gradient;
|
||||
}
|
||||
}
|
||||
|
||||
.page-container {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
@@ -40,6 +46,29 @@
|
||||
&--dashboard {
|
||||
height: calc(100% - 56px);
|
||||
}
|
||||
|
||||
// Sticky footer
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> div {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
> .footer {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
// Render in correct position even ng-view div is not rendered yet
|
||||
> .footer:first-child {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
|
||||
> * {
|
||||
width: 100%;
|
||||
align-self: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fix for phantomjs
|
||||
|
||||