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 @@ -72,10 +72,10 @@ const emit = defineEmits<{(e: 'click-next'): void, (e: 'click-cancel'): void }>(


watch(() => budgetCreatePageState, () => {
if (budgetCreatePageState.name && budgetCreatePageState.project && budgetCreatePageState.scope.type === 'project' && budgetCreatePageState.budgetManager) {
if (budgetCreatePageState.name && budgetCreatePageState.project && budgetCreatePageState.scope.type === 'project') {
state.isContinueAble = true;
} else if (budgetCreatePageState.name && budgetCreatePageState.project && budgetCreatePageState.scope.type === 'serviceAccount'
&& budgetCreatePageState.scope.serviceAccount && budgetCreatePageState.scope.serviceAccount.length > 0 && budgetCreatePageState.budgetManager
&& budgetCreatePageState.scope.serviceAccount && budgetCreatePageState.scope.serviceAccount.length > 0
) {
state.isContinueAble = true;
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import {
computed, reactive, watch,
computed, reactive, watch, ref,
} from 'vue';

import dayjs from 'dayjs';
Expand Down Expand Up @@ -30,8 +30,15 @@ import { DEFAULT_UNIFIED_COST_CURRENCY, YAHOO_FINANCE_ID } from '@/services/cost
import { useBudgetCreatePageStore } from '@/services/cost-explorer/stores/budget-create-page-store';



const budgetCreatePageStore = useBudgetCreatePageStore();
const budgetCreatePageState = budgetCreatePageStore.state;

const isStartMonthManuallyChanged = ref(false);

const handleStartMonthPickerClosed = () => {
isStartMonthManuallyChanged.value = true;
};
const domainStore = useDomainStore();
const domainState = domainStore.state;
const allReferenceStore = useAllReferenceStore();
Expand Down Expand Up @@ -71,8 +78,8 @@ const state = reactive({


const isCycleEnabled = computed(() => budgetCreatePageState.startMonth.length > 0
&& budgetCreatePageState.endMonth.length > 0
&& state.existingBudgetUsageList.length === 0);
&& budgetCreatePageState.endMonth.length > 0
&& state.existingBudgetUsageList.length === 0);

const emit = defineEmits<{(e: 'click-next'): void}>();

Expand Down Expand Up @@ -193,7 +200,7 @@ watch(() => [budgetCreatePageState.startMonth, budgetCreatePageState.endMonth],
);
budgetCreatePageState.budgetEachDate = Array(12).fill('');
}
}, { immediate: true });
}, { deep: true, immediate: true });

watch(() => budgetCreatePageState.selectedMonthlyBudgetAllocation, (nv, ov) => {
if (nv !== ov) {
Expand All @@ -212,7 +219,7 @@ watch(() => budgetCreatePageState.selectedMonthlyBudgetAllocation, (nv, ov) => {

budgetCreatePageStore.setPlannedLimits([]);
}
}, { immediate: true });
}, { deep: true, immediate: true });

watch(() => [
budgetCreatePageState.selectedMonthlyBudgetAllocation,
Expand Down Expand Up @@ -340,7 +347,7 @@ watch(() => [
if (isDateInRange(idx)) {
return isValidPositiveNumber(v);
}
return true; // skip validation for disabled months
return true;
});

if (allValuesFilled) {
Expand All @@ -358,7 +365,7 @@ watch(() => budgetCreatePageState.selectedMonthlyBudgetAllocation, (nv, ov) => {
if (nv !== ov) {
budgetCreatePageStore.setPlannedLimits([]);
}
}, { immediate: true });
}, { deep: true, immediate: true });

watch([() => budgetCreatePageState.startMonth, () => budgetCreatePageState.endMonth], () => {
if (budgetCreatePageState.startMonth.length > 0 || budgetCreatePageState.endMonth.length > 0) {
Expand Down Expand Up @@ -392,19 +399,28 @@ watch([
budgetCreatePageStore.setBudgetYear(endYear);
}
}
}, { immediate: true });
}, { deep: true, immediate: true });

watch(() => budgetCreatePageState.limit, () => {
if (budgetCreatePageState.limit === null) {
budgetCreatePageState.limit = undefined;
}
}, { immediate: true });
}, { deep: true, immediate: true });

