mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
refactoring: alert list improvments PR #10452
This commit is contained in:
commit
5d5de23025
@ -150,6 +150,7 @@
|
||||
"react-dom": "^16.2.0",
|
||||
"react-grid-layout": "^0.16.1",
|
||||
"react-popper": "^0.7.5",
|
||||
"react-highlight-words": "^0.10.0",
|
||||
"react-sizeme": "^2.3.6",
|
||||
"remarkable": "^1.7.1",
|
||||
"rxjs": "^5.4.3",
|
||||
|
@ -45,7 +45,7 @@ describe('AlertRuleList', () => {
|
||||
|
||||
it('should render 1 rule', () => {
|
||||
page.update();
|
||||
let ruleNode = page.find('.card-item-wrapper');
|
||||
let ruleNode = page.find('.alert-rule-item');
|
||||
expect(toJson(ruleNode)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
@ -5,6 +5,7 @@ import PageHeader from 'app/core/components/PageHeader/PageHeader';
|
||||
import { IAlertRule } from 'app/stores/AlertListStore/AlertListStore';
|
||||
import appEvents from 'app/core/app_events';
|
||||
import IContainerProps from 'app/containers/IContainerProps';
|
||||
import Highlighter from 'react-highlight-words';
|
||||
|
||||
@inject('view', 'nav', 'alertList')
|
||||
@observer
|
||||
@ -23,11 +24,6 @@ export class AlertRuleList extends React.Component<IContainerProps, any> {
|
||||
|
||||
this.props.nav.load('alerting', 'alert-list');
|
||||
this.fetchRules();
|
||||
this.handleTooltipPositionChange = this.handleTooltipPositionChange.bind(this);
|
||||
|
||||
this.state = {
|
||||
tooltipPosition: 'auto',
|
||||
};
|
||||
}
|
||||
|
||||
onStateFilterChanged = evt => {
|
||||
@ -49,12 +45,10 @@ export class AlertRuleList extends React.Component<IContainerProps, any> {
|
||||
});
|
||||
};
|
||||
|
||||
handleTooltipPositionChange(evt) {
|
||||
evt.preventDefault();
|
||||
this.setState({
|
||||
tooltipPosition: evt.target.value,
|
||||
});
|
||||
}
|
||||
onSearchQueryChange = evt => {
|
||||
this.props.alertList.setSearchQuery(evt.target.value);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { nav, alertList } = this.props;
|
||||
|
||||
@ -63,8 +57,20 @@ export class AlertRuleList extends React.Component<IContainerProps, any> {
|
||||
<PageHeader model={nav as any} />
|
||||
<div className="page-container page-body">
|
||||
<div className="page-action-bar">
|
||||
<div className="gf-form gf-form--grow">
|
||||
<label className="gf-form--has-input-icon gf-form--grow">
|
||||
<input
|
||||
type="text"
|
||||
className="gf-form-input"
|
||||
placeholder="Search alert"
|
||||
value={alertList.search}
|
||||
onChange={this.onSearchQueryChange}
|
||||
/>
|
||||
<i className="gf-form-input-icon fa fa-search" />
|
||||
</label>
|
||||
</div>
|
||||
<div className="gf-form">
|
||||
<label className="gf-form-label">Filter by state</label>
|
||||
<label className="gf-form-label">States</label>
|
||||
|
||||
<div className="gf-form-select-wrapper width-13">
|
||||
<select className="gf-form-input" onChange={this.onStateFilterChanged} value={alertList.stateFilter}>
|
||||
@ -80,8 +86,12 @@ export class AlertRuleList extends React.Component<IContainerProps, any> {
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<section className="card-section card-list-layout-list">
|
||||
<ol className="card-list">{alertList.rules.map(rule => <AlertRuleItem rule={rule} key={rule.id} />)}</ol>
|
||||
<section>
|
||||
<ol className="alert-rule-list">
|
||||
{alertList.filteredRules.map(rule => (
|
||||
<AlertRuleItem rule={rule} key={rule.id} search={alertList.search} />
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
@ -99,6 +109,7 @@ function AlertStateFilterOption({ text, value }) {
|
||||
|
||||
export interface AlertRuleItemProps {
|
||||
rule: IAlertRule;
|
||||
search: string;
|
||||
}
|
||||
|
||||
@observer
|
||||
@ -107,6 +118,16 @@ export class AlertRuleItem extends React.Component<AlertRuleItemProps, any> {
|
||||
this.props.rule.togglePaused();
|
||||
};
|
||||
|
||||
renderText(text: string) {
|
||||
return (
|
||||
<Highlighter
|
||||
highlightClassName="highlight-search-match"
|
||||
textToHighlight={text}
|
||||
searchWords={[this.props.search]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { rule } = this.props;
|
||||
|
||||
@ -119,36 +140,33 @@ export class AlertRuleItem extends React.Component<AlertRuleItemProps, any> {
|
||||
let ruleUrl = `dashboard/${rule.dashboardUri}?panelId=${rule.panelId}&fullscreen&edit&tab=alert`;
|
||||
|
||||
return (
|
||||
<li className="card-item-wrapper">
|
||||
<div className="card-item card-item--alert">
|
||||
<div className="card-item-header">
|
||||
<div className="card-item-type">
|
||||
<a
|
||||
className="card-item-cog"
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
onClick={this.toggleState}
|
||||
>
|
||||
<i className={stateClass} />
|
||||
</a>
|
||||
<a className="card-item-cog" href={ruleUrl} title="Edit alert rule">
|
||||
<i className="icon-gf icon-gf-settings" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card-item-body">
|
||||
<div className="card-item-details">
|
||||
<div className="card-item-name">
|
||||
<a href={ruleUrl}>{rule.name}</a>
|
||||
</div>
|
||||
<div className="card-item-sub-name">
|
||||
<span className={`alert-list-item-state ${rule.stateClass}`}>
|
||||
<i className={rule.stateIcon} /> {rule.stateText}
|
||||
</span>
|
||||
<span> for {rule.stateAge}</span>
|
||||
</div>
|
||||
{rule.info && <div className="small muted">{rule.info}</div>}
|
||||
<li className="alert-rule-item">
|
||||
<span className={`alert-rule-item__icon ${rule.stateClass}`}>
|
||||
<i className={rule.stateIcon} />
|
||||
</span>
|
||||
<div className="alert-rule-item__body">
|
||||
<div className="alert-rule-item__header">
|
||||
<div className="alert-rule-item__name">
|
||||
<a href={ruleUrl}>{this.renderText(rule.name)}</a>
|
||||
</div>
|
||||
<div className="alert-rule-item__text">
|
||||
<span className={`${rule.stateClass}`}>{this.renderText(rule.stateText)}</span>
|
||||
<span className="alert-rule-item__time"> for {rule.stateAge}</span>
|
||||
</div>
|
||||
</div>
|
||||
{rule.info && <div className="small muted alert-rule-item__info">{this.renderText(rule.info)}</div>}
|
||||
</div>
|
||||
<div className="alert-rule-item__actions">
|
||||
<a
|
||||
className="btn btn-small btn-inverse alert-list__btn width-2"
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
onClick={this.toggleState}
|
||||
>
|
||||
<i className={stateClass} />
|
||||
</a>
|
||||
<a className="btn btn-small btn-inverse alert-list__btn width-2" href={ruleUrl} title="Edit alert rule">
|
||||
<i className="icon-gf icon-gf-settings" />
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
|
@ -2,71 +2,102 @@
|
||||
|
||||
exports[`AlertRuleList should render 1 rule 1`] = `
|
||||
<li
|
||||
className="card-item-wrapper"
|
||||
className="alert-rule-item"
|
||||
>
|
||||
<span
|
||||
className="alert-rule-item__icon alert-state-ok"
|
||||
>
|
||||
<i
|
||||
className="icon-gf icon-gf-online"
|
||||
/>
|
||||
</span>
|
||||
<div
|
||||
className="card-item card-item--alert"
|
||||
className="alert-rule-item__body"
|
||||
>
|
||||
<div
|
||||
className="card-item-header"
|
||||
className="alert-rule-item__header"
|
||||
>
|
||||
<div
|
||||
className="card-item-type"
|
||||
className="alert-rule-item__name"
|
||||
>
|
||||
<a
|
||||
className="card-item-cog"
|
||||
onClick={[Function]}
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
>
|
||||
<i
|
||||
className="fa fa-pause"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
className="card-item-cog"
|
||||
href="dashboard/db/mygool?panelId=3&fullscreen&edit&tab=alert"
|
||||
title="Edit alert rule"
|
||||
>
|
||||
<i
|
||||
className="icon-gf icon-gf-settings"
|
||||
/>
|
||||
<Highlighter
|
||||
highlightClassName="highlight-search-match"
|
||||
searchWords={
|
||||
Array [
|
||||
"",
|
||||
]
|
||||
}
|
||||
textToHighlight="Panel Title alert"
|
||||
>
|
||||
<span>
|
||||
<span
|
||||
className=""
|
||||
key="0"
|
||||
>
|
||||
Panel Title alert
|
||||
</span>
|
||||
</span>
|
||||
</Highlighter>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="card-item-body"
|
||||
>
|
||||
<div
|
||||
className="card-item-details"
|
||||
className="alert-rule-item__text"
|
||||
>
|
||||
<div
|
||||
className="card-item-name"
|
||||
<span
|
||||
className="alert-state-ok"
|
||||
>
|
||||
<a
|
||||
href="dashboard/db/mygool?panelId=3&fullscreen&edit&tab=alert"
|
||||
<Highlighter
|
||||
highlightClassName="highlight-search-match"
|
||||
searchWords={
|
||||
Array [
|
||||
"",
|
||||
]
|
||||
}
|
||||
textToHighlight="OK"
|
||||
>
|
||||
Panel Title alert
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className="card-item-sub-name"
|
||||
<span>
|
||||
<span
|
||||
className=""
|
||||
key="0"
|
||||
>
|
||||
OK
|
||||
</span>
|
||||
</span>
|
||||
</Highlighter>
|
||||
</span>
|
||||
<span
|
||||
className="alert-rule-item__time"
|
||||
>
|
||||
<span
|
||||
className="alert-list-item-state alert-state-ok"
|
||||
>
|
||||
<i
|
||||
className="icon-gf icon-gf-online"
|
||||
/>
|
||||
|
||||
OK
|
||||
</span>
|
||||
<span>
|
||||
for
|
||||
5 minutes
|
||||
</span>
|
||||
</div>
|
||||
for
|
||||
5 minutes
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="alert-rule-item__actions"
|
||||
>
|
||||
<a
|
||||
className="btn btn-small btn-inverse alert-list__btn width-2"
|
||||
onClick={[Function]}
|
||||
title="Pausing an alert rule prevents it from executing"
|
||||
>
|
||||
<i
|
||||
className="fa fa-pause"
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
className="btn btn-small btn-inverse alert-list__btn width-2"
|
||||
href="dashboard/db/mygool?panelId=3&fullscreen&edit&tab=alert"
|
||||
title="Edit alert rule"
|
||||
>
|
||||
<i
|
||||
className="icon-gf icon-gf-settings"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
|
@ -138,10 +138,6 @@ function getAlertAnnotationInfo(ah) {
|
||||
return 'Error: ' + ah.data.error;
|
||||
}
|
||||
|
||||
if (ah.data.noData || ah.data.no_data) {
|
||||
return 'No Data';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<li ng-class="{active: ctrl.subTabIndex === 2}">
|
||||
<a ng-click="ctrl.changeTabIndex(2)">State history</a>
|
||||
</li>
|
||||
<li>
|
||||
<li>
|
||||
<a ng-click="ctrl.delete()">Delete</a>
|
||||
</li>
|
||||
</ul>
|
||||
@ -143,36 +143,33 @@
|
||||
<i>No state changes recorded</i>
|
||||
</div>
|
||||
|
||||
<section class="card-section card-list-layout-list">
|
||||
<ol class="card-list" >
|
||||
<li class="card-item-wrapper" ng-repeat="ah in ctrl.alertHistory">
|
||||
<div class="alert-list card-item card-item--alert">
|
||||
<div class="alert-list-body">
|
||||
<div class="alert-list-icon alert-list-item-state {{ah.stateModel.stateClass}}">
|
||||
<i class="{{ah.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-list-main alert-list-text">
|
||||
<span class="alert-list-state {{ah.stateModel.stateClass}}">{{ah.stateModel.text}}</span>
|
||||
<span class="alert-list-info">{{ah.info}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert-list-footer alert-list-text">
|
||||
<span>{{ah.time}}</span>
|
||||
<span><!--Img Link--></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<ol class="alert-rule-list" >
|
||||
<li class="alert-rule-item" ng-repeat="al in ctrl.alertHistory">
|
||||
<div class="alert-rule-item__icon {{al.stateModel.stateClass}}">
|
||||
<i class="{{al.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-rule-item__body">
|
||||
<div class="alert-rule-item__header">
|
||||
<div class="alert-rule-item__text">
|
||||
<span class="{{al.stateModel.stateClass}}">{{al.stateModel.text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="alert-list-info">{{al.info}}</span>
|
||||
</div>
|
||||
<div class="alert-rule-item__time">
|
||||
<span>{{al.time}}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group" ng-if="!ctrl.alert">
|
||||
<div class="gf-form-button-row">
|
||||
<button class="btn btn-inverse" ng-click="ctrl.enable()">
|
||||
<i class="icon-gf icon-gf-alert"></i>
|
||||
Create Alert
|
||||
</button>
|
||||
</div>
|
||||
<div class="gf-form-button-row">
|
||||
<button class="btn btn-inverse" ng-click="ctrl.enable()">
|
||||
<i class="icon-gf icon-gf-alert"></i>
|
||||
Create Alert
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,24 +3,22 @@
|
||||
{{ctrl.noAlertsMessage}}
|
||||
</div>
|
||||
|
||||
<section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'current'">
|
||||
<ol class="card-list">
|
||||
<li class="card-item-wrapper" ng-repeat="alert in ctrl.currentAlerts">
|
||||
<div class="alert-list card-item card-item--alert">
|
||||
<div class="alert-list-body">
|
||||
<div class="alert-list-icon alert-list-item-state {{alert.stateModel.stateClass}}">
|
||||
<i class="{{alert.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-list-main">
|
||||
<p class="alert-list-title">
|
||||
<a href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert">
|
||||
{{alert.name}}
|
||||
</a>
|
||||
</p>
|
||||
<p class="alert-list-text">
|
||||
<span class="alert-list-state {{alert.stateModel.stateClass}}">{{alert.stateModel.text}}</span>
|
||||
for {{alert.newStateDateAgo}}
|
||||
</p>
|
||||
<section ng-if="ctrl.panel.show === 'current'">
|
||||
<ol class="alert-rule-list">
|
||||
<li class="alert-rule-item" ng-repeat="alert in ctrl.currentAlerts">
|
||||
<div class="alert-rule-item__body">
|
||||
<div class="alert-rule-item__icon {{alert.stateModel.stateClass}}">
|
||||
<i class="{{alert.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-rule-item__header">
|
||||
<p class="alert-rule-item__name">
|
||||
<a href="dashboard/{{alert.dashboardUri}}?panelId={{alert.panelId}}&fullscreen&edit&tab=alert">
|
||||
{{alert.name}}
|
||||
</a>
|
||||
</p>
|
||||
<div class="alert-rule-item__text">
|
||||
<span class="{{alert.stateModel.stateClass}}">{{alert.stateModel.text}}</span>
|
||||
<span class="alert-rule-item__time">for {{alert.newStateDateAgo}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -28,30 +26,25 @@
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="card-section card-list-layout-list" ng-if="ctrl.panel.show === 'changes'">
|
||||
<ol class="card-list">
|
||||
<li class="card-item-wrapper" ng-repeat="al in ctrl.alertHistory">
|
||||
<div class="alert-list card-item card-item--alert">
|
||||
<div class="alert-list-body">
|
||||
<div class="alert-list-icon alert-list-item-state {{al.stateModel.stateClass}}">
|
||||
<i class="{{al.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-list-main">
|
||||
<p class="alert-list-title">{{al.alertName}}</p>
|
||||
<div class="alert-list-text">
|
||||
<span class="alert-list-state {{al.stateModel.stateClass}}">{{al.stateModel.text}}</span>
|
||||
<span class="alert-list-info alert-list-info-left">{{al.info}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert-list-footer">
|
||||
<span class="alert-list-text">{{al.time}}</span>
|
||||
<span class="alert-list-text">
|
||||
<!--Img Link-->
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section ng-if="ctrl.panel.show === 'changes'">
|
||||
<ol class="alert-rule-list">
|
||||
<li class="alert-rule-item" ng-repeat="al in ctrl.alertHistory">
|
||||
<div class="alert-rule-item__icon {{al.stateModel.stateClass}}">
|
||||
<i class="{{al.stateModel.iconClass}}"></i>
|
||||
</div>
|
||||
<div class="alert-rule-item__body">
|
||||
<div class="alert-rule-item__header">
|
||||
<p class="alert-rule-item__name">{{al.alertName}}</p>
|
||||
<div class="alert-rule-item__text">
|
||||
<span class="{{al.stateModel.stateClass}}">{{al.stateModel.text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="alert-rule-item__info">{{al.info}}</span>
|
||||
</div>
|
||||
<div class="alert-rule-item__time">
|
||||
<span>{{al.time}}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
</div>
|
||||
|
65
public/app/stores/AlertListStore/AlertListStore.jest.ts
Normal file
65
public/app/stores/AlertListStore/AlertListStore.jest.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { AlertListStore } from './AlertListStore';
|
||||
import { backendSrv } from 'test/mocks/common';
|
||||
import moment from 'moment';
|
||||
|
||||
function getRule(name, state, info) {
|
||||
return {
|
||||
id: 11,
|
||||
dashboardId: 58,
|
||||
panelId: 3,
|
||||
name: name,
|
||||
state: state,
|
||||
newStateDate: moment()
|
||||
.subtract(5, 'minutes')
|
||||
.format(),
|
||||
evalData: {},
|
||||
executionError: '',
|
||||
dashboardUri: 'db/mygool',
|
||||
stateText: state,
|
||||
stateIcon: 'fa',
|
||||
stateClass: 'asd',
|
||||
stateAge: '10m',
|
||||
info: info,
|
||||
};
|
||||
}
|
||||
|
||||
describe('AlertListStore', () => {
|
||||
let store;
|
||||
|
||||
beforeAll(() => {
|
||||
store = AlertListStore.create(
|
||||
{
|
||||
rules: [
|
||||
getRule('Europe', 'OK', 'backend-01'),
|
||||
getRule('Google', 'ALERTING', 'backend-02'),
|
||||
getRule('Amazon', 'PAUSED', 'backend-03'),
|
||||
getRule('West-Europe', 'PAUSED', 'backend-03'),
|
||||
],
|
||||
search: '',
|
||||
},
|
||||
{
|
||||
backendSrv: backendSrv,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('search should filter list on name', () => {
|
||||
store.setSearchQuery('urope');
|
||||
expect(store.filteredRules).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('search should filter list on state', () => {
|
||||
store.setSearchQuery('ale');
|
||||
expect(store.filteredRules).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('search should filter list on info', () => {
|
||||
store.setSearchQuery('-0');
|
||||
expect(store.filteredRules).toHaveLength(4);
|
||||
});
|
||||
|
||||
it('search should be equal', () => {
|
||||
store.setSearchQuery('alert');
|
||||
expect(store.search).toBe('alert');
|
||||
});
|
||||
});
|
@ -9,7 +9,16 @@ export const AlertListStore = types
|
||||
.model('AlertListStore', {
|
||||
rules: types.array(AlertRule),
|
||||
stateFilter: types.optional(types.string, 'all'),
|
||||
search: types.optional(types.string, ''),
|
||||
})
|
||||
.views(self => ({
|
||||
get filteredRules() {
|
||||
let regex = new RegExp(self.search, 'i');
|
||||
return self.rules.filter(alert => {
|
||||
return regex.test(alert.name) || regex.test(alert.stateText) || regex.test(alert.info);
|
||||
});
|
||||
},
|
||||
}))
|
||||
.actions(self => ({
|
||||
loadRules: flow(function* load(filters) {
|
||||
const backendSrv = getEnv(self).backendSrv;
|
||||
@ -31,4 +40,7 @@ export const AlertListStore = types
|
||||
self.rules.push(AlertRule.create(rule));
|
||||
}
|
||||
}),
|
||||
setSearchQuery(query: string) {
|
||||
self.search = query;
|
||||
},
|
||||
}));
|
||||
|
@ -299,7 +299,7 @@ blockquote {
|
||||
line-height: $line-height-base;
|
||||
color: $gray-2;
|
||||
&:before {
|
||||
content: "\2014 \00A0";
|
||||
content: '\2014 \00A0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,10 +316,10 @@ blockquote {
|
||||
}
|
||||
small {
|
||||
&:before {
|
||||
content: "";
|
||||
content: '';
|
||||
}
|
||||
&:after {
|
||||
content: "\00A0 \2014";
|
||||
content: '\00A0 \2014';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -330,7 +330,7 @@ q:before,
|
||||
q:after,
|
||||
blockquote:before,
|
||||
blockquote:after {
|
||||
content: "";
|
||||
content: '';
|
||||
}
|
||||
|
||||
// Addresses
|
||||
@ -409,3 +409,8 @@ a.external-link {
|
||||
.no-wrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.highlight-search-match {
|
||||
background: transparent;
|
||||
color: $yellow;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ $input-border: 1px solid $input-border-color;
|
||||
|
||||
.gf-form--has-input-icon {
|
||||
position: relative;
|
||||
margin-right: $gf-form-margin;
|
||||
|
||||
.gf-form-input-icon {
|
||||
position: absolute;
|
||||
|
@ -28,69 +28,6 @@
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Alert List
|
||||
.alert-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.alert-list-icon {
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.icon-gf,
|
||||
.fa {
|
||||
font-size: 200%;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-list-body {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.alert-list-main {
|
||||
padding: 0 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.alert-list-title {
|
||||
font-size: $font-size-base;
|
||||
margin: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.alert-list-state {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.alert-list-text {
|
||||
font-size: $font-size-sm;
|
||||
margin: 0;
|
||||
line-height: 1.5rem;
|
||||
color: $text-color-weak;
|
||||
}
|
||||
|
||||
.alert-list-info {
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.alert-list-info-left {
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
.alert-list-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.panel-has-alert {
|
||||
.panel-alert-icon:before {
|
||||
content: '\e611';
|
||||
@ -136,3 +73,94 @@
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Alert List
|
||||
// Alert List
|
||||
|
||||
.alert-rule-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.alert-rule-item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: $card-background;
|
||||
box-shadow: $card-shadow;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.alert-rule-item__body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.alert-rule-item__icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 40px;
|
||||
padding: 0 28px 0 16px;
|
||||
.icon-gf,
|
||||
.fa {
|
||||
font-size: 200%;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.alert-rule-item__header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.alert-rule-item__name {
|
||||
font-size: $font-size-base;
|
||||
margin: 0;
|
||||
font-weight: $font-weight-semi-bold;
|
||||
}
|
||||
|
||||
.alert-list__btn {
|
||||
margin: 0 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.alert-rule-item__text {
|
||||
font-weight: bold;
|
||||
font-size: $font-size-sm;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.alert-rule-item__time {
|
||||
color: $text-color-weak;
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.alert-rule-item__info {
|
||||
//color: $text-color;
|
||||
font-weight: normal;
|
||||
flex-grow: 2;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.alert-rule-item__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.alert-tesint {
|
||||
display: flex;
|
||||
}
|
||||
|
13
yarn.lock
13
yarn.lock
@ -4430,6 +4430,10 @@ header-case@^1.0.0:
|
||||
no-case "^2.2.0"
|
||||
upper-case "^1.1.3"
|
||||
|
||||
highlight-words-core@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/highlight-words-core/-/highlight-words-core-1.1.2.tgz#5c2717c4f6c6e7ea2462ab85b43ff8b24f58ec3e"
|
||||
|
||||
hmac-drbg@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||
@ -7921,7 +7925,7 @@ promzard@^0.3.0:
|
||||
dependencies:
|
||||
read "1"
|
||||
|
||||
prop-types@15.x, prop-types@^15.5.10, prop-types@^15.6.0:
|
||||
prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0:
|
||||
version "15.6.0"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||
dependencies:
|
||||
@ -8134,6 +8138,13 @@ react-popper@^0.7.5:
|
||||
popper.js "^1.12.5"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react-highlight-words@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/react-highlight-words/-/react-highlight-words-0.10.0.tgz#2e905c76c11635237f848ecad00600f1b6f6f4a8"
|
||||
dependencies:
|
||||
highlight-words-core "^1.1.0"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-resizable@^1.7.5:
|
||||
version "1.7.5"
|
||||
resolved "https://registry.yarnpkg.com/react-resizable/-/react-resizable-1.7.5.tgz#83eb75bb3684da6989bbbf4f826e1470f0af902e"
|
||||
|
Loading…
Reference in New Issue
Block a user