Skip to content

Commit

Permalink
Merge pull request #872 from knsv/feature/allow-inclusive-enddates
Browse files Browse the repository at this point in the history
Feature/allow inclusive enddates
  • Loading branch information
knsv authored Jul 12, 2019
2 parents 86f430f + c6511ed commit 3b41ba9
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 95 deletions.
20 changes: 20 additions & 0 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo=">
</head>
<body>
<div class="mermaid">
gantt
title Exclusive end dates (Manual date should end on 3d)
dateFormat YYYY-MM-DD
axisFormat %d
section Section1
2 Days: 1, 2019-01-01,2d
Manual Date: 2, 2019-01-01,2019-01-03
</div>

<div class="mermaid">
gantt
title Inclusive end dates (Manual date should end on 4th)
dateFormat YYYY-MM-DD
axisFormat %d
inclusiveEndDates
section Section1
2 Days: 1, 2019-01-01,2d
Manual Date: 2, 2019-01-01,2019-01-03
</div>
<div class="mermaid">
graph LR
sid-B3655226-6C29-4D00-B685-3D5C734DC7E1["
Expand Down
87 changes: 62 additions & 25 deletions src/diagrams/gantt/ganttDb.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ let tasks = []
let currentSection = ''
const tags = ['active', 'done', 'crit', 'milestone']
let funs = []
let inclusiveEndDates = false

export const clear = function () {
sections = []
Expand All @@ -22,6 +23,10 @@ export const clear = function () {
lastTask = undefined
lastTaskID = undefined
rawTasks = []
dateFormat = ''
axisFormat = ''
excludes = []
inclusiveEndDates = false
}

export const setAxisFormat = function (txt) {
Expand All @@ -36,10 +41,26 @@ export const setDateFormat = function (txt) {
dateFormat = txt
}

export const enableInclusiveEndDates = function () {
inclusiveEndDates = true
}

export const endDatesAreInclusive = function () {
return inclusiveEndDates
}

export const getDateFormat = function () {
return dateFormat
}

export const setExcludes = function (txt) {
excludes = txt.toLowerCase().split(/[\s,]+/)
}

export const getExcludes = function () {
return excludes
}

export const setTitle = function (txt) {
title = txt
}
Expand All @@ -53,6 +74,10 @@ export const addSection = function (txt) {
sections.push(txt)
}

export const getSections = function () {
return sections
}

export const getTasks = function () {
let allItemsPricessed = compileTasks()
const maxDepth = 10
Expand Down Expand Up @@ -134,41 +159,47 @@ const getStartDate = function (prevTime, dateFormat, str) {
return new Date()
}

const getEndDate = function (prevTime, dateFormat, str) {
str = str.trim()

// Check for actual date
let mDate = moment(str, dateFormat.trim(), true)
if (mDate.isValid()) {
return mDate.toDate()
}

const d = moment(prevTime)
// Check for length
const re = /^([\d]+)([wdhms])/
const durationStatement = re.exec(str.trim())

const durationToDate = function (durationStatement, relativeTime) {
if (durationStatement !== null) {
switch (durationStatement[2]) {
case 's':
d.add(durationStatement[1], 'seconds')
relativeTime.add(durationStatement[1], 'seconds')
break
case 'm':
d.add(durationStatement[1], 'minutes')
relativeTime.add(durationStatement[1], 'minutes')
break
case 'h':
d.add(durationStatement[1], 'hours')
relativeTime.add(durationStatement[1], 'hours')
break
case 'd':
d.add(durationStatement[1], 'days')
relativeTime.add(durationStatement[1], 'days')
break
case 'w':
d.add(durationStatement[1], 'weeks')
relativeTime.add(durationStatement[1], 'weeks')
break
}
}
// Default date - now
return d.toDate()
return relativeTime.toDate()
}

const getEndDate = function (prevTime, dateFormat, str, inclusive) {
inclusive = inclusive || false
str = str.trim()

// Check for actual date
let mDate = moment(str, dateFormat.trim(), true)
if (mDate.isValid()) {
if (inclusive) {
mDate.add(1, 'd')
}
return mDate.toDate()
}

return durationToDate(
/^([\d]+)([wdhms])/.exec(str.trim()),
moment(prevTime)
)
}

let taskCnt = 0
Expand Down Expand Up @@ -231,8 +262,8 @@ const compileData = function (prevTask, dataStr) {
}

if (endTimeData) {
task.endTime = getEndDate(task.startTime, dateFormat, endTimeData)
task.manualEndTime = endTimeData === moment(task.endTime).format(dateFormat.trim())
task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates)
task.manualEndTime = moment(endTimeData, 'YYYY-MM-DD', true).isValid()
checkTaskDates(task, dateFormat, excludes)
}

Expand Down Expand Up @@ -370,10 +401,10 @@ const compileTasks = function () {
}

if (rawTasks[pos].startTime) {
rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, rawTasks[pos].raw.endTime.data)
rawTasks[pos].endTime = getEndDate(rawTasks[pos].startTime, dateFormat, rawTasks[pos].raw.endTime.data, inclusiveEndDates)
if (rawTasks[pos].endTime) {
rawTasks[pos].processed = true
rawTasks[pos].manualEndTime = rawTasks[pos].raw.endTime.data === moment(rawTasks[pos].endTime).format(dateFormat.trim())
rawTasks[pos].manualEndTime = moment(rawTasks[pos].raw.endTime.data, 'YYYY-MM-DD', true).isValid()
checkTaskDates(rawTasks[pos], dateFormat, excludes)
}
}
Expand Down Expand Up @@ -495,19 +526,25 @@ export const bindFunctions = function (element) {
export default {
clear,
setDateFormat,
getDateFormat,
enableInclusiveEndDates,
endDatesAreInclusive,
setAxisFormat,
getAxisFormat,
setTitle,
getTitle,
addSection,
getSections,
getTasks,
addTask,
findTaskById,
addTaskOrg,
setExcludes,
getExcludes,
setClickEvent,
setLink,
bindFunctions
bindFunctions,
durationToDate
}

function getTaskTags (data, task, tags) {
Expand Down
58 changes: 58 additions & 0 deletions src/diagrams/gantt/ganttDb.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,41 @@ describe('when using the ganttDb', function () {
ganttDb.clear()
})

describe('when using relative times', function () {
it.each`
diff | date | expected
${' 1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()}
${' 1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()}
`('should add $diff to $date resulting in $expected', ({ diff, date, expected }) => {
expect(ganttDb.durationToDate(diff, date)).toEqual(expected)
})
})

describe('when calling the clear function', function () {
beforeEach(function () {
ganttDb.setDateFormat('YYYY-MM-DD')
ganttDb.enableInclusiveEndDates()
ganttDb.setExcludes('weekends 2019-02-06,friday')
ganttDb.addSection('weekends skip test')
ganttDb.addTask('test1', 'id1,2019-02-01,1d')
ganttDb.addTask('test2', 'id2,after id1,2d')
ganttDb.clear()
})

it.each`
fn | expected
${'getTasks'} | ${[]}
${'getTitle'} | ${''}
${'getDateFormat'} | ${''}
${'getAxisFormat'} | ${''}
${'getExcludes'} | ${[]}
${'getSections'} | ${[]}
${'endDatesAreInclusive'} | ${false}
`('should clear $fn', ({ fn, expected }) => {
expect(ganttDb[ fn ]()).toEqual(expected)
})
})

it.each`
testName | section | taskName | taskData | expStartDate | expEndDate | expId | expTask
${'should handle fixed dates'} | ${'testa1'} | ${'test1'} | ${'id1,2013-01-01,2013-01-12'} | ${new Date(2013, 0, 1)} | ${new Date(2013, 0, 12)} | ${'id1'} | ${'test1'}
Expand Down Expand Up @@ -125,4 +160,27 @@ describe('when using the ganttDb', function () {
expect(tasks[6].id).toEqual('id7')
expect(tasks[6].task).toEqual('test7')
})

describe('when setting inclusive end dates', function () {
beforeEach(function () {
ganttDb.setDateFormat('YYYY-MM-DD')
ganttDb.enableInclusiveEndDates()
ganttDb.addTask('test1', 'id1,2019-02-01,1d')
ganttDb.addTask('test2', 'id2,2019-02-01,2019-02-03')
})
it('should automatically add one day to all end dates', function () {
const tasks = ganttDb.getTasks()
expect(tasks[0].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
expect(tasks[0].endTime).toEqual(moment('2019-02-02', 'YYYY-MM-DD').toDate())
expect(tasks[0].id).toEqual('id1')
expect(tasks[0].task).toEqual('test1')

expect(tasks[1].startTime).toEqual(moment('2019-02-01', 'YYYY-MM-DD').toDate())
expect(tasks[1].endTime).toEqual(moment('2019-02-04', 'YYYY-MM-DD').toDate())
expect(tasks[1].renderEndTime).toBeNull() // Fixed end
expect(tasks[1].manualEndTime).toBeTruthy()
expect(tasks[1].id).toEqual('id2')
expect(tasks[1].task).toEqual('test2')
})
})
})
8 changes: 5 additions & 3 deletions src/diagrams/gantt/parser/gantt.jison
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ that id.

"gantt" return 'gantt';
"dateFormat"\s[^#\n;]+ return 'dateFormat';
"inclusiveEndDates" return 'inclusiveEndDates';
"axisFormat"\s[^#\n;]+ return 'axisFormat';
"excludes"\s[^#\n;]+ return 'excludes';
\d\d\d\d"-"\d\d"-"\d\d return 'date';
Expand Down Expand Up @@ -91,9 +92,10 @@ line
;

statement
: 'dateFormat' {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
| 'axisFormat' {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
| 'excludes' {yy.setExcludes($1.substr(9));$$=$1.substr(9);}
: dateFormat {yy.setDateFormat($1.substr(11));$$=$1.substr(11);}
| inclusiveEndDates {yy.enableInclusiveEndDates();$$=$1.substr(18);}
| axisFormat {yy.setAxisFormat($1.substr(11));$$=$1.substr(11);}
| excludes {yy.setExcludes($1.substr(9));$$=$1.substr(9);}
| title {yy.setTitle($1.substr(6));$$=$1.substr(6);}
| section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| clickStatement
Expand Down
Loading

0 comments on commit 3b41ba9

Please sign in to comment.