From e603a6155055bd83eebd8b2d6b41b04a8c97b875 Mon Sep 17 00:00:00 2001 From: Mireya Andres Date: Fri, 3 Oct 2025 23:10:23 +0800 Subject: [PATCH 1/2] Scaffold group secrets manager page This will be the foundation for the secrets manager in group context. Requires the `secrets_manager_group` FF. --- .../secret_form/secret_form_wrapper.vue | 13 +-- .../ci/secrets/components/secrets_app.vue | 20 +++-- .../secrets_table/secrets_table.vue | 11 +++ .../javascripts/ci/secrets/constants.js | 1 + ee/app/assets/javascripts/ci/secrets/index.js | 4 +- .../assets/javascripts/ci/secrets/router.js | 8 +- .../controllers/groups/secrets_controller.rb | 26 ++++++ ee/app/helpers/secrets_helper.rb | 8 +- ee/app/views/groups/secrets/index.html.haml | 3 + .../wip/secrets_manager_group.yml | 10 +++ ee/config/routes/group.rb | 2 + .../secret_form/secret_form_wrapper_spec.js | 16 +++- .../ci/secrets/components/secrets_app_spec.js | 22 ++++- .../secrets_table/secrets_table_spec.js | 18 +++- .../groups/secrets_controller_spec.rb | 84 +++++++++++++++++++ 15 files changed, 224 insertions(+), 22 deletions(-) create mode 100644 ee/app/controllers/groups/secrets_controller.rb create mode 100644 ee/app/views/groups/secrets/index.html.haml create mode 100644 ee/config/feature_flags/wip/secrets_manager_group.yml create mode 100644 ee/spec/requests/groups/secrets_controller_spec.rb diff --git a/ee/app/assets/javascripts/ci/secrets/components/secret_form/secret_form_wrapper.vue b/ee/app/assets/javascripts/ci/secrets/components/secret_form/secret_form_wrapper.vue index 158a96e5fb30f1..e715a7c7e7621e 100644 --- a/ee/app/assets/javascripts/ci/secrets/components/secret_form/secret_form_wrapper.vue +++ b/ee/app/assets/javascripts/ci/secrets/components/secret_form/secret_form_wrapper.vue @@ -9,7 +9,7 @@ import { ENVIRONMENT_QUERY_LIMIT, mapEnvironmentNames, } from '~/ci/common/private/ci_environments_dropdown'; -import { ENTITY_PROJECT, FAILED_TO_LOAD_ERROR_MESSAGE } from '../../constants'; +import { ENTITY_GROUP, ENTITY_PROJECT, FAILED_TO_LOAD_ERROR_MESSAGE } from '../../constants'; import getSecretDetailsQuery from '../../graphql/queries/get_secret_details.query.graphql'; import SecretForm from './secret_form.vue'; @@ -30,7 +30,7 @@ export default { SecretForm, }, props: { - entity: { + context: { type: String, required: true, }, @@ -58,8 +58,11 @@ export default { }, apollo: { environments: { + skip() { + return ![ENTITY_PROJECT, ENTITY_GROUP].includes(this.context); + }, query() { - return this.entity === ENTITY_PROJECT ? getProjectEnvironments : getGroupEnvironments; + return this.context === ENTITY_PROJECT ? getProjectEnvironments : getGroupEnvironments; }, variables() { return { @@ -69,7 +72,7 @@ export default { }; }, update(data) { - if (this.entity === ENTITY_PROJECT) { + if (this.context === ENTITY_PROJECT) { return mapEnvironmentNames(data.project?.environments?.nodes || []); } @@ -106,7 +109,7 @@ export default { return this.isEditing && this.$apollo.queries.secretData.loading; }, pageDescription() { - if (this.entity === ENTITY_PROJECT) { + if (this.context === ENTITY_PROJECT) { return this.$options.i18n.descriptionProject; } diff --git a/ee/app/assets/javascripts/ci/secrets/components/secrets_app.vue b/ee/app/assets/javascripts/ci/secrets/components/secrets_app.vue index 3a35ac6f7448e3..3d38e3f976dc49 100644 --- a/ee/app/assets/javascripts/ci/secrets/components/secrets_app.vue +++ b/ee/app/assets/javascripts/ci/secrets/components/secrets_app.vue @@ -3,8 +3,8 @@ import { GlLoadingIcon } from '@gitlab/ui'; import { s__ } from '~/locale'; import { createAlert } from '~/alert'; import { captureException } from '~/sentry/sentry_browser_wrapper'; -import getSecretManagerStatusQuery from '../graphql/queries/get_secret_manager_status.query.graphql'; -import { POLL_INTERVAL, SECRET_MANAGER_STATUS_PROVISIONING } from '../constants'; +import getProjectSecretsManagerStatusQuery from '../graphql/queries/get_secret_manager_status.query.graphql'; +import { ENTITY_PROJECT, POLL_INTERVAL, SECRET_MANAGER_STATUS_PROVISIONING } from '../constants'; export default { name: 'SecretsApp', @@ -12,6 +12,10 @@ export default { GlLoadingIcon, }, props: { + context: { + type: String, + required: true, + }, fullPath: { type: String, required: true, @@ -24,7 +28,10 @@ export default { }, apollo: { secretManagerStatus: { - query: getSecretManagerStatusQuery, + query: getProjectSecretsManagerStatusQuery, + skip() { + return !this.isProjectContext; + }, variables() { return { projectPath: this.fullPath, @@ -51,6 +58,9 @@ export default { }, }, computed: { + isProjectContext() { + return this.context === ENTITY_PROJECT; + }, isProvisioning() { return this.secretManagerStatus === SECRET_MANAGER_STATUS_PROVISIONING; }, @@ -64,12 +74,12 @@ export default {