diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-06 18:08:19 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-06 18:08:19 +0000 |
commit | da6cd333e7d29b356b398905c657be81a94b4621 (patch) | |
tree | 9455ef6355f90b710383d93aefa6b990117855b2 /app/assets | |
parent | 5472bef68de87deeb67594a98e7eb35ff83929ec (diff) | |
download | gitlab-ce-da6cd333e7d29b356b398905c657be81a94b4621.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
10 files changed, 243 insertions, 20 deletions
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index 33d7da8fd53..d2856d99ef0 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -93,6 +93,7 @@ const Api = { notificationSettingsPath: '/api/:version/notification_settings', deployKeysPath: '/api/:version/deploy_keys', secureFilesPath: '/api/:version/projects/:project_id/secure_files', + dependencyProxyPath: '/api/:version/groups/:id/dependency_proxy/cache', group(groupId, callback = () => {}) { const url = Api.buildUrl(Api.groupPath).replace(':id', groupId); @@ -999,6 +1000,12 @@ const Api = { return result; }, + + deleteDependencyProxyCacheList(groupId, options = {}) { + const url = Api.buildUrl(this.dependencyProxyPath).replace(':id', groupId); + + return axios.delete(url, { params: { ...options } }); + }, }; export default Api; diff --git a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue index eb112238c11..4ddefcbdf6a 100644 --- a/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue +++ b/app/assets/javascripts/packages_and_registries/dependency_proxy/app.vue @@ -1,13 +1,18 @@ <script> import { GlAlert, + GlDropdown, + GlDropdownItem, GlEmptyState, GlFormGroup, GlFormInputGroup, + GlModal, + GlModalDirective, GlSkeletonLoader, GlSprintf, } from '@gitlab/ui'; -import { s__ } from '~/locale'; +import { __, s__, n__, sprintf } from '~/locale'; +import Api from '~/api'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import ManifestsList from '~/packages_and_registries/dependency_proxy/components/manifests_list.vue'; @@ -22,16 +27,22 @@ import getDependencyProxyDetailsQuery from '~/packages_and_registries/dependency export default { components: { GlAlert, + GlDropdown, + GlDropdownItem, GlEmptyState, GlFormGroup, GlFormInputGroup, + GlModal, GlSkeletonLoader, GlSprintf, ClipboardButton, TitleArea, ManifestsList, }, - inject: ['groupPath', 'dependencyProxyAvailable', 'noManifestsIllustration'], + directives: { + GlModalDirective, + }, + inject: ['groupPath', 'groupId', 'dependencyProxyAvailable', 'noManifestsIllustration'], i18n: { proxyNotAvailableText: s__( 'DependencyProxy|Dependency Proxy feature is limited to public groups for now.', @@ -41,6 +52,19 @@ export default { blobCountAndSize: s__('DependencyProxy|Contains %{count} blobs of images (%{size})'), pageTitle: s__('DependencyProxy|Dependency Proxy'), noManifestTitle: s__('DependencyProxy|There are no images in the cache'), + deleteCacheAlertMessageSuccess: s__( + 'DependencyProxy|All items in the cache are scheduled for removal.', + ), + }, + confirmClearCacheModal: 'confirm-clear-cache-modal', + modalButtons: { + primary: { + text: s__('DependencyProxy|Clear cache'), + attributes: [{ variant: 'danger' }], + }, + secondary: { + text: __('Cancel'), + }, }, links: { DEPENDENCY_PROXY_DOCS_PATH, @@ -48,6 +72,8 @@ export default { data() { return { group: {}, + showDeleteCacheAlert: false, + deleteCacheAlertMessage: '', }; }, apollo: { @@ -80,6 +106,33 @@ export default { manifests() { return this.group.dependencyProxyManifests.nodes; }, + modalTitleWithCount() { + return sprintf( + n__( + 'Clear %{count} image from cache?', + 'Clear %{count} images from cache?', + this.group.dependencyProxyBlobCount, + ), + { + count: this.group.dependencyProxyBlobCount, + }, + ); + }, + modalConfirmationMessageWithCount() { + return sprintf( + n__( + 'You are about to clear %{count} image from the cache. Once you confirm, the next time a pipeline runs it must pull an image or tag from Docker Hub. Are you sure?', + 'You are about to clear %{count} images from the cache. Once you confirm, the next time a pipeline runs it must pull an image or tag from Docker Hub. Are you sure?', + this.group.dependencyProxyBlobCount, + ), + { + count: this.group.dependencyProxyBlobCount, + }, + ); + }, + showDeleteDropdown() { + return this.group.dependencyProxyBlobCount > 0; + }, }, methods: { fetchNextPage() { @@ -103,13 +156,47 @@ export default { }, }); }, + async submit() { + try { + await Api.deleteDependencyProxyCacheList(this.groupId); + + this.deleteCacheAlertMessage = this.$options.i18n.deleteCacheAlertMessageSuccess; + this.showDeleteCacheAlert = true; + } catch (err) { + this.deleteCacheAlertMessage = err; + this.showDeleteCacheAlert = true; + } + }, }, }; </script> <template> <div> - <title-area :title="$options.i18n.pageTitle" :info-messages="infoMessages" /> + <gl-alert + v-if="showDeleteCacheAlert" + data-testid="delete-cache-alert" + @dismiss="showDeleteCacheAlert = false" + > + {{ deleteCacheAlertMessage }} + </gl-alert> + <title-area :title="$options.i18n.pageTitle" :info-messages="infoMessages"> + <template v-if="showDeleteDropdown" #right-actions> + <gl-dropdown + icon="ellipsis_v" + text="More actions" + :text-sr-only="true" + category="tertiary" + no-caret + > + <gl-dropdown-item + v-gl-modal-directive="$options.confirmClearCacheModal" + variant="danger" + >{{ $options.i18n.clearCache }}</gl-dropdown-item + > + </gl-dropdown> + </template> + </title-area> <gl-alert v-if="!dependencyProxyAvailable" :dismissible="false" @@ -159,5 +246,15 @@ export default { :title="$options.i18n.noManifestTitle" /> </div> + + <gl-modal + :modal-id="$options.confirmClearCacheModal" + :title="modalTitleWithCount" + :action-primary="$options.modalButtons.primary" + :action-secondary="$options.modalButtons.secondary" + @primary="submit" + > + {{ modalConfirmationMessageWithCount }} + </gl-modal> </div> </template> diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue index b996d3f15d1..8511f9bdb0f 100644 --- a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue +++ b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_mini_graph.vue @@ -10,7 +10,7 @@ import { import { formatStages } from '../utils'; import getLinkedPipelinesQuery from '../graphql/queries/get_linked_pipelines.query.graphql'; import getPipelineStagesQuery from '../graphql/queries/get_pipeline_stages.query.graphql'; -import { PIPELINE_STAGES_POLL_INTERVAL } from '../constants'; +import { COMMIT_BOX_POLL_INTERVAL } from '../constants'; export default { i18n: { @@ -65,7 +65,7 @@ export default { return getQueryHeaders(this.graphqlResourceEtag); }, query: getPipelineStagesQuery, - pollInterval: PIPELINE_STAGES_POLL_INTERVAL, + pollInterval: COMMIT_BOX_POLL_INTERVAL, variables() { return { fullPath: this.fullPath, diff --git a/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_status.vue b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_status.vue new file mode 100644 index 00000000000..5a9d3129809 --- /dev/null +++ b/app/assets/javascripts/projects/commit_box/info/components/commit_box_pipeline_status.vue @@ -0,0 +1,74 @@ +<script> +import { GlLoadingIcon, GlLink } from '@gitlab/ui'; +import CiIcon from '~/vue_shared/components/ci_icon.vue'; +import createFlash from '~/flash'; +import { + getQueryHeaders, + toggleQueryPollingByVisibility, +} from '~/pipelines/components/graph/utils'; +import getLatestPipelineStatusQuery from '../graphql/queries/get_latest_pipeline_status.query.graphql'; +import { COMMIT_BOX_POLL_INTERVAL, PIPELINE_STATUS_FETCH_ERROR } from '../constants'; + +export default { + PIPELINE_STATUS_FETCH_ERROR, + components: { + CiIcon, + GlLoadingIcon, + GlLink, + }, + inject: { + fullPath: { + default: '', + }, + iid: { + default: '', + }, + graphqlResourceEtag: { + default: '', + }, + }, + apollo: { + pipelineStatus: { + context() { + return getQueryHeaders(this.graphqlResourceEtag); + }, + query: getLatestPipelineStatusQuery, + pollInterval: COMMIT_BOX_POLL_INTERVAL, + variables() { + return { + fullPath: this.fullPath, + iid: this.iid, + }; + }, + update({ project }) { + return project?.pipeline?.detailedStatus || {}; + }, + error() { + createFlash({ message: this.$options.PIPELINE_STATUS_FETCH_ERROR }); + }, + }, + }, + data() { + return { + pipelineStatus: {}, + }; + }, + computed: { + loading() { + return this.$apollo.queries.pipelineStatus.loading; + }, + }, + mounted() { + toggleQueryPollingByVisibility(this.$apollo.queries.pipelineStatus); + }, +}; +</script> + +<template> + <div class="gl-display-inline-block gl-vertical-align-middle gl-mr-2"> + <gl-loading-icon v-if="loading" /> + <gl-link v-else :href="pipelineStatus.detailsPath"> + <ci-icon :status="pipelineStatus" :size="24" /> + </gl-link> + </div> +</template> diff --git a/app/assets/javascripts/projects/commit_box/info/constants.js b/app/assets/javascripts/projects/commit_box/info/constants.js index fc4f03482e2..be0bf715314 100644 --- a/app/assets/javascripts/projects/commit_box/info/constants.js +++ b/app/assets/javascripts/projects/commit_box/info/constants.js @@ -1 +1,7 @@ -export const PIPELINE_STAGES_POLL_INTERVAL = 10000; +import { __ } from '~/locale'; + +export const COMMIT_BOX_POLL_INTERVAL = 10000; + +export const PIPELINE_STATUS_FETCH_ERROR = __( + 'There was a problem fetching the latest pipeline status.', +); diff --git a/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_latest_pipeline_status.query.graphql b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_latest_pipeline_status.query.graphql new file mode 100644 index 00000000000..cec96f82336 --- /dev/null +++ b/app/assets/javascripts/projects/commit_box/info/graphql/queries/get_latest_pipeline_status.query.graphql @@ -0,0 +1,14 @@ +query getLatestPipelineStatus($fullPath: ID!, $iid: ID!) { + project(fullPath: $fullPath) { + id + pipeline(iid: $iid) { + id + detailedStatus { + id + detailsPath + icon + group + } + } + } +} diff --git a/app/assets/javascripts/projects/commit_box/info/index.js b/app/assets/javascripts/projects/commit_box/info/index.js index 69fe2d30489..7500c152b6a 100644 --- a/app/assets/javascripts/projects/commit_box/info/index.js +++ b/app/assets/javascripts/projects/commit_box/info/index.js @@ -2,6 +2,7 @@ import { fetchCommitMergeRequests } from '~/commit_merge_requests'; import { initCommitPipelineMiniGraph } from './init_commit_pipeline_mini_graph'; import { initDetailsButton } from './init_details_button'; import { loadBranches } from './load_branches'; +import initCommitPipelineStatus from './init_commit_pipeline_status'; export const initCommitBoxInfo = () => { // Display commit related branches @@ -14,4 +15,6 @@ export const initCommitBoxInfo = () => { initCommitPipelineMiniGraph(); initDetailsButton(); + + initCommitPipelineStatus(); }; diff --git a/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_status.js b/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_status.js new file mode 100644 index 00000000000..d5e62531283 --- /dev/null +++ b/app/assets/javascripts/projects/commit_box/info/init_commit_pipeline_status.js @@ -0,0 +1,34 @@ +import Vue from 'vue'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; +import CommitBoxPipelineStatus from './components/commit_box_pipeline_status.vue'; + +Vue.use(VueApollo); + +const apolloProvider = new VueApollo({ + defaultClient: createDefaultClient({}, { useGet: true }), +}); + +export default (selector = '.js-commit-pipeline-status') => { + const el = document.querySelector(selector); + + if (!el) { + return; + } + + const { fullPath, iid, graphqlResourceEtag } = el.dataset; + + // eslint-disable-next-line no-new + new Vue({ + el, + apolloProvider, + provide: { + fullPath, + iid, + graphqlResourceEtag, + }, + render(createElement) { + return createElement(CommitBoxPipelineStatus); + }, + }); +}; diff --git a/app/assets/javascripts/reports/components/report_section.vue b/app/assets/javascripts/reports/components/report_section.vue index 7a490210f0b..ae201a61db6 100644 --- a/app/assets/javascripts/reports/components/report_section.vue +++ b/app/assets/javascripts/reports/components/report_section.vue @@ -172,7 +172,7 @@ export default { }, methods: { toggleCollapsed() { - if (this.trackAction && this.glFeatures.usersExpandingWidgetsUsageData) { + if (this.trackAction) { api.trackRedisHllUserEvent(this.trackAction); } diff --git a/app/assets/stylesheets/page_bundles/jira_connect_users.scss b/app/assets/stylesheets/page_bundles/jira_connect_users.scss index 6725bf8f1a1..602910adad9 100644 --- a/app/assets/stylesheets/page_bundles/jira_connect_users.scss +++ b/app/assets/stylesheets/page_bundles/jira_connect_users.scss @@ -1,13 +1 @@ -@import 'mixins_and_variables_and_functions'; - -.jira-connect-users-container { - margin-left: auto; - margin-right: auto; - width: px-to-rem(350px); -} - -.devise-layout-html body .navless-container { - @include media-breakpoint-down(xs) { - padding-top: 65px; - } -} +@import '../themes/theme_indigo'; |