Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue')
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue161
1 files changed, 111 insertions, 50 deletions
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
index 64f2ddc1d16..3feff8639a1 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -1,6 +1,9 @@
<script>
-import { GlIcon, GlLink, GlModal, GlModalDirective } from '@gitlab/ui';
+import { GlIcon, GlLink, GlModal, GlModalDirective, GlLoadingIcon } from '@gitlab/ui';
+import { IssuableType } from '~/issue_show/constants';
import { s__, __ } from '~/locale';
+import { timeTrackingQueries } from '~/sidebar/constants';
+
import eventHub from '../../event_hub';
import TimeTrackingCollapsedState from './collapsed_state.vue';
import TimeTrackingComparisonPane from './comparison_pane.vue';
@@ -18,6 +21,7 @@ export default {
GlIcon,
GlLink,
GlModal,
+ GlLoadingIcon,
TimeTrackingCollapsedState,
TimeTrackingSpentOnlyPane,
TimeTrackingComparisonPane,
@@ -27,29 +31,27 @@ export default {
directives: {
GlModal: GlModalDirective,
},
+ inject: ['issuableType'],
props: {
- timeEstimate: {
- type: Number,
- required: true,
- },
- timeSpent: {
- type: Number,
- required: true,
+ limitToHours: {
+ type: Boolean,
+ default: false,
+ required: false,
},
- humanTimeEstimate: {
+ fullPath: {
type: String,
required: false,
default: '',
},
- humanTimeSpent: {
+ issuableIid: {
type: String,
required: false,
default: '',
},
- limitToHours: {
- type: Boolean,
- default: false,
+ initialTimeTracking: {
+ type: Object,
required: false,
+ default: null,
},
/*
In issue list, "time-tracking-collapsed-state" is always rendered even if the sidebar isn't collapsed.
@@ -70,47 +72,103 @@ export default {
data() {
return {
showHelp: false,
+ timeTracking: {
+ ...this.initialTimeTracking,
+ },
};
},
+ apollo: {
+ issuableTimeTracking: {
+ query() {
+ return timeTrackingQueries[this.issuableType].query;
+ },
+ skip() {
+ // We don't fetch info via GraphQL in following cases
+ // 1. Time tracking info was provided via prop
+ // 2. issuableIid and fullPath are not provided.
+ if (!this.initialTimeTracking) {
+ return false;
+ } else if (this.issuableIid && this.fullPath) {
+ return false;
+ }
+ return true;
+ },
+ variables() {
+ return {
+ iid: this.issuableIid,
+ fullPath: this.fullPath,
+ };
+ },
+ update(data) {
+ this.timeTracking = {
+ ...data.workspace?.issuable,
+ };
+ },
+ },
+ },
computed: {
- hasTimeSpent() {
- return Boolean(this.timeSpent);
+ isTimeTrackingInfoLoading() {
+ return this.$apollo?.queries.issuableTimeTracking.loading ?? false;
+ },
+ timeEstimate() {
+ return this.timeTracking?.timeEstimate || 0;
+ },
+ totalTimeSpent() {
+ return this.timeTracking?.totalTimeSpent || 0;
+ },
+ humanTimeEstimate() {
+ return this.timeTracking?.humanTimeEstimate || '';
+ },
+ humanTotalTimeSpent() {
+ return this.timeTracking?.humanTotalTimeSpent || '';
+ },
+ hasTotalTimeSpent() {
+ return Boolean(this.totalTimeSpent);
},
hasTimeEstimate() {
return Boolean(this.timeEstimate);
},
showComparisonState() {
- return this.hasTimeEstimate && this.hasTimeSpent;
+ return this.hasTimeEstimate && this.hasTotalTimeSpent;
},
showEstimateOnlyState() {
- return this.hasTimeEstimate && !this.hasTimeSpent;
+ return this.hasTimeEstimate && !this.hasTotalTimeSpent;
},
showSpentOnlyState() {
- return this.hasTimeSpent && !this.hasTimeEstimate;
+ return this.hasTotalTimeSpent && !this.hasTimeEstimate;
},
showNoTimeTrackingState() {
- return !this.hasTimeEstimate && !this.hasTimeSpent;
+ return !this.hasTimeEstimate && !this.hasTotalTimeSpent;
},
showHelpState() {
return Boolean(this.showHelp);
},
+ isTimeReportSupported() {
+ return (
+ [IssuableType.Issue, IssuableType.MergeRequest].includes(this.issuableType) &&
+ this.issuableIid
+ );
+ },
+ },
+ watch: {
+ /**
+ * When `initialTimeTracking` is provided via prop,
+ * we don't query the same via GraphQl and instead
+ * monitor it for any updates (eg; Epic Swimlanes)
+ */
+ initialTimeTracking(timeTracking) {
+ this.timeTracking = timeTracking;
+ },
},
created() {
- eventHub.$on('timeTracker:updateData', this.update);
+ eventHub.$on('timeTracker:refresh', this.refresh);
},
methods: {
toggleHelpState(show) {
this.showHelp = show;
},
- update(data) {
- const { timeEstimate, timeSpent, humanTimeEstimate, humanTimeSpent } = data;
-
- /* eslint-disable vue/no-mutating-props */
- this.timeEstimate = timeEstimate;
- this.timeSpent = timeSpent;
- this.humanTimeEstimate = humanTimeEstimate;
- this.humanTimeSpent = humanTimeSpent;
- /* eslint-enable vue/no-mutating-props */
+ refresh() {
+ this.$apollo.queries.issuableTimeTracking.refetch();
},
},
};
@@ -125,11 +183,12 @@ export default {
:show-help-state="showHelpState"
:show-spent-only-state="showSpentOnlyState"
:show-estimate-only-state="showEstimateOnlyState"
- :time-spent-human-readable="humanTimeSpent"
+ :time-spent-human-readable="humanTotalTimeSpent"
:time-estimate-human-readable="humanTimeEstimate"
/>
- <div class="title hide-collapsed gl-mb-3">
+ <div class="hide-collapsed gl-line-height-20 gl-text-gray-900">
{{ __('Time tracking') }}
+ <gl-loading-icon v-if="isTimeTrackingInfoLoading" inline />
<div
v-if="!showHelpState"
data-testid="helpButton"
@@ -147,14 +206,14 @@ export default {
<gl-icon name="close" />
</div>
</div>
- <div class="time-tracking-content hide-collapsed">
+ <div v-if="!isTimeTrackingInfoLoading" class="hide-collapsed">
<div v-if="showEstimateOnlyState" data-testid="estimateOnlyPane">
<span class="gl-font-weight-bold">{{ $options.i18n.estimatedOnlyText }} </span
>{{ humanTimeEstimate }}
</div>
<time-tracking-spent-only-pane
v-if="showSpentOnlyState"
- :time-spent-human-readable="humanTimeSpent"
+ :time-spent-human-readable="humanTotalTimeSpent"
/>
<div v-if="showNoTimeTrackingState" data-testid="noTrackingPane">
<span class="gl-text-gray-500">{{ $options.i18n.noTimeTrackingText }}</span>
@@ -162,26 +221,28 @@ export default {
<time-tracking-comparison-pane
v-if="showComparisonState"
:time-estimate="timeEstimate"
- :time-spent="timeSpent"
- :time-spent-human-readable="humanTimeSpent"
+ :time-spent="totalTimeSpent"
+ :time-spent-human-readable="humanTotalTimeSpent"
:time-estimate-human-readable="humanTimeEstimate"
:limit-to-hours="limitToHours"
/>
- <gl-link
- v-if="hasTimeSpent"
- v-gl-modal="'time-tracking-report'"
- data-testid="reportLink"
- href="#"
- class="btn-link"
- >{{ __('Time tracking report') }}</gl-link
- >
- <gl-modal
- modal-id="time-tracking-report"
- :title="__('Time tracking report')"
- :hide-footer="true"
- >
- <time-tracking-report :limit-to-hours="limitToHours" />
- </gl-modal>
+ <template v-if="isTimeReportSupported">
+ <gl-link
+ v-if="hasTotalTimeSpent"
+ v-gl-modal="'time-tracking-report'"
+ data-testid="reportLink"
+ href="#"
+ >
+ {{ __('Time tracking report') }}
+ </gl-link>
+ <gl-modal
+ modal-id="time-tracking-report"
+ :title="__('Time tracking report')"
+ :hide-footer="true"
+ >
+ <time-tracking-report :limit-to-hours="limitToHours" :issuable-iid="issuableIid" />
+ </gl-modal>
+ </template>
<transition name="help-state-toggle">
<time-tracking-help-state v-if="showHelpState" />
</transition>