Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
ef7b6de4
Commit
ef7b6de4
authored
Nov 17, 2016
by
Bryce Johnson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Break out PrettyTime from IssuableTimeTracker.
parent
82d7d431
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
214 additions
and
187 deletions
+214
-187
app/assets/javascripts/issuable_time_tracker.js.es6
app/assets/javascripts/issuable_time_tracker.js.es6
+12
-44
app/assets/javascripts/lib/utils/pretty_time.js.es6
app/assets/javascripts/lib/utils/pretty_time.js.es6
+67
-0
spec/javascripts/issuable_time_tracker_spec.js.es6
spec/javascripts/issuable_time_tracker_spec.js.es6
+0
-143
spec/javascripts/pretty_time_spec.js.es6
spec/javascripts/pretty_time_spec.js.es6
+135
-0
No files found.
app/assets/javascripts/issuable_time_tracker.js.es6
View file @
ef7b6de4
//= require vue
//= lib/utils/pretty_time
(() => {
const PrettyTime = gl.PrettyTime;
gl.IssuableTimeTracker = Vue.component('issuable-time-tracker', {
name: 'issuable-time-tracker',
props: ['time_estimate', 'time_spent', 'human_time_estimate', 'human_time_spent'],
...
...
@@ -29,25 +32,25 @@
/* Parsed time values */
parsedEstimate() {
return
this
.parseSeconds(this.time_estimate);
return
PrettyTime
.parseSeconds(this.time_estimate);
},
parsedSpent() {
return
this
.parseSeconds(this.time_spent);
return
PrettyTime
.parseSeconds(this.time_spent);
},
parsedRemaining() {
const diffSeconds = this.time_estimate - this.time_spent;
return
this
.parseSeconds(diffSeconds);
return
PrettyTime
.parseSeconds(diffSeconds);
},
/* Human readable time values */
estimatedPretty() {
return this.human_time_estimate ||
this
.stringifyTime(this.parsedEstimate);
return this.human_time_estimate ||
PrettyTime
.stringifyTime(this.parsedEstimate);
},
spentPretty() {
return this.human_time_spent ||
this
.stringifyTime(this.parsedSpent);
return this.human_time_spent ||
PrettyTime
.stringifyTime(this.parsedSpent);
},
remainingPretty() {
return
this
.stringifyTime(this.parsedRemaining);
return
PrettyTime
.stringifyTime(this.parsedRemaining);
},
remainingTooltipPretty() {
const prefix = this.diffMinutes < 0 ? 'Over by' : 'Time remaining:';
...
...
@@ -66,47 +69,12 @@
},
},
methods: {
secondsToMinutes(seconds) {
return Math.abs(seconds / 60);
},
parseSeconds(seconds) {
const DAYS_PER_WEEK = 5;
const HOURS_PER_DAY = 8;
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;
const timePeriodConstraints = {
weeks: MINUTES_PER_WEEK,
days: MINUTES_PER_DAY,
hours: MINUTES_PER_HOUR,
minutes: 1,
};
let unorderedMinutes = this.secondsToMinutes(seconds);
return _.mapObject(timePeriodConstraints, (minutesPerPeriod) => {
const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod);
unorderedMinutes -= (periodCount * minutesPerPeriod);
return periodCount;
});
},
abbreviateTime(value) {
return value.split(' ')
.filter(unitStr => unitStr.charAt(0) !== '0')[0];
},
toggleHelpState(show) {
this.displayHelp = show;
},
stringifyTime(obj) {
const reducedTime = _.reduce(obj, (memo, unitValue, unitName) => {
const isNonZero = !!unitValue;
return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)} ` : memo;
}, '').trim();
return reducedTime.length ? reducedTime : '0m';
},
abbreviateTime(timeStr) {
return PrettyTime.abbreviateTime(timeStr);
}
},
template: `
<div class='time-tracking-component-wrap' v-cloak>
...
...
app/assets/javascripts/lib/utils/pretty_time.js.es6
0 → 100644
View file @
ef7b6de4
(() => {
/*
* TODO: Make these methods more configurable (e.g. parseSeconds timePeriodContstraints,
* stringifyTime condensed or non-condensed, abbreviateTimelengths)
* */
class PrettyTime {
/*
* Accepts seconds (Number) and returns a timeObject: { weeks: #, days: #, hours: #, minutes: # }.
* Seconds can be negative or positive, zero or non-zero.
*/
static parseSeconds(seconds) {
const DAYS_PER_WEEK = 5;
const HOURS_PER_DAY = 8;
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;
const timePeriodConstraints = {
weeks: MINUTES_PER_WEEK,
days: MINUTES_PER_DAY,
hours: MINUTES_PER_HOUR,
minutes: 1,
};
let unorderedMinutes = PrettyTime.secondsToMinutes(seconds);
return _.mapObject(timePeriodConstraints, (minutesPerPeriod) => {
const periodCount = Math.floor(unorderedMinutes / minutesPerPeriod);
unorderedMinutes -= (periodCount * minutesPerPeriod);
return periodCount;
});
}
/*
* Accepts a timeObject and returns a condensed string representation of it
* (e.g. '1w 2d 3h 1m' or '1h 30m'). Zero value units are not included.
*/
static stringifyTime(timeObject) {
const reducedTime = _.reduce(timeObject, (memo, unitValue, unitName) => {
const isNonZero = !!unitValue;
return isNonZero ? `${memo} ${unitValue}${unitName.charAt(0)} ` : memo;
}, '').trim();
return reducedTime.length ? reducedTime : '0m';
}
/*
* Accepts a time string of any size (e.g. '1w 2d 3h 5m' or '1w 2d') and returns
* the first non-zero unit/value pair.
*/
static abbreviateTime(timeStr) {
return timeStr.split(' ')
.filter(unitStr => unitStr.charAt(0) !== '0')[0];
}
static secondsToMinutes(seconds) {
return Math.abs(seconds / 60);
}
}
gl.PrettyTime = PrettyTime;
})(window.gl || (window.gl = {}));
spec/javascripts/issuable_time_tracker_spec.js.es6
View file @
ef7b6de4
...
...
@@ -210,148 +210,5 @@ function initComponent(time_estimate = 100000, time_spent = 5000 ) {
});
});
});
describe('Internal Component Logic', function() {
describe('Computed Intermediaries', function() {
});
describe('Methods', function() {
beforeEach(function() {
initComponent.apply(this);
});
describe('parseSeconds', function() {
it('should correctly parse a negative value', function() {
const parser = this.timeTracker.parseSeconds;
const zeroSeconds = parser(-1000);
expect(zeroSeconds.minutes).toBe(16);
expect(zeroSeconds.hours).toBe(0);
expect(zeroSeconds.days).toBe(0);
expect(zeroSeconds.weeks).toBe(0);
});
it('should correctly parse a zero value', function() {
const parser = this.timeTracker.parseSeconds;
const zeroSeconds = parser(0);
expect(zeroSeconds.minutes).toBe(0);
expect(zeroSeconds.hours).toBe(0);
expect(zeroSeconds.days).toBe(0);
expect(zeroSeconds.weeks).toBe(0);
});
it('should correctly parse a small non-zero second values', function() {
const parser = this.timeTracker.parseSeconds;
const subOneMinute = parser(10);
expect(subOneMinute.minutes).toBe(0);
expect(subOneMinute.hours).toBe(0);
expect(subOneMinute.days).toBe(0);
expect(subOneMinute.weeks).toBe(0);
const aboveOneMinute = parser(100);
expect(aboveOneMinute.minutes).toBe(1);
expect(aboveOneMinute.hours).toBe(0);
expect(aboveOneMinute.days).toBe(0);
expect(aboveOneMinute.weeks).toBe(0);
const manyMinutes = parser(1000);
expect(manyMinutes.minutes).toBe(16);
expect(manyMinutes.hours).toBe(0);
expect(manyMinutes.days).toBe(0);
expect(manyMinutes.weeks).toBe(0);
});
it('should correctly parse large second values', function() {
const parser = this.timeTracker.parseSeconds;
const aboveOneHour = parser(4800);
expect(aboveOneHour.minutes).toBe(20);
expect(aboveOneHour.hours).toBe(1);
expect(aboveOneHour.days).toBe(0);
expect(aboveOneHour.weeks).toBe(0);
const aboveOneDay = parser(110000);
expect(aboveOneDay.minutes).toBe(33);
expect(aboveOneDay.hours).toBe(6);
expect(aboveOneDay.days).toBe(3);
expect(aboveOneDay.weeks).toBe(0);
const aboveOneWeek = parser(25000000);
expect(aboveOneWeek.minutes).toBe(26);
expect(aboveOneWeek.hours).toBe(0);
expect(aboveOneWeek.days).toBe(3);
expect(aboveOneWeek.weeks).toBe(173);
});
});
describe('stringifyTime', function() {
it('should stringify values with all non-zero units', function() {
const timeObject = {
weeks: 1,
days: 4,
hours: 7,
minutes: 20
};
const timeString = this.timeTracker.stringifyTime(timeObject);
expect(timeString).toBe('1w 4d 7h 20m');
});
it('should stringify values with some non-zero units', function() {
const timeObject = {
weeks: 0,
days: 4,
hours: 0,
minutes: 20
};
const timeString = this.timeTracker.stringifyTime(timeObject);
expect(timeString).toBe('4d 20m');
});
it('should stringify values with no non-zero units', function() {
const timeObject = {
weeks: 0,
days: 0,
hours: 0,
minutes: 0
};
const timeString = this.timeTracker.stringifyTime(timeObject);
expect(timeString).toBe('0m');
});
});
describe('abbreviateTime', function() {
it('should abbreviate stringified times for weeks', function() {
const fullTimeString = '1w 3d 4h 5m';
expect(this.timeTracker.abbreviateTime(fullTimeString)).toBe('1w');
});
it('should abbreviate stringified times for non-weeks', function() {
const fullTimeString = '0w 3d 4h 5m';
expect(this.timeTracker.abbreviateTime(fullTimeString)).toBe('3d');
});
});
});
});
});
})(window.gl || (window.gl = {}));
spec/javascripts/pretty_time_spec.js.es6
0 → 100644
View file @
ef7b6de4
//= require directives/tooltip_title
(() => {
const PrettyTime = gl.PrettyTime;
describe('PrettyTime methods', function() {
describe('parseSeconds', function() {
it('should correctly parse a negative value', function() {
const parser = PrettyTime.parseSeconds;
const zeroSeconds = parser(-1000);
expect(zeroSeconds.minutes).toBe(16);
expect(zeroSeconds.hours).toBe(0);
expect(zeroSeconds.days).toBe(0);
expect(zeroSeconds.weeks).toBe(0);
});
it('should correctly parse a zero value', function() {
const parser = PrettyTime.parseSeconds;
const zeroSeconds = parser(0);
expect(zeroSeconds.minutes).toBe(0);
expect(zeroSeconds.hours).toBe(0);
expect(zeroSeconds.days).toBe(0);
expect(zeroSeconds.weeks).toBe(0);
});
it('should correctly parse a small non-zero second values', function() {
const parser = PrettyTime.parseSeconds;
const subOneMinute = parser(10);
expect(subOneMinute.minutes).toBe(0);
expect(subOneMinute.hours).toBe(0);
expect(subOneMinute.days).toBe(0);
expect(subOneMinute.weeks).toBe(0);
const aboveOneMinute = parser(100);
expect(aboveOneMinute.minutes).toBe(1);
expect(aboveOneMinute.hours).toBe(0);
expect(aboveOneMinute.days).toBe(0);
expect(aboveOneMinute.weeks).toBe(0);
const manyMinutes = parser(1000);
expect(manyMinutes.minutes).toBe(16);
expect(manyMinutes.hours).toBe(0);
expect(manyMinutes.days).toBe(0);
expect(manyMinutes.weeks).toBe(0);
});
it('should correctly parse large second values', function() {
const parser = PrettyTime.parseSeconds;
const aboveOneHour = parser(4800);
expect(aboveOneHour.minutes).toBe(20);
expect(aboveOneHour.hours).toBe(1);
expect(aboveOneHour.days).toBe(0);
expect(aboveOneHour.weeks).toBe(0);
const aboveOneDay = parser(110000);
expect(aboveOneDay.minutes).toBe(33);
expect(aboveOneDay.hours).toBe(6);
expect(aboveOneDay.days).toBe(3);
expect(aboveOneDay.weeks).toBe(0);
const aboveOneWeek = parser(25000000);
expect(aboveOneWeek.minutes).toBe(26);
expect(aboveOneWeek.hours).toBe(0);
expect(aboveOneWeek.days).toBe(3);
expect(aboveOneWeek.weeks).toBe(173);
});
});
describe('stringifyTime', function() {
it('should stringify values with all non-zero units', function() {
const timeObject = {
weeks: 1,
days: 4,
hours: 7,
minutes: 20
};
const timeString = PrettyTime.stringifyTime(timeObject);
expect(timeString).toBe('1w 4d 7h 20m');
});
it('should stringify values with some non-zero units', function() {
const timeObject = {
weeks: 0,
days: 4,
hours: 0,
minutes: 20
};
const timeString = PrettyTime.stringifyTime(timeObject);
expect(timeString).toBe('4d 20m');
});
it('should stringify values with no non-zero units', function() {
const timeObject = {
weeks: 0,
days: 0,
hours: 0,
minutes: 0
};
const timeString = PrettyTime.stringifyTime(timeObject);
expect(timeString).toBe('0m');
});
});
describe('abbreviateTime', function() {
it('should abbreviate stringified times for weeks', function() {
const fullTimeString = '1w 3d 4h 5m';
expect(PrettyTime.abbreviateTime(fullTimeString)).toBe('1w');
});
it('should abbreviate stringified times for non-weeks', function() {
const fullTimeString = '0w 3d 4h 5m';
expect(PrettyTime.abbreviateTime(fullTimeString)).toBe('3d');
});
});
});
})(window.gl || (window.gl = {}));
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment