summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/registry/explorer/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/registry/explorer/components')
-rw-r--r--app/assets/javascripts/registry/explorer/components/delete_button.vue1
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/details_header.vue11
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_list.vue1
-rw-r--r--app/assets/javascripts/registry/explorer/components/details_page/tags_list_row.vue4
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_item.vue128
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/cli_commands.vue102
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list.vue1
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/image_list_row.vue2
-rw-r--r--app/assets/javascripts/registry/explorer/components/list_page/registry_header.vue66
-rw-r--r--app/assets/javascripts/registry/explorer/components/registry_breadcrumb.vue6
10 files changed, 81 insertions, 241 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">