debian-mirror-gitlab/app/assets/javascripts/reports/components/report_section.vue

235 lines
5.5 KiB
Vue
Raw Normal View History

2018-11-18 11:00:15 +05:30
<script>
2021-04-29 21:17:54 +05:30
import { GlButton } from '@gitlab/ui';
import api from '~/api';
2018-11-18 11:00:15 +05:30
import { __ } from '~/locale';
import StatusIcon from '~/vue_merge_request_widget/components/mr_widget_status_icon.vue';
2018-11-20 20:47:30 +05:30
import Popover from '~/vue_shared/components/help_popover.vue';
2021-04-29 21:17:54 +05:30
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
2021-02-22 17:27:13 +05:30
import { status, SLOT_SUCCESS, SLOT_LOADING, SLOT_ERROR } from '../constants';
2021-03-11 19:13:27 +05:30
import IssuesList from './issues_list.vue';
2018-11-18 11:00:15 +05:30
export default {
name: 'ReportSection',
components: {
2021-04-29 21:17:54 +05:30
GlButton,
2018-11-18 11:00:15 +05:30
IssuesList,
Popover,
2021-04-29 21:17:54 +05:30
StatusIcon,
2018-11-18 11:00:15 +05:30
},
2021-04-29 21:17:54 +05:30
mixins: [glFeatureFlagsMixin()],
2018-11-18 11:00:15 +05:30
props: {
alwaysOpen: {
type: Boolean,
required: false,
default: false,
},
component: {
type: String,
required: false,
default: '',
},
status: {
type: String,
required: true,
},
loadingText: {
type: String,
required: false,
default: '',
},
errorText: {
type: String,
required: false,
default: '',
},
successText: {
type: String,
2019-09-04 21:01:54 +05:30
required: false,
default: '',
2018-11-18 11:00:15 +05:30
},
unresolvedIssues: {
type: Array,
required: false,
default: () => [],
},
resolvedIssues: {
type: Array,
required: false,
default: () => [],
},
neutralIssues: {
type: Array,
required: false,
default: () => [],
},
infoText: {
type: [String, Boolean],
required: false,
default: false,
},
hasIssues: {
type: Boolean,
required: true,
},
popoverOptions: {
type: Object,
default: () => ({}),
required: false,
},
2019-09-04 21:01:54 +05:30
showReportSectionStatusIcon: {
type: Boolean,
required: false,
default: true,
},
issuesUlElementClass: {
type: String,
required: false,
default: undefined,
},
issuesListContainerClass: {
type: String,
required: false,
default: undefined,
},
issueItemClass: {
type: String,
required: false,
default: undefined,
},
2020-07-28 23:09:34 +05:30
shouldEmitToggleEvent: {
type: Boolean,
required: false,
default: false,
},
2021-04-29 21:17:54 +05:30
trackAction: {
type: String,
required: false,
default: null,
},
2018-11-18 11:00:15 +05:30
},
data() {
return {
isCollapsed: true,
};
},
computed: {
collapseText() {
return this.isCollapsed ? __('Expand') : __('Collapse');
},
isLoading() {
2019-09-04 21:01:54 +05:30
return this.status === status.LOADING;
2018-11-18 11:00:15 +05:30
},
loadingFailed() {
2019-09-04 21:01:54 +05:30
return this.status === status.ERROR;
2018-11-18 11:00:15 +05:30
},
isSuccess() {
2019-09-04 21:01:54 +05:30
return this.status === status.SUCCESS;
2018-11-18 11:00:15 +05:30
},
isCollapsible() {
return !this.alwaysOpen && this.hasIssues;
},
isExpanded() {
return this.alwaysOpen || !this.isCollapsed;
},
statusIconName() {
if (this.isLoading) {
return 'loading';
}
if (this.loadingFailed || this.unresolvedIssues.length || this.neutralIssues.length) {
return 'warning';
}
return 'success';
},
headerText() {
if (this.isLoading) {
return this.loadingText;
}
if (this.isSuccess) {
return this.successText;
}
if (this.loadingFailed) {
return this.errorText;
}
return '';
},
hasPopover() {
return Object.keys(this.popoverOptions).length > 0;
},
2019-09-04 21:01:54 +05:30
slotName() {
if (this.isSuccess) {
2021-02-22 17:27:13 +05:30
return SLOT_SUCCESS;
2019-09-04 21:01:54 +05:30
} else if (this.isLoading) {
2021-02-22 17:27:13 +05:30
return SLOT_LOADING;
2019-09-04 21:01:54 +05:30
}
2021-02-22 17:27:13 +05:30
return SLOT_ERROR;
2019-09-04 21:01:54 +05:30
},
2018-11-18 11:00:15 +05:30
},
methods: {
toggleCollapsed() {
2021-04-29 21:17:54 +05:30
if (this.trackAction && this.glFeatures.usersExpandingWidgetsUsageData) {
api.trackRedisHllUserEvent(this.trackAction);
}
2020-07-28 23:09:34 +05:30
if (this.shouldEmitToggleEvent) {
this.$emit('toggleEvent');
}
2018-11-18 11:00:15 +05:30
this.isCollapsed = !this.isCollapsed;
},
},
};
</script>
<template>
<section class="media-section">
<div class="media">
2020-03-13 15:44:24 +05:30
<status-icon :status="statusIconName" :size="24" class="align-self-center" />
<div class="media-body d-flex flex-align-self-center align-items-center">
2020-05-24 23:13:21 +05:30
<div data-testid="report-section-code-text" class="js-code-text code-text">
2021-06-08 01:23:25 +05:30
<div class="gl-display-flex gl-align-items-center">
<p class="gl-line-height-normal gl-m-0">{{ headerText }}</p>
2020-03-13 15:44:24 +05:30
<slot :name="slotName"></slot>
2021-06-08 01:23:25 +05:30
<popover
v-if="hasPopover"
:options="popoverOptions"
class="gl-ml-2 gl-display-inline-flex"
/>
2020-03-13 15:44:24 +05:30
</div>
2021-01-29 00:20:46 +05:30
<slot name="sub-heading"></slot>
2020-03-13 15:44:24 +05:30
</div>
2018-11-18 11:00:15 +05:30
2021-04-17 20:07:23 +05:30
<slot name="action-buttons" :is-collapsible="isCollapsible"></slot>
2018-11-18 11:00:15 +05:30
2021-04-29 21:17:54 +05:30
<gl-button
2018-11-18 11:00:15 +05:30
v-if="isCollapsible"
2021-04-29 21:17:54 +05:30
class="js-collapse-btn"
2021-01-29 00:20:46 +05:30
data-testid="report-section-expand-button"
2021-04-17 20:07:23 +05:30
data-qa-selector="expand_report_button"
2018-11-18 11:00:15 +05:30
@click="toggleCollapsed"
>
{{ collapseText }}
2021-04-29 21:17:54 +05:30
</gl-button>
2018-11-18 11:00:15 +05:30
</div>
</div>
2019-02-15 15:39:39 +05:30
<div v-if="hasIssues" v-show="isExpanded" class="js-report-section-container">
2018-11-18 11:00:15 +05:30
<slot name="body">
<issues-list
:unresolved-issues="unresolvedIssues"
:resolved-issues="resolvedIssues"
:neutral-issues="neutralIssues"
:component="component"
2019-09-04 21:01:54 +05:30
:show-report-section-status-icon="showReportSectionStatusIcon"
:issues-ul-element-class="issuesUlElementClass"
:class="issuesListContainerClass"
:issue-item-class="issueItemClass"
2018-11-18 11:00:15 +05:30
/>
</slot>
</div>
</section>
</template>