From 30c9d07958cf28024cf334c5652a258479664ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=8A=B9=EC=97=B0?= <165753731+seungyeoneeee@users.noreply.github.com> Date: Tue, 10 Jun 2025 13:49:41 +0900 Subject: [PATCH 01/13] feat(alert-service): enhance pagination logic in service page (#5934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: enhance pagination logic in service page Signed-off-by: 이승연 * feat: apply debounced resize and move window logic out of store Signed-off-by: 이승연 --------- Signed-off-by: 이승연 --- .../v2/components/ServiceList.vue | 22 ++++++++++++- .../v2/components/ServiceListContent.vue | 32 +++++++++++++++++-- .../v2/stores/service-list-page-store.ts | 5 ++- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/apps/web/src/services/alert-manager/v2/components/ServiceList.vue b/apps/web/src/services/alert-manager/v2/components/ServiceList.vue index 09c92d1dff..b2afcce0a3 100644 --- a/apps/web/src/services/alert-manager/v2/components/ServiceList.vue +++ b/apps/web/src/services/alert-manager/v2/components/ServiceList.vue @@ -6,6 +6,8 @@ import { useRoute, useRouter, } from 'vue-router/composables'; +import { debounce } from 'lodash'; + 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'; @@ -197,7 +199,25 @@ const handleNavigateToDetail = (serviceId: string) => { }).catch(() => {}); }; +// ✅ event listener to change healthy page size (6 -> 8) when window width is 1920px or more +const handleResize = debounce(async () => { + const width = window.innerWidth; + const newPageSize = width >= 1920 ? 8 : 6; + + if (newPageSize !== serviceListPageStore.healthyPageSize) { + const oldPageSize = serviceListPageStore.healthyPageSize; + const oldPage = serviceListPageStore.healthyThisPage; + const startIndex = (oldPage - 1) * oldPageSize; + const newPage = Math.floor(startIndex / newPageSize) + 1; + + serviceListPageStore.setHealthyPageSize(newPageSize); + serviceListPageStore.setHealthyPage(newPage); + fetchHealthyServiceList(); + } +}, 300); + onMounted(async () => { + await handleResize(); const { serviceName, unhealthyPage, healthyPage } = route.query; if (serviceName && typeof serviceName === 'string') { @@ -254,7 +274,7 @@ watch(() => serviceListPageStore.healthyThisPage, (val) => { handleHealthyPageChange(); }); -watch(async () => route.query.serviceName, async (newServiceName) => { +watch(async () => route.query.serviceName, async (newServiceName: any) => { if (typeof newServiceName === 'string') { const nameValues = newServiceName.split(',').map((name) => ({ key: { name: 'name' }, diff --git a/apps/web/src/services/alert-manager/v2/components/ServiceListContent.vue b/apps/web/src/services/alert-manager/v2/components/ServiceListContent.vue index e2514e95af..a2c16d136c 100644 --- a/apps/web/src/services/alert-manager/v2/components/ServiceListContent.vue +++ b/apps/web/src/services/alert-manager/v2/components/ServiceListContent.vue @@ -121,7 +121,7 @@ const handleClickEscalationPolicy = (id: string, escalationPolicyId: string) => /> {{ state.title }} -
+
.collapsible-contents { opacity: 1; transition: opacity 0.3s ease, visibility 0.3s ease; + + @apply grid grid-cols-3 gap-4; + } + + @media (min-width: 120rem) { + .collapsible-contents { + @apply grid grid-cols-4 gap-4; + } + } + + @screen laptop { + .collapsible-contents { + @apply grid grid-cols-3 gap-4; + } } + + @screen tablet { + .collapsible-contents { + @apply grid grid-cols-2 gap-4; + } + } + + @screen mobile { + .collapsible-contents { + @apply grid grid-cols-1 gap-4; + } + } + &.is-collapsed { .collapsible-title { .arrow-button { @@ -270,8 +297,7 @@ const handleClickEscalationPolicy = (id: string, escalationPolicyId: string) => } } .card { - width: 28rem; - max-width: 28rem; + min-width: 25rem; padding: 1.25rem 1.5rem 1rem 1.5rem; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06); .card-inner-wrapper { diff --git a/apps/web/src/services/alert-manager/v2/stores/service-list-page-store.ts b/apps/web/src/services/alert-manager/v2/stores/service-list-page-store.ts index e782976b0c..f88ad050e9 100644 --- a/apps/web/src/services/alert-manager/v2/stores/service-list-page-store.ts +++ b/apps/web/src/services/alert-manager/v2/stores/service-list-page-store.ts @@ -5,7 +5,7 @@ import type { ConsoleFilter } from '@cloudforet/core-lib/query/type'; export const useServiceListPageStore = defineStore('page-service-list', { state: () => ({ unhealthyThisPage: 1, - unhealthyPageSize: 10, + unhealthyPageSize: 12, healthyThisPage: 1, healthyPageSize: 6, searchFilters: [] as ConsoleFilter[], @@ -20,5 +20,8 @@ export const useServiceListPageStore = defineStore('page-service-list', { setSearchFilters(filters: ConsoleFilter[]) { this.searchFilters = filters; }, + setHealthyPageSize(size: number) { + this.healthyPageSize = size; + }, }, }); From 5cea1dd82603b6a2170120e98c9b52f12458b117 Mon Sep 17 00:00:00 2001 From: Dahyun Yu Date: Tue, 10 Jun 2025 14:05:35 +0900 Subject: [PATCH 02/13] Merge pull request #5933 from yuda110/feature/cost-analysis-page feat: create schema for cost analysis apis --- .../composables/use-cost-query-set-api.ts | 21 +++++ .../cost/composables/use-cost-api.ts | 28 ++++++ .../AnomalyDetectionConfigurationTable.vue | 2 +- .../AnomalyDetectionHistoryTable.vue | 2 +- .../components/CostAnalysisContent.vue | 90 ------------------- .../components/CostAnalysisHeader.vue | 2 +- .../queries/use-cost-analysis-query.ts | 30 +++++++ .../queries/use-cost-query-set-query.ts | 50 +++++++++++ .../queries/use-cost-report-config-query.ts | 3 +- .../AnomalyDetectionConfigurationPage.vue | 2 +- .../cost-explorer/pages/CostAnalysisPage.vue | 87 +++++++++++++++++- .../pages/admin/AdminCostAnalysisPage.vue | 7 -- .../cost-explorer/routes/admin/routes.ts | 4 +- 13 files changed, 221 insertions(+), 107 deletions(-) delete mode 100644 apps/web/src/services/cost-explorer/components/CostAnalysisContent.vue create mode 100644 apps/web/src/services/cost-explorer/composables/queries/use-cost-analysis-query.ts create mode 100644 apps/web/src/services/cost-explorer/composables/queries/use-cost-query-set-query.ts delete mode 100644 apps/web/src/services/cost-explorer/pages/admin/AdminCostAnalysisPage.vue diff --git a/apps/web/src/api-clients/cost-analysis/cost-query-set/composables/use-cost-query-set-api.ts b/apps/web/src/api-clients/cost-analysis/cost-query-set/composables/use-cost-query-set-api.ts index e69de29bb2..aef7cd8f0e 100644 --- a/apps/web/src/api-clients/cost-analysis/cost-query-set/composables/use-cost-query-set-api.ts +++ b/apps/web/src/api-clients/cost-analysis/cost-query-set/composables/use-cost-query-set-api.ts @@ -0,0 +1,21 @@ +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; + +import type { ListResponse } from '@/api-clients/_common/schema/api-verbs/list'; +import type { CostQuerySetCreateParameters } from '@/api-clients/cost-analysis/cost-query-set/schema/api-verbs/create'; +import type { CostQuerySetDeleteParameters } from '@/api-clients/cost-analysis/cost-query-set/schema/api-verbs/delete'; +import type { CostQuerySetListParameters } from '@/api-clients/cost-analysis/cost-query-set/schema/api-verbs/list'; +import type { CostQuerySetUpdateParameters } from '@/api-clients/cost-analysis/cost-query-set/schema/api-verbs/update'; +import type { CostQuerySetModel } from '@/api-clients/cost-analysis/cost-query-set/schema/model'; + +export const useCostQuerySetApi = () => { + const actions = { + create: SpaceConnector.clientV2.costAnalysis.costQuerySet.create, + list: SpaceConnector.clientV2.costAnalysis.costQuerySet.list>, + update: SpaceConnector.clientV2.costAnalysis.costQuerySet.update, + delete: SpaceConnector.clientV2.costAnalysis.costQuerySet.delete, + }; + + return { + costQuerySetAPI: actions, + }; +}; diff --git a/apps/web/src/api-clients/cost-analysis/cost/composables/use-cost-api.ts b/apps/web/src/api-clients/cost-analysis/cost/composables/use-cost-api.ts index e69de29bb2..98d080e22e 100644 --- a/apps/web/src/api-clients/cost-analysis/cost/composables/use-cost-api.ts +++ b/apps/web/src/api-clients/cost-analysis/cost/composables/use-cost-api.ts @@ -0,0 +1,28 @@ +import { SpaceConnector } from '@cloudforet/core-lib/space-connector'; + +import type { AnalyzeResponse } from '@/api-clients/_common/schema/api-verbs/analyze'; +import type { CostAnalyzeParameters } from '@/api-clients/cost-analysis/cost/schema/api-verbs/analyze'; +import type { CostStatParameters } from '@/api-clients/cost-analysis/cost/schema/api-verbs/stat'; + +import type { ListResponse } from '@/lib/variable-models/_base/types'; + +import type { CostAnalyzeRawData } from '@/services/cost-explorer/types/cost-analyze-type'; + +import type { CostModel } from '../schema/model'; + +interface UseCostApiReturn { + costAPI: { + analyze: (params: CostAnalyzeParameters) => Promise>; + stat: (params: CostStatParameters) => Promise>; + } +} +export const useCostApi = (): UseCostApiReturn => { + const actions = { + analyze: SpaceConnector.clientV2.costAnalysis.cost.analyze>, + stat: SpaceConnector.clientV2.costAnalysis.cost.stat>, + }; + + return { + costAPI: actions, + }; +}; diff --git a/apps/web/src/services/cost-explorer/components/AnomalyDetectionConfigurationTable.vue b/apps/web/src/services/cost-explorer/components/AnomalyDetectionConfigurationTable.vue index e7243c2e02..b606d5d009 100644 --- a/apps/web/src/services/cost-explorer/components/AnomalyDetectionConfigurationTable.vue +++ b/apps/web/src/services/cost-explorer/components/AnomalyDetectionConfigurationTable.vue @@ -57,7 +57,7 @@ const tableState = reactive({