diff options
Diffstat (limited to 'app/assets/javascripts/registry/explorer')
12 files changed, 81 insertions, 243 deletions
diff --git a/app/assets/javascripts/registry/explorer/components/delete_button.vue b/app/assets/javascripts/registry/explorer/components/delete_button.vue index dab6a26ea16..ee856a3e546 100644 --- a/app/assets/javascripts/registry/explorer/components/delete_button.vue +++ b/app/assets/javascripts/registry/explorer/components/delete_button.vue @@ -47,7 +47,6 @@ export default { :disabled="disabled" :title="title" :aria-label="title" - category="secondary" variant="danger" icon="remove" @click="$emit('delete')" diff --git a/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue index c254dd05aa4..ff613daf7fa 100644 --- a/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue +++ b/app/assets/javascripts/registry/explorer/components/details_page/details_header.vue @@ -1,9 +1,10 @@ <script> import { GlSprintf } from '@gitlab/ui'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; import { DETAILS_PAGE_TITLE } from '../../constants/index'; export default { - components: { GlSprintf }, + components: { GlSprintf, TitleArea }, props: { imageName: { type: String, @@ -18,13 +19,13 @@ export default { </script> <template> - <div class="gl-display-flex gl-my-2 gl-align-items-center"> - <h4> + <title-area> + <template #title> <gl-sprintf :message="$options.i18n.DETAILS_PAGE_TITLE"> <template #imageName> {{ imageName }} </template> </gl-sprintf> - </h4> - </div> + </template> + </title-area> </template> diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue index 8494967ab57..328026d0953 100644 --- a/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue +++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue @@ -67,7 +67,6 @@ export default { :key="tag.path" :tag="tag" :first="index === 0" - :last="index === tags.length - 1" :selected="selectedItems[tag.name]" :is-desktop="isDesktop" @select="updateSelectedItems(tag.name)" diff --git a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue index 8ec5cebbe8e..661213733ac 100644 --- a/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue +++ b/app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue @@ -5,9 +5,9 @@ import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import { numberToHumanSize } from '~/lib/utils/number_utils'; import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue'; import { formatDate } from '~/lib/utils/datetime_utility'; +import ListItem from '~/vue_shared/components/registry/list_item.vue'; import DeleteButton from '../delete_button.vue'; -import ListItem from '../list_item.vue'; -import DetailsRow from '~/registry/shared/components/details_row.vue'; +import DetailsRow from '~/vue_shared/components/registry/details_row.vue'; import { REMOVE_TAG_BUTTON_TITLE, DIGEST_LABEL, diff --git a/app/assets/javascripts/registry/explorer/components/list_item.vue b/app/assets/javascripts/registry/explorer/components/list_item.vue deleted file mode 100644 index c57645cc3a1..00000000000 --- a/app/assets/javascripts/registry/explorer/components/list_item.vue +++ /dev/null @@ -1,128 +0,0 @@ -<script> -import { GlButton } from '@gitlab/ui'; - -export default { - name: 'ListItem', - components: { GlButton }, - props: { - first: { - type: Boolean, - default: false, - required: false, - }, - last: { - type: Boolean, - default: false, - required: false, - }, - disabled: { - type: Boolean, - default: false, - required: false, - }, - selected: { - type: Boolean, - default: false, - required: false, - }, - }, - data() { - return { - isDetailsShown: false, - detailsSlots: [], - }; - }, - computed: { - optionalClasses() { - return { - 'gl-border-t-1': !this.first, - 'gl-border-t-2': this.first, - 'gl-border-b-1': !this.last, - 'gl-border-b-2': this.last, - 'disabled-content': this.disabled, - 'gl-border-gray-100': !this.selected, - 'gl-bg-blue-50 gl-border-blue-200': this.selected, - }; - }, - }, - mounted() { - this.detailsSlots = Object.keys(this.$slots).filter(k => k.startsWith('details_')); - }, - methods: { - toggleDetails() { - this.isDetailsShown = !this.isDetailsShown; - }, - }, -}; -</script> - -<template> - <div - class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid" - :class="optionalClasses" - > - <div class="gl-display-flex gl-align-items-center gl-py-4 gl-px-2"> - <div - v-if="$slots['left-action']" - class="gl-w-7 gl-display-none gl-display-sm-flex gl-justify-content-start gl-pl-2" - > - <slot name="left-action"></slot> - </div> - <div class="gl-display-flex gl-flex-direction-column gl-flex-fill-1"> - <div - class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-text-body gl-font-weight-bold" - > - <div class="gl-display-flex gl-align-items-center"> - <slot name="left-primary"></slot> - <gl-button - v-if="detailsSlots.length > 0" - :selected="isDetailsShown" - icon="ellipsis_h" - size="small" - class="gl-ml-2 gl-display-none gl-display-sm-block" - @click="toggleDetails" - /> - </div> - <div> - <slot name="right-primary"></slot> - </div> - </div> - <div - class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-font-sm gl-text-gray-300" - > - <div> - <slot name="left-secondary"></slot> - </div> - <div> - <slot name="right-secondary"></slot> - </div> - </div> - </div> - <div - v-if="$slots['right-action']" - class="gl-w-9 gl-display-none gl-display-sm-flex gl-justify-content-end gl-pr-2" - > - <slot name="right-action"></slot> - </div> - </div> - <div class="gl-display-flex"> - <div class="gl-w-7"></div> - <div - v-if="isDetailsShown" - class="gl-display-flex gl-flex-direction-column gl-flex-fill-1 gl-bg-gray-10 gl-rounded-base gl-inset-border-1-gray-100 gl-mb-3" - > - <div - v-for="(row, detailIndex) in detailsSlots" - :key="detailIndex" - class="gl-px-5 gl-py-2" - :class="{ - 'gl-border-gray-100 gl-border-t-solid gl-border-t-1': detailIndex !== 0, - }" - > - <slot :name="row"></slot> - </div> - </div> - <div class="gl-w-9"></div> - </div> - </div> -</template> diff --git a/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue index 36a46ed58f4..85d87dab042 100644 --- a/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue +++ b/app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue @@ -1,8 +1,8 @@ <script> -import { GlDeprecatedDropdown, GlFormGroup, GlFormInputGroup } from '@gitlab/ui'; +import { GlDeprecatedDropdown } from '@gitlab/ui'; import { mapGetters } from 'vuex'; import Tracking from '~/tracking'; -import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; +import CodeInstruction from '~/vue_shared/components/registry/code_instruction.vue'; import { QUICK_START, LOGIN_COMMAND_LABEL, @@ -13,22 +13,23 @@ import { COPY_PUSH_TITLE, } from '../../constants/index'; +const trackingLabel = 'quickstart_dropdown'; + export default { components: { GlDeprecatedDropdown, - GlFormGroup, - GlFormInputGroup, - ClipboardButton, + CodeInstruction, }, - mixins: [Tracking.mixin({ label: 'quickstart_dropdown' })], + mixins: [Tracking.mixin({ label: trackingLabel })], + trackingLabel, i18n: { - dropdownTitle: QUICK_START, - loginCommandLabel: LOGIN_COMMAND_LABEL, - copyLoginTitle: COPY_LOGIN_TITLE, - buildCommandLabel: BUILD_COMMAND_LABEL, - copyBuildTitle: COPY_BUILD_TITLE, - pushCommandLabel: PUSH_COMMAND_LABEL, - copyPushTitle: COPY_PUSH_TITLE, + QUICK_START, + LOGIN_COMMAND_LABEL, + COPY_LOGIN_TITLE, + BUILD_COMMAND_LABEL, + COPY_BUILD_TITLE, + PUSH_COMMAND_LABEL, + COPY_PUSH_TITLE, }, computed: { ...mapGetters(['dockerBuildCommand', 'dockerPushCommand', 'dockerLoginCommand']), @@ -37,7 +38,7 @@ export default { </script> <template> <gl-deprecated-dropdown - :text="$options.i18n.dropdownTitle" + :text="$options.i18n.QUICK_START" variant="primary" size="sm" right @@ -45,59 +46,30 @@ export default { > <!-- This li is used as a container since gl-dropdown produces a root ul, this mimics the functionality exposed by b-dropdown-form --> <li role="presentation" class="px-2 py-1 dropdown-menu-large"> - <form> - <gl-form-group - label-size="sm" - label-for="docker-login-btn" - :label="$options.i18n.loginCommandLabel" - > - <gl-form-input-group id="docker-login-btn" :value="dockerLoginCommand" readonly> - <template #append> - <clipboard-button - class="border" - :text="dockerLoginCommand" - :title="$options.i18n.copyLoginTitle" - @click.native="track('click_copy_login')" - /> - </template> - </gl-form-input-group> - </gl-form-group> + <code-instruction + :label="$options.i18n.LOGIN_COMMAND_LABEL" + :instruction="dockerLoginCommand" + :copy-text="$options.i18n.COPY_LOGIN_TITLE" + tracking-action="click_copy_login" + :tracking-label="$options.trackingLabel" + /> - <gl-form-group - label-size="sm" - label-for="docker-build-btn" - :label="$options.i18n.buildCommandLabel" - > - <gl-form-input-group id="docker-build-btn" :value="dockerBuildCommand" readonly> - <template #append> - <clipboard-button - class="border" - :text="dockerBuildCommand" - :title="$options.i18n.copyBuildTitle" - @click.native="track('click_copy_build')" - /> - </template> - </gl-form-input-group> - </gl-form-group> + <code-instruction + :label="$options.i18n.BUILD_COMMAND_LABEL" + :instruction="dockerBuildCommand" + :copy-text="$options.i18n.COPY_BUILD_TITLE" + tracking-action="click_copy_build" + :tracking-label="$options.trackingLabel" + /> - <gl-form-group - class="mb-0" - label-size="sm" - label-for="docker-push-btn" - :label="$options.i18n.pushCommandLabel" - > - <gl-form-input-group id="docker-push-btn" :value="dockerPushCommand" readonly> - <template #append> - <clipboard-button - class="border" - :text="dockerPushCommand" - :title="$options.i18n.copyPushTitle" - @click.native="track('click_copy_push')" - /> - </template> - </gl-form-input-group> - </gl-form-group> - </form> + <code-instruction + class="mb-0" + :label="$options.i18n.PUSH_COMMAND_LABEL" + :instruction="dockerPushCommand" + :copy-text="$options.i18n.COPY_PUSH_TITLE" + tracking-action="click_copy_push" + :tracking-label="$options.trackingLabel" + /> </li> </gl-deprecated-dropdown> </template> diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue index 65cf51fd1d1..d1b9894da0e 100644 --- a/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue +++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list.vue @@ -38,7 +38,6 @@ export default { :key="index" :item="listItem" :first="index === 0" - :last="index === images.length - 1" @delete="$emit('delete', $event)" /> diff --git a/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue index 102311c6062..32bf27f1143 100644 --- a/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue +++ b/app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue @@ -2,7 +2,7 @@ import { GlTooltipDirective, GlIcon, GlSprintf } from '@gitlab/ui'; import { n__ } from '~/locale'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; -import ListItem from '../list_item.vue'; +import ListItem from '~/vue_shared/components/registry/list_item.vue'; import DeleteButton from '../delete_button.vue'; import { diff --git a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue index c7b4fd5f4b4..7be68e77def 100644 --- a/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue +++ b/app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue @@ -1,6 +1,8 @@ <script> -import { GlSprintf, GlLink, GlIcon } from '@gitlab/ui'; -import { n__ } from '~/locale'; +import { GlSprintf, GlLink } from '@gitlab/ui'; +import TitleArea from '~/vue_shared/components/registry/title_area.vue'; +import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue'; +import { n__, sprintf } from '~/locale'; import { approximateDuration, calculateRemainingMilliseconds } from '~/lib/utils/datetime_utility'; import { @@ -13,9 +15,10 @@ import { export default { components: { - GlIcon, GlSprintf, GlLink, + TitleArea, + MetadataItem, }, props: { expirationPolicy: { @@ -56,11 +59,12 @@ export default { }, computed: { imagesCountText() { - return n__( + const pluralisedString = n__( 'ContainerRegistry|%{count} Image repository', 'ContainerRegistry|%{count} Image repositories', this.imagesCount, ); + return sprintf(pluralisedString, { count: this.imagesCount }); }, timeTillRun() { const difference = calculateRemainingMilliseconds(this.expirationPolicy?.next_run_at); @@ -71,7 +75,7 @@ export default { }, expirationPolicyText() { return this.expirationPolicyEnabled - ? EXPIRATION_POLICY_WILL_RUN_IN + ? sprintf(EXPIRATION_POLICY_WILL_RUN_IN, { time: this.timeTillRun }) : EXPIRATION_POLICY_DISABLED_TEXT; }, showExpirationPolicyTip() { @@ -85,37 +89,29 @@ export default { <template> <div> - <div - class="gl-display-flex gl-justify-content-space-between gl-align-items-center" - data-testid="header" - > - <h4 data-testid="title">{{ $options.i18n.CONTAINER_REGISTRY_TITLE }}</h4> - <div class="gl-display-none d-sm-block" data-testid="commands-slot"> + <title-area :title="$options.i18n.CONTAINER_REGISTRY_TITLE"> + <template #right-actions> <slot name="commands"></slot> - </div> - </div> - <div - v-if="imagesCount" - class="gl-display-flex gl-align-items-center gl-mt-1 gl-mb-3 gl-text-gray-500" - data-testid="subheader" - > - <span class="gl-mr-3" data-testid="images-count"> - <gl-icon class="gl-mr-1" name="container-image" /> - <gl-sprintf :message="imagesCountText"> - <template #count> - {{ imagesCount }} - </template> - </gl-sprintf> - </span> - <span v-if="!hideExpirationPolicyData" data-testid="expiration-policy"> - <gl-icon class="gl-mr-1" name="expire" /> - <gl-sprintf :message="expirationPolicyText"> - <template #time> - {{ timeTillRun }} - </template> - </gl-sprintf> - </span> - </div> + </template> + <template #metadata_count> + <metadata-item + v-if="imagesCount" + data-testid="images-count" + icon="container-image" + :text="imagesCountText" + /> + </template> + <template #metadata_exp_policies> + <metadata-item + v-if="!hideExpirationPolicyData" + data-testid="expiration-policy" + icon="expire" + :text="expirationPolicyText" + size="xl" + /> + </template> + </title-area> + <div data-testid="info-area"> <p> <span data-testid="default-intro"> diff --git a/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue index d935ca091a1..146d1434b18 100644 --- a/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue +++ b/app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue @@ -1,7 +1,9 @@ <script> import { initial, first, last } from 'lodash'; +import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui'; export default { + directives: { SafeHtml }, props: { crumbs: { type: Array, @@ -41,14 +43,14 @@ export default { <li v-for="(crumb, index) in rootCrumbs" :key="index" + v-safe-html="crumb.innerHTML" :class="crumb.className" - v-html="crumb.innerHTML" ></li> <li v-if="!isRootRoute"> <router-link ref="rootRouteLink" :to="rootRoute.path"> {{ rootRoute.meta.nameGenerator(rootRoute) }} </router-link> - <component :is="divider.tagName" :class="divider.classList" v-html="divider.innerHTML" /> + <component :is="divider.tagName" v-safe-html="divider.innerHTML" :class="divider.classList" /> </li> <li> <component :is="lastCrumb.tagName" ref="lastCrumb" :class="lastCrumb.className"> diff --git a/app/assets/javascripts/registry/explorer/stores/index.js b/app/assets/javascripts/registry/explorer/stores/index.js index 54a8e0e1c1c..18e3351ed13 100644 --- a/app/assets/javascripts/registry/explorer/stores/index.js +++ b/app/assets/javascripts/registry/explorer/stores/index.js @@ -7,7 +7,6 @@ import state from './state'; Vue.use(Vuex); -// eslint-disable-next-line import/prefer-default-export export const createStore = () => new Vuex.Store({ state, diff --git a/app/assets/javascripts/registry/explorer/utils.js b/app/assets/javascripts/registry/explorer/utils.js index b1df87c6993..44262a6cbb6 100644 --- a/app/assets/javascripts/registry/explorer/utils.js +++ b/app/assets/javascripts/registry/explorer/utils.js @@ -1,2 +1 @@ -// eslint-disable-next-line import/prefer-default-export export const decodeAndParse = param => JSON.parse(window.atob(param)); |