Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
import type { TranslateResult } from 'vue-i18n';
import { useRoute } from 'vue-router/composables';

import dayjs from 'dayjs';

import { makeDistinctValueHandler } from '@cloudforet/core-lib/component-util/query-search';
import { QueryHelper } from '@cloudforet/core-lib/query';
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
Expand All @@ -30,6 +32,7 @@ import { FILE_NAME_PREFIX } from '@/lib/excel-export/constant';
import { downloadExcel } from '@/lib/helper/file-download-helper';
import { replaceUrlQuery } from '@/lib/router-query-string';

import CustomDateModal from '@/common/components/custom-date-modal/CustomDateModal.vue';
import ErrorHandler from '@/common/composables/error/errorHandler';
import { useQueryTags } from '@/common/composables/query-tags';
import CustomFieldModal from '@/common/modules/custom-table/custom-field-modal/CustomFieldModal.vue';
Expand All @@ -45,12 +48,18 @@ import {
ALERT_EXCEL_FIELDS,
ALERT_MANAGEMENT_TABLE_FIELDS,
ALERT_MANAGEMENT_TABLE_HANDLER,
ALERT_STATUS_FILTERS,
ALERT_STATUS_FILTERS, ALERT_PERIOD_DROPDOWN_MENU,
} from '@/services/alert-manager/v2/constants/alert-table-constant';
import {
convertRelativePeriodToPeriod, initiatePeriodByGranularity,
} from '@/services/alert-manager/v2/helpers/alert-period-helper';
import { ALERT_MANAGER_ROUTE } from '@/services/alert-manager/v2/routes/route-constant';
import { useAlertPageStore } from '@/services/alert-manager/v2/stores/alert-page-store';
import { useServiceDetailPageStore } from '@/services/alert-manager/v2/stores/service-detail-page-store';
import type { AlertFilterType } from '@/services/alert-manager/v2/types/alert-manager-type';
import type {
AlertFilterType, AlertPeriodItemType,
AlertPeriodDropdownMenuType,
} from '@/services/alert-manager/v2/types/alert-manager-type';

