diff --git a/app/assets/javascripts/usage_quotas/group_view_metadata.js b/app/assets/javascripts/usage_quotas/group_view_metadata.js index 7ff3ff1aabfc1d0337b3a0241da5f4c7c7f89902..e90ae19bd7b93033de7cf2e1543ed5fd0afa862f 100644 --- a/app/assets/javascripts/usage_quotas/group_view_metadata.js +++ b/app/assets/javascripts/usage_quotas/group_view_metadata.js @@ -10,6 +10,7 @@ export const usageQuotasViewProvideData = { export const storageTabMetadata = { title: __('Storage'), component: NamespaceStorageApp, + shouldRender: () => document.querySelector(STORAGE_TAB_METADATA_EL_SELECTOR), }; export const usageQuotasTabsMetadata = [storageTabMetadata]; diff --git a/ee/app/assets/javascripts/usage_quotas/constants.js b/ee/app/assets/javascripts/usage_quotas/constants.js index fe57892d186d462c0c96857d47a685f55c7291cf..6c28045bb7e80535d09178fd19df78ae27291f5d 100644 --- a/ee/app/assets/javascripts/usage_quotas/constants.js +++ b/ee/app/assets/javascripts/usage_quotas/constants.js @@ -2,3 +2,5 @@ import { s__ } from '~/locale'; export const USAGE_BY_MONTH_HEADER = s__('UsageQuota|Usage by month'); export const USAGE_BY_PROJECT_HEADER = s__('UsageQuota|Usage by project'); + +export const PIPELINES_TAB_METADATA_EL_SELECTOR = '#js-pipeline-usage-app'; diff --git a/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js b/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js index 80c52028b37f1beba96de10fb8ec9164bd9f15c7..51785752c34ee9616fe1e4183754f1e2fc5df038 100644 --- a/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js +++ b/ee/app/assets/javascripts/usage_quotas/group_view_metadata.js @@ -1,9 +1,22 @@ +import { __ } from '~/locale'; import { storageTabMetadata } from '~/usage_quotas/group_view_metadata'; import { STORAGE_TAB_METADATA_EL_SELECTOR } from '~/usage_quotas/constants'; +import PipelineUsageApp from './pipelines/components/app.vue'; import { parseProvideData as parseStorageTabProvideData } from './storage/utils'; +import { parseProvideData as parsePipelinesTabProvideData } from './pipelines/utils'; +import { PIPELINES_TAB_METADATA_EL_SELECTOR } from './constants'; export const usageQuotasViewProvideData = { ...parseStorageTabProvideData(document.querySelector(STORAGE_TAB_METADATA_EL_SELECTOR)), + ...parsePipelinesTabProvideData(document.querySelector(PIPELINES_TAB_METADATA_EL_SELECTOR)), }; -export const usageQuotasTabsMetadata = [storageTabMetadata]; +const pipelineTabMetadata = { + title: __('Pipelines'), + component: PipelineUsageApp, + shouldRender: () => document.querySelector(PIPELINES_TAB_METADATA_EL_SELECTOR), +}; + +export const usageQuotasTabsMetadata = [pipelineTabMetadata, storageTabMetadata].filter((tab) => + tab.shouldRender(), +); diff --git a/ee/app/assets/javascripts/usage_quotas/pipelines/index.js b/ee/app/assets/javascripts/usage_quotas/pipelines/index.js index 4597201af641c1c7fc5eac1bf1e55361f0a40a6d..bfb82de565180309608549a8250c6757063f6f1f 100644 --- a/ee/app/assets/javascripts/usage_quotas/pipelines/index.js +++ b/ee/app/assets/javascripts/usage_quotas/pipelines/index.js @@ -1,59 +1,23 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; -import { parseBoolean } from '~/lib/utils/common_utils'; import apolloProvider from 'ee/usage_quotas/shared/provider'; +import { PIPELINES_TAB_METADATA_EL_SELECTOR } from '../constants'; import PipelineUsageApp from './components/app.vue'; +import { parseProvideData } from './utils'; Vue.use(VueApollo); export default () => { - const el = document.getElementById('js-pipeline-usage-app'); + const el = document.querySelector(PIPELINES_TAB_METADATA_EL_SELECTOR); if (!el) { return false; } - const { - pageSize, - namespacePath, - namespaceId, - namespaceActualPlanName, - userNamespace, - ciMinutesAnyProjectEnabled, - ciMinutesDisplayMinutesAvailableData, - ciMinutesLastResetDate, - ciMinutesMonthlyMinutesLimit, - ciMinutesMonthlyMinutesUsed, - ciMinutesMonthlyMinutesUsedPercentage, - ciMinutesPurchasedMinutesLimit, - ciMinutesPurchasedMinutesUsed, - ciMinutesPurchasedMinutesUsedPercentage, - buyAdditionalMinutesPath, - buyAdditionalMinutesTarget, - } = el.dataset; - return new Vue({ el, name: 'PipelinesUsageView', - provide: { - pageSize: Number(pageSize), - namespacePath, - namespaceId, - namespaceActualPlanName, - userNamespace: parseBoolean(userNamespace), - ciMinutesAnyProjectEnabled: parseBoolean(ciMinutesAnyProjectEnabled), - ciMinutesDisplayMinutesAvailableData: parseBoolean(ciMinutesDisplayMinutesAvailableData), - ciMinutesLastResetDate, - // Limit and Usage could be a number or a string (e.g. `Unlimited`) so we shouldn't parse these - ciMinutesMonthlyMinutesLimit, - ciMinutesMonthlyMinutesUsed, - ciMinutesMonthlyMinutesUsedPercentage, - ciMinutesPurchasedMinutesLimit, - ciMinutesPurchasedMinutesUsed, - ciMinutesPurchasedMinutesUsedPercentage, - buyAdditionalMinutesPath, - buyAdditionalMinutesTarget, - }, + provide: parseProvideData(el), apolloProvider, render(createElement) { return createElement(PipelineUsageApp); diff --git a/ee/app/assets/javascripts/usage_quotas/pipelines/utils.js b/ee/app/assets/javascripts/usage_quotas/pipelines/utils.js index 118422a1fc05175de9252a1c7ae91cce58b05af4..e5af13d11d68a661bcdda3357dc951de78af9596 100644 --- a/ee/app/assets/javascripts/usage_quotas/pipelines/utils.js +++ b/ee/app/assets/javascripts/usage_quotas/pipelines/utils.js @@ -1,3 +1,4 @@ +import { parseBoolean } from '~/lib/utils/common_utils'; import { dateToYearMonthDate, newDateAsLocaleTime } from '~/lib/utils/datetime_utility'; const formatMonthData = (cur) => { @@ -53,3 +54,48 @@ export const formatIso8601Date = (year, monthIndex, day) => { .map((s) => s.padStart(2, '0')) .join('-'); }; + +export const parseProvideData = (el) => { + if (!el) { + return {}; + } + + const { + pageSize, + namespacePath, + namespaceId, + namespaceActualPlanName, + userNamespace, + ciMinutesAnyProjectEnabled, + ciMinutesDisplayMinutesAvailableData, + ciMinutesLastResetDate, + ciMinutesMonthlyMinutesLimit, + ciMinutesMonthlyMinutesUsed, + ciMinutesMonthlyMinutesUsedPercentage, + ciMinutesPurchasedMinutesLimit, + ciMinutesPurchasedMinutesUsed, + ciMinutesPurchasedMinutesUsedPercentage, + buyAdditionalMinutesPath, + buyAdditionalMinutesTarget, + } = el.dataset; + + return { + pageSize: Number(pageSize), + namespacePath, + namespaceId, + namespaceActualPlanName, + userNamespace: parseBoolean(userNamespace), + ciMinutesAnyProjectEnabled: parseBoolean(ciMinutesAnyProjectEnabled), + ciMinutesDisplayMinutesAvailableData: parseBoolean(ciMinutesDisplayMinutesAvailableData), + ciMinutesLastResetDate, + // Limit and Usage could be a number or a string (e.g. `Unlimited`) so we shouldn't parse these + ciMinutesMonthlyMinutesLimit, + ciMinutesMonthlyMinutesUsed, + ciMinutesMonthlyMinutesUsedPercentage, + ciMinutesPurchasedMinutesLimit, + ciMinutesPurchasedMinutesUsed, + ciMinutesPurchasedMinutesUsedPercentage, + buyAdditionalMinutesPath, + buyAdditionalMinutesTarget, + }; +}; diff --git a/ee/app/views/groups/usage_quotas/index.html.haml b/ee/app/views/groups/usage_quotas/index.html.haml index 029088200ae0b7b472cbac4d0dd4afc6dffc0a5d..2cc3dc900feaccfe4f552120c7059212ee2d50aa 100644 --- a/ee/app/views/groups/usage_quotas/index.html.haml +++ b/ee/app/views/groups/usage_quotas/index.html.haml @@ -9,6 +9,8 @@ - if Feature.enabled?(:usage_quotas_for_all_editions, @group) #js-usage-quotas-view{ data: { namespace_name: @group.name } } #js-namespace-storage-app{ data: storage_usage_app_data(@group) } + - if can? current_user, :admin_ci_minutes, @group + #js-pipeline-usage-app{ data: pipeline_usage_app_data(@group) } - else - if show_product_purchase_success_alert? = render 'product_purchase_success_alert', product_name: params[:purchased_product]