summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-30 12:08:43 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-30 12:08:43 +0000
commite99d2e196cd87ed071f856f80ae085c7be640876 (patch)
tree9caaeb14cc4997180b480f1a22600abd5f92ac06 /app
parent14846d722eb52ea70bc3092eb5da80ce1c2e9750 (diff)
downloadgitlab-ce-e99d2e196cd87ed071f856f80ae085c7be640876.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/api/user_api.js4
-rw-r--r--app/assets/javascripts/awards_handler.js4
-rw-r--r--app/assets/javascripts/badges/components/badge_form.vue14
-rw-r--r--app/assets/javascripts/badges/components/badge_settings.vue8
-rw-r--r--app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js12
-rw-r--r--app/assets/javascripts/behaviors/preview_markdown.js4
-rw-r--r--app/assets/javascripts/blob/file_template_mediator.js4
-rw-r--r--app/assets/javascripts/blob/openapi/index.js4
-rw-r--r--app/assets/javascripts/blob/viewer/index.js6
-rw-r--r--app/assets/javascripts/blob_edit/blob_bundle.js4
-rw-r--r--app/assets/javascripts/blob_edit/edit_blob.js6
-rw-r--r--app/assets/javascripts/deploy_tokens/components/new_deploy_token.vue332
-rw-r--r--app/assets/javascripts/deploy_tokens/index.js33
-rw-r--r--app/assets/javascripts/notes/components/discussion_counter.vue7
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/cleanup_image_tags.vue7
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue2
-rw-r--r--app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js2
-rw-r--r--app/assets/javascripts/pages/groups/settings/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/settings/index.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/state_container.vue4
-rw-r--r--app/views/ci/variables/_index.html.haml8
-rw-r--r--app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml3
-rw-r--r--app/views/shared/deploy_tokens/_index.html.haml20
25 files changed, 444 insertions, 51 deletions
diff --git a/app/assets/javascripts/api/user_api.js b/app/assets/javascripts/api/user_api.js
index c743b18d572..369abe95d49 100644
--- a/app/assets/javascripts/api/user_api.js
+++ b/app/assets/javascripts/api/user_api.js
@@ -1,5 +1,5 @@
import { DEFAULT_PER_PAGE } from '~/api';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { __ } from '~/locale';
import axios from '../lib/utils/axios_utils';
import { buildApiUrl } from './api_utils';
@@ -55,7 +55,7 @@ export function getUserProjects(userId, query, options, callback) {
})
.then(({ data }) => callback(data))
.catch(() =>
- createFlash({
+ createAlert({
message: __('Something went wrong while fetching projects'),
}),
);
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index a3ffb4df7b7..9ab1d6bfd80 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -7,7 +7,7 @@ import { getEmojiScoreWithIntent } from '~/emoji/utils';
import { getCookie, setCookie, scrollToElement } from '~/lib/utils/common_utils';
import * as Emoji from '~/emoji';
import { dispose, fixTitle } from '~/tooltips';
-import createFlash from './flash';
+import { createAlert } from '~/flash';
import axios from './lib/utils/axios_utils';
import { isInVueNoteablePage } from './lib/utils/dom_utils';
import { __ } from './locale';
@@ -491,7 +491,7 @@ export class AwardsHandler {
}
})
.catch(() =>
- createFlash({
+ createAlert({
message: __('Something went wrong on our end.'),
}),
);
diff --git a/app/assets/javascripts/badges/components/badge_form.vue b/app/assets/javascripts/badges/components/badge_form.vue
index d1570e16639..f68666f8a0c 100644
--- a/app/assets/javascripts/badges/components/badge_form.vue
+++ b/app/assets/javascripts/badges/components/badge_form.vue
@@ -2,7 +2,7 @@
import { GlLoadingIcon, GlFormInput, GlFormGroup, GlButton, GlSafeHtmlDirective } from '@gitlab/ui';
import { escape, debounce } from 'lodash';
import { mapActions, mapState } from 'vuex';
-import createFlash from '~/flash';
+import { createAlert, VARIANT_INFO } from '~/flash';
import { s__, sprintf } from '~/locale';
import createEmptyBadge from '../empty_badge';
import Badge from './badge.vue';
@@ -136,14 +136,14 @@ export default {
if (this.isEditing) {
return this.saveBadge()
.then(() => {
- createFlash({
+ createAlert({
message: s__('Badges|Badge saved.'),
- type: 'notice',
+ variant: VARIANT_INFO,
});
this.wasValidated = false;
})
.catch((error) => {
- createFlash({
+ createAlert({
message: s__(
'Badges|Saving the badge failed, please check the entered URLs and try again.',
),
@@ -154,14 +154,14 @@ export default {
return this.addBadge()
.then(() => {
- createFlash({
+ createAlert({
message: s__('Badges|New badge added.'),
- type: 'notice',
+ variant: VARIANT_INFO,
});
this.wasValidated = false;
})
.catch((error) => {
- createFlash({
+ createAlert({
message: s__(
'Badges|Adding the badge failed, please check the entered URLs and try again.',
),
diff --git a/app/assets/javascripts/badges/components/badge_settings.vue b/app/assets/javascripts/badges/components/badge_settings.vue
index 0303930de5d..a7a21d65475 100644
--- a/app/assets/javascripts/badges/components/badge_settings.vue
+++ b/app/assets/javascripts/badges/components/badge_settings.vue
@@ -1,7 +1,7 @@
<script>
import { GlSprintf, GlModal } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
-import createFlash from '~/flash';
+import { createAlert, VARIANT_INFO } from '~/flash';
import { __, s__ } from '~/locale';
import Badge from './badge.vue';
import BadgeForm from './badge_form.vue';
@@ -40,13 +40,13 @@ export default {
onSubmitModal() {
this.deleteBadge(this.badgeInModal)
.then(() => {
- createFlash({
+ createAlert({
message: s__('Badges|The badge was deleted.'),
- type: 'notice',
+ variant: VARIANT_INFO,
});
})
.catch((error) => {
- createFlash({
+ createAlert({
message: s__('Badges|Deleting the badge failed, please try again.'),
});
throw error;
diff --git a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
index 2b0aaa74e83..feac6f10b1e 100644
--- a/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
+++ b/app/assets/javascripts/batch_comments/stores/modules/batch_comments/actions.js
@@ -1,5 +1,5 @@
import { isEmpty } from 'lodash';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { scrollToElement } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import { CHANGES_TAB, DISCUSSION_TAB, SHOW_TAB } from '../../../constants';
@@ -18,7 +18,7 @@ export const addDraftToDiscussion = ({ commit }, { endpoint, data }) =>
return res;
})
.catch(() => {
- createFlash({
+ createAlert({
message: __('An error occurred adding a draft to the thread.'),
});
});
@@ -32,7 +32,7 @@ export const createNewDraft = ({ commit }, { endpoint, data }) =>
return res;
})
.catch(() => {
- createFlash({
+ createAlert({
message: __('An error occurred adding a new draft.'),
});
});
@@ -44,7 +44,7 @@ export const deleteDraft = ({ commit, getters }, draft) =>
commit(types.DELETE_DRAFT, draft.id);
})
.catch(() =>
- createFlash({
+ createAlert({
message: __('An error occurred while deleting the comment'),
}),
);
@@ -62,7 +62,7 @@ export const fetchDrafts = ({ commit, getters, state, dispatch }) =>
});
})
.catch(() =>
- createFlash({
+ createAlert({
message: __('An error occurred while fetching pending comments'),
}),
);
@@ -122,7 +122,7 @@ export const updateDraft = (
.then((data) => commit(types.RECEIVE_DRAFT_UPDATE_SUCCESS, data))
.then(callback)
.catch(() =>
- createFlash({
+ createAlert({
message: __('An error occurred while updating the comment'),
}),
);
diff --git a/app/assets/javascripts/behaviors/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js
index 679940d1317..68f5180cc03 100644
--- a/app/assets/javascripts/behaviors/preview_markdown.js
+++ b/app/assets/javascripts/behaviors/preview_markdown.js
@@ -1,7 +1,7 @@
/* eslint-disable func-names */
import $ from 'jquery';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
@@ -80,7 +80,7 @@ MarkdownPreview.prototype.fetchMarkdownPreview = function (text, url, success) {
success(data);
})
.catch(() =>
- createFlash({
+ createAlert({
message: __('An error occurred while fetching Markdown preview'),
}),
);
diff --git a/app/assets/javascripts/blob/file_template_mediator.js b/app/assets/javascripts/blob/file_template_mediator.js
index 991f98c89e7..adc2649e5df 100644
--- a/app/assets/javascripts/blob/file_template_mediator.js
+++ b/app/assets/javascripts/blob/file_template_mediator.js
@@ -2,7 +2,7 @@ import $ from 'jquery';
import Api from '~/api';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { __ } from '~/locale';
import toast from '~/vue_shared/plugins/global_toast';
@@ -155,7 +155,7 @@ export default class FileTemplateMediator {
}
})
.catch((err) =>
- createFlash({
+ createAlert({
message: __(`An error occurred while fetching the template: ${err}`),
}),
);
diff --git a/app/assets/javascripts/blob/openapi/index.js b/app/assets/javascripts/blob/openapi/index.js
index 4c497db9842..44b75cc3e68 100644
--- a/app/assets/javascripts/blob/openapi/index.js
+++ b/app/assets/javascripts/blob/openapi/index.js
@@ -1,5 +1,5 @@
import { SwaggerUIBundle } from 'swagger-ui-dist';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { __ } from '~/locale';
export default () => {
@@ -15,7 +15,7 @@ export default () => {
});
})
.catch((error) => {
- createFlash({
+ createAlert({
message: __('Something went wrong while initializing the OpenAPI viewer'),
});
throw error;
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js
index 5ca3f131d99..8d323c335d3 100644
--- a/app/assets/javascripts/blob/viewer/index.js
+++ b/app/assets/javascripts/blob/viewer/index.js
@@ -1,6 +1,6 @@
import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { __ } from '~/locale';
import {
REPO_BLOB_LOAD_VIEWER_START,
@@ -69,7 +69,7 @@ export const handleBlobRichViewer = (viewer, type) => {
loadRichBlobViewer(type)
.then((module) => module?.default(viewer))
.catch((error) => {
- createFlash({
+ createAlert({
message: __('Error loading file viewer.'),
});
throw error;
@@ -221,7 +221,7 @@ export class BlobViewer {
});
})
.catch(() =>
- createFlash({
+ createAlert({
message: __('Error loading viewer'),
}),
);
diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js
index d73e1cc43b0..1c9c99dcc2f 100644
--- a/app/assets/javascripts/blob_edit/blob_bundle.js
+++ b/app/assets/javascripts/blob_edit/blob_bundle.js
@@ -2,7 +2,7 @@
import $ from 'jquery';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils';
import Tracking from '~/tracking';
import BlobFileDropzone from '../blob/blob_file_dropzone';
@@ -79,7 +79,7 @@ export default () => {
initPopovers();
})
.catch((e) =>
- createFlash({
+ createAlert({
message: e,
}),
);
diff --git a/app/assets/javascripts/blob_edit/edit_blob.js b/app/assets/javascripts/blob_edit/edit_blob.js
index 2ee2e199358..78e3f934183 100644
--- a/app/assets/javascripts/blob_edit/edit_blob.js
+++ b/app/assets/javascripts/blob_edit/edit_blob.js
@@ -3,7 +3,7 @@ import { SourceEditorExtension } from '~/editor/extensions/source_editor_extensi
import { FileTemplateExtension } from '~/editor/extensions/source_editor_file_template_ext';
import { ToolbarExtension } from '~/editor/extensions/source_editor_toolbar_ext';
import SourceEditor from '~/editor/source_editor';
-import createFlash from '~/flash';
+import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { addEditorMarkdownListeners } from '~/lib/utils/text_markdown';
import { insertFinalNewline } from '~/lib/utils/text_utility';
@@ -44,7 +44,7 @@ export default class EditBlob {
},
]);
} catch (e) {
- createFlash({
+ createAlert({
message: `${BLOB_EDITOR_ERROR}: ${e}`,
});
}
@@ -130,7 +130,7 @@ export default class EditBlob {
currentPane.renderGFM();
})
.catch(() =>
- createFlash({
+ createAlert({
message: BLOB_PREVIEW_ERROR,
}),
);
diff --git a/app/assets/javascripts/deploy_tokens/components/new_deploy_token.vue b/app/assets/javascripts/deploy_tokens/components/new_deploy_token.vue
new file mode 100644
index 00000000000..639dd21bd7b
--- /dev/null
+++ b/app/assets/javascripts/deploy_tokens/components/new_deploy_token.vue
@@ -0,0 +1,332 @@
+<script>
+import {
+ GlFormGroup,
+ GlFormInput,
+ GlFormCheckbox,
+ GlButton,
+ GlDatepicker,
+ GlFormInputGroup,
+ GlSprintf,
+ GlLink,
+} from '@gitlab/ui';
+import { createAlert, VARIANT_INFO } from '~/flash';
+import axios from '~/lib/utils/axios_utils';
+import { formatDate } from '~/lib/utils/datetime_utility';
+import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import { s__ } from '~/locale';
+
+function defaultData() {
+ return {
+ expiresAt: null,
+ name: '',
+ newTokenDetails: null,
+ readRepository: false,
+ writeRepository: false,
+ readRegistry: false,
+ writeRegistry: false,
+ readPackageRegistry: false,
+ writePackageRegistry: false,
+ username: '',
+ placeholders: {
+ link: { link: ['link_start', 'link_end'] },
+ i: { i: ['i_start', 'i_end'] },
+ code: { code: ['code_start', 'code_end'] },
+ },
+ };
+}
+
+export default {
+ components: {
+ GlFormGroup,
+ GlFormInput,
+ GlDatepicker,
+ GlFormCheckbox,
+ GlButton,
+ GlFormInputGroup,
+ ClipboardButton,
+ GlSprintf,
+ GlLink,
+ },
+
+ props: {
+ createNewTokenPath: {
+ type: String,
+ required: true,
+ },
+ deployTokensHelpUrl: {
+ type: String,
+ required: true,
+ },
+ containerRegistryEnabled: {
+ type: Boolean,
+ required: true,
+ },
+ packagesRegistryEnabled: {
+ type: Boolean,
+ required: true,
+ },
+ tokenType: {
+ type: String,
+ required: true,
+ },
+ },
+
+ data() {
+ return defaultData();
+ },
+ translations: {
+ addTokenButton: s__('DeployTokens|Create deploy token'),
+ addTokenExpiryLabel: s__('DeployTokens|Expiration date (optional)'),
+ addTokenExpiryDescription: s__(
+ 'DeployTokens|Enter an expiration date for your token. Defaults to never expire.',
+ ),
+ addTokenHeader: s__('DeployTokens|New deploy token'),
+ addTokenDescription: s__(
+ 'DeployTokens|Create a new deploy token for all projects in this group. %{link_start}What are deploy tokens?%{link_end}',
+ ),
+ addTokenNameLabel: s__('DeployTokens|Name'),
+ addTokenNameDescription: s__('DeployTokens|Enter a unique name for your deploy token.'),
+ addTokenScopesLabel: s__('DeployTokens|Scopes (select at least one)'),
+ addTokenUsernameDescription: s__(
+ 'DeployTokens|Enter a username for your token. Defaults to %{code_start}gitlab+deploy-token-{n}%{code_end}.',
+ ),
+ addTokenUsernameLabel: s__('DeployTokens|Username (optional)'),
+ newTokenCopyMessage: s__('DeployTokens|Copy deploy token'),
+ newProjectTokenCreated: s__('DeployTokens|Your new project deploy token has been created.'),
+ newGroupTokenCreated: s__('DeployTokens|Your new group deploy token has been created.'),
+ newTokenDescription: s__(
+ 'DeployTokens|Use this token as a password. Save it. This password can %{i_start}not%{i_end} be recovered.',
+ ),
+ newTokenMessage: s__('DeployTokens|Your New Deploy Token'),
+ newTokenUsernameCopy: s__('DeployTokens|Copy username'),
+ newTokenUsernameDescription: s__(
+ 'DeployTokens|This username supports access. %{link_start}What kind of access?%{link_end}',
+ ),
+ readRepositoryHelp: s__('DeployTokens|Allows read-only access to the repository.'),
+ readRegistryHelp: s__('DeployTokens|Allows read-only access to registry images.'),
+ writeRegistryHelp: s__('DeployTokens|Allows read and write access to registry images.'),
+ readPackageRegistryHelp: s__('DeployTokens|Allows read-only access to the package registry.'),
+ writePackageRegistryHelp: s__(
+ 'DeployTokens|Allows read and write access to the package registry.',
+ ),
+ },
+ computed: {
+ formattedExpiryDate() {
+ return formatDate(this.expiresAt, 'yyyy-mm-dd');
+ },
+ newTokenCreatedMessage() {
+ return this.tokenType === 'group'
+ ? this.$options.translations.newGroupTokenCreated
+ : this.$options.translations.newProjectTokenCreated;
+ },
+ },
+ methods: {
+ createDeployToken() {
+ return axios
+ .post(this.createNewTokenPath, {
+ deploy_token: {
+ expires_at: this.expiresAt,
+ name: this.name,
+ read_repository: this.readRepository,
+ read_registry: this.readRegistry,
+ username: this.username,
+ },
+ })
+ .then((response) => {
+ this.newTokenDetails = response.data;
+ this.resetData();
+ createAlert({
+ variant: VARIANT_INFO,
+ message: this.newTokenCreatedMessage,
+ });
+ })
+ .catch((error) => {
+ createAlert({
+ message: error.response.data.message,
+ });
+ });
+ },
+ resetData() {
+ const newData = defaultData();
+ delete newData.newTokenDetails;
+ Object.keys(newData).forEach((k) => {
+ this[k] = newData[k];
+ });
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <div v-if="newTokenDetails" class="created-deploy-token-container info-well">
+ <div class="well-segment">
+ <h5>{{ $options.translations.newTokenMessage }}</h5>
+ <gl-form-group>
+ <template #description>
+ <div class="deploy-token-help-block gl-mt-2 text-success">
+ <gl-sprintf
+ :message="$options.translations.newTokenUsernameDescription"
+ :placeholders="placeholders.link"
+ >
+ <template #link="{ content }">
+ <gl-link :href="deployTokensHelpUrl" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ </template>
+ <gl-form-input-group
+ name="deploy-token-user"
+ :value="newTokenDetails.username"
+ select-on-click
+ readonly
+ >
+ <template #append>
+ <clipboard-button
+ :text="newTokenDetails.username"
+ :title="$options.translations.newTokenUsernameCopy"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+ <gl-form-group>
+ <template #description>
+ <div class="deploy-token-help-block gl-mt-2 text-danger">
+ <gl-sprintf
+ :message="$options.translations.newTokenDescription"
+ :placeholders="placeholders.i"
+ >
+ <template #i="{ content }">
+ <i>{{ content }}</i>
+ </template>
+ </gl-sprintf>
+ </div>
+ </template>
+ <gl-form-input-group :value="newTokenDetails.token" name="deploy-token" readonly>
+ <template #append>
+ <clipboard-button
+ :text="newTokenDetails.token"
+ :title="$options.translations.newTokenCopyMessage"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+ </div>
+ </div>
+ <h5>{{ $options.translations.addTokenHeader }}</h5>
+ <p class="profile-settings-content">
+ <gl-sprintf
+ :message="$options.translations.addTokenDescription"
+ :placeholders="placeholders.link"
+ >
+ <template #link="{ content }">
+ <gl-link :href="deployTokensHelpUrl" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ <gl-form-group
+ :label="$options.translations.addTokenNameLabel"
+ :description="$options.translations.addTokenNameDescription"
+ label-for="deploy_token_name"
+ >
+ <gl-form-input
+ id="deploy_token_name"
+ v-model="name"
+ name="deploy_token_name"
+ class="qa-deploy-token-name"
+ data-qa-selector="deploy_token_name_field"
+ />
+ </gl-form-group>
+ <gl-form-group
+ :label="$options.translations.addTokenExpiryLabel"
+ :description="$options.translations.addTokenExpiryDescription"
+ label-for="deploy_token_expires_at"
+ >
+ <gl-form-input
+ id="deploy_token_expires_at"
+ name="deploy_token_expires_at"
+ :value="formattedExpiryDate"
+ data-qa-selector="deploy_token_expires_at_field"
+ />
+ </gl-form-group>
+ <gl-form-group
+ :label="$options.translations.addTokenUsernameLabel"
+ label-for="deploy_token_username"
+ >
+ <template #description>
+ <gl-sprintf
+ :message="$options.translations.addTokenUsernameDescription"
+ :placeholders="placeholders.code"
+ >
+ <template #code="{ content }">
+ <code>{{ content }}</code>
+ </template>
+ </gl-sprintf>
+ </template>
+ <gl-form-input id="deploy_token_username" v-model="username" />
+ </gl-form-group>
+ <gl-form-group
+ :label="$options.translations.addTokenScopesLabel"
+ label-for="deploy-token-scopes"
+ >
+ <div id="deploy-token-scopes">
+ <!-- eslint-disable @gitlab/vue-require-i18n-strings -->
+ <gl-form-checkbox
+ id="deploy_token_read_repository"
+ v-model="readRepository"
+ name="deploy_token_read_repository"
+ data-qa-selector="deploy_token_read_repository_checkbox"
+ >
+ read_repository
+ <template #help>{{ $options.translations.readRepositoryHelp }}</template>
+ </gl-form-checkbox>
+ <gl-form-checkbox
+ v-if="containerRegistryEnabled"
+ id="deploy_token_read_registry"
+ v-model="readRegistry"
+ name="deploy_token_read_registry"
+ data-qa-selector="deploy_token_read_registry_checkbox"
+ >
+ read_registry
+ <template #help>{{ $options.translations.readRegistryHelp }}</template>
+ </gl-form-checkbox>
+ <gl-form-checkbox
+ v-if="containerRegistryEnabled"
+ id="deploy_token_write_registry"
+ v-model="writeRegistry"
+ name="deploy_token_write_registry"
+ data-qa-selector="deploy_token_write_registry_checkbox"
+ >
+ write_registry
+ <template #help>{{ $options.translations.writeRegistryHelp }}</template>
+ </gl-form-checkbox>
+ <gl-form-checkbox
+ v-if="packagesRegistryEnabled"
+ id="deploy_token_read_package_registry"
+ v-model="readPackageRegistry"
+ name="deploy_token_read_package_registry"
+ data-qa-selector="deploy_token_read_package_registry_checkbox"
+ >
+ read_package_registry
+ <template #help>{{ $options.translations.readPackageRegistryHelp }}</template>
+ </gl-form-checkbox>
+ <gl-form-checkbox
+ v-if="packagesRegistryEnabled"
+ id="deploy_token_write_package_registry"
+ v-model="writePackageRegistry"
+ name="deploy_token_write_package_registry"
+ data-qa-selector="deploy_token_write_package_registry_checkbox"
+ >
+ write_package_registry
+ <template #help>{{ $options.translations.writePackageRegistryHelp }}</template>
+ </gl-form-checkbox>
+ <!-- eslint-enable @gitlab/vue-require-i18n-strings -->
+ </div>
+ </gl-form-group>
+ <div>
+ <gl-button variant="success" @click="createDeployToken">
+ {{ $options.translations.addTokenButton }}
+ </gl-button>
+ </div>
+ <gl-datepicker v-model="expiresAt" target="#deploy_token_expires_at" container="body" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/deploy_tokens/index.js b/app/assets/javascripts/deploy_tokens/index.js
new file mode 100644
index 00000000000..334c9930f4b
--- /dev/null
+++ b/app/assets/javascripts/deploy_tokens/index.js
@@ -0,0 +1,33 @@
+import Vue from 'vue';
+import NewDeployToken from './components/new_deploy_token.vue';
+
+export default function initDeployTokens() {
+ const el = document.getElementById('js-new-deploy-token');
+
+ if (el == null) return null;
+
+ const {
+ createNewTokenPath,
+ deployTokensHelpUrl,
+ containerRegistryEnabled,
+ packagesRegistryEnabled,
+ tokenType,
+ } = el.dataset;
+ return new Vue({
+ el,
+ components: {
+ NewDeployToken,
+ },
+ render(createElement) {
+ return createElement(NewDeployToken, {
+ props: {
+ createNewTokenPath,
+ deployTokensHelpUrl,
+ containerRegistryEnabled: containerRegistryEnabled !== undefined,
+ packagesRegistryEnabled: packagesRegistryEnabled !== undefined,
+ tokenType,
+ },
+ });
+ },
+ });
+}
diff --git a/app/assets/javascripts/notes/components/discussion_counter.vue b/app/assets/javascripts/notes/components/discussion_counter.vue
index 6521b86edbb..37935e9c3c6 100644
--- a/app/assets/javascripts/notes/components/discussion_counter.vue
+++ b/app/assets/javascripts/notes/components/discussion_counter.vue
@@ -81,16 +81,18 @@ export default {
:class="{
'gl-bg-orange-50': blocksMerge && !allResolved,
'gl-bg-gray-50': !blocksMerge || allResolved,
- 'gl-pr-2': !allResolved,
}"
data-testid="discussions-counter-text"
>
<template v-if="allResolved">
{{ __('All threads resolved!') }}
<gl-dropdown
+ v-gl-tooltip:discussionCounter.hover.bottom
size="small"
category="tertiary"
right
+ :title="__('Thread options')"
+ :aria-label="__('Thread options')"
toggle-class="btn-icon"
class="gl-pt-0! gl-px-2 gl-h-full gl-ml-2"
>
@@ -133,9 +135,12 @@ export default {
@click="jumpNext"
/>
<gl-dropdown
+ v-gl-tooltip:discussionCounter.hover.bottom
size="small"
category="tertiary"
right
+ :title="__('Thread options')"
+ :aria-label="__('Thread options')"
toggle-class="btn-icon"
class="gl-pt-0! gl-px-2"
>
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/cleanup_image_tags.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/cleanup_image_tags.vue
index 72e68aca070..b8405b09840 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/cleanup_image_tags.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/cleanup_image_tags.vue
@@ -57,6 +57,9 @@ export default {
isEnabled() {
return this.containerExpirationPolicy || this.enableHistoricEntries;
},
+ isLoading() {
+ return this.$apollo.queries.containerExpirationPolicy.loading;
+ },
showDisabledFormMessage() {
return !this.isEnabled && !this.fetchSettingsError;
},
@@ -86,10 +89,10 @@ export default {
<container-expiration-policy-form
v-if="isEnabled"
v-model="workingCopy"
- :is-loading="$apollo.queries.containerExpirationPolicy.loading"
+ :is-loading="isLoading"
:is-edited="isEdited"
/>
- <template v-else>
+ <template v-if="!isLoading">
<gl-alert
v-if="showDisabledFormMessage"
:dismissible="false"
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
index b003b6aeb6b..1dd88d69d30 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/container_expiration_policy.vue
@@ -110,7 +110,7 @@ export default {
{{ cleanupRulesButtonText }}
</gl-button>
</gl-card>
- <template v-else>
+ <template v-if="!$apollo.queries.containerExpirationPolicy.loading">
<gl-alert
v-if="showDisabledFormMessage"
:dismissible="false"
diff --git a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
index bf77d968e7d..b1a1cc21764 100644
--- a/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
+++ b/app/assets/javascripts/pages/groups/settings/ci_cd/show/index.js
@@ -2,9 +2,11 @@ import initStaleRunnerCleanupSetting from 'ee_else_ce/group_settings/stale_runne
import initVariableList from '~/ci_variable_list';
import initSharedRunnersForm from '~/group_settings/mount_shared_runners';
import initSettingsPanels from '~/settings_panels';
+import initDeployTokens from '~/deploy_tokens';
// Initialize expandable settings panels
initSettingsPanels();
+initDeployTokens();
initSharedRunnersForm();
initStaleRunnerCleanupSetting();
diff --git a/app/assets/javascripts/pages/groups/settings/index.js b/app/assets/javascripts/pages/groups/settings/index.js
index cb787c60002..7e97cd865b7 100644
--- a/app/assets/javascripts/pages/groups/settings/index.js
+++ b/app/assets/javascripts/pages/groups/settings/index.js
@@ -1,5 +1,7 @@
import initRevokeButton from '~/deploy_tokens/init_revoke_button';
import initSearchSettings from '~/search_settings';
+import initDeployTokens from '~/deploy_tokens';
+initDeployTokens();
initSearchSettings();
initRevokeButton();
diff --git a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
index 6a9bd34db22..8909ff1f221 100644
--- a/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
+++ b/app/assets/javascripts/pages/projects/settings/ci_cd/show/index.js
@@ -10,6 +10,7 @@ import initSharedRunnersToggle from '~/projects/settings/mount_shared_runners_to
import initSettingsPanels from '~/settings_panels';
import { initTokenAccess } from '~/token_access';
import { initCiSecureFiles } from '~/ci_secure_files';
+import initDeployTokens from '~/deploy_tokens';
// Initialize expandable settings panels
initSettingsPanels();
@@ -34,6 +35,7 @@ document.querySelector('.js-toggle-extra-settings').addEventListener('click', (e
});
registrySettingsApp();
+initDeployTokens();
initDeployFreeze();
initSettingsPipelinesTriggers();
diff --git a/app/assets/javascripts/pages/projects/settings/index.js b/app/assets/javascripts/pages/projects/settings/index.js
index cb787c60002..7e97cd865b7 100644
--- a/app/assets/javascripts/pages/projects/settings/index.js
+++ b/app/assets/javascripts/pages/projects/settings/index.js
@@ -1,5 +1,7 @@
import initRevokeButton from '~/deploy_tokens/init_revoke_button';
import initSearchSettings from '~/search_settings';
+import initDeployTokens from '~/deploy_tokens';
+initDeployTokens();
initSearchSettings();
initRevokeButton();
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index 7d69a2d78b1..3d03dbd9db3 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -315,7 +315,6 @@ export default {
data-qa-selector="mr_widget_extension"
>
<state-container
- :mr="mr"
:status="statusIconName"
:is-loading="isLoadingSummary"
:class="{ 'gl-cursor-pointer': isCollapsible }"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue b/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
index 822c5a68093..932659f3c89 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/state_container.vue
@@ -16,7 +16,8 @@ export default {
props: {
mr: {
type: Object,
- required: true,
+ required: false,
+ default: null,
},
isLoading: {
type: Boolean,
@@ -80,6 +81,7 @@ export default {
</div>
</div>
<div
+ v-if="mr"
class="gl-md-display-none gl-border-l-1 gl-border-l-solid gl-border-gray-100 gl-ml-3 gl-pl-3 gl-h-6 gl-mt-1"
>
<gl-button
diff --git a/app/views/ci/variables/_index.html.haml b/app/views/ci/variables/_index.html.haml
index 02c468cebd7..9ca11b35064 100644
--- a/app/views/ci/variables/_index.html.haml
+++ b/app/views/ci/variables/_index.html.haml
@@ -1,9 +1,11 @@
- save_endpoint = local_assigns.fetch(:save_endpoint, nil)
- if ci_variable_protected_by_default?
- %p.settings-message.text-center
- - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/index', anchor: 'protected-cicd-variables') }
- = s_('Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ = render Pajamas::AlertComponent.new(variant: :warning, show_icon: false, dismissible: false,
+ alert_options: { class: 'gl-mb-3'}) do |c|
+ = c.body do
+ - link_start = '<a href="%{url}">'.html_safe % { url: help_page_path('ci/variables/index', anchor: 'protected-cicd-variables') }
+ = _('Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default.').html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- is_group = !@group.nil?
- is_project = !@project.nil?
diff --git a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
index 22571b11639..880017dbe36 100644
--- a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
+++ b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
@@ -1,8 +1,7 @@
- display_issuable_type = issuable_display_type(@merge_request)
.float-left.btn-group.gl-md-ml-3.gl-display-flex.dropdown.gl-new-dropdown.gl-md-w-auto.gl-w-full
- = button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret gl-display-none! gl-md-display-inline-flex!", data: { 'toggle' => 'dropdown' } do
- %span.gl-sr-only= _('Toggle dropdown')
+ = button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret has-tooltip gl-display-none! gl-md-display-inline-flex!", data: { 'toggle' => 'dropdown' }, title: _('Merge request actions') , 'aria-label': _('Merge request actions') do
= sprite_icon "ellipsis_v", size: 16, css_class: "dropdown-icon gl-icon"
= button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md btn-block gl-button gl-dropdown-toggle gl-md-display-none!", data: { 'toggle' => 'dropdown' } do
%span.gl-new-dropdown-button-text= _('Merge request actions')
diff --git a/app/views/shared/deploy_tokens/_index.html.haml b/app/views/shared/deploy_tokens/_index.html.haml
index 79bf35e2726..faec379e42b 100644
--- a/app/views/shared/deploy_tokens/_index.html.haml
+++ b/app/views/shared/deploy_tokens/_index.html.haml
@@ -8,10 +8,20 @@
%p
= description
.settings-content
- - if @created_deploy_token
- = render 'shared/deploy_tokens/new_deploy_token', deploy_token: @created_deploy_token
- %h5.gl-mt-0
- = s_('DeployTokens|New deploy token')
- = render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens
+ - if Feature.enabled?(:ajax_new_deploy_token, group_or_project)
+ #js-new-deploy-token{ data: {
+ container_registry_enabled: container_registry_enabled?(group_or_project),
+ packages_registry_enabled: packages_registry_enabled?(group_or_project),
+ create_new_token_path: create_deploy_token_path(group_or_project),
+ token_type: group_or_project.is_a?(Group) ? 'group' : 'project',
+ deploy_tokens_help_url: help_page_path('user/project/deploy_tokens/index.md')
+ }
+ }
+ - else
+ - if @created_deploy_token
+ = render 'shared/deploy_tokens/new_deploy_token', deploy_token: @created_deploy_token
+ %h5.gl-mt-0
+ = s_('DeployTokens|New deploy token')
+ = render 'shared/deploy_tokens/form', group_or_project: group_or_project, token: @new_deploy_token, presenter: @deploy_tokens
%hr
= render 'shared/deploy_tokens/table', group_or_project: group_or_project, active_tokens: @deploy_tokens