summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2019-06-25 07:58:26 +0000
committerPhil Hughes <me@iamphill.com>2019-06-25 07:58:26 +0000
commited8605c42e46263d0aec58062ddd80f5511d0014 (patch)
treea9212613674c52b2b83ac47e478522c61347badb /app
parentfc5475b461f902464f156e13dda19fc276b62031 (diff)
parent275a17589c2d468d8671a9f754a50b212273d509 (diff)
downloadgitlab-ce-ed8605c42e46263d0aec58062ddd80f5511d0014.tar.gz
Merge branch '30355-use-hours-only-for-time-tracking' into 'master'
Limit time tracking units to hours Closes #30355 See merge request gitlab-org/gitlab-ce!29469
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/components/board_sidebar.js1
-rw-r--r--app/assets/javascripts/boards/components/issue_time_estimate.vue10
-rw-r--r--app/assets/javascripts/boards/index.js1
-rw-r--r--app/assets/javascripts/boards/stores/boards_store.js7
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js17
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue7
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.vue1
-rw-r--r--app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue5
-rw-r--r--app/assets/javascripts/sidebar/mount_milestone_sidebar.js4
-rw-r--r--app/assets/javascripts/sidebar/stores/sidebar_store.js3
-rw-r--r--app/helpers/application_settings_helper.rb1
-rw-r--r--app/helpers/boards_helper.rb3
-rw-r--r--app/helpers/issuables_helper.rb3
-rw-r--r--app/models/application_setting_implementation.rb1
-rw-r--r--app/views/admin/application_settings/_localization.html.haml7
-rw-r--r--app/views/shared/boards/components/sidebar/_time_tracker.html.haml1
-rw-r--r--app/views/shared/milestones/_sidebar.html.haml6
17 files changed, 68 insertions, 10 deletions
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index c587b276fa3..2ace0060c42 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -38,6 +38,7 @@ export default Vue.extend({
issue: {},
list: {},
loadingAssignees: false,
+ timeTrackingLimitToHours: boardsStore.timeTracking.limitToHours,
};
},
computed: {
diff --git a/app/assets/javascripts/boards/components/issue_time_estimate.vue b/app/assets/javascripts/boards/components/issue_time_estimate.vue
index 98c1d29db16..3385aad5b11 100644
--- a/app/assets/javascripts/boards/components/issue_time_estimate.vue
+++ b/app/assets/javascripts/boards/components/issue_time_estimate.vue
@@ -2,6 +2,7 @@
import { GlTooltip } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import { parseSeconds, stringifyTime } from '~/lib/utils/datetime_utility';
+import boardsStore from '../stores/boards_store';
export default {
components: {
@@ -14,12 +15,17 @@ export default {
required: true,
},
},
+ data() {
+ return {
+ limitToHours: boardsStore.timeTracking.limitToHours,
+ };
+ },
computed: {
title() {
- return stringifyTime(parseSeconds(this.estimate), true);
+ return stringifyTime(parseSeconds(this.estimate, { limitToHours: this.limitToHours }), true);
},
timeEstimate() {
- return stringifyTime(parseSeconds(this.estimate));
+ return stringifyTime(parseSeconds(this.estimate, { limitToHours: this.limitToHours }));
},
},
};
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index f2f37d22b97..a020765f335 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -49,6 +49,7 @@ export default () => {
}
boardsStore.create();
+ boardsStore.setTimeTrackingLimitToHours($boardApp.dataset.timeTrackingLimitToHours);
issueBoardsApp = new Vue({
el: $boardApp,
diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js
index 4b3b44574a8..4ba4cde6bae 100644
--- a/app/assets/javascripts/boards/stores/boards_store.js
+++ b/app/assets/javascripts/boards/stores/boards_store.js
@@ -12,6 +12,9 @@ import eventHub from '../eventhub';
const boardsStore = {
disabled: false,
+ timeTracking: {
+ limitToHours: false,
+ },
scopedLabels: {
helpLink: '',
enabled: false,
@@ -222,6 +225,10 @@ const boardsStore = {
setIssueDetail(issueDetail) {
this.detail.issue = issueDetail;
},
+
+ setTimeTrackingLimitToHours(limitToHours) {
+ this.timeTracking.limitToHours = parseBoolean(limitToHours);
+ },
};
BoardsStoreEE.initEESpecific(boardsStore);
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index d521c462ad8..062d21ed247 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -479,9 +479,13 @@ export const pikadayToString = date => {
* Seconds can be negative or positive, zero or non-zero. Can be configured for any day
* or week length.
*/
-export const parseSeconds = (seconds, { daysPerWeek = 5, hoursPerDay = 8 } = {}) => {
+export const parseSeconds = (
+ seconds,
+ { daysPerWeek = 5, hoursPerDay = 8, limitToHours = false } = {},
+) => {
const DAYS_PER_WEEK = daysPerWeek;
const HOURS_PER_DAY = hoursPerDay;
+ const SECONDS_PER_MINUTE = 60;
const MINUTES_PER_HOUR = 60;
const MINUTES_PER_WEEK = DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR;
const MINUTES_PER_DAY = HOURS_PER_DAY * MINUTES_PER_HOUR;
@@ -493,9 +497,18 @@ export const parseSeconds = (seconds, { daysPerWeek = 5, hoursPerDay = 8 } = {})
minutes: 1,
};
- let unorderedMinutes = Math.abs(seconds / MINUTES_PER_HOUR);
+ if (limitToHours) {
+ timePeriodConstraints.weeks = 0;
+ timePeriodConstraints.days = 0;
+ }
+
+ let unorderedMinutes = Math.abs(seconds / SECONDS_PER_MINUTE);
return _.mapObject(timePeriodConstraints, minutesPerPeriod => {
+ if (minutesPerPeriod === 0) {
+ return 0;
+ }
+
const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod);
unorderedMinutes -= periodCount * minutesPerPeriod;
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
index f4d926cd3ec..13955529cab 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/comparison_pane.vue
@@ -28,11 +28,16 @@ export default {
type: String,
required: true,
},
+ limitToHours: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
parsedTimeRemaining() {
const diffSeconds = this.timeEstimate - this.timeSpent;
- return parseSeconds(diffSeconds);
+ return parseSeconds(diffSeconds, { limitToHours: this.limitToHours });
},
timeRemainingHumanReadable() {
return stringifyTime(this.parsedTimeRemaining);
diff --git a/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.vue b/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.vue
index 8e8b9f19b6e..018b30d2a67 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/sidebar_time_tracking.vue
@@ -53,6 +53,7 @@ export default {
:time-spent="store.totalTimeSpent"
:human-time-estimate="store.humanTimeEstimate"
:human-time-spent="store.humanTotalTimeSpent"
+ :limit-to-hours="store.timeTrackingLimitToHours"
:root-path="store.rootPath"
/>
</div>
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 d84d5344935..682ca600b6a 100644
--- a/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
+++ b/app/assets/javascripts/sidebar/components/time_tracking/time_tracker.vue
@@ -37,6 +37,10 @@ export default {
required: false,
default: '',
},
+ limitToHours: {
+ type: Boolean,
+ default: false,
+ },
rootPath: {
type: String,
required: true,
@@ -129,6 +133,7 @@ export default {
:time-spent="timeSpent"
:time-spent-human-readable="humanTimeSpent"
:time-estimate-human-readable="humanTimeEstimate"
+ :limit-to-hours="limitToHours"
/>
<transition name="help-state-toggle">
<time-tracking-help-state v-if="showHelpState" :root-path="rootPath" />
diff --git a/app/assets/javascripts/sidebar/mount_milestone_sidebar.js b/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
index 1ebdbec7bc9..d934463382f 100644
--- a/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_milestone_sidebar.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import timeTracker from './components/time_tracking/time_tracker.vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
export default class SidebarMilestone {
constructor() {
@@ -7,7 +8,7 @@ export default class SidebarMilestone {
if (!el) return;
- const { timeEstimate, timeSpent, humanTimeEstimate, humanTimeSpent } = el.dataset;
+ const { timeEstimate, timeSpent, humanTimeEstimate, humanTimeSpent, limitToHours } = el.dataset;
// eslint-disable-next-line no-new
new Vue({
@@ -22,6 +23,7 @@ export default class SidebarMilestone {
timeSpent: parseInt(timeSpent, 10),
humanTimeEstimate,
humanTimeSpent,
+ limitToHours: parseBoolean(limitToHours),
rootPath: '/',
},
}),
diff --git a/app/assets/javascripts/sidebar/stores/sidebar_store.js b/app/assets/javascripts/sidebar/stores/sidebar_store.js
index 7b8b4c5d856..63c4a2a3f84 100644
--- a/app/assets/javascripts/sidebar/stores/sidebar_store.js
+++ b/app/assets/javascripts/sidebar/stores/sidebar_store.js
@@ -8,7 +8,7 @@ export default class SidebarStore {
}
initSingleton(options) {
- const { currentUser, rootPath, editable } = options;
+ const { currentUser, rootPath, editable, timeTrackingLimitToHours } = options;
this.currentUser = currentUser;
this.rootPath = rootPath;
this.editable = editable;
@@ -16,6 +16,7 @@ export default class SidebarStore {
this.totalTimeSpent = 0;
this.humanTimeEstimate = '';
this.humanTimeSpent = '';
+ this.timeTrackingLimitToHours = timeTrackingLimitToHours;
this.assignees = [];
this.isFetching = {
assignees: true,
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 4469118f065..d837c42fd68 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -253,6 +253,7 @@ module ApplicationSettingsHelper
:throttle_unauthenticated_enabled,
:throttle_unauthenticated_period_in_seconds,
:throttle_unauthenticated_requests_per_period,
+ :time_tracking_limit_to_hours,
:two_factor_grace_period,
:unique_ips_limit_enabled,
:unique_ips_limit_per_user,
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index 1640f4fc93f..c5130b430b9 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -14,7 +14,8 @@ module BoardsHelper
issue_link_base: build_issue_link_base,
root_path: root_path,
bulk_update_path: @bulk_issues_path,
- default_avatar: image_path(default_avatar)
+ default_avatar: image_path(default_avatar),
+ time_tracking_limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s
}
end
diff --git a/app/helpers/issuables_helper.rb b/app/helpers/issuables_helper.rb
index 150f24a5d5b..045de105b77 100644
--- a/app/helpers/issuables_helper.rb
+++ b/app/helpers/issuables_helper.rb
@@ -430,7 +430,8 @@ module IssuablesHelper
editable: issuable.dig(:current_user, :can_edit),
currentUser: issuable[:current_user],
rootPath: root_path,
- fullPath: issuable[:project_full_path]
+ fullPath: issuable[:project_full_path],
+ timeTrackingLimitToHours: Gitlab::CurrentSettings.time_tracking_limit_to_hours
}
end
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 904d650ef96..cf328bcd994 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -82,6 +82,7 @@ module ApplicationSettingImplementation
throttle_unauthenticated_enabled: false,
throttle_unauthenticated_period_in_seconds: 3600,
throttle_unauthenticated_requests_per_period: 3600,
+ time_tracking_limit_to_hours: false,
two_factor_grace_period: 48,
unique_ips_limit_enabled: false,
unique_ips_limit_per_user: 10,
diff --git a/app/views/admin/application_settings/_localization.html.haml b/app/views/admin/application_settings/_localization.html.haml
index bb4d1fa1241..e01c123d1db 100644
--- a/app/views/admin/application_settings/_localization.html.haml
+++ b/app/views/admin/application_settings/_localization.html.haml
@@ -8,4 +8,11 @@
.form-text.text-muted
= _('Default first day of the week in calendars and date pickers.')
+ .form-group
+ = f.label :time_tracking, _('Time tracking'), class: 'label-bold'
+ .form-check
+ = f.check_box :time_tracking_limit_to_hours, class: 'form-check-input'
+ = f.label :time_tracking_limit_to_hours, class: 'form-check-label' do
+ = _('Limit display of time tracking units to hours.')
+
= f.submit _('Save changes'), class: "btn btn-success"
diff --git a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml
index b76d44c5907..43081499920 100644
--- a/app/views/shared/boards/components/sidebar/_time_tracker.html.haml
+++ b/app/views/shared/boards/components/sidebar/_time_tracker.html.haml
@@ -3,4 +3,5 @@
":time-spent" => "issue.timeSpent || 0",
":human-time-estimate" => "issue.humanTimeEstimate",
":human-time-spent" => "issue.humanTimeSpent",
+ ":limit-to-hours" => "timeTrackingLimitToHours",
"root-path" => "#{root_url}" }
diff --git a/app/views/shared/milestones/_sidebar.html.haml b/app/views/shared/milestones/_sidebar.html.haml
index b24075c7849..ced6af50501 100644
--- a/app/views/shared/milestones/_sidebar.html.haml
+++ b/app/views/shared/milestones/_sidebar.html.haml
@@ -93,7 +93,11 @@
= milestone.issues_visible_to_user(current_user).closed.count
.block
- #issuable-time-tracker{ data: { time_estimate: @milestone.total_issue_time_estimate, time_spent: @milestone.total_issue_time_spent, human_time_estimate: @milestone.human_total_issue_time_estimate, human_time_spent: @milestone.human_total_issue_time_spent } }
+ #issuable-time-tracker{ data: { time_estimate: @milestone.total_issue_time_estimate,
+ time_spent: @milestone.total_issue_time_spent,
+ human_time_estimate: @milestone.human_total_issue_time_estimate,
+ human_time_spent: @milestone.human_total_issue_time_spent,
+ limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s } }
// Fallback while content is loading
.title.hide-collapsed
= _('Time tracking')