Bump MobX version to 6.12 and simplify stores (#3561)
# What this PR does - update "mobx" to "6.12.0", "mobx-react" to "9.1.0", - add `runInAction` when update observables after async operations - update babel config and ts config according to the [guide](https://mobx.js.org/migrating-from-4-or-5.html) - add `makeObservable(this);` to each model constructor ## Which issue(s) this PR fixes https://github.com/grafana/oncall/issues/3453 ## Checklist - [ ] Unit, integration, and e2e (if applicable) tests updated - [ ] Documentation added (or `pr:no public docs` PR label added if not required) - [ ] `CHANGELOG.md` updated (or `pr:no changelog` PR label added if not required)
This commit is contained in:
parent
44ec718d7c
commit
59a064e05a
53 changed files with 954 additions and 807 deletions
|
|
@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Changed
|
||||
|
||||
- Handle message to reply to not found in Telegram send log ([#3587](https://github.com/grafana/oncall/pull/3587))
|
||||
- Upgrade mobx lib to the latest version 6.12.0 ([#3453](https://github.com/grafana/oncall/issues/3453))
|
||||
|
||||
## v1.3.81 (2023-12-28)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
||||
["@babel/plugin-transform-destructuring", { "useBuiltIns": true }],
|
||||
"@babel/plugin-transform-runtime",
|
||||
"@babel/proposal-class-properties",
|
||||
["@babel/plugin-proposal-class-properties", { "loose": false }],
|
||||
"@babel/transform-regenerator",
|
||||
"@babel/plugin-transform-template-literals"
|
||||
]
|
||||
|
|
|
|||
|
|
@ -133,8 +133,8 @@
|
|||
"dayjs": "^1.11.5",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"immutability-helper": "^3.1.1",
|
||||
"mobx": "5.13.0",
|
||||
"mobx-react": "6.1.1",
|
||||
"mobx": "6.12.0",
|
||||
"mobx-react": "9.1.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"openapi-fetch": "^0.8.1",
|
||||
"prettier": "^2.8.2",
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import {
|
|||
import { GrafanaTeamStore } from 'models/grafana_team/grafana_team';
|
||||
import { OutgoingWebhookStore } from 'models/outgoing_webhook/outgoing_webhook';
|
||||
import { ScheduleStore } from 'models/schedule/schedule';
|
||||
import { WaitDelay } from 'models/wait_delay';
|
||||
import { SelectOption } from 'state/types';
|
||||
import { getVar } from 'utils/DOM';
|
||||
import { UserActions } from 'utils/authorization';
|
||||
|
|
@ -255,7 +254,7 @@ export class EscalationPolicy extends React.Component<EscalationPolicyProps, any
|
|||
// @ts-ignore
|
||||
value={wait_delay}
|
||||
onChange={this._getOnSelectChangeHandler('wait_delay')}
|
||||
options={waitDelays.map((waitDelay: WaitDelay) => ({
|
||||
options={waitDelays.map((waitDelay: SelectOption) => ({
|
||||
value: waitDelay.value,
|
||||
label: waitDelay.display_name,
|
||||
}))}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ import { SortableElement } from 'react-sortable-hoc';
|
|||
import PluginLink from 'components/PluginLink/PluginLink';
|
||||
import Timeline from 'components/Timeline/Timeline';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { Channel } from 'models/channel';
|
||||
import { NotificationPolicyType, prepareNotificationPolicy } from 'models/notification_policy';
|
||||
import { NotifyBy } from 'models/notify_by';
|
||||
import { Channel } from 'models/channel/channel';
|
||||
import { NotificationPolicyType, prepareNotificationPolicy } from 'models/notification_policy/notification_policy';
|
||||
import { User } from 'models/user/user.types';
|
||||
import { WaitDelay } from 'models/wait_delay';
|
||||
import { RootStore } from 'state';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { SelectOption } from 'state/types';
|
||||
import { UserAction } from 'utils/authorization';
|
||||
|
||||
import DragHandle from './DragHandle';
|
||||
|
|
@ -34,8 +33,8 @@ export interface NotificationPolicyProps {
|
|||
onDelete: (id: string) => void;
|
||||
notificationChoices: any[];
|
||||
channels?: any[];
|
||||
waitDelays?: WaitDelay[];
|
||||
notifyByOptions?: NotifyBy[];
|
||||
waitDelays?: SelectOption[];
|
||||
notifyByOptions?: SelectOption[];
|
||||
telegramVerified: boolean;
|
||||
phoneStatus: number;
|
||||
isMobileAppConnected: boolean;
|
||||
|
|
@ -185,7 +184,7 @@ export class NotificationPolicy extends React.Component<NotificationPolicyProps,
|
|||
value={wait_delay}
|
||||
disabled={disabled}
|
||||
onChange={this._getOnChangeHandler('wait_delay')}
|
||||
options={waitDelays.map((waitDelay: WaitDelay) => ({
|
||||
options={waitDelays.map((waitDelay: SelectOption) => ({
|
||||
label: waitDelay.display_name,
|
||||
value: waitDelay.value,
|
||||
}))}
|
||||
|
|
@ -208,7 +207,7 @@ export class NotificationPolicy extends React.Component<NotificationPolicyProps,
|
|||
value={notify_by}
|
||||
disabled={disabled}
|
||||
onChange={this._getOnChangeHandler('notify_by')}
|
||||
options={notifyByOptions.map((notifyByOption: NotifyBy) => ({
|
||||
options={notifyByOptions.map((notifyByOption: SelectOption) => ({
|
||||
label: notifyByOption.display_name,
|
||||
value: notifyByOption.value,
|
||||
}))}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { VerticalGroup } from '@grafana/ui';
|
|||
import Timeline from 'components/Timeline/Timeline';
|
||||
import SlackConnector from 'containers/AlertRules/parts/connectors/SlackConnector';
|
||||
import TelegramConnector from 'containers/AlertRules/parts/connectors/TelegramConnector';
|
||||
import { ChannelFilter } from 'models/channel_filter';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { getVar } from 'utils/DOM';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import TooltipBadge from 'components/TooltipBadge/TooltipBadge';
|
|||
import styles from 'containers/IntegrationContainers/CollapsedIntegrationRouteDisplay/CollapsedIntegrationRouteDisplay.module.scss';
|
||||
import { RouteButtonsDisplay } from 'containers/IntegrationContainers/ExpandedIntegrationRouteDisplay/ExpandedIntegrationRouteDisplay';
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { ChannelFilter } from 'models/channel_filter';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
import CommonIntegrationHelper from 'pages/integration/CommonIntegration.helper';
|
||||
import IntegrationHelper from 'pages/integration/Integration.helper';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import styles from 'containers/IntegrationContainers/ExpandedIntegrationRouteDis
|
|||
import TeamName from 'containers/TeamName/TeamName';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
|
||||
import CommonIntegrationHelper from 'pages/integration/CommonIntegration.helper';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { MONACO_READONLY_CONFIG } from 'components/MonacoEditor/MonacoEditor.con
|
|||
import Text from 'components/Text/Text';
|
||||
import { templatesToRender } from 'containers/IntegrationContainers/IntegrationTemplatesList.config';
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import IntegrationHelper from 'pages/integration/Integration.helper';
|
||||
import styles from 'pages/integration/Integration.module.scss';
|
||||
import { MONACO_INPUT_HEIGHT_TALL } from 'pages/integration/IntegrationCommon.config';
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import TemplateResult from 'containers/TemplateResult/TemplateResult';
|
|||
import TemplatesAlertGroupsList, { TEMPLATE_PAGE } from 'containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import { Alert } from 'models/alertgroup/alertgroup.types';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
import { TemplateOptions } from 'pages/integration/Integration.config';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import SortableList from 'components/SortableList/SortableList';
|
|||
import Text from 'components/Text/Text';
|
||||
import Timeline from 'components/Timeline/Timeline';
|
||||
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
|
||||
import { NotificationPolicyType } from 'models/notification_policy';
|
||||
import { NotificationPolicyType } from 'models/notification_policy/notification_policy';
|
||||
import { User as UserType } from 'models/user/user.types';
|
||||
import { AppFeature } from 'state/features';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { MONACO_EDITABLE_CONFIG } from 'components/MonacoEditor/MonacoEditor.con
|
|||
import Text from 'components/Text/Text';
|
||||
import TooltipBadge from 'components/TooltipBadge/TooltipBadge';
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import { Alert } from 'models/alertgroup/alertgroup.types';
|
||||
import { OutgoingWebhook, OutgoingWebhookResponse } from 'models/outgoing_webhook/outgoing_webhook.types';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { omit } from 'lodash-es';
|
||||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import { Alert } from 'models/alertgroup/alertgroup.types';
|
||||
import BaseStore from 'models/base_store';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
|
|
@ -9,7 +9,6 @@ import { GrafanaTeam } from 'models/grafana_team/grafana_team.types';
|
|||
import { Heartbeat } from 'models/heartbeat/heartbeat.types';
|
||||
import { OutgoingWebhook } from 'models/outgoing_webhook/outgoing_webhook.types';
|
||||
import { makeRequest } from 'network';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
import { move } from 'state/helpers';
|
||||
import { SelectOption } from 'state/types';
|
||||
|
|
@ -64,6 +63,8 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/alert_receive_channels/';
|
||||
}
|
||||
|
||||
|
|
@ -95,11 +96,13 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
async loadItem(id: AlertReceiveChannel['id'], skipErrorHandling = false): Promise<AlertReceiveChannel> {
|
||||
const alertReceiveChannel = await this.getById(id, skipErrorHandling);
|
||||
|
||||
// @ts-ignore
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: omit(alertReceiveChannel, 'heartbeat'),
|
||||
};
|
||||
runInAction(() => {
|
||||
// @ts-ignore
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: omit(alertReceiveChannel, 'heartbeat'),
|
||||
};
|
||||
});
|
||||
|
||||
this.populateHearbeats([alertReceiveChannel]);
|
||||
|
||||
|
|
@ -112,20 +115,24 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
|
||||
const { results } = await makeRequest(this.path, { params });
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: AlertReceiveChannel }, item: AlertReceiveChannel) => ({
|
||||
...acc,
|
||||
[item.id]: omit(item, 'heartbeat'),
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: AlertReceiveChannel }, item: AlertReceiveChannel) => ({
|
||||
...acc,
|
||||
[item.id]: omit(item, 'heartbeat'),
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
this.populateHearbeats(results);
|
||||
|
||||
this.searchResult = results.map((item: AlertReceiveChannel) => item.id);
|
||||
runInAction(() => {
|
||||
this.searchResult = results.map((item: AlertReceiveChannel) => item.id);
|
||||
});
|
||||
|
||||
this.updateCounters();
|
||||
|
||||
|
|
@ -149,24 +156,28 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: AlertReceiveChannel }, item: AlertReceiveChannel) => ({
|
||||
...acc,
|
||||
[item.id]: omit(item, 'heartbeat'),
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: AlertReceiveChannel }, item: AlertReceiveChannel) => ({
|
||||
...acc,
|
||||
[item.id]: omit(item, 'heartbeat'),
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
this.populateHearbeats(results);
|
||||
|
||||
this.paginatedSearchResult = {
|
||||
count,
|
||||
results: results.map((item: AlertReceiveChannel) => item.id),
|
||||
page_size,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.paginatedSearchResult = {
|
||||
count,
|
||||
results: results.map((item: AlertReceiveChannel) => item.id),
|
||||
page_size,
|
||||
};
|
||||
});
|
||||
|
||||
if (updateCounters) {
|
||||
this.updateCounters();
|
||||
|
|
@ -184,10 +195,12 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
return acc;
|
||||
}, {});
|
||||
|
||||
this.rootStore.heartbeatStore.items = {
|
||||
...this.rootStore.heartbeatStore.items,
|
||||
...heartbeats,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.rootStore.heartbeatStore.items = {
|
||||
...this.rootStore.heartbeatStore.items,
|
||||
...heartbeats,
|
||||
};
|
||||
});
|
||||
|
||||
const alertReceiveChannelToHeartbeat = alertReceiveChannels.reduce(
|
||||
(acc: any, alertReceiveChannel: AlertReceiveChannel) => {
|
||||
|
|
@ -200,10 +213,12 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
{}
|
||||
);
|
||||
|
||||
this.alertReceiveChannelToHeartbeat = {
|
||||
...this.alertReceiveChannelToHeartbeat,
|
||||
...alertReceiveChannelToHeartbeat,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.alertReceiveChannelToHeartbeat = {
|
||||
...this.alertReceiveChannelToHeartbeat,
|
||||
...alertReceiveChannelToHeartbeat,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -220,42 +235,48 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
{}
|
||||
);
|
||||
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
...channelFilters,
|
||||
};
|
||||
|
||||
if (isOverwrite) {
|
||||
// This is needed because on Move Up/Down/Removal the store no longer reflects the correct state
|
||||
runInAction(() => {
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
...channelFilters,
|
||||
};
|
||||
});
|
||||
|
||||
if (isOverwrite) {
|
||||
runInAction(() => {
|
||||
// This is needed because on Move Up/Down/Removal the store no longer reflects the correct state
|
||||
this.channelFilters = {
|
||||
...channelFilters,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
this.channelFilterIds = {
|
||||
...this.channelFilterIds,
|
||||
[alertReceiveChannelId]: response.map((channelFilter: ChannelFilter) => channelFilter.id),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.channelFilterIds = {
|
||||
...this.channelFilterIds,
|
||||
[alertReceiveChannelId]: response.map((channelFilter: ChannelFilter) => channelFilter.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateChannelFilter(channelFilterId: ChannelFilter['id']) {
|
||||
const response = await makeRequest(`/channel_filters/${channelFilterId}/`, {});
|
||||
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
[channelFilterId]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
[channelFilterId]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async migrateChannel(id: AlertReceiveChannel['id']) {
|
||||
return await makeRequest(`/alert_receive_channels/${id}/migrate`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async createChannelFilter(data: Partial<ChannelFilter>) {
|
||||
return await makeRequest('/channel_filters/', {
|
||||
method: 'POST',
|
||||
|
|
@ -270,10 +291,12 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
data,
|
||||
});
|
||||
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
[response.id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.channelFilters = {
|
||||
...this.channelFilters,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -284,8 +307,6 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
oldIndex: number,
|
||||
newIndex: number
|
||||
) {
|
||||
Mixpanel.track('Move ChannelFilter', null);
|
||||
|
||||
const channelFilterId = this.channelFilterIds[alertReceiveChannelId][oldIndex];
|
||||
|
||||
this.channelFilterIds[alertReceiveChannelId] = move(
|
||||
|
|
@ -301,8 +322,6 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
|
||||
@action
|
||||
async deleteChannelFilter(channelFilterId: ChannelFilter['id']) {
|
||||
Mixpanel.track('Delete ChannelFilter', null);
|
||||
|
||||
const channelFilter = this.channelFilters[channelFilterId];
|
||||
|
||||
this.channelFilterIds[channelFilter.alert_receive_channel].splice(
|
||||
|
|
@ -320,7 +339,10 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
@action.bound
|
||||
async updateAlertReceiveChannelOptions() {
|
||||
const response = await makeRequest(`/alert_receive_channels/integration_options/`, {});
|
||||
this.alertReceiveChannelOptions = response;
|
||||
|
||||
runInAction(() => {
|
||||
this.alertReceiveChannelOptions = response;
|
||||
});
|
||||
}
|
||||
|
||||
getIntegration(alertReceiveChannel: Partial<AlertReceiveChannel>): SelectOption {
|
||||
|
|
@ -338,13 +360,14 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
async saveAlertReceiveChannel(id: AlertReceiveChannel['id'], data: Partial<AlertReceiveChannel>) {
|
||||
const item = await this.update(id, data, undefined, true);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: item,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: item,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteAlertReceiveChannel(id: AlertReceiveChannel['id']) {
|
||||
return await this.delete(id);
|
||||
}
|
||||
|
|
@ -356,20 +379,24 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
withCredentials: true,
|
||||
});
|
||||
|
||||
this.templates = {
|
||||
...this.templates,
|
||||
[alertReceiveChannelId]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.templates = {
|
||||
...this.templates,
|
||||
[alertReceiveChannelId]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItem(id: AlertReceiveChannel['id']) {
|
||||
const item = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: item,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: item,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -380,10 +407,12 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
withCredentials: true,
|
||||
});
|
||||
|
||||
this.templates = {
|
||||
...this.templates,
|
||||
[alertReceiveChannelId]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.templates = {
|
||||
...this.templates,
|
||||
[alertReceiveChannelId]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async getGrafanaAlertingContactPoints() {
|
||||
|
|
@ -394,22 +423,24 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
async updateConnectedContactPoints(alertReceiveChannelId: AlertReceiveChannel['id']) {
|
||||
const response = await makeRequest(`${this.path}${alertReceiveChannelId}/connected_contact_points `, {});
|
||||
|
||||
this.connectedContactPoints = {
|
||||
...this.connectedContactPoints,
|
||||
runInAction(() => {
|
||||
this.connectedContactPoints = {
|
||||
...this.connectedContactPoints,
|
||||
|
||||
[alertReceiveChannelId]: response.reduce((list: ContactPoint[], payload) => {
|
||||
payload.contact_points.forEach((contactPoint: { name: string; notification_connected: boolean }) => {
|
||||
list.push({
|
||||
dataSourceName: payload.name,
|
||||
dataSourceId: payload.uid,
|
||||
contactPoint: contactPoint.name,
|
||||
notificationConnected: contactPoint.notification_connected,
|
||||
} as ContactPoint);
|
||||
});
|
||||
[alertReceiveChannelId]: response.reduce((list: ContactPoint[], payload) => {
|
||||
payload.contact_points.forEach((contactPoint: { name: string; notification_connected: boolean }) => {
|
||||
list.push({
|
||||
dataSourceName: payload.name,
|
||||
dataSourceId: payload.uid,
|
||||
contactPoint: contactPoint.name,
|
||||
notificationConnected: contactPoint.notification_connected,
|
||||
} as ContactPoint);
|
||||
});
|
||||
|
||||
return list;
|
||||
}, []),
|
||||
};
|
||||
return list;
|
||||
}, []),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async connectContactPoint(
|
||||
|
|
@ -460,13 +491,6 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
return integration_log;
|
||||
}
|
||||
|
||||
async installSentry(sentry_payload: string) {
|
||||
return await makeRequest('/sentry_complete_install/', {
|
||||
method: 'POST',
|
||||
params: { sentry_payload },
|
||||
});
|
||||
}
|
||||
|
||||
async sendDemoAlert(id: AlertReceiveChannel['id'], payload: string = undefined) {
|
||||
const requestConfig: any = {
|
||||
method: 'POST',
|
||||
|
|
@ -479,8 +503,6 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
}
|
||||
|
||||
await makeRequest(`${this.path}${id}/send_demo_alert/`, requestConfig).catch(showApiError);
|
||||
|
||||
Mixpanel.track('Send Demo Incident', null);
|
||||
}
|
||||
|
||||
async sendDemoAlertToParticularRoute(id: ChannelFilter['id']) {
|
||||
|
|
@ -508,25 +530,31 @@ export class AlertReceiveChannelStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateCounters() {
|
||||
const counters = await makeRequest(`${this.path}counters`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
this.counters = counters;
|
||||
runInAction(() => {
|
||||
this.counters = counters;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateCountersForIntegration(id: AlertReceiveChannel['id']): Promise<any> {
|
||||
const counters = await makeRequest(`${this.path}${id}/counters`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
this.counters = {
|
||||
...this.counters,
|
||||
[id]: {
|
||||
...counters[id],
|
||||
},
|
||||
};
|
||||
runInAction(() => {
|
||||
this.counters = {
|
||||
...this.counters,
|
||||
[id]: {
|
||||
...counters[id],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return counters;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -15,6 +15,8 @@ export class AlertReceiveChannelFiltersStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/alert_receive_channels/';
|
||||
}
|
||||
|
||||
|
|
@ -32,17 +34,19 @@ export class AlertReceiveChannelFiltersStore extends BaseStore {
|
|||
params: { search: query, filters: true },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: string]: SelectOption }, item: SelectOption) => ({
|
||||
...acc,
|
||||
[item.value]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: string]: SelectOption }, item: SelectOption) => ({
|
||||
...acc,
|
||||
[item.value]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = results.map((item: SelectOption) => item.value);
|
||||
this.searchResult = results.map((item: SelectOption) => item.value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
import qs from 'query-string';
|
||||
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
|
|
@ -7,7 +7,6 @@ import { ActionKey } from 'models/loader/action-keys';
|
|||
import { User } from 'models/user/user.types';
|
||||
import { makeRequest } from 'network';
|
||||
import { ApiSchemas } from 'network/oncall-api/api.types';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
import { SelectOption } from 'state/types';
|
||||
import { openErrorNotification, refreshPageError, showApiError } from 'utils';
|
||||
|
|
@ -80,6 +79,8 @@ export class AlertGroupStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/alertgroups/';
|
||||
}
|
||||
|
||||
|
|
@ -96,13 +97,16 @@ export class AlertGroupStore extends BaseStore {
|
|||
}).catch(showApiError);
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItem(id: Alert['pk']) {
|
||||
const item = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[item.id]: item,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[item.id]: item,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
@ -124,12 +128,14 @@ export class AlertGroupStore extends BaseStore {
|
|||
return await makeRequest(`${this.path}${pk}`, {});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateSilenceOptions() {
|
||||
this.silenceOptions = await makeRequest(`${this.path}silence_options/`, {});
|
||||
const result = await makeRequest(`${this.path}silence_options/`, {});
|
||||
|
||||
runInAction(() => {
|
||||
this.silenceOptions = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async resolve(id: Alert['pk'], delay: number) {
|
||||
await makeRequest(`${this.path}${id}/silence/`, {
|
||||
method: 'POST',
|
||||
|
|
@ -137,28 +143,24 @@ export class AlertGroupStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async unresolve(id: Alert['pk']) {
|
||||
await makeRequest(`${this.path}${id}/unresolve/`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async acknowledge(id: Alert['pk']) {
|
||||
await makeRequest(`${this.path}${id}/acknowledge/`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async unacknowledge(id: Alert['pk']) {
|
||||
await makeRequest(`${this.path}${id}/unacknowledge/`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async silence(id: Alert['pk'], delay: number) {
|
||||
await makeRequest(`${this.path}${id}/silence/`, {
|
||||
method: 'POST',
|
||||
|
|
@ -166,7 +168,6 @@ export class AlertGroupStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async unsilence(id: Alert['pk']) {
|
||||
await makeRequest(`${this.path}${id}/unsilence/`, {
|
||||
method: 'POST',
|
||||
|
|
@ -177,13 +178,15 @@ export class AlertGroupStore extends BaseStore {
|
|||
async updateBulkActions() {
|
||||
const response = await makeRequest(`${this.path}bulk_action_options/`, {});
|
||||
|
||||
this.bulkActions = response.reduce(
|
||||
(acc: { [key: string]: boolean }, item: SelectOption) => ({
|
||||
...acc,
|
||||
[item.value]: true,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
runInAction(() => {
|
||||
this.bulkActions = response.reduce(
|
||||
(acc: { [key: string]: boolean }, item: SelectOption) => ({
|
||||
...acc,
|
||||
[item.value]: true,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async bulkAction(data: any) {
|
||||
|
|
@ -202,7 +205,6 @@ export class AlertGroupStore extends BaseStore {
|
|||
|
||||
// methods were moved from rootBaseStore.
|
||||
// TODO check if methods are dublicating existing ones
|
||||
@action
|
||||
async updateIncidents() {
|
||||
await Promise.all([
|
||||
this.getNewIncidentsStats(),
|
||||
|
|
@ -212,7 +214,12 @@ export class AlertGroupStore extends BaseStore {
|
|||
this.updateAlertGroups(),
|
||||
]);
|
||||
|
||||
this.liveUpdatesPaused = false;
|
||||
this.setLiveUpdatesPaused(false);
|
||||
}
|
||||
|
||||
@action
|
||||
setLiveUpdatesPaused(value: boolean) {
|
||||
this.liveUpdatesPaused = value;
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -276,17 +283,19 @@ export class AlertGroupStore extends BaseStore {
|
|||
})
|
||||
);
|
||||
|
||||
// @ts-ignore
|
||||
this.alerts = new Map<number, Alert>([...this.alerts, ...newAlerts]);
|
||||
runInAction(() => {
|
||||
// @ts-ignore
|
||||
this.alerts = new Map<number, Alert>([...this.alerts, ...newAlerts]);
|
||||
|
||||
this.alertsSearchResult['default'] = {
|
||||
prev: prevCursor,
|
||||
next: nextCursor,
|
||||
results: results.map((alert: Alert) => alert.pk),
|
||||
page_size,
|
||||
};
|
||||
this.alertsSearchResult['default'] = {
|
||||
prev: prevCursor,
|
||||
next: nextCursor,
|
||||
results: results.map((alert: Alert) => alert.pk),
|
||||
page_size,
|
||||
};
|
||||
|
||||
this.alertGroupsLoading = false;
|
||||
this.alertGroupsLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
getAlertSearchResult(query: string) {
|
||||
|
|
@ -303,10 +312,11 @@ export class AlertGroupStore extends BaseStore {
|
|||
};
|
||||
}
|
||||
|
||||
@action
|
||||
async getAlert(pk: Alert['pk']) {
|
||||
return await makeRequest(`${this.path}${pk}`, {}).then((alert: Alert) => {
|
||||
this.alerts.set(pk, alert);
|
||||
runInAction(() => {
|
||||
this.alerts.set(pk, alert);
|
||||
});
|
||||
|
||||
return alert;
|
||||
});
|
||||
|
|
@ -324,7 +334,10 @@ export class AlertGroupStore extends BaseStore {
|
|||
status: [IncidentStatus.Firing],
|
||||
},
|
||||
});
|
||||
this.newIncidents = result;
|
||||
|
||||
runInAction(() => {
|
||||
this.newIncidents = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -336,7 +349,9 @@ export class AlertGroupStore extends BaseStore {
|
|||
},
|
||||
});
|
||||
|
||||
this.acknowledgedIncidents = result;
|
||||
runInAction(() => {
|
||||
this.acknowledgedIncidents = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -348,7 +363,9 @@ export class AlertGroupStore extends BaseStore {
|
|||
},
|
||||
});
|
||||
|
||||
this.resolvedIncidents = result;
|
||||
runInAction(() => {
|
||||
this.resolvedIncidents = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -360,7 +377,9 @@ export class AlertGroupStore extends BaseStore {
|
|||
},
|
||||
});
|
||||
|
||||
this.silencedIncidents = result;
|
||||
runInAction(() => {
|
||||
this.silencedIncidents = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -371,32 +390,26 @@ export class AlertGroupStore extends BaseStore {
|
|||
if (!isUndo) {
|
||||
switch (action) {
|
||||
case AlertAction.Acknowledge:
|
||||
Mixpanel.track('Acknowledge Incident', null);
|
||||
undoAction = AlertAction.unAcknowledge;
|
||||
break;
|
||||
case AlertAction.unAcknowledge:
|
||||
Mixpanel.track('Unacknowledge Incident', null);
|
||||
undoAction = AlertAction.Acknowledge;
|
||||
break;
|
||||
case AlertAction.Resolve:
|
||||
Mixpanel.track('Resolve Incident', null);
|
||||
undoAction = AlertAction.unResolve;
|
||||
break;
|
||||
case AlertAction.unResolve:
|
||||
Mixpanel.track('Unresolve Incident', null);
|
||||
undoAction = AlertAction.Resolve;
|
||||
break;
|
||||
case AlertAction.Silence:
|
||||
Mixpanel.track('Silence Incident', null);
|
||||
undoAction = AlertAction.unSilence;
|
||||
break;
|
||||
case AlertAction.unSilence:
|
||||
Mixpanel.track('Unsilence Incident', null);
|
||||
undoAction = AlertAction.Silence;
|
||||
break;
|
||||
}
|
||||
|
||||
this.liveUpdatesPaused = true;
|
||||
this.setLiveUpdatesPaused(true);
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -424,11 +437,6 @@ export class AlertGroupStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
toggleLiveUpdate(value: boolean) {
|
||||
this.liveUpdatesEnabled = value;
|
||||
}
|
||||
|
||||
async unpageUser(alertId: Alert['pk'], userId: User['pk']) {
|
||||
return await makeRequest(`${this.path}${alertId}/unpage_user`, {
|
||||
method: 'POST',
|
||||
|
|
@ -442,11 +450,13 @@ export class AlertGroupStore extends BaseStore {
|
|||
|
||||
const { hidden, visible, default: isDefaultOrder } = tableSettings;
|
||||
|
||||
this.isDefaultColumnOrder = isDefaultOrder;
|
||||
this.columns = [
|
||||
...visible.map((item: AlertGroupColumn): AlertGroupColumn => ({ ...item, isVisible: true })),
|
||||
...hidden.map((item: AlertGroupColumn): AlertGroupColumn => ({ ...item, isVisible: false })),
|
||||
];
|
||||
runInAction(() => {
|
||||
this.isDefaultColumnOrder = isDefaultOrder;
|
||||
this.columns = [
|
||||
...visible.map((item: AlertGroupColumn): AlertGroupColumn => ({ ...item, isVisible: true })),
|
||||
...hidden.map((item: AlertGroupColumn): AlertGroupColumn => ({ ...item, isVisible: false })),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -462,24 +472,23 @@ export class AlertGroupStore extends BaseStore {
|
|||
data: { ...columns },
|
||||
});
|
||||
|
||||
this.isDefaultColumnOrder = isDefaultOrder;
|
||||
runInAction(() => {
|
||||
this.isDefaultColumnOrder = isDefaultOrder;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async resetTableSettings(): Promise<void> {
|
||||
return await makeRequest('/alertgroup_table_settings/reset', { method: 'POST' }).catch(() =>
|
||||
openErrorNotification('There was an error resetting the table settings')
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadLabelsKeys(): Promise<Array<ApiSchemas['LabelKey']>> {
|
||||
return await makeRequest(`/alertgroups/labels/keys/`, {}).catch(() =>
|
||||
openErrorNotification('There was an error processing your request')
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadValuesForLabelKey(
|
||||
key: ApiSchemas['LabelKey']['id'],
|
||||
search = ''
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { Channel } from 'models/channel';
|
||||
import { Channel } from 'models/channel/channel';
|
||||
import { GrafanaTeam } from 'models/grafana_team/grafana_team.types';
|
||||
import { LabelKeyValue } from 'models/label/label.types';
|
||||
import { PagedUser, User } from 'models/user/user.types';
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
export interface ApiTokenDTO {
|
||||
pk: string;
|
||||
token_name: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
|
||||
import { ApiToken } from './api_token.types';
|
||||
|
|
@ -17,6 +16,8 @@ export class ApiTokenStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/tokens/';
|
||||
}
|
||||
|
||||
|
|
@ -26,21 +27,23 @@ export class ApiTokenStore extends BaseStore {
|
|||
params: { search: query },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: ApiToken }, item: ApiToken) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: ApiToken }, item: ApiToken) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: ApiToken) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: ApiToken) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
@ -52,8 +55,6 @@ export class ApiTokenStore extends BaseStore {
|
|||
}
|
||||
|
||||
async revokeApiToken(id: ApiToken['id']) {
|
||||
Mixpanel.track('Revoke ApiToken', null);
|
||||
|
||||
return await makeRequest(`${this.path}${id}/`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { SlackChannel } from 'models/slack_channel/slack_channel.types';
|
||||
import { TelegramChannel } from 'models/telegram_channel/telegram_channel.types';
|
||||
|
||||
export interface ChannelFilter {
|
||||
id: string;
|
||||
alert_receive_channel: AlertReceiveChannel['id'];
|
||||
slack_channel_id?: SlackChannel['id'];
|
||||
telegram_channel?: TelegramChannel['id'];
|
||||
escalation_chain?: string;
|
||||
created_at: string;
|
||||
filtering_term: string;
|
||||
is_default: boolean;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -19,6 +19,8 @@ export class CloudStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/cloud_users/';
|
||||
}
|
||||
|
||||
|
|
@ -28,21 +30,23 @@ export class CloudStore extends BaseStore {
|
|||
params: { page },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Cloud }, item: Cloud) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Cloud }, item: Cloud) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
matched_users_count,
|
||||
results: results.map((item: Cloud) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
matched_users_count,
|
||||
results: results.map((item: Cloud) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult() {
|
||||
|
|
@ -70,14 +74,17 @@ export class CloudStore extends BaseStore {
|
|||
|
||||
@action.bound
|
||||
async loadCloudConnectionStatus() {
|
||||
this.cloudConnectionStatus = await this.getCloudConnectionStatus();
|
||||
const result = await this.getCloudConnectionStatus();
|
||||
|
||||
runInAction(() => {
|
||||
this.cloudConnectionStatus = result;
|
||||
});
|
||||
}
|
||||
|
||||
async getCloudConnectionStatus() {
|
||||
return await makeRequest(`/cloud_connection/`, { method: 'GET' });
|
||||
}
|
||||
|
||||
@action
|
||||
async disconnectToCloud() {
|
||||
return await makeRequest(`/cloud_connection/`, { method: 'DELETE' });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable } from 'mobx';
|
||||
|
||||
import { UserResponders } from 'containers/AddResponders/AddResponders.types';
|
||||
import { Alert } from 'models/alertgroup/alertgroup.types';
|
||||
|
|
@ -24,6 +24,8 @@ export class DirectPagingStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/direct_paging/';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -25,6 +25,8 @@ export class EscalationChainStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/escalation_chains/';
|
||||
}
|
||||
|
||||
|
|
@ -32,10 +34,12 @@ export class EscalationChainStore extends BaseStore {
|
|||
async loadItem(id: EscalationChain['id'], skipErrorHandling = false): Promise<EscalationChain> {
|
||||
const escalationChain = await this.getById(id, skipErrorHandling);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: escalationChain,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: escalationChain,
|
||||
};
|
||||
});
|
||||
|
||||
return escalationChain;
|
||||
}
|
||||
|
|
@ -44,30 +48,36 @@ export class EscalationChainStore extends BaseStore {
|
|||
async updateById(id: EscalationChain['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async save(id: EscalationChain['id'], data: Partial<EscalationChain>) {
|
||||
const response = await super.update(id, data);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateEscalationChainDetails(id: EscalationChain['id']) {
|
||||
const response = await makeRequest(`${this.path}${id}/details/`, {});
|
||||
|
||||
this.details = {
|
||||
...this.details,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.details = {
|
||||
...this.details,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -86,10 +96,12 @@ export class EscalationChainStore extends BaseStore {
|
|||
}
|
||||
|
||||
if (escalationChain) {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: escalationChain,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: escalationChain,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return escalationChain;
|
||||
|
|
@ -105,23 +117,25 @@ export class EscalationChainStore extends BaseStore {
|
|||
params,
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: EscalationChain }, item: EscalationChain) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: EscalationChain }, item: EscalationChain) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
const key = typeof query === 'string' ? query : '';
|
||||
const key = typeof query === 'string' ? query : '';
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[key]: results.map((item: EscalationChain) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[key]: results.map((item: EscalationChain) => item.id),
|
||||
};
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import { Channel } from 'models/channel';
|
||||
import { Schedule } from 'models/schedule/schedule.types';
|
||||
import { UserGroup } from 'models/user_group/user_group.types';
|
||||
|
||||
import { ChannelFilter } from './channel_filter';
|
||||
import { ScheduleDTO } from './schedule';
|
||||
import { User } from './user/user.types';
|
||||
|
||||
export interface EscalationPolicyType {
|
||||
id: string;
|
||||
notify_to_user: User['pk'] | null;
|
||||
// it's option value from api/internal/v1/escalation_policies/escalation_options/
|
||||
step: number;
|
||||
wait_delay: string | null;
|
||||
is_final: boolean;
|
||||
channel_filter: ChannelFilter['id'];
|
||||
notify_to_users_queue: Array<User['pk']>;
|
||||
from_time: string | null;
|
||||
to_time: string | null;
|
||||
notify_to_schedule: ScheduleDTO['id'] | null;
|
||||
notify_to_channel: Channel['id'] | null;
|
||||
notify_to_group: UserGroup['id'];
|
||||
notify_schedule: Schedule['id'];
|
||||
}
|
||||
|
||||
export function prepareEscalationPolicy(value: EscalationPolicyType): EscalationPolicyType {
|
||||
return {
|
||||
...value,
|
||||
notify_to_user: null,
|
||||
wait_delay: null,
|
||||
notify_to_users_queue: [],
|
||||
from_time: null,
|
||||
to_time: null,
|
||||
notify_to_schedule: null,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import { get } from 'lodash-es';
|
||||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
|
||||
import { EscalationPolicy } from 'models/escalation_policy/escalation_policy.types';
|
||||
import { makeRequest } from 'network';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
import { move } from 'state/helpers';
|
||||
import { SelectOption } from 'state/types';
|
||||
|
|
@ -31,13 +30,18 @@ export class EscalationPolicyStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/escalation_policies/';
|
||||
}
|
||||
|
||||
@action.bound
|
||||
async updateWebEscalationPolicyOptions() {
|
||||
const response = await makeRequest('/escalation_policies/escalation_options/', {});
|
||||
this.webEscalationChoices = response;
|
||||
|
||||
runInAction(() => {
|
||||
this.webEscalationChoices = response;
|
||||
});
|
||||
}
|
||||
|
||||
@action.bound
|
||||
|
|
@ -45,13 +49,19 @@ export class EscalationPolicyStore extends BaseStore {
|
|||
const response = await makeRequest('/escalation_policies/', {
|
||||
method: 'OPTIONS',
|
||||
});
|
||||
this.escalationChoices = get(response, 'actions.POST', []);
|
||||
|
||||
runInAction(() => {
|
||||
this.escalationChoices = get(response, 'actions.POST', []);
|
||||
});
|
||||
}
|
||||
|
||||
@action.bound
|
||||
async updateNumMinutesInWindowOptions() {
|
||||
const response = await makeRequest('/escalation_policies/num_minutes_in_window_options/', {});
|
||||
this.numMinutesInWindowOptions = response;
|
||||
|
||||
runInAction(() => {
|
||||
this.numMinutesInWindowOptions = response;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -68,15 +78,17 @@ export class EscalationPolicyStore extends BaseStore {
|
|||
{}
|
||||
);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...escalationPolicies,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...escalationPolicies,
|
||||
};
|
||||
|
||||
this.escalationChainToEscalationPolicy = {
|
||||
...this.escalationChainToEscalationPolicy,
|
||||
[escalationChainId]: response.map((escalationPolicy: EscalationPolicy) => escalationPolicy.id),
|
||||
};
|
||||
this.escalationChainToEscalationPolicy = {
|
||||
...this.escalationChainToEscalationPolicy,
|
||||
[escalationChainId]: response.map((escalationPolicy: EscalationPolicy) => escalationPolicy.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -103,8 +115,6 @@ export class EscalationPolicyStore extends BaseStore {
|
|||
|
||||
@action
|
||||
async moveEscalationPolicyToPosition(oldIndex: any, newIndex: any, escalationChainId: EscalationChain['id']) {
|
||||
Mixpanel.track('Move EscalationPolicy', null);
|
||||
|
||||
const escalationPolicyId = this.escalationChainToEscalationPolicy[escalationChainId][oldIndex];
|
||||
|
||||
this.escalationChainToEscalationPolicy[escalationChainId] = move(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { Channel } from 'models/channel';
|
||||
import { Channel } from 'models/channel/channel';
|
||||
import { EscalationChain } from 'models/escalation_chain/escalation_chain.types';
|
||||
import { OutgoingWebhook } from 'models/outgoing_webhook/outgoing_webhook.types';
|
||||
import { Schedule } from 'models/schedule/schedule.types';
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { LabelKeyValue } from 'models/label/label.types';
|
||||
|
|
@ -31,6 +31,8 @@ export class FiltersStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
const savedFilters = getItem(LOCAL_STORAGE_FILTERS_KEY);
|
||||
if (savedFilters) {
|
||||
this._globalValues = { ...savedFilters };
|
||||
|
|
@ -61,10 +63,12 @@ export class FiltersStore extends BaseStore {
|
|||
result.unshift({ name: 'search', type: 'search' });
|
||||
}
|
||||
|
||||
this.options = {
|
||||
...this.options,
|
||||
[page]: result,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.options = {
|
||||
...this.options,
|
||||
[page]: result,
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { RootStore } from 'state';
|
||||
|
|
@ -15,6 +15,8 @@ export class GlobalSettingStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/live_settings/';
|
||||
}
|
||||
|
||||
|
|
@ -22,31 +24,35 @@ export class GlobalSettingStore extends BaseStore {
|
|||
async updateById(id: GlobalSetting['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItems(query = '') {
|
||||
const results = await this.getAll();
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: GlobalSetting }, item: GlobalSetting) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: GlobalSetting }, item: GlobalSetting) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: GlobalSetting) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: GlobalSetting) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { GrafanaTeam } from 'models/grafana_team/grafana_team.types';
|
||||
|
|
@ -17,6 +17,8 @@ export class GrafanaTeamStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/teams/';
|
||||
}
|
||||
|
||||
|
|
@ -24,10 +26,12 @@ export class GrafanaTeamStore extends BaseStore {
|
|||
async updateTeam(id: GrafanaTeam['id'], data: Partial<GrafanaTeam>) {
|
||||
const result = await this.update(id, data);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: result,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: result,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action.bound
|
||||
|
|
@ -40,18 +44,21 @@ export class GrafanaTeamStore extends BaseStore {
|
|||
only_include_notifiable_teams: onlyIncludeNotifiableTeams ? 'true' : 'false',
|
||||
},
|
||||
});
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce<TeamItems>(
|
||||
(acc, item) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = result.map((item: GrafanaTeam) => item.id);
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce<TeamItems>(
|
||||
(acc, item) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = result.map((item: GrafanaTeam) => item.id);
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import BaseStore from 'models/base_store';
|
||||
|
|
@ -17,12 +17,18 @@ export class HeartbeatStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/heartbeats/';
|
||||
}
|
||||
|
||||
@action
|
||||
async updateTimeoutOptions() {
|
||||
this.timeoutOptions = await makeRequest(`${this.path}timeout_options/`, {});
|
||||
const result = await makeRequest(`${this.path}timeout_options/`, {});
|
||||
|
||||
runInAction(() => {
|
||||
this.timeoutOptions = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -33,10 +39,12 @@ export class HeartbeatStore extends BaseStore {
|
|||
return;
|
||||
}
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -50,14 +58,16 @@ export class HeartbeatStore extends BaseStore {
|
|||
return;
|
||||
}
|
||||
|
||||
this.rootStore.alertReceiveChannelStore.alertReceiveChannelToHeartbeat = {
|
||||
...this.rootStore.alertReceiveChannelStore.alertReceiveChannelToHeartbeat,
|
||||
[alertReceiveChannelId]: response.id,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.rootStore.alertReceiveChannelStore.alertReceiveChannelToHeartbeat = {
|
||||
...this.rootStore.alertReceiveChannelStore.alertReceiveChannelToHeartbeat,
|
||||
[alertReceiveChannelId]: response.id,
|
||||
};
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.id]: response,
|
||||
};
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -17,13 +17,18 @@ export class LabelStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/labels/';
|
||||
}
|
||||
|
||||
@action.bound
|
||||
public async loadKeys() {
|
||||
const { data } = await onCallApi.GET('/labels/keys/', undefined);
|
||||
this.keys = data;
|
||||
|
||||
runInAction(() => {
|
||||
this.keys = data;
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -40,15 +45,16 @@ export class LabelStore extends BaseStore {
|
|||
|
||||
const filteredValues = result.values.filter((v) => v.name.toLowerCase().includes(search.toLowerCase())); // TODO remove after backend search implementation
|
||||
|
||||
this.values = {
|
||||
...this.values,
|
||||
[key]: filteredValues,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.values = {
|
||||
...this.values,
|
||||
[key]: filteredValues,
|
||||
};
|
||||
});
|
||||
|
||||
return { ...result, values: filteredValues };
|
||||
}
|
||||
|
||||
@action.bound
|
||||
@WithGlobalNotification({ success: 'New key has been added', failure: 'Failed to add new key' })
|
||||
async createKey(name: string) {
|
||||
const data = await makeRequest(`${this.path}`, {
|
||||
|
|
@ -58,7 +64,6 @@ export class LabelStore extends BaseStore {
|
|||
return data.key;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
@WithGlobalNotification({ success: 'New value has been added', failure: 'Failed to add new value' })
|
||||
async createValue(keyId: ApiSchemas['LabelKey']['id'], value: string) {
|
||||
const result = await makeRequest(`${this.path}id/${keyId}/values`, {
|
||||
|
|
@ -68,7 +73,6 @@ export class LabelStore extends BaseStore {
|
|||
return result.values.find((v) => v.name === value); // TODO remove after backend API change
|
||||
}
|
||||
|
||||
@action.bound
|
||||
@WithGlobalNotification({ success: 'Key has been renamed', failure: 'Failed to rename key' })
|
||||
async updateKey(keyId: ApiSchemas['LabelKey']['id'], name: string) {
|
||||
const result = await makeRequest(`${this.path}id/${keyId}`, {
|
||||
|
|
@ -78,7 +82,6 @@ export class LabelStore extends BaseStore {
|
|||
return result.key;
|
||||
}
|
||||
|
||||
@action.bound
|
||||
@WithGlobalNotification({ success: 'Value has been renamed', failure: 'Failed to rename value' })
|
||||
async updateKeyValue(keyId: ApiSchemas['LabelKey']['id'], valueId: ApiSchemas['LabelValue']['id'], name: string) {
|
||||
const result = await makeRequest(`${this.path}id/${keyId}/values/${valueId}`, {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable } from 'mobx';
|
||||
|
||||
interface LoadingResult {
|
||||
[key: string]: boolean;
|
||||
|
|
@ -8,6 +8,10 @@ class LoaderStoreClass {
|
|||
@observable
|
||||
items: LoadingResult = {};
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@action
|
||||
setLoadingAction(actionKey: string, isLoading: boolean) {
|
||||
this.items[actionKey] = isLoading;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { User } from './user/user.types';
|
||||
import { User } from 'models/user/user.types';
|
||||
|
||||
export interface NotificationPolicyType {
|
||||
id: string;
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
export interface NotifyBy {
|
||||
value: string;
|
||||
display_name: string;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -12,16 +12,19 @@ export class OrganizationStore extends BaseStore {
|
|||
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
makeObservable(this);
|
||||
this.path = '/organization/';
|
||||
}
|
||||
|
||||
@action.bound
|
||||
async loadCurrentOrganization() {
|
||||
const organization = await makeRequest(this.path, {});
|
||||
this.currentOrganization = organization;
|
||||
|
||||
runInAction(() => {
|
||||
this.currentOrganization = organization;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async saveCurrentOrganization(data: Partial<Organization>) {
|
||||
this.currentOrganization = await makeRequest(this.path, {
|
||||
method: 'PUT',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { LabelsErrors } from 'models/label/label.types';
|
||||
|
|
@ -23,6 +23,8 @@ export class OutgoingWebhookStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/webhooks/';
|
||||
}
|
||||
|
||||
|
|
@ -30,10 +32,12 @@ export class OutgoingWebhookStore extends BaseStore {
|
|||
async loadItem(id: OutgoingWebhook['id'], skipErrorHandling = false): Promise<OutgoingWebhook> {
|
||||
const outgoingWebhook = await this.getById(id, skipErrorHandling);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: outgoingWebhook,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: outgoingWebhook,
|
||||
};
|
||||
});
|
||||
|
||||
return outgoingWebhook;
|
||||
}
|
||||
|
|
@ -42,19 +46,24 @@ export class OutgoingWebhookStore extends BaseStore {
|
|||
async updateById(id: OutgoingWebhook['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItem(id: OutgoingWebhook['id'], fromOrganization = false) {
|
||||
const response = await this.getById(id, false, fromOrganization);
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -65,23 +74,25 @@ export class OutgoingWebhookStore extends BaseStore {
|
|||
params,
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: OutgoingWebhook }, item: OutgoingWebhook) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: OutgoingWebhook }, item: OutgoingWebhook) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
const key = typeof query === 'string' ? query : '';
|
||||
const key = typeof query === 'string' ? query : '';
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[key]: results.map((item: OutgoingWebhook) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[key]: results.map((item: OutgoingWebhook) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
@ -108,7 +119,10 @@ export class OutgoingWebhookStore extends BaseStore {
|
|||
@action.bound
|
||||
async updateOutgoingWebhookPresetsOptions() {
|
||||
const response = await makeRequest(`/webhooks/preset_options/`, {});
|
||||
this.outgoingWebhookPresets = response;
|
||||
|
||||
runInAction(() => {
|
||||
this.outgoingWebhookPresets = response;
|
||||
});
|
||||
}
|
||||
|
||||
@action.bound
|
||||
|
|
|
|||
|
|
@ -1,16 +1,9 @@
|
|||
import { observable } from 'mobx';
|
||||
|
||||
import { Alert } from 'models/alertgroup/alertgroup.types';
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
import { RootStore } from 'state';
|
||||
|
||||
import { ResolutionNote } from './resolution_note.types';
|
||||
|
||||
export class ResolutionNotesStore extends BaseStore {
|
||||
@observable.shallow
|
||||
resolutionNotes: { [id: string]: ResolutionNote[] } = {};
|
||||
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
export interface ScheduleDTO {
|
||||
id: string;
|
||||
name: string;
|
||||
ical_url_primary: string;
|
||||
ical_url_overrides: string;
|
||||
type: ScheduleType;
|
||||
channel_name: string;
|
||||
channel: string;
|
||||
}
|
||||
|
||||
export enum ScheduleType {
|
||||
CalendarSchedule,
|
||||
IcalSchedule,
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import dayjs from 'dayjs';
|
||||
import { action, observable } from 'mobx';
|
||||
import { action, makeObservable, observable, runInAction } from 'mobx';
|
||||
|
||||
import { RemoteFiltersType } from 'containers/RemoteFilters/RemoteFilters.types';
|
||||
import BaseStore from 'models/base_store';
|
||||
|
|
@ -118,6 +118,8 @@ export class ScheduleStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/schedules/';
|
||||
}
|
||||
|
||||
|
|
@ -125,10 +127,12 @@ export class ScheduleStore extends BaseStore {
|
|||
async loadItem(id: Schedule['id'], skipErrorHandling = false): Promise<Schedule> {
|
||||
const schedule = await this.getById(id, skipErrorHandling);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: schedule,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: schedule,
|
||||
};
|
||||
});
|
||||
|
||||
return schedule;
|
||||
}
|
||||
|
|
@ -149,23 +153,26 @@ export class ScheduleStore extends BaseStore {
|
|||
return;
|
||||
}
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Schedule }, item: Schedule) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
this.searchResult = {
|
||||
page_size,
|
||||
count,
|
||||
results: results.map((item: Schedule) => item.id),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Schedule }, item: Schedule) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
this.searchResult = {
|
||||
page_size,
|
||||
count,
|
||||
results: results.map((item: Schedule) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItem(id: Schedule['id'], fromOrganization = false) {
|
||||
if (id) {
|
||||
let schedule;
|
||||
|
|
@ -182,10 +189,12 @@ export class ScheduleStore extends BaseStore {
|
|||
}
|
||||
|
||||
if (schedule) {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: schedule,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: schedule,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return schedule;
|
||||
|
|
@ -204,7 +213,6 @@ export class ScheduleStore extends BaseStore {
|
|||
return await makeRequest(`/schedules/${scheduleId}/quality`, { method: 'GET' });
|
||||
}
|
||||
|
||||
@action
|
||||
async reloadIcal(scheduleId: Schedule['id']) {
|
||||
await makeRequest(`/schedules/${scheduleId}/reload_ical/`, {
|
||||
method: 'POST',
|
||||
|
|
@ -231,6 +239,7 @@ export class ScheduleStore extends BaseStore {
|
|||
|
||||
// ------- NEW SCHEDULES API ENDPOINTS ---------
|
||||
|
||||
@action
|
||||
async createRotation(scheduleId: Schedule['id'], isOverride: boolean, params: Partial<Shift>) {
|
||||
const type = isOverride ? 3 : 2;
|
||||
|
||||
|
|
@ -239,10 +248,12 @@ export class ScheduleStore extends BaseStore {
|
|||
method: 'POST',
|
||||
});
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -270,26 +281,28 @@ export class ScheduleStore extends BaseStore {
|
|||
method: 'POST',
|
||||
});
|
||||
|
||||
if (isOverride) {
|
||||
const overridePreview = enrichOverrides(
|
||||
[...(this.events[scheduleId]?.['override']?.[fromString] as Array<{ shiftId: string; events: Event[] }>)],
|
||||
response.rotation,
|
||||
shiftId
|
||||
);
|
||||
runInAction(() => {
|
||||
if (isOverride) {
|
||||
const overridePreview = enrichOverrides(
|
||||
[...(this.events[scheduleId]?.['override']?.[fromString] as Array<{ shiftId: string; events: Event[] }>)],
|
||||
response.rotation,
|
||||
shiftId
|
||||
);
|
||||
|
||||
this.overridePreview = { ...this.overridePreview, [fromString]: overridePreview };
|
||||
} else {
|
||||
const layers = enrichLayers(
|
||||
[...(this.events[scheduleId]?.['rotation']?.[fromString] as Layer[])],
|
||||
response.rotation,
|
||||
shiftId,
|
||||
params.priority_level
|
||||
);
|
||||
this.overridePreview = { ...this.overridePreview, [fromString]: overridePreview };
|
||||
} else {
|
||||
const layers = enrichLayers(
|
||||
[...(this.events[scheduleId]?.['rotation']?.[fromString] as Layer[])],
|
||||
response.rotation,
|
||||
shiftId,
|
||||
params.priority_level
|
||||
);
|
||||
|
||||
this.rotationPreview = { ...this.rotationPreview, [fromString]: layers };
|
||||
}
|
||||
this.rotationPreview = { ...this.rotationPreview, [fromString]: layers };
|
||||
}
|
||||
|
||||
this.finalPreview = { ...this.finalPreview, [fromString]: fillGapsInShifts(splitToShifts(response.final)) };
|
||||
this.finalPreview = { ...this.finalPreview, [fromString]: fillGapsInShifts(splitToShifts(response.final)) };
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -310,10 +323,12 @@ export class ScheduleStore extends BaseStore {
|
|||
|
||||
const shiftEventsListFlattened = flattenShiftEvents([...existingShiftEventsList, newShiftEvents]);
|
||||
|
||||
this.shiftSwapsPreview = {
|
||||
...this.shiftSwapsPreview,
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shiftSwapsPreview = {
|
||||
...this.shiftSwapsPreview,
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -325,6 +340,7 @@ export class ScheduleStore extends BaseStore {
|
|||
this.rotationFormLiveParams = undefined;
|
||||
}
|
||||
|
||||
@action
|
||||
async updateRotation(shiftId: Shift['id'], params: Partial<Shift>) {
|
||||
const response = await makeRequest(`/oncall_shifts/${shiftId}`, {
|
||||
params: { force: true },
|
||||
|
|
@ -332,54 +348,66 @@ export class ScheduleStore extends BaseStore {
|
|||
method: 'PUT',
|
||||
});
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@action
|
||||
async updateRotationAsNew(shiftId: Shift['id'], params: Partial<Shift>) {
|
||||
const response = await makeRequest(`/oncall_shifts/${shiftId}`, {
|
||||
data: { ...params },
|
||||
method: 'PUT',
|
||||
});
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[response.id]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@action
|
||||
updateRelatedEscalationChains = async (id: Schedule['id']) => {
|
||||
const response = await makeRequest(`/schedules/${id}/related_escalation_chains`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
this.relatedEscalationChains = {
|
||||
...this.relatedEscalationChains,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.relatedEscalationChains = {
|
||||
...this.relatedEscalationChains,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
@action
|
||||
updateRelatedUsers = async (id: Schedule['id']) => {
|
||||
const { users } = await makeRequest(`/schedules/${id}/next_shifts_per_user`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
this.relatedUsers = {
|
||||
...this.relatedUsers,
|
||||
[id]: users,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.relatedUsers = {
|
||||
...this.relatedUsers,
|
||||
[id]: users,
|
||||
};
|
||||
});
|
||||
|
||||
return users;
|
||||
};
|
||||
|
||||
@action
|
||||
async updateOncallShifts(scheduleId: Schedule['id']) {
|
||||
const { results } = await makeRequest(`/oncall_shifts/`, {
|
||||
params: {
|
||||
|
|
@ -388,16 +416,18 @@ export class ScheduleStore extends BaseStore {
|
|||
method: 'GET',
|
||||
});
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Shift }, item: Shift) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: Shift }, item: Shift) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -410,10 +440,12 @@ export class ScheduleStore extends BaseStore {
|
|||
|
||||
const response = await makeRequest(`/oncall_shifts/${shiftId}`, {});
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[shiftId]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[shiftId]: response,
|
||||
};
|
||||
});
|
||||
|
||||
delete this.shiftsCurrentlyUpdating[shiftId];
|
||||
|
||||
|
|
@ -424,10 +456,12 @@ export class ScheduleStore extends BaseStore {
|
|||
async saveOncallShift(shiftId: Shift['id'], data: Partial<Shift>) {
|
||||
const response = await makeRequest(`/oncall_shifts/${shiftId}`, { method: 'PUT', data });
|
||||
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[shiftId]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.shifts = {
|
||||
...this.shifts,
|
||||
[shiftId]: response,
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -439,6 +473,7 @@ export class ScheduleStore extends BaseStore {
|
|||
}).catch(this.onApiError);
|
||||
}
|
||||
|
||||
@action
|
||||
async updateEvents(scheduleId: Schedule['id'], startMoment: dayjs.Dayjs, type: RotationType = 'rotation', days = 9) {
|
||||
const dayBefore = startMoment.subtract(1, 'day');
|
||||
|
||||
|
|
@ -457,16 +492,18 @@ export class ScheduleStore extends BaseStore {
|
|||
const shifts = fillGapsInShifts(shiftsUnflattened);
|
||||
const layers = type === 'rotation' ? splitToLayers(shifts) : undefined;
|
||||
|
||||
this.events = {
|
||||
...this.events,
|
||||
[scheduleId]: {
|
||||
...this.events[scheduleId],
|
||||
[type]: {
|
||||
...this.events[scheduleId]?.[type],
|
||||
[fromString]: layers ? layers : shifts,
|
||||
runInAction(() => {
|
||||
this.events = {
|
||||
...this.events,
|
||||
[scheduleId]: {
|
||||
...this.events[scheduleId],
|
||||
[type]: {
|
||||
...this.events[scheduleId]?.[type],
|
||||
[fromString]: layers ? layers : shifts,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async updateFrequencyOptions() {
|
||||
|
|
@ -475,10 +512,15 @@ export class ScheduleStore extends BaseStore {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateDaysOptions() {
|
||||
this.byDayOptions = await makeRequest(`/oncall_shifts/days_options/`, {
|
||||
const result = await makeRequest(`/oncall_shifts/days_options/`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.byDayOptions = result;
|
||||
});
|
||||
}
|
||||
|
||||
async createShiftSwap(params: Partial<ShiftSwap>) {
|
||||
|
|
@ -493,14 +535,18 @@ export class ScheduleStore extends BaseStore {
|
|||
return await makeRequest(`/shift_swaps/${shiftSwapId}/take`, { method: 'POST' }).catch(this.onApiError);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadShiftSwap(id: ShiftSwap['id']) {
|
||||
const result = await makeRequest(`/shift_swaps/${id}`, { params: { expand_users: true } });
|
||||
|
||||
this.shiftSwaps = { ...this.shiftSwaps, [id]: result };
|
||||
runInAction(() => {
|
||||
this.shiftSwaps = { ...this.shiftSwaps, [id]: result };
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async updateShiftSwaps(scheduleId: Schedule['id'], startMoment: dayjs.Dayjs, days = 9) {
|
||||
const fromString = getFromString(startMoment);
|
||||
|
||||
|
|
@ -522,23 +568,26 @@ export class ScheduleStore extends BaseStore {
|
|||
|
||||
const shiftEventsListFlattened = flattenShiftEvents(shiftEventsList);
|
||||
|
||||
this.shiftSwaps = result.shift_swaps.reduce(
|
||||
(memo, shiftSwap) => ({
|
||||
...memo,
|
||||
[shiftSwap.id]: shiftSwap,
|
||||
}),
|
||||
this.shiftSwaps
|
||||
);
|
||||
runInAction(() => {
|
||||
this.shiftSwaps = result.shift_swaps.reduce(
|
||||
(memo, shiftSwap) => ({
|
||||
...memo,
|
||||
[shiftSwap.id]: shiftSwap,
|
||||
}),
|
||||
this.shiftSwaps
|
||||
);
|
||||
|
||||
this.scheduleAndDateToShiftSwaps = {
|
||||
...this.scheduleAndDateToShiftSwaps,
|
||||
[scheduleId]: {
|
||||
...this.scheduleAndDateToShiftSwaps[scheduleId],
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
},
|
||||
};
|
||||
this.scheduleAndDateToShiftSwaps = {
|
||||
...this.scheduleAndDateToShiftSwaps,
|
||||
[scheduleId]: {
|
||||
...this.scheduleAndDateToShiftSwaps[scheduleId],
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updatePersonalEvents(userPk: User['pk'], startMoment: dayjs.Dayjs, days = 9, isUpdateOnCallNow = false) {
|
||||
const fromString = getFromString(startMoment);
|
||||
|
||||
|
|
@ -558,20 +607,22 @@ export class ScheduleStore extends BaseStore {
|
|||
|
||||
const shiftEventsListFlattened = flattenShiftEvents(shiftEventsList);
|
||||
|
||||
this.personalEvents = {
|
||||
...this.personalEvents,
|
||||
[userPk]: {
|
||||
...this.personalEvents[userPk],
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
},
|
||||
};
|
||||
|
||||
if (isUpdateOnCallNow) {
|
||||
// since current endpoint works incorrectly we are waiting for https://github.com/grafana/oncall/issues/3164
|
||||
this.onCallNow = {
|
||||
...this.onCallNow,
|
||||
[userPk]: is_oncall,
|
||||
runInAction(() => {
|
||||
this.personalEvents = {
|
||||
...this.personalEvents,
|
||||
[userPk]: {
|
||||
...this.personalEvents[userPk],
|
||||
[fromString]: shiftEventsListFlattened,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if (isUpdateOnCallNow) {
|
||||
// since current endpoint works incorrectly we are waiting for https://github.com/grafana/oncall/issues/3164
|
||||
this.onCallNow = {
|
||||
...this.onCallNow,
|
||||
[userPk]: is_oncall,
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { SlackChannel } from 'models/slack_channel/slack_channel.types';
|
||||
|
|
@ -16,19 +16,28 @@ export class SlackStore extends BaseStore {
|
|||
|
||||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@action
|
||||
async updateSlackSettings() {
|
||||
this.slackSettings = await makeRequest('/slack_settings/', {});
|
||||
const result = await makeRequest('/slack_settings/', {});
|
||||
|
||||
runInAction(() => {
|
||||
this.slackSettings = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async saveSlackSettings(data: Partial<SlackSettings>) {
|
||||
this.slackSettings = await makeRequest('/slack_settings/', {
|
||||
const result = await makeRequest('/slack_settings/', {
|
||||
data,
|
||||
method: 'PUT',
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.slackSettings = result;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -41,12 +50,17 @@ export class SlackStore extends BaseStore {
|
|||
|
||||
@action
|
||||
async updateSlackIntegrationData(slack_id: string) {
|
||||
return (this.slackIntegrationData = await makeRequest('/slack_integration/', {
|
||||
const result = await makeRequest('/slack_integration/', {
|
||||
params: { slack_id },
|
||||
}));
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.slackIntegrationData = result;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async reinstallSlackIntegration(slack_id: string) {
|
||||
return await makeRequest('/slack_integration/', {
|
||||
validateStatus: function (status) {
|
||||
|
|
@ -57,7 +71,6 @@ export class SlackStore extends BaseStore {
|
|||
}).catch(this.onApiError);
|
||||
}
|
||||
|
||||
@action
|
||||
async slackLogin() {
|
||||
const url_for_redirect = await makeRequest('/login/slack-login/', {});
|
||||
window.location = url_for_redirect;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -16,6 +16,8 @@ export class SlackChannelStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/slack_channels/';
|
||||
}
|
||||
|
||||
|
|
@ -23,20 +25,24 @@ export class SlackChannelStore extends BaseStore {
|
|||
async updateById(id: SlackChannel['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItem(id: SlackChannel['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -45,21 +51,23 @@ export class SlackChannelStore extends BaseStore {
|
|||
params: { search: query },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: SlackChannel }, item: SlackChannel) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: SlackChannel }, item: SlackChannel) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: SlackChannel) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: results.map((item: SlackChannel) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, computed, observable } from 'mobx';
|
||||
import { action, computed, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -21,6 +21,8 @@ export class TelegramChannelStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/telegram_channels/';
|
||||
}
|
||||
|
||||
|
|
@ -36,43 +38,49 @@ export class TelegramChannelStore extends BaseStore {
|
|||
{}
|
||||
);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...items,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...items,
|
||||
};
|
||||
|
||||
this.currentTeamToTelegramChannel = response.map((telegramChannel: TelegramChannel) => telegramChannel.id);
|
||||
this.currentTeamToTelegramChannel = response.map((telegramChannel: TelegramChannel) => telegramChannel.id);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateById(id: TelegramChannel['id']) {
|
||||
const response = await this.getById(id);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[id]: response,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async updateItems(query = '') {
|
||||
const result = await this.getAll();
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce(
|
||||
(acc: { [key: number]: TelegramChannel }, item: TelegramChannel) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce(
|
||||
(acc: { [key: number]: TelegramChannel }, item: TelegramChannel) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: result.map((item: TelegramChannel) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...this.searchResult,
|
||||
[query]: result.map((item: TelegramChannel) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import { config } from '@grafana/runtime';
|
||||
import dayjs from 'dayjs';
|
||||
import { get } from 'lodash-es';
|
||||
import { action, computed, observable } from 'mobx';
|
||||
import { action, computed, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { NotificationPolicyType } from 'models/notification_policy';
|
||||
import { NotificationPolicyType } from 'models/notification_policy/notification_policy';
|
||||
import { makeRequest } from 'network';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
import { move } from 'state/helpers';
|
||||
import { throttlingError } from 'utils';
|
||||
|
|
@ -48,6 +47,8 @@ export class UserStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/users/';
|
||||
}
|
||||
|
||||
|
|
@ -64,11 +65,13 @@ export class UserStore extends BaseStore {
|
|||
const response = await makeRequest('/user/', {});
|
||||
const timezone = await this.refreshTimezone(response.pk);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.pk]: { ...response, timezone },
|
||||
};
|
||||
this.currentUserPk = response.pk;
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[response.pk]: { ...response, timezone },
|
||||
};
|
||||
this.currentUserPk = response.pk;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -88,10 +91,12 @@ export class UserStore extends BaseStore {
|
|||
async loadUser(userPk: User['pk'], skipErrorHandling = false): Promise<User> {
|
||||
const user = await this.getById(userPk, skipErrorHandling);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: { ...user, timezone: getTimezone(user) },
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: { ...user, timezone: getTimezone(user) },
|
||||
};
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
|
@ -106,10 +111,12 @@ export class UserStore extends BaseStore {
|
|||
|
||||
const user = await this.getById(userPk);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: { ...user, timezone: getTimezone(user) },
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: { ...user, timezone: getTimezone(user) },
|
||||
};
|
||||
});
|
||||
|
||||
delete this.itemsCurrentlyUpdating[userPk];
|
||||
}
|
||||
|
|
@ -135,25 +142,27 @@ export class UserStore extends BaseStore {
|
|||
|
||||
const { count, results, page_size } = response;
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: User }, item: User) => ({
|
||||
...acc,
|
||||
[item.pk]: {
|
||||
...item,
|
||||
timezone: getTimezone(item),
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...results.reduce(
|
||||
(acc: { [key: number]: User }, item: User) => ({
|
||||
...acc,
|
||||
[item.pk]: {
|
||||
...item,
|
||||
timezone: getTimezone(item),
|
||||
},
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
count,
|
||||
page_size,
|
||||
results: results.map((item: User) => item.pk),
|
||||
};
|
||||
this.searchResult = {
|
||||
count,
|
||||
page_size,
|
||||
results: results.map((item: User) => item.pk),
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
}
|
||||
|
|
@ -178,10 +187,12 @@ export class UserStore extends BaseStore {
|
|||
|
||||
const user = await this.getById(userPk);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
@action
|
||||
|
|
@ -192,10 +203,12 @@ export class UserStore extends BaseStore {
|
|||
|
||||
const user = await this.getById(userPk);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
sendBackendConfirmationCode = (userPk: User['pk'], backend: string) =>
|
||||
|
|
@ -216,10 +229,12 @@ export class UserStore extends BaseStore {
|
|||
async createUser(data: any) {
|
||||
const user = await this.create(data);
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[user.pk]: user,
|
||||
};
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
|
@ -238,10 +253,12 @@ export class UserStore extends BaseStore {
|
|||
this.rootStore.userStore.loadCurrentUser();
|
||||
}
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[data.pk as User['pk']]: user,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[data.pk as User['pk']]: user,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -254,10 +271,12 @@ export class UserStore extends BaseStore {
|
|||
},
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
[this.currentUserPk as User['pk']]: user,
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
[this.currentUserPk as User['pk']]: user,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -300,15 +319,16 @@ export class UserStore extends BaseStore {
|
|||
params: { user: id, important: false },
|
||||
});
|
||||
|
||||
this.notificationPolicies = {
|
||||
...this.notificationPolicies,
|
||||
[id]: [...nonImportantEPs, ...importantEPs],
|
||||
};
|
||||
runInAction(() => {
|
||||
this.notificationPolicies = {
|
||||
...this.notificationPolicies,
|
||||
[id]: [...nonImportantEPs, ...importantEPs],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async moveNotificationPolicyToPosition(userPk: User['pk'], oldIndex: number, newIndex: number, offset: number) {
|
||||
Mixpanel.track('Move NotificationPolicy', null);
|
||||
const notificationPolicy = this.notificationPolicies[userPk][oldIndex + offset];
|
||||
|
||||
this.notificationPolicies[userPk] = move(this.notificationPolicies[userPk], oldIndex + offset, newIndex + offset);
|
||||
|
|
@ -348,20 +368,20 @@ export class UserStore extends BaseStore {
|
|||
data: value,
|
||||
});
|
||||
|
||||
this.notificationPolicies = {
|
||||
...this.notificationPolicies,
|
||||
[userPk]: this.notificationPolicies[userPk].map((policy: NotificationPolicyType) =>
|
||||
id === policy.id ? { ...policy, ...notificationPolicy } : policy
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.notificationPolicies = {
|
||||
...this.notificationPolicies,
|
||||
[userPk]: this.notificationPolicies[userPk].map((policy: NotificationPolicyType) =>
|
||||
id === policy.id ? { ...policy, ...notificationPolicy } : policy
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
this.updateItem(userPk); // to update notification_chain_verbal
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteNotificationPolicy(userPk: User['pk'], id: NotificationPolicyType['id']) {
|
||||
Mixpanel.track('Delete NotificationPolicy', null);
|
||||
|
||||
await makeRequest(`/notification_policies/${id}`, { method: 'DELETE' }).catch(this.onApiError);
|
||||
|
||||
this.updateNotificationPolicies(userPk);
|
||||
|
|
@ -374,7 +394,10 @@ export class UserStore extends BaseStore {
|
|||
const response = await makeRequest('/notification_policies/', {
|
||||
method: 'OPTIONS',
|
||||
});
|
||||
this.notificationChoices = get(response, 'actions.POST', []);
|
||||
|
||||
runInAction(() => {
|
||||
this.notificationChoices = get(response, 'actions.POST', []);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
@ -390,9 +413,13 @@ export class UserStore extends BaseStore {
|
|||
@action.bound
|
||||
async updateNotifyByOptions() {
|
||||
const response = await makeRequest('/notification_policies/notify_by_options/', {});
|
||||
this.notifyByOptions = response;
|
||||
|
||||
runInAction(() => {
|
||||
this.notifyByOptions = response;
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async makeTestCall(userPk: User['pk']) {
|
||||
this.isTestCallInProgress = true;
|
||||
|
||||
|
|
@ -401,7 +428,9 @@ export class UserStore extends BaseStore {
|
|||
})
|
||||
.catch(this.onApiError)
|
||||
.finally(() => {
|
||||
this.isTestCallInProgress = false;
|
||||
runInAction(() => {
|
||||
this.isTestCallInProgress = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { action, observable } from 'mobx';
|
||||
import { action, observable, makeObservable, runInAction } from 'mobx';
|
||||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { makeRequest } from 'network';
|
||||
|
|
@ -16,6 +16,8 @@ export class UserGroupStore extends BaseStore {
|
|||
constructor(rootStore: RootStore) {
|
||||
super(rootStore);
|
||||
|
||||
makeObservable(this);
|
||||
|
||||
this.path = '/user_groups/';
|
||||
}
|
||||
|
||||
|
|
@ -25,21 +27,23 @@ export class UserGroupStore extends BaseStore {
|
|||
params: { search: query },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce(
|
||||
(acc: { [key: number]: UserGroup }, item: UserGroup) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
runInAction(() => {
|
||||
this.items = {
|
||||
...this.items,
|
||||
...result.reduce(
|
||||
(acc: { [key: number]: UserGroup }, item: UserGroup) => ({
|
||||
...acc,
|
||||
[item.id]: item,
|
||||
}),
|
||||
{}
|
||||
),
|
||||
};
|
||||
|
||||
this.searchResult = {
|
||||
...(this.searchResult || {}),
|
||||
[query]: result.map((item: UserGroup) => item.id),
|
||||
};
|
||||
this.searchResult = {
|
||||
...(this.searchResult || {}),
|
||||
[query]: result.map((item: UserGroup) => item.id),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
getSearchResult(query = '') {
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
export interface WaitDelay {
|
||||
value: string;
|
||||
display_name: string;
|
||||
}
|
||||
|
|
@ -179,9 +179,7 @@ class Incidents extends React.Component<IncidentsPageProps, IncidentsPageState>
|
|||
);
|
||||
}
|
||||
|
||||
renderCards(filtersState, setFiltersState, filtersOnFiltersValueChange) {
|
||||
const { store } = this.props;
|
||||
|
||||
renderCards(filtersState, setFiltersState, filtersOnFiltersValueChange, store) {
|
||||
const { values } = filtersState;
|
||||
|
||||
const { newIncidents, acknowledgedIncidents, resolvedIncidents, silencedIncidents } = store.alertGroupStore;
|
||||
|
|
@ -301,7 +299,9 @@ class Incidents extends React.Component<IncidentsPageProps, IncidentsPageState>
|
|||
query={query}
|
||||
page={PAGE.Incidents}
|
||||
onChange={this.handleFiltersChange}
|
||||
extraFilters={this.renderCards.bind(this)}
|
||||
extraFilters={(...args) => {
|
||||
return this.renderCards(...args, store);
|
||||
}}
|
||||
grafanaTeamStore={store.grafanaTeamStore}
|
||||
defaultFilters={{
|
||||
team: [],
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ import {
|
|||
AlertReceiveChannel,
|
||||
AlertReceiveChannelCounters,
|
||||
} from 'models/alert_receive_channel/alert_receive_channel.types';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates';
|
||||
import { ChannelFilter } from 'models/channel_filter';
|
||||
import { AlertTemplatesDTO } from 'models/alert_templates/alert_templates';
|
||||
import { ChannelFilter } from 'models/channel_filter/channel_filter.types';
|
||||
import { INTEGRATION_TEMPLATES_LIST } from 'pages/integration/Integration.config';
|
||||
import IntegrationHelper from 'pages/integration/Integration.helper';
|
||||
import styles from 'pages/integration/Integration.module.scss';
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ import React from 'react';
|
|||
|
||||
import { Button, Checkbox, HorizontalGroup, Icon } from '@grafana/ui';
|
||||
import cn from 'classnames/bind';
|
||||
import { observe } from 'mobx';
|
||||
import { Lambda, observe } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Lambda } from 'mobx/lib/internal';
|
||||
|
||||
import GTable from 'components/GTable/GTable';
|
||||
import Text from 'components/Text/Text';
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
const mixpanel = window.mixpanel;
|
||||
|
||||
let actions = {
|
||||
identify: (id: any) => {
|
||||
if (mixpanel) {
|
||||
mixpanel.identify(id);
|
||||
}
|
||||
},
|
||||
alias: (id: any) => {
|
||||
if (mixpanel) {
|
||||
mixpanel.alias(id);
|
||||
}
|
||||
},
|
||||
track: (name: any, props: any) => {
|
||||
if (mixpanel) {
|
||||
mixpanel.track(name, props);
|
||||
}
|
||||
},
|
||||
people: {
|
||||
set: (props: any) => {
|
||||
if (mixpanel) {
|
||||
mixpanel.people.set(props);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export let Mixpanel = actions;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { locationService } from '@grafana/runtime';
|
||||
import { contextSrv } from 'grafana/app/core/core';
|
||||
import { action, observable } from 'mobx';
|
||||
import { action, makeObservable, observable, runInAction } from 'mobx';
|
||||
import moment from 'moment-timezone';
|
||||
import qs from 'query-string';
|
||||
import { OnCallAppPluginMeta } from 'types';
|
||||
|
|
@ -113,8 +113,11 @@ export class RootBaseStore {
|
|||
labelsStore = new LabelStore(this);
|
||||
loaderStore = LoaderStore;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this);
|
||||
}
|
||||
@action.bound
|
||||
async loadBasicData() {
|
||||
loadBasicData = async () => {
|
||||
const updateFeatures = async () => {
|
||||
await this.updateFeatures();
|
||||
|
||||
|
|
@ -131,18 +134,24 @@ export class RootBaseStore {
|
|||
() => this.grafanaTeamStore.updateItems(),
|
||||
() => updateFeatures(),
|
||||
]);
|
||||
this.isBasicDataLoaded = true;
|
||||
}
|
||||
this.setIsBasicDataLoaded(true);
|
||||
};
|
||||
|
||||
@action.bound
|
||||
async loadMasterData() {
|
||||
@action
|
||||
loadMasterData = async () => {
|
||||
Promise.all([
|
||||
this.userStore.updateNotificationPolicyOptions(),
|
||||
this.userStore.updateNotifyByOptions(),
|
||||
this.alertReceiveChannelStore.updateAlertReceiveChannelOptions(),
|
||||
]);
|
||||
};
|
||||
|
||||
@action
|
||||
setIsBasicDataLoaded(value: boolean) {
|
||||
this.isBasicDataLoaded = value;
|
||||
}
|
||||
|
||||
@action
|
||||
setupPluginError(errorMsg: string) {
|
||||
this.initializationError = errorMsg;
|
||||
}
|
||||
|
|
@ -167,7 +176,7 @@ export class RootBaseStore {
|
|||
* Finally, try to load the current user from the OnCall backend
|
||||
*/
|
||||
async setupPlugin(meta: OnCallAppPluginMeta) {
|
||||
this.initializationError = null;
|
||||
this.setupPluginError(null);
|
||||
this.onCallApiUrl = getOnCallApiUrl(meta);
|
||||
|
||||
if (!FaroHelper.faro) {
|
||||
|
|
@ -245,9 +254,11 @@ export class RootBaseStore {
|
|||
}
|
||||
} else {
|
||||
// everything is all synced successfully at this point..
|
||||
this.backendVersion = pluginConnectionStatus.version;
|
||||
this.backendLicense = pluginConnectionStatus.license;
|
||||
this.recaptchaSiteKey = pluginConnectionStatus.recaptcha_site_key;
|
||||
runInAction(() => {
|
||||
this.backendVersion = pluginConnectionStatus.version;
|
||||
this.backendLicense = pluginConnectionStatus.license;
|
||||
this.recaptchaSiteKey = pluginConnectionStatus.recaptcha_site_key;
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.userStore.currentUser) {
|
||||
|
|
@ -292,13 +303,16 @@ export class RootBaseStore {
|
|||
@action.bound
|
||||
async updateFeatures() {
|
||||
const response = await makeRequest('/features/', {});
|
||||
this.features = response.reduce(
|
||||
(acc: any, key: string) => ({
|
||||
...acc,
|
||||
[key]: true,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
|
||||
runInAction(() => {
|
||||
this.features = response.reduce(
|
||||
(acc: any, key: string) => ({
|
||||
...acc,
|
||||
[key]: true,
|
||||
}),
|
||||
{}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
"strict": false,
|
||||
"resolveJsonModule": true,
|
||||
"noImplicitAny": false,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"useDefineForClassFields": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11101,22 +11101,24 @@ mkdirp@^1.0.4:
|
|||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
mobx-react-lite@1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-1.4.0.tgz#193beb5fdddf17ae61542f65ff951d84db402351"
|
||||
integrity sha512-5xCuus+QITQpzKOjAOIQ/YxNhOl/En+PlNJF+5QU4Qxn9gnNMJBbweAdEW3HnuVQbfqDYEUnkGs5hmkIIStehg==
|
||||
|
||||
mobx-react@6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.1.1.tgz#24a2c8a3393890fa732b4efd34cc6dcccf6e0e7a"
|
||||
integrity sha512-hjACWCTpxZf9Sv1YgWF/r6HS6Nsly1SYF22qBJeUE3j+FMfoptgjf8Zmcx2d6uzA07Cezwap5Cobq9QYa0MKUw==
|
||||
mobx-react-lite@^4.0.4:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-4.0.5.tgz#e2cb98f813e118917bcc463638f5bf6ea053a67b"
|
||||
integrity sha512-StfB2wxE8imKj1f6T8WWPf4lVMx3cYH9Iy60bbKXEs21+HQ4tvvfIBZfSmMXgQAefi8xYEwQIz4GN9s0d2h7dg==
|
||||
dependencies:
|
||||
mobx-react-lite "1.4.0"
|
||||
use-sync-external-store "^1.2.0"
|
||||
|
||||
mobx@5.13.0:
|
||||
version "5.13.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-5.13.0.tgz#0fd68f10aa5ff2d146a4ed9e145b53337cfbca59"
|
||||
integrity sha512-eSAntMSMNj0PFL705rgv+aB/z1RjNqDnFEpBe18yQVreXTWiVgIrmBUXzjnJfuba+eo4eAk6zi+/gXQkSUea8A==
|
||||
mobx-react@9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-9.1.0.tgz#5e54919ca27ffad5f2c0d835148a1f681cebdbc1"
|
||||
integrity sha512-DeDRTYw4AlgHw8xEXtiZdKKEnp+c5/jeUgTbTQXEqnAzfkrgYRWP3p3Nv3Whc2CEcM/mDycbDWGjxKokQdlffg==
|
||||
dependencies:
|
||||
mobx-react-lite "^4.0.4"
|
||||
|
||||
mobx@6.12.0:
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.0.tgz#72b2685ca5af031aaa49e77a4d76ed67fcbf9135"
|
||||
integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ==
|
||||
|
||||
module-details-from-path@^1.0.3:
|
||||
version "1.0.3"
|
||||
|
|
@ -15686,6 +15688,11 @@ use-memo-one@^1.1.1:
|
|||
resolved "https://registry.yarnpkg.com/use-memo-one/-/use-memo-one-1.1.3.tgz#2fd2e43a2169eabc7496960ace8c79efef975e99"
|
||||
integrity sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==
|
||||
|
||||
use-sync-external-store@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
|
||||
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
|
||||
|
||||
use@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue