Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-20 02:18:09 +0300
commit6ed4ec3e0b1340f96b7c043ef51d1b33bbe85fde (patch)
treedc4d20fe6064752c0bd323187252c77e0a89144b /app/assets/javascripts/ci_variable_list
parent9868dae7fc0655bd7ce4a6887d4e6d487690eeed (diff)
Add latest changes from gitlab-org/gitlab@15-4-stable-eev15.4.0-rc42
Diffstat (limited to 'app/assets/javascripts/ci_variable_list')
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue4
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue4
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue120
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue18
-rw-r--r--app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_modal.vue2
-rw-r--r--app/assets/javascripts/ci_variable_list/constants.js10
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql3
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql30
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql30
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql30
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql11
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql15
-rw-r--r--app/assets/javascripts/ci_variable_list/graphql/resolvers.js56
-rw-r--r--app/assets/javascripts/ci_variable_list/index.js9
14 files changed, 322 insertions, 20 deletions
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue
index 83bad9eb518..59ddf4b19d8 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_admin_variables.vue
@@ -11,11 +11,11 @@ import {
import addAdminVariable from '../graphql/mutations/admin_add_variable.mutation.graphql';
import deleteAdminVariable from '../graphql/mutations/admin_delete_variable.mutation.graphql';
import updateAdminVariable from '../graphql/mutations/admin_update_variable.mutation.graphql';
-import ciVariableSettings from './ci_variable_settings.vue';
+import CiVariableSettings from './ci_variable_settings.vue';
export default {
components: {
- ciVariableSettings,
+ CiVariableSettings,
},
inject: ['endpoint'],
data() {
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue
index 3af83ffa8ed..3522243e3e7 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_group_variables.vue
@@ -14,11 +14,11 @@ import {
import addGroupVariable from '../graphql/mutations/group_add_variable.mutation.graphql';
import deleteGroupVariable from '../graphql/mutations/group_delete_variable.mutation.graphql';
import updateGroupVariable from '../graphql/mutations/group_update_variable.mutation.graphql';
-import ciVariableSettings from './ci_variable_settings.vue';
+import CiVariableSettings from './ci_variable_settings.vue';
export default {
components: {
- ciVariableSettings,
+ CiVariableSettings,
},
mixins: [glFeatureFlagsMixin()],
inject: ['endpoint', 'groupPath', 'groupId'],
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue b/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue
new file mode 100644
index 00000000000..29db02a3c59
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/components/ci_project_variables.vue
@@ -0,0 +1,120 @@
+<script>
+import createFlash from '~/flash';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
+import getProjectEnvironments from '../graphql/queries/project_environments.query.graphql';
+import getProjectVariables from '../graphql/queries/project_variables.query.graphql';
+import { mapEnvironmentNames } from '../utils';
+import {
+ ADD_MUTATION_ACTION,
+ DELETE_MUTATION_ACTION,
+ GRAPHQL_PROJECT_TYPE,
+ UPDATE_MUTATION_ACTION,
+ environmentFetchErrorText,
+ genericMutationErrorText,
+ variableFetchErrorText,
+} from '../constants';
+import addProjectVariable from '../graphql/mutations/project_add_variable.mutation.graphql';
+import deleteProjectVariable from '../graphql/mutations/project_delete_variable.mutation.graphql';
+import updateProjectVariable from '../graphql/mutations/project_update_variable.mutation.graphql';
+import CiVariableSettings from './ci_variable_settings.vue';
+
+export default {
+ components: {
+ CiVariableSettings,
+ },
+ inject: ['endpoint', 'projectFullPath', 'projectId'],
+ data() {
+ return {
+ projectEnvironments: [],
+ projectVariables: [],
+ };
+ },
+ apollo: {
+ projectEnvironments: {
+ query: getProjectEnvironments,
+ variables() {
+ return {
+ fullPath: this.projectFullPath,
+ };
+ },
+ update(data) {
+ return mapEnvironmentNames(data?.project?.environments?.nodes);
+ },
+ error() {
+ createFlash({ message: environmentFetchErrorText });
+ },
+ },
+ projectVariables: {
+ query: getProjectVariables,
+ variables() {
+ return {
+ fullPath: this.projectFullPath,
+ };
+ },
+ update(data) {
+ return data?.project?.ciVariables?.nodes || [];
+ },
+ error() {
+ createFlash({ message: variableFetchErrorText });
+ },
+ },
+ },
+ computed: {
+ isLoading() {
+ return (
+ this.$apollo.queries.projectVariables.loading ||
+ this.$apollo.queries.projectEnvironments.loading
+ );
+ },
+ },
+ methods: {
+ addVariable(variable) {
+ this.variableMutation(ADD_MUTATION_ACTION, variable);
+ },
+ deleteVariable(variable) {
+ this.variableMutation(DELETE_MUTATION_ACTION, variable);
+ },
+ updateVariable(variable) {
+ this.variableMutation(UPDATE_MUTATION_ACTION, variable);
+ },
+ async variableMutation(mutationAction, variable) {
+ try {
+ const currentMutation = this.$options.mutationData[mutationAction];
+ const { data } = await this.$apollo.mutate({
+ mutation: currentMutation.action,
+ variables: {
+ endpoint: this.endpoint,
+ fullPath: this.projectFullPath,
+ projectId: convertToGraphQLId(GRAPHQL_PROJECT_TYPE, this.projectId),
+ variable,
+ },
+ });
+
+ const { errors } = data[currentMutation.name];
+ if (errors.length > 0) {
+ createFlash({ message: errors[0] });
+ }
+ } catch (e) {
+ createFlash({ message: genericMutationErrorText });
+ }
+ },
+ },
+ mutationData: {
+ [ADD_MUTATION_ACTION]: { action: addProjectVariable, name: 'addProjectVariable' },
+ [UPDATE_MUTATION_ACTION]: { action: updateProjectVariable, name: 'updateProjectVariable' },
+ [DELETE_MUTATION_ACTION]: { action: deleteProjectVariable, name: 'deleteProjectVariable' },
+ },
+};
+</script>
+
+<template>
+ <ci-variable-settings
+ :are-scoped-variables-available="true"
+ :environments="projectEnvironments"
+ :is-loading="isLoading"
+ :variables="projectVariables"
+ @add-variable="addVariable"
+ @delete-variable="deleteVariable"
+ @update-variable="updateVariable"
+ />
+</template>
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
index 5ba63de8c96..56c1804910a 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_modal.vue
@@ -108,7 +108,6 @@ export default {
return {
newEnvironments: [],
isTipDismissed: getCookie(AWS_TIP_DISMISSED_COOKIE_NAME) === 'true',
- typeOptions: variableOptions,
validationErrorEventProperty: '',
variable: { ...defaultVariableState, ...this.selectedVariable },
};
@@ -259,6 +258,7 @@ export default {
},
},
defaultScope: allEnvironments.text,
+ variableOptions,
};
</script>
@@ -277,6 +277,7 @@ export default {
v-model="variable.key"
:token-list="$options.tokenList"
:label-text="__('Key')"
+ data-testid="pipeline-form-ci-variable-key"
data-qa-selector="ci_variable_key_field"
/>
@@ -293,21 +294,26 @@ export default {
:state="variableValidationState"
rows="3"
max-rows="6"
+ data-testid="pipeline-form-ci-variable-value"
data-qa-selector="ci_variable_value_field"
class="gl-font-monospace!"
/>
</gl-form-group>
- <div class="d-flex">
- <gl-form-group :label="__('Type')" label-for="ci-variable-type" class="w-50 gl-mr-5">
+ <div class="gl-display-flex">
+ <gl-form-group :label="__('Type')" label-for="ci-variable-type" class="gl-w-half gl-mr-5">
<gl-form-select
id="ci-variable-type"
v-model="variable.variableType"
- :options="typeOptions"
+ :options="$options.variableOptions"
/>
</gl-form-group>
- <gl-form-group label-for="ci-variable-env" class="w-50" data-testid="environment-scope">
+ <gl-form-group
+ label-for="ci-variable-env"
+ class="gl-w-half"
+ data-testid="environment-scope"
+ >
<template #label>
{{ __('Environment scope') }}
<gl-link
@@ -380,7 +386,7 @@ export default {
data-testid="aws-guidance-tip"
@dismiss="dismissTip"
>
- <div class="gl-display-flex gl-flex-direction-row">
+ <div class="gl-display-flex gl-flex-direction-row gl-flex-wrap-wrap gl-md-flex-wrap-nowrap">
<div>
<p>
<gl-sprintf :message="$options.awsTipMessage">
diff --git a/app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_modal.vue b/app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_modal.vue
index cebb7eb85ac..1fbe52388c9 100644
--- a/app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_modal.vue
+++ b/app/assets/javascripts/ci_variable_list/components/legacy_ci_variable_modal.vue
@@ -255,6 +255,7 @@ export default {
v-model="key"
:token-list="$options.tokenList"
:label-text="__('Key')"
+ data-testid="pipeline-form-ci-variable-key"
data-qa-selector="ci_variable_key_field"
/>
@@ -271,6 +272,7 @@ export default {
:state="variableValidationState"
rows="3"
max-rows="6"
+ data-testid="pipeline-form-ci-variable-value"
data-qa-selector="ci_variable_value_field"
class="gl-font-monospace!"
/>
diff --git a/app/assets/javascripts/ci_variable_list/constants.js b/app/assets/javascripts/ci_variable_list/constants.js
index 5d22974ffbb..e2dd28cdaa1 100644
--- a/app/assets/javascripts/ci_variable_list/constants.js
+++ b/app/assets/javascripts/ci_variable_list/constants.js
@@ -10,7 +10,7 @@ export const displayText = {
};
export const variableTypes = {
- variableType: 'ENV_VAR',
+ envType: 'ENV_VAR',
fileType: 'FILE',
};
@@ -29,13 +29,13 @@ export const allEnvironments = {
export const variableText = {
[types.variableType]: __('Variable'),
[types.fileType]: __('File'),
- [variableTypes.variableType]: __('Variable'),
+ [variableTypes.envType]: __('Variable'),
[variableTypes.fileType]: __('File'),
};
export const variableOptions = [
- { value: types.variableType, text: variableText[types.variableType] },
- { value: types.fileType, text: variableText[types.fileType] },
+ { value: variableTypes.envType, text: variableText[variableTypes.envType] },
+ { value: variableTypes.fileType, text: variableText[variableTypes.fileType] },
];
export const defaultVariableState = {
@@ -44,7 +44,7 @@ export const defaultVariableState = {
masked: false,
protected: false,
value: '',
- variableType: types.variableType,
+ variableType: variableTypes.envType,
};
// eslint-disable-next-line @gitlab/require-i18n-strings
diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql
new file mode 100644
index 00000000000..45109762e80
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/mutations/client/add_project_environment.mutation.graphql
@@ -0,0 +1,3 @@
+mutation addProjectEnvironment($environment: CiEnvironment, $fullPath: ID!) {
+ addProjectEnvironment(environment: $environment, fullPath: $fullPath) @client
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql
new file mode 100644
index 00000000000..ab3a46da854
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_add_variable.mutation.graphql
@@ -0,0 +1,30 @@
+#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql"
+
+mutation addProjectVariable(
+ $variable: CiVariable!
+ $endpoint: String!
+ $fullPath: ID!
+ $projectId: ID!
+) {
+ addProjectVariable(
+ variable: $variable
+ endpoint: $endpoint
+ fullPath: $fullPath
+ projectId: $projectId
+ ) @client {
+ project {
+ id
+ ciVariables {
+ nodes {
+ ...BaseCiVariable
+ ... on CiProjectVariable {
+ environmentScope
+ masked
+ protected
+ }
+ }
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql
new file mode 100644
index 00000000000..e83dc9a5e5e
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_delete_variable.mutation.graphql
@@ -0,0 +1,30 @@
+#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql"
+
+mutation deleteProjectVariable(
+ $variable: CiVariable!
+ $endpoint: String!
+ $fullPath: ID!
+ $projectId: ID!
+) {
+ deleteProjectVariable(
+ variable: $variable
+ endpoint: $endpoint
+ fullPath: $fullPath
+ projectId: $projectId
+ ) @client {
+ project {
+ id
+ ciVariables {
+ nodes {
+ ...BaseCiVariable
+ ... on CiProjectVariable {
+ environmentScope
+ masked
+ protected
+ }
+ }
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql
new file mode 100644
index 00000000000..4788911431b
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/mutations/project_update_variable.mutation.graphql
@@ -0,0 +1,30 @@
+#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql"
+
+mutation updateProjectVariable(
+ $variable: CiVariable!
+ $endpoint: String!
+ $fullPath: ID!
+ $projectId: ID!
+) {
+ updateProjectVariable(
+ variable: $variable
+ endpoint: $endpoint
+ fullPath: $fullPath
+ projectId: $projectId
+ ) @client {
+ project {
+ id
+ ciVariables {
+ nodes {
+ ...BaseCiVariable
+ ... on CiProjectVariable {
+ environmentScope
+ masked
+ protected
+ }
+ }
+ }
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql
new file mode 100644
index 00000000000..921e0ca25b9
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/queries/project_environments.query.graphql
@@ -0,0 +1,11 @@
+query getProjectEnvironments($fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ environments {
+ nodes {
+ id
+ name
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql b/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql
new file mode 100644
index 00000000000..a60a50e4bc4
--- /dev/null
+++ b/app/assets/javascripts/ci_variable_list/graphql/queries/project_variables.query.graphql
@@ -0,0 +1,15 @@
+#import "~/ci_variable_list/graphql/fragments/ci_variable.fragment.graphql"
+
+query getProjectVariables($fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ ciVariables {
+ nodes {
+ ...BaseCiVariable
+ environmentScope
+ masked
+ protected
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/ci_variable_list/graphql/resolvers.js b/app/assets/javascripts/ci_variable_list/graphql/resolvers.js
index be7e3f88cfd..c041531ae30 100644
--- a/app/assets/javascripts/ci_variable_list/graphql/resolvers.js
+++ b/app/assets/javascripts/ci_variable_list/graphql/resolvers.js
@@ -4,9 +4,16 @@ import {
convertObjectPropsToSnakeCase,
} from '../../lib/utils/common_utils';
import { getIdFromGraphQLId } from '../../graphql_shared/utils';
-import { GRAPHQL_GROUP_TYPE, groupString, instanceString } from '../constants';
-import getAdminVariables from './queries/variables.query.graphql';
+import {
+ GRAPHQL_GROUP_TYPE,
+ GRAPHQL_PROJECT_TYPE,
+ groupString,
+ instanceString,
+ projectString,
+} from '../constants';
+import getProjectVariables from './queries/project_variables.query.graphql';
import getGroupVariables from './queries/group_variables.query.graphql';
+import getAdminVariables from './queries/variables.query.graphql';
const prepareVariableForApi = ({ variable, destroy = false }) => {
return {
@@ -28,6 +35,20 @@ const mapVariableTypes = (variables = [], kind) => {
});
};
+const prepareProjectGraphQLResponse = ({ data, projectId, errors = [] }) => {
+ return {
+ errors,
+ project: {
+ __typename: GRAPHQL_PROJECT_TYPE,
+ id: projectId,
+ ciVariables: {
+ __typename: 'CiVariableConnection',
+ nodes: mapVariableTypes(data.variables, projectString),
+ },
+ },
+ };
+};
+
const prepareGroupGraphQLResponse = ({ data, groupId, errors = [] }) => {
return {
errors,
@@ -52,6 +73,28 @@ const prepareAdminGraphQLResponse = ({ data, errors = [] }) => {
};
};
+const callProjectEndpoint = async ({
+ endpoint,
+ fullPath,
+ variable,
+ projectId,
+ cache,
+ destroy = false,
+}) => {
+ try {
+ const { data } = await axios.patch(endpoint, {
+ variables_attributes: [prepareVariableForApi({ variable, destroy })],
+ });
+ return prepareProjectGraphQLResponse({ data, projectId });
+ } catch (e) {
+ return prepareProjectGraphQLResponse({
+ data: cache.readQuery({ query: getProjectVariables, variables: { fullPath } }),
+ projectId,
+ errors: [...e.response.data],
+ });
+ }
+};
+
const callGroupEndpoint = async ({
endpoint,
fullPath,
@@ -91,6 +134,15 @@ const callAdminEndpoint = async ({ endpoint, variable, cache, destroy = false })
export const resolvers = {
Mutation: {
+ addProjectVariable: async (_, { endpoint, fullPath, variable, projectId }, { cache }) => {
+ return callProjectEndpoint({ endpoint, fullPath, variable, projectId, cache });
+ },
+ updateProjectVariable: async (_, { endpoint, fullPath, variable, projectId }, { cache }) => {
+ return callProjectEndpoint({ endpoint, fullPath, variable, projectId, cache });
+ },
+ deleteProjectVariable: async (_, { endpoint, fullPath, variable, projectId }, { cache }) => {
+ return callProjectEndpoint({ endpoint, fullPath, variable, projectId, cache, destroy: true });
+ },
addGroupVariable: async (_, { endpoint, fullPath, variable, groupId }, { cache }) => {
return callGroupEndpoint({ endpoint, fullPath, variable, groupId, cache });
},
diff --git a/app/assets/javascripts/ci_variable_list/index.js b/app/assets/javascripts/ci_variable_list/index.js
index a74af8aed12..f5bdd4c7b1e 100644
--- a/app/assets/javascripts/ci_variable_list/index.js
+++ b/app/assets/javascripts/ci_variable_list/index.js
@@ -4,6 +4,7 @@ import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
import CiAdminVariables from './components/ci_admin_variables.vue';
import CiGroupVariables from './components/ci_group_variables.vue';
+import CiProjectVariables from './components/ci_project_variables.vue';
import LegacyCiVariableSettings from './components/legacy_ci_variable_settings.vue';
import { resolvers } from './graphql/resolvers';
import createStore from './store';
@@ -37,6 +38,8 @@ const mountCiVariableListApp = (containerEl) => {
if (parsedIsGroup) {
component = CiGroupVariables;
+ } else if (parsedIsProject) {
+ component = CiProjectVariables;
}
Vue.use(VueApollo);
@@ -77,7 +80,7 @@ const mountLegacyCiVariableListApp = (containerEl) => {
const {
endpoint,
projectId,
- group,
+ isGroup,
maskableRegex,
protectedByDefault,
awsLogoSvgPath,
@@ -89,13 +92,13 @@ const mountLegacyCiVariableListApp = (containerEl) => {
maskedEnvironmentVariablesLink,
environmentScopeLink,
} = containerEl.dataset;
- const isGroup = parseBoolean(group);
+ const parsedIsGroup = parseBoolean(isGroup);
const isProtectedByDefault = parseBoolean(protectedByDefault);
const store = createStore({
endpoint,
projectId,
- isGroup,
+ isGroup: parsedIsGroup,
maskableRegex,
isProtectedByDefault,
awsLogoSvgPath,