Skip to content

feat: add alert fields and fix copy value bug #5755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from 3 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: { unit: 'month', value: 1 },
Copy link
Preview

Copilot AI Apr 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'relativePeriod' object includes an extra 'unit' property which is not defined in the AlertRelativePeriod type. Consider removing the 'unit' property from all relativePeriod definitions to ensure consistency with the expected type.

Suggested change
relativePeriod: { unit: 'month', value: 1 },
relativePeriod: { value: 1 },

Copilot uses AI. Check for mistakes.

label: i18n.t('ALERT_MANAGER.ALERTS.LAST_1_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_3_MONTHS,
relativePeriod: { unit: 'month', value: 2 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_3_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_6_MONTHS,
relativePeriod: { unit: 'month', value: 5 },
label: i18n.t('ALERT_MANAGER.ALERTS.LAST_6_MONTHS'),
},
{
name: ALERT_PERIOD_DROPDOWN_MENU.LAST_12_MONTHS,
relativePeriod: { unit: 'month', 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