diff --git a/ee/app/assets/javascripts/pages/admin/gitlab_duo/usage/index.js b/ee/app/assets/javascripts/pages/admin/gitlab_duo/usage/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..c1d00af3b4132b99928322369578dcbedd7c0c3a
--- /dev/null
+++ b/ee/app/assets/javascripts/pages/admin/gitlab_duo/usage/index.js
@@ -0,0 +1,21 @@
+import Vue from 'vue';
+import AdminUsageDashboard from 'ee/usage_quotas/usage_billing/components/app.vue';
+
+function initAdminUsageDashboard() {
+ const el = document.getElementById('js-instance-usage-billing-dashboard');
+
+ if (!el) {
+ return null;
+ }
+
+ return new Vue({
+ el,
+ name: 'AdminUsageBillingDashboardApp',
+ provide: {},
+ render(createElement) {
+ return createElement(AdminUsageDashboard);
+ },
+ });
+}
+
+initAdminUsageDashboard();
diff --git a/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.stories.js b/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.stories.js
new file mode 100644
index 0000000000000000000000000000000000000000..e71a8fa00ce529caa0f4023d230856929bdc5b0c
--- /dev/null
+++ b/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.stories.js
@@ -0,0 +1,14 @@
+import UsageBillingApp from './app.vue';
+
+export default {
+ component: UsageBillingApp,
+ title: 'ee/usage_billing/App',
+};
+
+const Template = (args, { argTypes }) => ({
+ props: Object.keys(argTypes),
+ components: { UsageBillingApp },
+ template: '',
+});
+
+export const Default = Template.bind({});
diff --git a/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.vue b/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1ce9ae760f619031372c62de44524ed6bb319632
--- /dev/null
+++ b/ee/app/assets/javascripts/usage_quotas/usage_billing/components/app.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+ {{ s__('UsageBilling|Usage Billing') }}
+
+
+
+
+
+
+ {{ s__('UsageBilling|Current month usage') }}
+
+
+
+
+
+ {{ s__('UsageBilling|Purchase a monthly commitment') }}
+
+
+
+
+
+ {{ s__('UsageBilling|Usage trends') }}
+
+
+ {{ s__('UsageBilling|Usage by user') }}
+
+
+
+
diff --git a/ee/lib/sidebars/admin/menus/duo_settings_menu.rb b/ee/lib/sidebars/admin/menus/duo_settings_menu.rb
index ac55ee778b519c232e4610008f4cb8b0c17506c8..fcdab45e2af3235bfccb53ef24c87f744b08b542 100644
--- a/ee/lib/sidebars/admin/menus/duo_settings_menu.rb
+++ b/ee/lib/sidebars/admin/menus/duo_settings_menu.rb
@@ -22,7 +22,7 @@ def sprite_icon
override :active_routes
def active_routes
{
- controller: [:gitlab_duo, :seat_utilization, :configuration],
+ controller: [:gitlab_duo, :seat_utilization, :configuration, :usage],
action: %w[show index]
}
end
diff --git a/ee/spec/frontend/usage_quotas/usage_billing/components/app_spec.js b/ee/spec/frontend/usage_quotas/usage_billing/components/app_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..ee225a336106bc1a5554895ed76c579188115d0a
--- /dev/null
+++ b/ee/spec/frontend/usage_quotas/usage_billing/components/app_spec.js
@@ -0,0 +1,27 @@
+import { GlTab } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import UsageBillingApp from 'ee/usage_quotas/usage_billing/components/app.vue';
+
+describe('UsageBillingApp', () => {
+ /** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMountExtended(UsageBillingApp);
+ };
+
+ const findTabs = () => wrapper.findAllComponents(GlTab);
+
+ describe('rendering elements', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders the correct tabs', () => {
+ const tabs = findTabs();
+
+ expect(tabs.at(0).attributes('title')).toBe('Usage trends');
+ expect(tabs.at(1).attributes('title')).toBe('Usage by user');
+ });
+ });
+});
diff --git a/ee/spec/lib/sidebars/admin/menus/duo_settings_menu_spec.rb b/ee/spec/lib/sidebars/admin/menus/duo_settings_menu_spec.rb
index d4d77c6797778d7458fb5c432ed5cd36a05e1926..563869223cf1d19501709c27570c4001eeaa1f5f 100644
--- a/ee/spec/lib/sidebars/admin/menus/duo_settings_menu_spec.rb
+++ b/ee/spec/lib/sidebars/admin/menus/duo_settings_menu_spec.rb
@@ -10,6 +10,6 @@
it_behaves_like 'Admin menu without sub menus', active_routes: {
action: %w[show index],
- controller: [:gitlab_duo, :seat_utilization, :configuration]
+ controller: [:gitlab_duo, :seat_utilization, :configuration, :usage]
}
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5f434d8c1b9afa35af70bf2eb50be325a184be76..27700ada8871a9a8768648d515903ddff107a6cb 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -68713,9 +68713,21 @@ msgstr ""
msgid "Usage trends"
msgstr ""
+msgid "UsageBilling|Current month usage"
+msgstr ""
+
+msgid "UsageBilling|Purchase a monthly commitment"
+msgstr ""
+
msgid "UsageBilling|Usage Billing"
msgstr ""
+msgid "UsageBilling|Usage by user"
+msgstr ""
+
+msgid "UsageBilling|Usage trends"
+msgstr ""
+
msgid "UsageQuotas|(of %{totalStorageSize})"
msgstr ""