watch(() => budgetCreatePageState.startMonth[0], (newVal, oldVal) => {
if (newVal !== oldVal && budgetCreatePageState.currentStep === 2) {
const isValidationReturn = budgetCreatePageState.time_unit !== '' || budgetCreatePageState.endMonth.length > 0;
if (!isValidationReturn) {
budgetCreatePageState.endMonth = [];
if (isStartMonthManuallyChanged.value) {
budgetCreatePageStore.setEnd([]);
budgetCreatePageState.selectedMonthlyBudgetAllocation = '';
budgetCreatePageState.budgetAppliedSameAmount = undefined;
budgetCreatePageState.initialAmount = undefined;
budgetCreatePageState.monthlyGrowthRate = undefined;
budgetCreatePageState.budgetEachDate = Array(12).fill('');
isStartMonthManuallyChanged.value = false;
}
if (budgetCreatePageState.startMonth.length === 0
|| budgetCreatePageState.endMonth.length === 0
|| state.existingBudgetUsageList.length > 0) {
budgetCreatePageState.time_unit = '';
}
}
Expand Down Expand Up @@ -460,6 +476,7 @@ watch(() => budgetCreatePageState.startMonth[0], (newVal, oldVal) => {
:selected-dates.sync="budgetCreatePageState.startMonth"
:placeholder="$t('BILLING.COST_MANAGEMENT.BUDGET.FORM.CREATE.SELECT_MONTH')"
:invalid="state.existingBudgetUsageList.length > 0"
@close="handleStartMonthPickerClosed"
/>
</p-field-group>
<p-field-group :label="$t('BILLING.COST_MANAGEMENT.BUDGET.FORM.CREATE.END_MONTH')"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,18 @@ const userReferenceStore = useUserReferenceStore();

const router = useRouter();

const invalidThreshold = ref<boolean>(false);
const invalidThreshold = ref<boolean[]>([]);

const isAlertRecipientsSelected = ref<boolean>(false);

watch(() => budgetCreatePageState.thresholds, () => {
const filteredThresholdInvalidState = budgetCreatePageState.thresholds.filter((threshold) => {
if (threshold.value) {
if (Number(threshold.value) > 0 && Number(threshold.value) < 101) {
return false;
} if (Number(threshold.value) <= 0 || typeof threshold.value !== 'number') {
return true;
}
return true;
}
return true;
const values = budgetCreatePageState.thresholds.map((t) => Number(t.value));
invalidThreshold.value = budgetCreatePageState.thresholds.map((threshold, idx) => {
const val = values[idx];
const isValidNumber = val > 0 && val < 101;
const isDuplicate = values.indexOf(val) !== idx;
return !(isValidNumber && !isDuplicate);
});

if (filteredThresholdInvalidState.length === 0) {
invalidThreshold.value = true;
} else {
invalidThreshold.value = false;
}
}, { deep: true, immediate: true });

watch(() => budgetCreatePageState.recipients.users, () => {
Expand Down Expand Up @@ -140,7 +130,7 @@ const createBudget = async (type: 'skip' | 'set') => {
:help-text="$t('BILLING.COST_MANAGEMENT.BUDGET.FORM.CREATE.EXCEEDS_AMOUNT_DESCRIPTION')"
required
:invalid-text="$t('BILLING.COST_MANAGEMENT.BUDGET.FORM.CREATE.THRESHOLD_INVALID_TEXT')"
:invalid="!invalidThreshold"
:invalid="invalidThreshold.some(v => v)"
>
<div class="flex flex-col gap-2">
<div v-for="(threshold, idx) in budgetCreatePageState.thresholds"
Expand All @@ -149,7 +139,7 @@ const createBudget = async (type: 'skip' | 'set') => {
>
<p-text-input
:value="threshold.value"
:invalid="!invalidThreshold"
:invalid="invalidThreshold[idx]"
@update:value="(value) => handleUpdateThreshold(value, idx)"
>
<template #input-right>
Expand Down Expand Up @@ -199,7 +189,7 @@ const createBudget = async (type: 'skip' | 'set') => {
{{ $t('BILLING.COST_MANAGEMENT.BUDGET.FORM.CREATE.SKIP_FOR_LATER') }}
</p-button>
<p-button class="substitutive"
:disabled="!invalidThreshold || !isAlertRecipientsSelected"
:disabled="invalidThreshold.includes(true) || !isAlertRecipientsSelected"
:loading="budgetCreatePageState.loading"
@click="createBudget('set')"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ const getBudgetFilters = (): ApiFilter[] => {
});
}

if (state.query?.workspaceList && state.query.workspaceList.length > 0) {
filters.push({
k: 'workspace_id',
v: state.query.workspaceList,
o: 'contain_in',
});
}

if (state.query?.projectList && state.query?.projectList?.length) {
filters.push({
k: 'project_id',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<script lang="ts" setup>
import { computed, reactive, watch } from 'vue';
import type { ComputedRef } from 'vue';
import {
computed, reactive, watch,
} from 'vue';

import dayjs from 'dayjs';

Expand All @@ -8,6 +11,7 @@ import type { SelectDropdownMenuItem } from '@cloudforet/mirinae/types/controls/

import { i18n } from '@/translations';

import { useAppContextStore } from '@/store/app-context/app-context-store';
import { useAllReferenceStore } from '@/store/reference/all-reference-store';
import type { ProjectReferenceMap } from '@/store/reference/project-reference-store';

Expand All @@ -16,6 +20,7 @@ const emit = defineEmits<{(e: 'update:select-month-modal-visible', value: boolea

const allReferenceStore = useAllReferenceStore();
const allReferenceGetters = allReferenceStore.getters;
const appContextStore = useAppContextStore();

interface BudgetMainToolsetState {
targetList: SelectDropdownMenuItem[];
Expand All @@ -30,11 +35,15 @@ interface BudgetMainToolsetState {
selectedServiceAccountList: SelectDropdownMenuItem[];
utilizationList: SelectDropdownMenuItem[];
selectedUtilization: string;
workspaceList: ComputedRef<SelectDropdownMenuItem[]>;
selectedWorkspaceList: SelectDropdownMenuItem[];
}

const storeState = reactive({
serviceAccount: computed(() => allReferenceGetters.serviceAccount),
project: computed<ProjectReferenceMap>(() => allReferenceGetters.project),
isAdminMode: computed<boolean>(() => appContextStore.getters.isAdminMode),
workspace: computed(() => allReferenceGetters.workspace),
});

const state = reactive<BudgetMainToolsetState>({
Expand Down Expand Up @@ -78,6 +87,11 @@ const state = reactive<BudgetMainToolsetState>({
{ name: 'overTenPercentSpent', label: i18n.t('BILLING.COST_MANAGEMENT.BUDGET.MAIN.BUDGET_SPENT_USAGE', { percent: 10 }) },
],
selectedUtilization: 'all',
workspaceList: computed(() => Object.values(storeState.workspace).map((c: any) => ({
name: c.key,
label: c.label,
}))),
selectedWorkspaceList: [],
});

watch(() => storeState.serviceAccount, () => {
Expand All @@ -97,6 +111,7 @@ watch(() => storeState.project, () => {
watch(() => state, () => {
emit('update:query', {
target: state.selectedTarget,
workspaceList: state.selectedWorkspaceList.map((w) => w.name) ?? [],
projectList: state.selectedProjectList.map((p) => p.name) ?? [],
serviceAccountList: state.selectedServiceAccountList.map((s) => s.name),
year: state.selectedYear,
Expand All @@ -121,18 +136,33 @@ watch(() => state, () => {
/>
<span class="font-bold text-sm">{{ $t('BILLING.COST_MANAGEMENT.BUDGET.MAIN.FILTER') }}:</span>
</div>
<p-select-dropdown v-if="storeState.isAdminMode"
selection-label="Workspace"
style-type="rounded"
show-select-marker
multi-selectable
show-clear-selection
appearance-type="badge"
is-filterable
selection-highlight
:menu="state.workspaceList"
:selected.sync="state.selectedWorkspaceList"
class="filterable-select-dropdown"
/>
<p-select-dropdown style-type="rounded"
:menu="state.projectList"
:selected.sync="state.selectedProjectList"
selection-label="Project"
appearance-type="badge"
use-fixed-menu-style
show-select-marker
is-filterable
multi-selectable
show-clear-selection
show-delete-all-button
selection-highlight
:page-size="15"
class="filterable-select-dropdown"
>
<template #dropdown-left-area>
<p-i name="ic_project"
Expand All @@ -149,11 +179,13 @@ watch(() => state, () => {
appearance-type="badge"
use-fixed-menu-style
show-select-marker
is-filterable
multi-selectable
show-clear-selection
show-delete-all-button
selection-highlight
:page-size="15"
class="filterable-select-dropdown"
>
<template #dropdown-left-area>
<p-i name="ic_service_service-account"
Expand Down Expand Up @@ -186,11 +218,17 @@ watch(() => state, () => {

<style scoped lang="postcss">
.budget-main-toolset {
@apply mt-3 flex gap-2 items-center;
@apply mt-3 flex items-center gap-2;

.p-select-dropdown {
min-width: unset;
}
}

.filterable-select-dropdown {
width: initial;
}

.divider {
height: 1rem;
width: 0.0625rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ watch(() => state.budgetData, async () => {

<template>
<div>
<budget-usage-trend-monthly-chart />
<budget-usage-trend-monthly-chart :data="state.data" />
<budget-usage-trend-monthly-table :data="state.data" />
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,14 @@ const budgetData = computed(() => budgetPageStore.$state.budgetData);

const chartContext = ref<HTMLElement|null>(null);

interface Props {
data: any;
}

const props = defineProps<Props>();

const state = reactive({
data: [],
data: props.data,
xAxisData: computed(() => state.data.map((d) => dayjs.utc(d.date).format('MMM YYYY'))),
yAxisData: computed(() => [0, 25, 50, 75, 100]),
chart: null as EChartsType | null,
Expand Down
Loading
Loading