161 lines
4.1 KiB
Vue
161 lines
4.1 KiB
Vue
<script>
|
|
import { GlAccordion, GlAccordionItem, GlBadge, GlIcon } from '@gitlab/ui';
|
|
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
|
|
import { __, s__ } from '~/locale';
|
|
import { STATUSES } from '../constants';
|
|
|
|
const STATISTIC_ITEMS = {
|
|
diff_note: __('Diff notes'),
|
|
issue: __('Issues'),
|
|
label: __('Labels'),
|
|
milestone: __('Milestones'),
|
|
note: __('Notes'),
|
|
pull_request: s__('GithubImporter|Pull requests'),
|
|
pull_request_merged_by: s__('GithubImporter|PR mergers'),
|
|
pull_request_review: s__('GithubImporter|PR reviews'),
|
|
release: __('Releases'),
|
|
};
|
|
|
|
// support both camel case and snake case versions
|
|
Object.assign(STATISTIC_ITEMS, convertObjectPropsToCamelCase(STATISTIC_ITEMS));
|
|
|
|
const SCHEDULED_STATUS = {
|
|
icon: 'status-scheduled',
|
|
text: __('Pending'),
|
|
variant: 'muted',
|
|
};
|
|
|
|
const STATUS_MAP = {
|
|
[STATUSES.NONE]: {
|
|
icon: 'status-waiting',
|
|
text: __('Not started'),
|
|
variant: 'muted',
|
|
},
|
|
[STATUSES.SCHEDULING]: SCHEDULED_STATUS,
|
|
[STATUSES.SCHEDULED]: SCHEDULED_STATUS,
|
|
[STATUSES.CREATED]: SCHEDULED_STATUS,
|
|
[STATUSES.STARTED]: {
|
|
icon: 'status-running',
|
|
text: __('Importing...'),
|
|
variant: 'info',
|
|
},
|
|
[STATUSES.FAILED]: {
|
|
icon: 'status-failed',
|
|
text: __('Failed'),
|
|
variant: 'danger',
|
|
},
|
|
[STATUSES.TIMEOUT]: {
|
|
icon: 'status-failed',
|
|
text: __('Timeout'),
|
|
variant: 'danger',
|
|
},
|
|
[STATUSES.CANCELLED]: {
|
|
icon: 'status-stopped',
|
|
text: __('Cancelled'),
|
|
variant: 'neutral',
|
|
},
|
|
};
|
|
|
|
function isIncompleteImport(stats) {
|
|
return Object.keys(stats.fetched).some((key) => stats.fetched[key] !== stats.imported[key]);
|
|
}
|
|
|
|
export default {
|
|
name: 'ImportStatus',
|
|
components: {
|
|
GlAccordion,
|
|
GlAccordionItem,
|
|
GlBadge,
|
|
GlIcon,
|
|
},
|
|
props: {
|
|
status: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
stats: {
|
|
type: Object,
|
|
required: false,
|
|
default: () => ({ fetched: {}, imported: {} }),
|
|
},
|
|
},
|
|
|
|
computed: {
|
|
knownStats() {
|
|
const knownStatisticKeys = Object.keys(STATISTIC_ITEMS);
|
|
return Object.keys(this.stats.fetched).filter((key) => knownStatisticKeys.includes(key));
|
|
},
|
|
|
|
hasStats() {
|
|
return this.stats && this.knownStats.length > 0;
|
|
},
|
|
|
|
mappedStatus() {
|
|
if (this.status === STATUSES.FINISHED) {
|
|
const isIncomplete = this.stats && isIncompleteImport(this.stats);
|
|
return {
|
|
icon: 'status-success',
|
|
...(isIncomplete
|
|
? {
|
|
text: __('Partial import'),
|
|
variant: 'warning',
|
|
}
|
|
: {
|
|
text: __('Complete'),
|
|
variant: 'success',
|
|
}),
|
|
};
|
|
}
|
|
|
|
return STATUS_MAP[this.status];
|
|
},
|
|
},
|
|
|
|
methods: {
|
|
getStatisticIconProps(key) {
|
|
const fetched = this.stats.fetched[key];
|
|
const imported = this.stats.imported[key];
|
|
|
|
if (fetched === imported) {
|
|
return { name: 'status-success', class: 'gl-text-green-400' };
|
|
} else if (imported === 0) {
|
|
return { name: 'status-scheduled', class: 'gl-text-gray-400' };
|
|
}
|
|
|
|
return { name: 'status-running', class: 'gl-text-blue-400' };
|
|
},
|
|
},
|
|
|
|
STATISTIC_ITEMS,
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="gl-display-inline-block gl-w-13">
|
|
<gl-badge :icon="mappedStatus.icon" :variant="mappedStatus.variant" size="md" class="gl-mr-2">
|
|
{{ mappedStatus.text }}
|
|
</gl-badge>
|
|
</div>
|
|
<gl-accordion v-if="hasStats" :header-level="3">
|
|
<gl-accordion-item :title="__('Details')">
|
|
<ul class="gl-p-0 gl-list-style-none gl-font-sm">
|
|
<li v-for="key in knownStats" :key="key">
|
|
<div class="gl-display-flex gl-w-20 gl-align-items-center">
|
|
<gl-icon
|
|
:size="12"
|
|
class="gl-mr-3 gl-flex-shrink-0"
|
|
v-bind="getStatisticIconProps(key)"
|
|
/>
|
|
<span class="">{{ $options.STATISTIC_ITEMS[key] }}</span>
|
|
<span class="gl-ml-auto">
|
|
{{ stats.imported[key] || 0 }}/{{ stats.fetched[key] }}
|
|
</span>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</gl-accordion-item>
|
|
</gl-accordion>
|
|
</div>
|
|
</template>
|