const allReferenceStore = useAllReferenceStore();
const allReferenceGetters = allReferenceStore.getters;
Expand Down Expand Up @@ -88,13 +97,62 @@ const state = reactive({
? calculateTime(alert?.resolved_at, storeState.timezone) || '0m'
: calculateTime(alert?.created_at, storeState.timezone) || '0m',
created_at: iso8601Formatter(alert.created_at, storeState.timezone),
resolved_at: iso8601Formatter(alert.resolved_at, storeState.timezone) || '-',
}))),
alertStateLabels: getAlertStateI18n(),
urgencyLabels: getAlertUrgencyI18n(),
defaultFields: computed<DataTableFieldType[]>(() => (state.isServicePage ? ALERT_MANAGEMENT_TABLE_FIELDS : [{ name: 'service_id', label: 'Service' }, ...ALERT_MANAGEMENT_TABLE_FIELDS])),
fields: route.name === ALERT_MANAGER_ROUTE.SERVICE.DETAIL._NAME ? ALERT_MANAGEMENT_TABLE_FIELDS : [{ name: 'service_id', label: 'Service' }, ...ALERT_MANAGEMENT_TABLE_FIELDS],
customRangeModalVisible: false,
});
const filterState = reactive({
urgencyFields: computed<SelectDropdownMenuItem[]>(() => ([
{ label: i18n.t('ALERT_MANAGER.ALERTS.ALL'), name: 'ALL' },
{ label: i18n.t('ALERT_MANAGER.ALERTS.HIGH'), name: ALERT_URGENCY.HIGH },
{ label: i18n.t('ALERT_MANAGER.ALERTS.LOW'), name: ALERT_URGENCY.LOW },
])),
period: initiatePeriodByGranularity()[0],
periodMenuItems: computed<AlertPeriodItemType[]>(() => [
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_1_MONTH,
relativePeriod: { value: 1 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_1_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_3_MONTHS,
relativePeriod: { value: 2 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_3_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_6_MONTHS,
relativePeriod: { value: 5 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_6_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_12_MONTHS,
relativePeriod: { value: 11 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_12_MONTHS'),
},
{
type: 'divider',
}, {
type: 'item',
name: ALERT_PERIOD_DROPDOWN_MENU.CUSTOM,
label: i18n.t('ALERT_MANAGER.ALERTS.CUSTOM'),
},
]),
isPeriodInvalid: computed<boolean>(() => {
const now = dayjs().utc();
const checkPeriod = (limit:number):{isStartInvalid:boolean, isEndInvalid:boolean} => {
const isStartInvalid = now.diff(filterState.period?.start, 'month') >= limit;
const isEndInvalid = now.diff(filterState.period?.end, 'month') >= limit;
return { isStartInvalid, isEndInvalid };
};
const LIMIT_MONTH = 36;
const { isStartInvalid, isEndInvalid } = checkPeriod(LIMIT_MONTH);
return isStartInvalid || isEndInvalid;
}),
selectedPeriod: ALERT_PERIOD_DROPDOWN_MENU.LAST_1_MONTH as string,
serviceDropdownList: computed<SelectDropdownMenuItem[]>(() => alertPageGetters.serviceDropdownList),
statusFields: computed<AlertFilterType[]>(() => ([
{ label: i18n.t('ALERT_MANAGER.ALERTS.OPEN'), name: ALERT_STATUS_FILTERS.OPEN },
Expand All @@ -104,11 +162,6 @@ const filterState = reactive({
{ label: i18n.t('ALERT_MANAGER.ALERTS.IGNORED'), name: ALERT_STATUS_FILTERS.IGNORED },
{ label: i18n.t('ALERT_MANAGER.ALERTS.ALL'), name: 'ALL' },
])),
urgencyFields: computed<SelectDropdownMenuItem[]>(() => ([
{ label: i18n.t('ALERT_MANAGER.ALERTS.ALL'), name: 'ALL' },
{ label: i18n.t('ALERT_MANAGER.ALERTS.HIGH'), name: ALERT_URGENCY.HIGH },
{ label: i18n.t('ALERT_MANAGER.ALERTS.LOW'), name: ALERT_URGENCY.LOW },
])),
labelHandler: computed(() => makeDistinctValueHandler('alert_manager.Alert', 'labels')),
selectedLabels: [] as SelectDropdownMenuItem[],
});
Expand Down Expand Up @@ -179,6 +232,16 @@ const handleSelectFilter = async (type: 'status' | 'urgency', value: string) =>
}
await fetchAlertsList();
};
const handleSelectPeriod = async (periodMenuName: AlertPeriodDropdownMenuType) => {
if (periodMenuName === ALERT_PERIOD_DROPDOWN_MENU.CUSTOM) {
state.customRangeModalVisible = true;
return;
}
filterState.selectedPeriod = periodMenuName;
const selectedPeriodItem = filterState.periodMenuItems.find((d) => d.name === periodMenuName) || {} as AlertPeriodItemType;
filterState.period = selectedPeriodItem.relativePeriod ? convertRelativePeriodToPeriod(selectedPeriodItem.relativePeriod) : filterState.period;
await fetchAlertsList();
};
const handleChange = async (options: any = {}) => {
if (options.sortBy !== undefined) alertListApiQueryHelper.setSort(options.sortBy, options.sortDesc);
if (options.queryTags !== undefined) {
Expand Down Expand Up @@ -210,22 +273,35 @@ const handleExportToExcel = async () => {
timezone: storeState.timezone,
});
};
const handleCustomRangeModalConfirm = (start: string, end: string) => {
filterState.period = { start: dayjs(start).startOf('month').format('YYYY-MM-DD'), end: dayjs(end).endOf('month').format('YYYY-MM-DD') };
filterState.selectedPeriod = ALERT_PERIOD_DROPDOWN_MENU.CUSTOM;
state.customRangeModalVisible = false;
fetchAlertsList();
};

const fetchAlertsList = async () => {
try {
filterQueryHelper.setFilters([]);
if (storeState.selectedUrgency !== 'ALL') {
filterQueryHelper.addFilter({ k: 'urgency', v: storeState.selectedUrgency, o: '=' });
}
if (storeState.selectedStatus === ALERT_STATUS_FILTERS.OPEN) {
filterQueryHelper.addFilter({ k: 'status', v: [ALERT_STATUS_FILTERS.TRIGGERED, ALERT_STATUS_FILTERS.ACKNOWLEDGED], o: '=' });
} else if (storeState.selectedStatus !== 'ALL') {
filterQueryHelper.addFilter({ k: 'status', v: storeState.selectedStatus, o: '=' });
}
if (storeState.selectedUrgency !== 'ALL') {
filterQueryHelper.addFilter({ k: 'urgency', v: storeState.selectedUrgency, o: '=' });
}
if (filterState.selectedLabels.length > 0) {
filterQueryHelper.addFilter({ k: 'labels', v: filterState.selectedLabels.map((i) => i.name), o: '=' });
}

if (filterState.period.start) {
filterQueryHelper.addFilter({ k: 'created_at', v: filterState.period.start, o: '>=' });
}
if (filterState.period.end) {
filterQueryHelper.addFilter({ k: 'created_at', v: filterState.period.end, o: '<=' });
}

if (state.isServicePage) {
filterQueryHelper.addFilter({ k: 'service_id', v: storeState.serviceId, o: '=' });
} else if (storeState.selectedServiceId) {
Expand Down Expand Up @@ -322,6 +398,15 @@ watch(() => storeState.serviceId, async (serviceId) => {
<span>{{ item.label }}</span>
</template>
</p-select-dropdown>
<p-select-dropdown :menu="filterState.periodMenuItems"
:selection-label="$t('ALERT_MANAGER.ALERTS.PERIOD')"
disable-proxy
style-type="rounded"
use-fixed-menu-style
:selected="filterState.selectedPeriod"
:invalid="filterState.isPeriodInvalid"
@select="handleSelectPeriod"
/>
<p-divider vertical
class="divider"
/>
Expand Down Expand Up @@ -433,6 +518,13 @@ watch(() => storeState.serviceId, async (serviceId) => {
@complete="fetchAlertsList"
@custom-field-loaded="handleCustomFieldUpdate"
/>
<custom-date-modal :visible.sync="state.customRangeModalVisible"
:start="filterState.period?.start"
:end="filterState.period?.end"
:datetime-picker-data-type="'yearToMonth'"
use-restricted-mode
@confirm="handleCustomRangeModalConfirm"
/>
</div>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ const state = reactive({
SUN: i18n.t('ALERT_MANAGER.NOTIFICATIONS.SUNDAY'),
})),
fields: computed<DataTableFieldType[]>(() => {
const forwardField = (state.notificationInfo.channel_type === SERVICE_CHANNEL_TYPE.FORWARD) ? [{ label: 'Member', name: 'data' }] : [];
const forwardField = (state.notificationInfo.channel_type === SERVICE_CHANNEL_TYPE.FORWARD) ? [{ label: 'Member', name: 'data', disableCopy: true }] : [];
return [
{ label: 'Name', name: 'name' },
{ label: 'Name', name: 'name', disableCopy: true },
{ label: 'Channel', name: 'protocol_id' },
{ label: 'State', name: 'state' },
{ label: 'State', name: 'state', disableCopy: true },
...forwardField,
{ label: 'Schedule', name: 'schedule', disableCopy: true },
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import type { ExcelDataField } from '@/lib/helper/file-download-helper/type';

import type { AlertManagementTableHandlerType } from '@/services/alert-manager/v2/types/alert-manager-type';

export const ALERT_PERIOD_DROPDOWN_MENU = {
LAST_1_MONTH: 'LAST_1_MONTH',
LAST_3_MONTHS: 'LAST_3_MONTHS',
LAST_6_MONTHS: 'LAST_6_MONTHS',
LAST_12_MONTHS: 'LAST_12_MONTHS',
CUSTOM: 'CUSTOM',
} as const;
export const ALERT_STATUS_FILTERS = {
OPEN: 'OPEN',
TRIGGERED: 'TRIGGERED',
Expand All @@ -20,6 +27,7 @@ export const ALERT_MANAGEMENT_TABLE_FIELDS: DataTableFieldType[] = [
{ name: 'triggered_by', label: 'Triggered by' },
{ name: 'duration', label: 'Duration', sortable: false },
{ name: 'created_at', label: 'Created' },
{ name: 'resolved_at', label: 'Resolved' },
];
export const ALERT_MANAGEMENT_TABLE_HANDLER: AlertManagementTableHandlerType = {
keyItemSets: [{
Expand All @@ -44,7 +52,8 @@ export const ALERT_EXCEL_FIELDS: ExcelDataField[] = [
{ key: 'urgency', name: 'Urgency' },
{ key: 'labels', name: 'Labels' },
{ key: 'triggered_by', name: 'Triggered by', reference: { reference_key: 'webhook_id', resource_type: 'alert_manager.Webhook' } },
{ key: 'created_at', name: 'Created' },
{ key: 'created_at', name: 'Created', type: 'datetime' },
{ key: 'resolved_at', name: 'Resolved', type: 'datetime' },
];

export const ALERT_CHANNEL_TABLE_FIELDS: DataTableFieldType[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export const ALERT_EXCEL_FIELDS: ExcelDataField[] = [
];

export const WEBHOOK_DEFINITION_FIELDS: DataTableFieldType[] = [
{ name: 'name', label: 'Name' },
{ name: 'plugin_info.plugin_id', label: 'Plugin' },
{ name: 'state', label: 'State' },
{ name: 'name', label: 'Name', disableCopy: true },
{ name: 'plugin_info.plugin_id', label: 'Plugin', disableCopy: true },
{ name: 'state', label: 'State', disableCopy: true },
{ name: 'plugin_info.version', label: 'Version' },
{ name: 'webhook_id', label: 'Webhook ID' },
{ name: 'webhook_url', label: 'Webhook URL' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import dayjs from 'dayjs';

import type { AlertRelativePeriod, Period } from '@/services/alert-manager/v2/types/alert-manager-type';

export const convertRelativePeriodToPeriod = (alertRelativePeriod: AlertRelativePeriod): Period => {
const today = dayjs.utc();
return {
start: today.subtract(alertRelativePeriod.value, 'month').format('YYYY-MM-DD'),
};
};

export const initiatePeriodByGranularity = (): [Period, AlertRelativePeriod|undefined] => {
const last1MonthsRelativePeriod: AlertRelativePeriod = { value: 1 };
return [convertRelativePeriodToPeriod(last1MonthsRelativePeriod), last1MonthsRelativePeriod];
};
16 changes: 16 additions & 0 deletions apps/web/src/services/alert-manager/v2/types/alert-manager-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { ServiceChannelDataType, ServiceChannelScheduleInfoType } from '@/s
import type { ServiceModel } from '@/schema/alert-manager/service/model';
import type { AlertsInfoType, AlertsType } from '@/schema/alert-manager/service/type';

import type { ALERT_PERIOD_DROPDOWN_MENU } from '@/services/alert-manager/v2/constants/alert-table-constant';
import type {
SERVICE_DETAIL_TABS,
WEBHOOK_DETAIL_TABS,
Expand All @@ -33,6 +34,12 @@ export type WebhookModalType = 'UPDATE' | 'ENABLE' | 'DISABLE' | 'DELETE';

export type EventRuleSettingsType = typeof EVENT_RULE_SETTINGS_TYPE[keyof typeof EVENT_RULE_SETTINGS_TYPE];

export type AlertPeriodDropdownMenuType = typeof ALERT_PERIOD_DROPDOWN_MENU[keyof typeof ALERT_PERIOD_DROPDOWN_MENU];

export type Period = {
start?: string;
end?: string;
};
export type AlertFilterType = {
label: TranslateResult;
name: string;
Expand All @@ -41,6 +48,15 @@ export type AlertUrgencyRadioType = {
label: TranslateResult,
name: AlertUrgencyType
};
export type AlertRelativePeriod = {
value: number;
};
export type AlertPeriodItemType = {
name?: AlertPeriodDropdownMenuType;
label?: TranslateResult;
period?: Period;
relativePeriod?: AlertRelativePeriod;
};
export type AlertManagementTableHandlerType = {
keyItemSets: KeyItemSet[],
valueHandlerMap: ValueHandlerMap
Expand Down
Loading
Loading