mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 00:55:47 -06:00
* Refactor: Adds Redux Toolkit package * Refactor: Uses configureStore from Redux Toolkit * Refactor: Migrates applicationReducer * Refactor: Migrates appNotificationsReducer * Refactor: Migrates locationReducer * Refactor: Migrates navModelReducer * Refactor: Migrates teamsReducer and teamReducer * Refactor: Migrates cleanUpAction * Refactor: Migrates alertRulesReducer * Refactor: Cleans up recursiveCleanState * Refactor: Switched to Angular compatible reducers * Refactor: Migrates folderReducer * Refactor: Migrates dashboardReducer * Migrates panelEditorReducer * Refactor: Migrates dataSourcesReducer * Refactor: Migrates usersReducer * Refactor: Migrates organizationReducer * Refactor: Migrates pluginsReducer * Refactor: Migrates ldapReducer and ldapUserReducer * Refactor: Migrates apiKeysReducer * Refactor: Migrates exploreReducer and itemReducer * Refactor: Removes actionCreatorFactory and reducerFactory * Refactor: Moves mocks to test section * Docs: Removes sections about home grown framework * Update contribute/style-guides/redux.md Co-Authored-By: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> * Refactor: Cleans up some code * Refactor: Adds state typings * Refactor: Cleans up typings * Refactor: Adds comment about ImmerJs autoFreeze Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
155 lines
4.7 KiB
TypeScript
155 lines
4.7 KiB
TypeScript
import React, { PureComponent } from 'react';
|
|
import { hot } from 'react-hot-loader';
|
|
import { connect } from 'react-redux';
|
|
import Page from 'app/core/components/Page/Page';
|
|
import AlertRuleItem from './AlertRuleItem';
|
|
import appEvents from 'app/core/app_events';
|
|
import { updateLocation } from 'app/core/actions';
|
|
import { getNavModel } from 'app/core/selectors/navModel';
|
|
import { AlertRule, CoreEvents, StoreState } from 'app/types';
|
|
import { getAlertRulesAsync, togglePauseAlertRule } from './state/actions';
|
|
import { getAlertRuleItems, getSearchQuery } from './state/selectors';
|
|
import { FilterInput } from 'app/core/components/FilterInput/FilterInput';
|
|
import { NavModel } from '@grafana/data';
|
|
import { setSearchQuery } from './state/reducers';
|
|
|
|
export interface Props {
|
|
navModel: NavModel;
|
|
alertRules: AlertRule[];
|
|
updateLocation: typeof updateLocation;
|
|
getAlertRulesAsync: typeof getAlertRulesAsync;
|
|
setSearchQuery: typeof setSearchQuery;
|
|
togglePauseAlertRule: typeof togglePauseAlertRule;
|
|
stateFilter: string;
|
|
search: string;
|
|
isLoading: boolean;
|
|
}
|
|
|
|
export class AlertRuleList extends PureComponent<Props, any> {
|
|
stateFilters = [
|
|
{ text: 'All', value: 'all' },
|
|
{ text: 'OK', value: 'ok' },
|
|
{ text: 'Not OK', value: 'not_ok' },
|
|
{ text: 'Alerting', value: 'alerting' },
|
|
{ text: 'No Data', value: 'no_data' },
|
|
{ text: 'Paused', value: 'paused' },
|
|
{ text: 'Pending', value: 'pending' },
|
|
];
|
|
|
|
componentDidMount() {
|
|
this.fetchRules();
|
|
}
|
|
|
|
componentDidUpdate(prevProps: Props) {
|
|
if (prevProps.stateFilter !== this.props.stateFilter) {
|
|
this.fetchRules();
|
|
}
|
|
}
|
|
|
|
async fetchRules() {
|
|
await this.props.getAlertRulesAsync({ state: this.getStateFilter() });
|
|
}
|
|
|
|
getStateFilter(): string {
|
|
const { stateFilter } = this.props;
|
|
if (stateFilter) {
|
|
return stateFilter.toString();
|
|
}
|
|
return 'all';
|
|
}
|
|
|
|
onStateFilterChanged = (evt: React.ChangeEvent<HTMLSelectElement>) => {
|
|
this.props.updateLocation({
|
|
query: { state: evt.target.value },
|
|
});
|
|
};
|
|
|
|
onOpenHowTo = () => {
|
|
appEvents.emit(CoreEvents.showModal, {
|
|
src: 'public/app/features/alerting/partials/alert_howto.html',
|
|
modalClass: 'confirm-modal',
|
|
model: {},
|
|
});
|
|
};
|
|
|
|
onSearchQueryChange = (value: string) => {
|
|
this.props.setSearchQuery(value);
|
|
};
|
|
|
|
onTogglePause = (rule: AlertRule) => {
|
|
this.props.togglePauseAlertRule(rule.id, { paused: rule.state !== 'paused' });
|
|
};
|
|
|
|
alertStateFilterOption = ({ text, value }: { text: string; value: string }) => {
|
|
return (
|
|
<option key={value} value={value}>
|
|
{text}
|
|
</option>
|
|
);
|
|
};
|
|
|
|
render() {
|
|
const { navModel, alertRules, search, isLoading } = this.props;
|
|
|
|
return (
|
|
<Page navModel={navModel}>
|
|
<Page.Contents isLoading={isLoading}>
|
|
<div className="page-action-bar">
|
|
<div className="gf-form gf-form--grow">
|
|
<FilterInput
|
|
labelClassName="gf-form--has-input-icon gf-form--grow"
|
|
inputClassName="gf-form-input"
|
|
placeholder="Search alerts"
|
|
value={search}
|
|
onChange={this.onSearchQueryChange}
|
|
/>
|
|
</div>
|
|
<div className="gf-form">
|
|
<label className="gf-form-label">States</label>
|
|
|
|
<div className="gf-form-select-wrapper width-13">
|
|
<select className="gf-form-input" onChange={this.onStateFilterChanged} value={this.getStateFilter()}>
|
|
{this.stateFilters.map(this.alertStateFilterOption)}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div className="page-action-bar__spacer" />
|
|
<a className="btn btn-secondary" onClick={this.onOpenHowTo}>
|
|
How to add an alert
|
|
</a>
|
|
</div>
|
|
<section>
|
|
<ol className="alert-rule-list">
|
|
{alertRules.map(rule => (
|
|
<AlertRuleItem
|
|
rule={rule}
|
|
key={rule.id}
|
|
search={search}
|
|
onTogglePause={() => this.onTogglePause(rule)}
|
|
/>
|
|
))}
|
|
</ol>
|
|
</section>
|
|
</Page.Contents>
|
|
</Page>
|
|
);
|
|
}
|
|
}
|
|
|
|
const mapStateToProps = (state: StoreState) => ({
|
|
navModel: getNavModel(state.navIndex, 'alert-list'),
|
|
alertRules: getAlertRuleItems(state.alertRules),
|
|
stateFilter: state.location.query.state,
|
|
search: getSearchQuery(state.alertRules),
|
|
isLoading: state.alertRules.isLoading,
|
|
});
|
|
|
|
const mapDispatchToProps = {
|
|
updateLocation,
|
|
getAlertRulesAsync,
|
|
setSearchQuery,
|
|
togglePauseAlertRule,
|
|
};
|
|
|
|
export default hot(module)(connect(mapStateToProps, mapDispatchToProps)(AlertRuleList));
|