summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/packages
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/packages')
-rw-r--r--app/assets/javascripts/packages/details/components/app.vue79
-rw-r--r--app/assets/javascripts/packages/details/components/package_files.vue107
-rw-r--r--app/assets/javascripts/packages/details/components/package_history.vue121
-rw-r--r--app/assets/javascripts/packages/details/constants.js2
-rw-r--r--app/assets/javascripts/packages/list/constants.js4
-rw-r--r--app/assets/javascripts/packages/shared/constants.js1
-rw-r--r--app/assets/javascripts/packages/shared/utils.js3
7 files changed, 216 insertions, 101 deletions
diff --git a/app/assets/javascripts/packages/details/components/app.vue b/app/assets/javascripts/packages/details/components/app.vue
index af3220840a6..c9f1c8b903c 100644
--- a/app/assets/javascripts/packages/details/components/app.vue
+++ b/app/assets/javascripts/packages/details/components/app.vue
@@ -5,29 +5,26 @@ import {
GlModal,
GlModalDirective,
GlTooltipDirective,
- GlLink,
GlEmptyState,
GlTab,
GlTabs,
- GlTable,
GlSprintf,
} from '@gitlab/ui';
import { mapActions, mapState } from 'vuex';
import Tracking from '~/tracking';
+import { s__ } from '~/locale';
+import { objectToQueryString } from '~/lib/utils/common_utils';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
import PackageHistory from './package_history.vue';
import PackageTitle from './package_title.vue';
import PackagesListLoader from '../../shared/components/packages_list_loader.vue';
import PackageListRow from '../../shared/components/package_list_row.vue';
+import { packageTypeToTrackCategory } from '../../shared/utils';
+import { PackageType, TrackingActions, SHOW_DELETE_SUCCESS_ALERT } from '../../shared/constants';
import DependencyRow from './dependency_row.vue';
import AdditionalMetadata from './additional_metadata.vue';
import InstallationCommands from './installation_commands.vue';
-import { numberToHumanSize } from '~/lib/utils/number_utils';
-import timeagoMixin from '~/vue_shared/mixins/timeago';
-import FileIcon from '~/vue_shared/components/file_icon.vue';
-import { __, s__ } from '~/locale';
-import { PackageType, TrackingActions, SHOW_DELETE_SUCCESS_ALERT } from '../../shared/constants';
-import { packageTypeToTrackCategory } from '../../shared/utils';
-import { objectToQueryString } from '~/lib/utils/common_utils';
+import PackageFiles from './package_files.vue';
export default {
name: 'PackagesApp',
@@ -35,12 +32,9 @@ export default {
GlBadge,
GlButton,
GlEmptyState,
- GlLink,
GlModal,
GlTab,
GlTabs,
- GlTable,
- FileIcon,
GlSprintf,
PackageTitle,
PackagesListLoader,
@@ -49,12 +43,13 @@ export default {
PackageHistory,
AdditionalMetadata,
InstallationCommands,
+ PackageFiles,
},
directives: {
GlTooltip: GlTooltipDirective,
GlModal: GlModalDirective,
},
- mixins: [timeagoMixin, Tracking.mixin()],
+ mixins: [Tracking.mixin()],
trackingActions: { ...TrackingActions },
computed: {
...mapState([
@@ -72,14 +67,6 @@ export default {
isValidPackage() {
return Boolean(this.packageEntity.name);
},
- filesTableRows() {
- return this.packageFiles.map(x => ({
- name: x.file_name,
- downloadPath: x.download_path,
- size: this.formatSize(x.size),
- created: x.created_at,
- }));
- },
tracking() {
return {
category: packageTypeToTrackCategory(this.packageEntity.package_type),
@@ -128,22 +115,6 @@ export default {
`PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?`,
),
},
- filesTableHeaderFields: [
- {
- key: 'name',
- label: __('Name'),
- tdClass: 'd-flex align-items-center',
- },
- {
- key: 'size',
- label: __('Size'),
- },
- {
- key: 'created',
- label: __('Created'),
- class: 'text-right',
- },
- ],
};
</script>
@@ -185,35 +156,11 @@ export default {
<additional-metadata :package-entity="packageEntity" />
</div>
- <template v-if="showFiles">
- <h3 class="gl-font-lg gl-mt-5">{{ __('Files') }}</h3>
- <gl-table
- :fields="$options.filesTableHeaderFields"
- :items="filesTableRows"
- tbody-tr-class="js-file-row"
- >
- <template #cell(name)="{ item }">
- <gl-link
- :href="item.downloadPath"
- class="js-file-download gl-relative"
- @click="track($options.trackingActions.PULL_PACKAGE)"
- >
- <file-icon
- :file-name="item.name"
- css-classes="gl-relative file-icon"
- class="gl-mr-1 gl-relative"
- />
- <span class="gl-relative">{{ item.name }}</span>
- </gl-link>
- </template>
-
- <template #cell(created)="{ item }">
- <span v-gl-tooltip :title="tooltipTitle(item.created)">{{
- timeFormatted(item.created)
- }}</span>
- </template>
- </gl-table>
- </template>
+ <package-files
+ v-if="showFiles"
+ :package-files="packageFiles"
+ @download-file="track($options.trackingActions.PULL_PACKAGE)"
+ />
</gl-tab>
<gl-tab v-if="showDependencies" title-item-class="js-dependencies-tab">
diff --git a/app/assets/javascripts/packages/details/components/package_files.vue b/app/assets/javascripts/packages/details/components/package_files.vue
new file mode 100644
index 00000000000..ab46dd0114d
--- /dev/null
+++ b/app/assets/javascripts/packages/details/components/package_files.vue
@@ -0,0 +1,107 @@
+<script>
+import { GlLink, GlTable } from '@gitlab/ui';
+import { last } from 'lodash';
+import { __ } from '~/locale';
+import Tracking from '~/tracking';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import FileIcon from '~/vue_shared/components/file_icon.vue';
+
+export default {
+ name: 'PackageFiles',
+ components: {
+ GlLink,
+ GlTable,
+ FileIcon,
+ TimeAgoTooltip,
+ },
+ mixins: [Tracking.mixin()],
+ props: {
+ packageFiles: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ },
+ computed: {
+ filesTableRows() {
+ return this.packageFiles.map(pf => ({
+ ...pf,
+ size: this.formatSize(pf.size),
+ pipeline: last(pf.pipelines),
+ }));
+ },
+ showCommitColumn() {
+ return this.filesTableRows.some(row => Boolean(row.pipeline?.id));
+ },
+ filesTableHeaderFields() {
+ return [
+ {
+ key: 'name',
+ label: __('Name'),
+ tdClass: 'gl-display-flex gl-align-items-center',
+ },
+ {
+ key: 'commit',
+ label: __('Commit'),
+ hide: !this.showCommitColumn,
+ },
+ {
+ key: 'size',
+ label: __('Size'),
+ },
+ {
+ key: 'created',
+ label: __('Created'),
+ class: 'gl-text-right',
+ },
+ ].filter(c => !c.hide);
+ },
+ },
+ methods: {
+ formatSize(size) {
+ return numberToHumanSize(size);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <h3 class="gl-font-lg gl-mt-5">{{ __('Files') }}</h3>
+ <gl-table
+ :fields="filesTableHeaderFields"
+ :items="filesTableRows"
+ :tbody-tr-attr="{ 'data-testid': 'file-row' }"
+ >
+ <template #cell(name)="{ item }">
+ <gl-link
+ :href="item.download_path"
+ class="gl-relative gl-text-gray-500"
+ data-testid="download-link"
+ @click="$emit('download-file')"
+ >
+ <file-icon
+ :file-name="item.file_name"
+ css-classes="gl-relative file-icon"
+ class="gl-mr-1 gl-relative"
+ />
+ <span class="gl-relative">{{ item.file_name }}</span>
+ </gl-link>
+ </template>
+
+ <template #cell(commit)="{item}">
+ <gl-link
+ :href="item.pipeline.project.commit_url"
+ class="gl-text-gray-500"
+ data-testid="commit-link"
+ >{{ item.pipeline.git_commit_message }}</gl-link
+ >
+ </template>
+
+ <template #cell(created)="{ item }">
+ <time-ago-tooltip :time="item.created_at" />
+ </template>
+ </gl-table>
+ </div>
+</template>
diff --git a/app/assets/javascripts/packages/details/components/package_history.vue b/app/assets/javascripts/packages/details/components/package_history.vue
index 413ab1d15cb..62550602428 100644
--- a/app/assets/javascripts/packages/details/components/package_history.vue
+++ b/app/assets/javascripts/packages/details/components/package_history.vue
@@ -1,17 +1,26 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
-import { s__ } from '~/locale';
+import { first } from 'lodash';
+import { s__, n__ } from '~/locale';
+import { truncateSha } from '~/lib/utils/text_utility';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
+import { HISTORY_PIPELINES_LIMIT } from '~/packages/details/constants';
export default {
name: 'PackageHistory',
i18n: {
- createdOn: s__('PackageRegistry|%{name} version %{version} was created %{datetime}'),
- updatedAtText: s__('PackageRegistry|%{name} version %{version} was updated %{datetime}'),
- commitText: s__('PackageRegistry|Commit %{link} on branch %{branch}'),
- pipelineText: s__('PackageRegistry|Pipeline %{link} triggered %{datetime} by %{author}'),
+ createdOn: s__('PackageRegistry|%{name} version %{version} was first created %{datetime}'),
+ createdByCommitText: s__('PackageRegistry|Created by commit %{link} on branch %{branch}'),
+ createdByPipelineText: s__(
+ 'PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}',
+ ),
publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'),
+ combinedUpdateText: s__(
+ 'PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}',
+ ),
+ archivedPipelineMessageSingular: s__('PackageRegistry|Package has %{number} archived update'),
+ archivedPipelineMessagePlural: s__('PackageRegistry|Package has %{number} archived updates'),
},
components: {
GlLink,
@@ -35,8 +44,32 @@ export default {
};
},
computed: {
- packagePipeline() {
- return this.packageEntity.pipeline?.id ? this.packageEntity.pipeline : null;
+ pipelines() {
+ return this.packageEntity.pipelines || [];
+ },
+ firstPipeline() {
+ return first(this.pipelines);
+ },
+ lastPipelines() {
+ return this.pipelines.slice(1).slice(-HISTORY_PIPELINES_LIMIT);
+ },
+ showPipelinesInfo() {
+ return Boolean(this.firstPipeline?.id);
+ },
+ archiviedLines() {
+ return Math.max(this.pipelines.length - HISTORY_PIPELINES_LIMIT - 1, 0);
+ },
+ archivedPipelineMessage() {
+ return n__(
+ this.$options.i18n.archivedPipelineMessageSingular,
+ this.$options.i18n.archivedPipelineMessagePlural,
+ this.archiviedLines,
+ );
+ },
+ },
+ methods: {
+ truncate(value) {
+ return truncateSha(value);
},
},
};
@@ -59,46 +92,35 @@ export default {
</template>
</gl-sprintf>
</history-item>
- <history-item icon="pencil" data-testid="updated-at">
- <gl-sprintf :message="$options.i18n.updatedAtText">
- <template #name>
- <strong>{{ packageEntity.name }}</strong>
- </template>
- <template #version>
- <strong>{{ packageEntity.version }}</strong>
- </template>
- <template #datetime>
- <time-ago-tooltip :time="packageEntity.updated_at" />
- </template>
- </gl-sprintf>
- </history-item>
- <template v-if="packagePipeline">
- <history-item icon="commit" data-testid="commit">
- <gl-sprintf :message="$options.i18n.commitText">
+
+ <template v-if="showPipelinesInfo">
+ <!-- FIRST PIPELINE BLOCK -->
+ <history-item icon="commit" data-testid="first-pipeline-commit">
+ <gl-sprintf :message="$options.i18n.createdByCommitText">
<template #link>
- <gl-link :href="packagePipeline.project.commit_url">{{
- packagePipeline.sha
- }}</gl-link>
+ <gl-link :href="firstPipeline.project.commit_url"
+ >#{{ truncate(firstPipeline.sha) }}</gl-link
+ >
</template>
<template #branch>
- <strong>{{ packagePipeline.ref }}</strong>
+ <strong>{{ firstPipeline.ref }}</strong>
</template>
</gl-sprintf>
</history-item>
- <history-item icon="pipeline" data-testid="pipeline">
- <gl-sprintf :message="$options.i18n.pipelineText">
+ <history-item icon="pipeline" data-testid="first-pipeline-pipeline">
+ <gl-sprintf :message="$options.i18n.createdByPipelineText">
<template #link>
- <gl-link :href="packagePipeline.project.pipeline_url"
- >#{{ packagePipeline.id }}</gl-link
- >
+ <gl-link :href="firstPipeline.project.pipeline_url">#{{ firstPipeline.id }}</gl-link>
</template>
<template #datetime>
- <time-ago-tooltip :time="packagePipeline.created_at" />
+ <time-ago-tooltip :time="firstPipeline.created_at" />
</template>
- <template #author>{{ packagePipeline.user.name }}</template>
+ <template #author>{{ firstPipeline.user.name }}</template>
</gl-sprintf>
</history-item>
</template>
+
+ <!-- PUBLISHED LINE -->
<history-item icon="package" data-testid="published">
<gl-sprintf :message="$options.i18n.publishText">
<template #project>
@@ -109,6 +131,37 @@ export default {
</template>
</gl-sprintf>
</history-item>
+
+ <history-item v-if="archiviedLines" icon="history" data-testid="archived">
+ <gl-sprintf :message="archivedPipelineMessage">
+ <template #number>
+ <strong>{{ archiviedLines }}</strong>
+ </template>
+ </gl-sprintf>
+ </history-item>
+
+ <!-- PIPELINES LIST ENTRIES -->
+ <history-item
+ v-for="pipeline in lastPipelines"
+ :key="pipeline.id"
+ icon="pencil"
+ data-testid="pipeline-entry"
+ >
+ <gl-sprintf :message="$options.i18n.combinedUpdateText">
+ <template #link>
+ <gl-link :href="pipeline.project.commit_url">#{{ truncate(pipeline.sha) }}</gl-link>
+ </template>
+ <template #branch>
+ <strong>{{ pipeline.ref }}</strong>
+ </template>
+ <template #pipeline>
+ <gl-link :href="pipeline.project.pipeline_url">#{{ pipeline.id }}</gl-link>
+ </template>
+ <template #datetime>
+ <time-ago-tooltip :time="pipeline.created_at" />
+ </template>
+ </gl-sprintf>
+ </history-item>
</ul>
</div>
</template>
diff --git a/app/assets/javascripts/packages/details/constants.js b/app/assets/javascripts/packages/details/constants.js
index c6e1b388132..986b0667356 100644
--- a/app/assets/javascripts/packages/details/constants.js
+++ b/app/assets/javascripts/packages/details/constants.js
@@ -45,3 +45,5 @@ export const NpmManager = {
export const FETCH_PACKAGE_VERSIONS_ERROR = s__(
'PackageRegistry|Unable to fetch package version information.',
);
+
+export const HISTORY_PIPELINES_LIMIT = 5;
diff --git a/app/assets/javascripts/packages/list/constants.js b/app/assets/javascripts/packages/list/constants.js
index 6a0e92bff2d..e14696e0d1c 100644
--- a/app/assets/javascripts/packages/list/constants.js
+++ b/app/assets/javascripts/packages/list/constants.js
@@ -68,6 +68,10 @@ export const PACKAGE_REGISTRY_TABS = [
title: s__('PackageRegistry|Conan'),
type: PackageType.CONAN,
},
+ {
+ title: s__('PackageRegistry|Generic'),
+ type: PackageType.GENERIC,
+ },
{
title: s__('PackageRegistry|Maven'),
diff --git a/app/assets/javascripts/packages/shared/constants.js b/app/assets/javascripts/packages/shared/constants.js
index c481abd8658..c0f7f150337 100644
--- a/app/assets/javascripts/packages/shared/constants.js
+++ b/app/assets/javascripts/packages/shared/constants.js
@@ -7,6 +7,7 @@ export const PackageType = {
NUGET: 'nuget',
PYPI: 'pypi',
COMPOSER: 'composer',
+ GENERIC: 'generic',
};
export const TrackingActions = {
diff --git a/app/assets/javascripts/packages/shared/utils.js b/app/assets/javascripts/packages/shared/utils.js
index b0807558266..d7a883e4397 100644
--- a/app/assets/javascripts/packages/shared/utils.js
+++ b/app/assets/javascripts/packages/shared/utils.js
@@ -21,7 +21,8 @@ export const getPackageTypeLabel = packageType => {
return s__('PackageType|PyPI');
case PackageType.COMPOSER:
return s__('PackageType|Composer');
-
+ case PackageType.GENERIC:
+ return s__('PackageType|Generic');
default:
return null;
}