Skip to content

Commit

Permalink
feat: apply qa (#5375)
Browse files Browse the repository at this point in the history
* chore: changed service key creation condition

Signed-off-by: NaYeong,Kim <[email protected]>

* chore: changed selected service dropdown design

Signed-off-by: NaYeong,Kim <[email protected]>

* chore: changed alert table field

Signed-off-by: NaYeong,Kim <[email protected]>

* feat: apply Excluded Items from List

Signed-off-by: NaYeong,Kim <[email protected]>

* chore: apply placeholder

Signed-off-by: NaYeong,Kim <[email protected]>

---------

Signed-off-by: NaYeong,Kim <[email protected]>
  • Loading branch information
skdud4659 authored Jan 2, 2025
1 parent d9d2c88 commit 76fb9e7
Show file tree
Hide file tree
Showing 14 changed files with 212 additions and 89 deletions.
72 changes: 46 additions & 26 deletions apps/web/src/common/modules/user/UserSelectDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@ import type {
SelectDropdownMenuItem,
} from '@cloudforet/mirinae/types/controls/dropdown/select-dropdown/type';
import type { MembersType } from '@/schema/alert-manager/service/type';
import { i18n } from '@/translations';
import { useAllReferenceStore } from '@/store/reference/all-reference-store';
import type { UserGroupReferenceMap } from '@/store/reference/user-group-reference-store';
import type { UserReferenceMap } from '@/store/reference/user-reference-store';
import type { SelectedUserDropdownIdsType } from '@/common/modules/user/typte';
import { indigo } from '@/styles/colors';
interface DropdownItem extends SelectDropdownMenuItem {
Expand All @@ -35,8 +34,8 @@ type DropdownCategoriesType = {
};
const props = withDefaults(defineProps<{
selectedId?: SelectedUserDropdownIdsType;
selectedIds?: SelectedUserDropdownIdsType[];
selectedId?: string;
selectedIds?: string[];
selectionType?: 'single'|'multiple';
useFixedMenuStyle?: boolean;
invalid?: boolean;
Expand All @@ -49,6 +48,7 @@ const props = withDefaults(defineProps<{
showUserGroupList?: boolean;
showCategoryTitle?: boolean;
placeholder?: string;
excludedSelectedIds?: string[];
}>(), {
selectedId: undefined,
selectedIds: undefined,
Expand All @@ -63,10 +63,12 @@ const props = withDefaults(defineProps<{
showUserGroupList: true,
showCategoryTitle: true,
placeholder: 'Select',
excludedSelectedIds: undefined,
});
const emit = defineEmits<{(event: 'update:selected-ids', value: SelectedUserDropdownIdsType[]): void;
(event: 'update:selected-id', value?: SelectedUserDropdownIdsType): void;
const emit = defineEmits<{(event: 'update:selected-id', value?: string): void;
(event: 'update:selected-ids', value: string[]): void;
(event: 'formatted-selected-ids', value: Record<MembersType, string[]>): void;
}>();
const allReferenceStore = useAllReferenceStore();
Expand Down Expand Up @@ -101,7 +103,10 @@ const state = reactive({
label: storeState.userReferenceMap[userId]?.label || storeState.userReferenceMap[userId]?.name || userId,
}));
}
return Object.values(storeState.userReferenceMap).map((u: UserReferenceMap[string]) => ({
const list = props.excludedSelectedIds
? Object.values(storeState.userReferenceMap).filter((i) => !props.excludedSelectedIds?.includes(i.key))
: Object.values(storeState.userReferenceMap);
return list.map((u: UserReferenceMap[string]) => ({
name: u.key,
label: u.key,
userName: u.name,
Expand All @@ -115,7 +120,10 @@ const state = reactive({
label: storeState.userGroupReferenceMap[userGroupId]?.label || storeState.userGroupReferenceMap[userGroupId]?.name || userGroupId,
}));
}
return Object.values(storeState.userGroupReferenceMap).map((u: UserGroupReferenceMap[string]) => ({
const list = props.excludedSelectedIds
? Object.values(storeState.userGroupReferenceMap).filter((i) => !props.excludedSelectedIds?.includes(i.key))
: Object.values(storeState.userGroupReferenceMap);
return list.map((u: UserGroupReferenceMap[string]) => ({
name: u.key,
label: u.label,
members: u.data.users?.length,
Expand All @@ -124,6 +132,7 @@ const state = reactive({
selectedItems: [] as SelectDropdownMenuItem[],
});
const checkUserGroup = (id: string): boolean => state.allUserGroupItems.some((i) => i.name === id);
const menuItemsHandler = (): AutocompleteHandler => async (keyword: string, pageStart = 1, pageLimit = 10, filters, resultIndex) => {
const _totalCount = pageStart - 1 + pageLimit;
const filterItems = (items: SelectDropdownMenuItem[]) => items.filter((item) => getTextHighlightRegex(keyword).test(item.name)).slice(pageStart - 1, _totalCount);
Expand Down Expand Up @@ -156,8 +165,8 @@ const menuItemsHandler = (): AutocompleteHandler => async (keyword: string, page
});
};
const currentUserIds = computed<SelectedUserDropdownIdsType[]>(() => state.selectedItems.map((item) => ({ value: item.name, type: checkUserGroup(item.name) ? 'USER_GROUP' : 'USER' })));
const currentUserId = computed<SelectedUserDropdownIdsType|undefined>(() => ({ value: state.selectedItems[0]?.name, type: checkUserGroup(state.selectedItems[0]?.name) ? 'USER_GROUP' : 'USER' }));
const currentUserId = computed<string|undefined>(() => state.selectedItems[0]?.name);
const currentUserIds = computed<string[]>(() => state.selectedItems.map((item) => item.name));
const handleUpdateSelectedUserItems = (selectedUsers: SelectDropdownMenuItem[]) => {
if (isEqual(selectedUsers, state.selectedItems)) return; // prevent unnecessary update
Expand All @@ -168,53 +177,64 @@ const handleUpdateSelectedUserItems = (selectedUsers: SelectDropdownMenuItem[])
} else {
if (isEqual(currentUserIds.value, props.selectedIds)) return; // prevent unnecessary update
emit('update:selected-ids', currentUserIds.value);
emit('formatted-selected-ids', {
USER: currentUserIds.value.filter((i) => !checkUserGroup(i)),
USER_GROUP: currentUserIds.value.filter((i) => checkUserGroup(i)),
});
}
};
const handleTagDelete = (idx: number) => {
state.selectedItems.splice(idx, 1);
emit('update:selected-ids', currentUserIds.value);
emit('formatted-selected-ids', {
USER: currentUserIds.value.filter((i) => !checkUserGroup(i)),
USER_GROUP: currentUserIds.value.filter((i) => checkUserGroup(i)),
});
};
const initSingleType = (_userId?: SelectedUserDropdownIdsType) => {
if (currentUserId?.value !== _userId?.value) {
const value = _userId?.value || '';
const initSingleType = (_userId?: string) => {
if (currentUserId?.value !== _userId) {
const value = _userId || '';
const label = (() => {
if (props.showUserList && storeState.userReferenceMap[value]) {
return storeState.userReferenceMap[value]?.label ?? _userId?.value;
return storeState.userReferenceMap[value]?.label ?? _userId;
}
if (props.showUserGroupList && storeState.userGroupReferenceMap[value]) {
return storeState.userGroupReferenceMap[value]?.label ?? _userId?.value;
return storeState.userGroupReferenceMap[value]?.label ?? _userId;
}
return _userId?.value;
return _userId;
})();
state.selectedItems = _userId?.value
? [{ name: _userId?.value, label }]
state.selectedItems = _userId
? [{ name: _userId, label }]
: [];
}
};
const initMultipleType = (_userIds?: SelectedUserDropdownIdsType[]) => {
const initMultipleType = (_userIds?: string[]) => {
if (!Array.isArray(_userIds)) throw new Error('userIds should be an array');
if (!isEqual(currentUserIds.value, _userIds)) {
state.selectedItems = _userIds.map((userId) => {
const label = (() => {
if (props.showUserList && storeState.userReferenceMap[userId.value]) {
return storeState.userReferenceMap[userId.value]?.label ?? userId.value;
if (props.showUserList && storeState.userReferenceMap[userId]) {
return storeState.userReferenceMap[userId]?.label ?? userId;
}
if (props.showUserGroupList && storeState.userGroupReferenceMap[userId.value]) {
return storeState.userGroupReferenceMap[userId.value]?.label ?? userId.value;
if (props.showUserGroupList && storeState.userGroupReferenceMap[userId]) {
return storeState.userGroupReferenceMap[userId]?.label ?? userId;
}
return userId.value;
return userId;
})();
return {
name: userId.value,
name: userId,
label,
};
});
emit('formatted-selected-ids', {
USER: currentUserIds.value.filter((i) => !checkUserGroup(i)),
USER_GROUP: currentUserIds.value.filter((i) => checkUserGroup(i)),
});
}
};
const checkUserGroup = (id: string): boolean => state.allUserGroupItems.some((i) => i.name === id);
watch([() => props.selectedId, () => props.selectedIds], ([newUserId, newUserIds]) => {
if (props.selectionType === 'single') {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/common/modules/user/typte.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type SelectedUserDropdownIdsType = {
export type SelectedIdsType = {
value: string;
type: 'USER'|'USER_GROUP';
};
2 changes: 2 additions & 0 deletions apps/web/src/schema/alert-manager/alert/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export interface AlertModel {
updated_at: string;
acknowledged_at: string;
resolved_at: string;
acknowledged_by: string,
resolved_by: string,
}

export interface AlertEventModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ const tableState = reactive({
{ name: 'triggered_by', label: i18n.t('ALERT_MANAGER.ALERTS.TRIGGERED_BY'), copyValueFormatter: () => storeState.alertInfo.triggered_by },
{ name: 'service_id', label: i18n.t('ALERT_MANAGER.ALERTS.SERVICE'), disableCopy: true },
{ name: 'resources', label: i18n.t('ALERT_MANAGER.ALERTS.RESOURCE'), disableCopy: true },
{ name: 'created_at', label: i18n.t('ALERT_MANAGER.ALERTS.CREATED'), disableCopy: true },
{ name: 'acknowledged_at', label: i18n.t('ALERT_MANAGER.ALERTS.ACKNOWLEDGED'), disableCopy: true },
{ name: 'resolved_at', label: i18n.t('ALERT_MANAGER.ALERTS.RESOLVED'), disableCopy: true },
{ name: 'created_at', label: i18n.t('ALERT_MANAGER.ALERTS.CREATED_AT'), disableCopy: true },
{ name: 'acknowledged_at', label: i18n.t('ALERT_MANAGER.ALERTS.ACKNOWLEDGED_AT'), disableCopy: true },
{ name: 'resolved_at', label: i18n.t('ALERT_MANAGER.ALERTS.RESOLVED_AT'), disableCopy: true },
]),
});
Expand Down Expand Up @@ -143,8 +143,8 @@ const getAssetInfo = (assetId: string) => {
{{ value || '--' }}
</template>
<template #data-service_id="{ value }">
<p-link v-if="storeState.serviceMap[value].label "
:text="storeState.serviceMap[value].label"
<p-link v-if="storeState.serviceMap[value]?.label "
:text="storeState.serviceMap[value]?.label"
:to="{
name: ALERT_MANAGER_ROUTE.SERVICE.DETAIL._NAME,
params: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import type { DataTableFieldType } from '@cloudforet/mirinae/src/data-display/tables/data-table/type';
import { ACTION_ICON } from '@cloudforet/mirinae/src/navigation/link/type';
import type { SelectDropdownMenuItem } from '@cloudforet/mirinae/types/controls/dropdown/select-dropdown/type';
import { iso8601Formatter } from '@cloudforet/utils';
import { ALERT_STATUS, ALERT_URGENCY } from '@/schema/alert-manager/alert/constants';
import type { AlertModel } from '@/schema/alert-manager/alert/model';
Expand Down Expand Up @@ -80,6 +81,7 @@ const state = reactive({
return {
...alert,
alert_number: number[number.length - 1],
created_at: iso8601Formatter(alert.created_at, storeState.timezone),
};
})),
alertStateLabels: getAlertStateI18n(),
Expand Down Expand Up @@ -240,9 +242,10 @@ watch(() => route.query, async (query) => {
:selection-label="$t('ALERT_MANAGER.ALERTS.SERVICE')"
style-type="rounded"
show-delete-all-button
selection-highlight
use-fixed-menu-style
:selected="filterState.selectedServiceId"
class="service-dropdown pt-6 pl-4"
class="service-dropdown mt-6 pl-4"
@update:selected="handleSelectServiceDropdownItem"
/>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { assetUrlConverter } from '@/lib/helper/asset-helper';
import type { ScheduleSettingFormType } from '@/common/components/schedule-setting-form/schedule-setting-form';
import ScheduleSettingForm from '@/common/components/schedule-setting-form/ScheduleSettingForm.vue';
import { useFormValidator } from '@/common/composables/form-validator';
import type { SelectedUserDropdownIdsType } from '@/common/modules/user/typte';
import UserSelectDropdown from '@/common/modules/user/UserSelectDropdown.vue';
import { useServiceCreateFormStore } from '@/services/alert-manager/stores/service-create-form-store';
Expand Down Expand Up @@ -54,13 +53,16 @@ const state = reactive({
},
])),
selectedRadioIdx: 0,
selectedMemberItems: [] as SelectedUserDropdownIdsType[],
selectedMemberItems: {} as Record<MembersType, string[]>,
isSchemaDataValid: false,
isMemberDataValid: computed<boolean>(() => {
if (state.selectedRadioIdx === 0) {
return true;
}
return state.selectedMemberItems.length > 0;
if (state.selectedRadioIdx === 1) {
return (state.selectedMemberItems.USER_GROUP || []).length > 0;
}
return (state.selectedMemberItems.USER || []).length > 0;
}),
});
Expand All @@ -85,14 +87,17 @@ const {
},
});
const handleFormattedSelectedIds = (value: Record<MembersType, string[]>) => {
state.selectedMemberItems = value;
};
const handleSchemaValidate = (isValid: boolean) => {
state.isSchemaDataValid = isValid;
};
const handleScheduleForm = (form: ScheduleSettingFormType) => {
state.scheduleForm = form;
};
const handleChangeRadio = () => {
state.selectedMemberItems = [];
state.selectedMemberItems = {};
};
watch([() => name.value, () => state.scheduleForm, () => state.selectedRadioIdx, () => state.selectedMemberItems, () => state.schemaForm], (
Expand All @@ -105,8 +110,8 @@ watch([() => name.value, () => state.scheduleForm, () => state.selectedRadioIdx,
schedule: scheduleForm,
data: !state.isForwardTypeProtocol ? schemaForm : {
FORWARD_TYPE: state.radioMenuList[selectedRadioIdx].name,
USER_GROUP: selectedRadioIdx === 1 ? selectedMemberItems.map((item) => item.value) : undefined,
USER: selectedRadioIdx === 2 ? selectedMemberItems.map((item) => item.value) : undefined,
USER_GROUP: selectedRadioIdx === 1 ? selectedMemberItems.USER_GROUP : undefined,
USER: selectedRadioIdx === 2 ? selectedMemberItems.USER : undefined,
},
},
isAllValid.value && (state.isForwardTypeProtocol ? state.isMemberDataValid : state.isSchemaDataValid),
Expand Down Expand Up @@ -174,7 +179,7 @@ watch([() => name.value, () => state.scheduleForm, () => state.selectedRadioIdx,
:show-category-title="false"
:show-user-group-list="state.selectedRadioIdx === 1"
:show-user-list="state.selectedRadioIdx === 2"
:selected-ids.sync="state.selectedMemberItems"
@formatted-selected-ids="handleFormattedSelectedIds"
/>
</div>
</template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import type { ServiceCreateParameters } from '@/schema/alert-manager/service/api-verbs/create';
import type { ServiceModel } from '@/schema/alert-manager/service/model';
import type { MembersType } from '@/schema/alert-manager/service/type';
import { i18n } from '@/translations';
import { useAllReferenceStore } from '@/store/reference/all-reference-store';
Expand All @@ -19,7 +20,6 @@ import { showSuccessMessage } from '@/lib/helper/notice-alert-helper';
import ErrorHandler from '@/common/composables/error/errorHandler';
import { useFormValidator } from '@/common/composables/form-validator';
import type { SelectedUserDropdownIdsType } from '@/common/modules/user/typte';
import UserSelectDropdown from '@/common/modules/user/UserSelectDropdown.vue';
import ServiceCreateStepContainer from '@/services/alert-manager/components/ServiceCreateStepContainer.vue';
Expand All @@ -30,15 +30,13 @@ const allReferenceStore = useAllReferenceStore();
const allReferenceGetters = allReferenceStore.getters;
const dropdownState = reactive({
selectedMemberItems: [] as SelectedUserDropdownIdsType[],
selectedMemberItems: {} as Record<MembersType, string[]>,
});
const storeState = reactive({
serviceListMap: computed<ServiceReferenceMap>(() => allReferenceGetters.service),
});
const state = reactive({
isFocusedKey: false,
selectedWorkspaceMemberList: computed<string[]>(() => dropdownState.selectedMemberItems.filter((i) => i.type === 'USER').map((i) => i.value)),
selectedUserGroupList: computed<string[]>(() => dropdownState.selectedMemberItems.filter((i) => i.type === 'USER_GROUP').map((i) => i.value)),
});
const {
Expand Down Expand Up @@ -74,10 +72,13 @@ const {
},
});
const handleFormattedSelectedIds = (value: Record<MembersType, string[]>) => {
dropdownState.selectedMemberItems = value;
};
const convertToSnakeCase = (str): string => {
const cleanedInput = str.replace(/[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/g, '');
return cleanedInput
.toLowerCase()
.toUpperCase()
.split(' ')
.filter((word) => word.trim() !== '')
.join('_');
Expand All @@ -93,8 +94,8 @@ const handleCreateService = async () => {
name: name.value,
service_key: key.value,
members: {
USER: state.selectedWorkspaceMemberList,
USER_GROUP: state.selectedUserGroupList,
USER: dropdownState.selectedMemberItems.USER,
USER_GROUP: dropdownState.selectedMemberItems.USER_GROUP,
},
description: description.value,
});
Expand Down Expand Up @@ -160,7 +161,7 @@ watch(() => state.isFocusedKey, (isFocusedKey) => {
<user-select-dropdown selection-type="multiple"
appearance-type="stack"
use-fixed-menu-style
:selected-ids.sync="dropdownState.selectedMemberItems"
@formatted-selected-ids="handleFormattedSelectedIds"
/>
</p-field-group>
<p-field-group :label="$t('ALERT_MANAGER.DESCRIPTION')">
Expand Down
Loading

0 comments on commit 76fb9e7

Please sign in to comment.