Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@strategies/react-timeline",
"version": "1.2.5",
"version": "1.3.1",
"description": "A timeline component for React",
"author": "Eric Youngberg <eyoungberg@sasaki.com>",
"repository": "https://github.com/sasakiassociates/react-timeline",
Expand Down Expand Up @@ -52,8 +52,7 @@
"react-dom": "^18.2.0"
},
"dependencies": {
"@strategies/tokens": "^4.0.29",
"@strategies/ui": "^2.4.19",
"@strategies/tokens": "^4.0.36",
"react-icons": "^5.3.0",
"uuid": "^8.3.2"
}
Expand Down
5,992 changes: 1,387 additions & 4,605 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

7 changes: 3 additions & 4 deletions src/components/Block/Block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import BlockState from '../../models/BlockState';
import BlockProxy from '../../models/BlockProxy';
import Action, { Actions } from '../../models/Action';

import { BaseIcon, Sizes, States } from '@strategies/ui';
import {
PiGitCommitBold,
PiLeafBold,
Expand Down Expand Up @@ -165,11 +164,11 @@ export default observer(function Block(props: BlockProps) {
</>
) : <></>}

{(block.projects_on_requiredByProject.length > 0) && <span
{((block.projects_on_requiredByProject.length > 0) || (block.projects_on_requiresProject.length > 0)) && <span
className='ReactTimeline__Block-dependency'
style={{left: '10px', top: '25%'}} // TODO this is very manual I know ...
style={{left: '10px', top: '0'}} // TODO this is very manual I know ...
>
<BaseIcon size={Sizes.XSMALL} icon={<PiGitCommitBold />} />
<PiGitCommitBold />
</span>}
<div className="ReactTimeline__Block-content" onMouseDown={e => onMouseDown(e)} />

Expand Down
9 changes: 7 additions & 2 deletions src/components/Editor/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ export default observer(function Editor({ children }: EditorProps) {
{blocks.groupNames.map((name)=>(
<>
{name !== 'nan' &&
<span className='ReactTimeline__Editor--blocks--GroupLabel' style={{
<>
<span className='ReactTimeline__Editor--blocks--GroupLabel' style={{
'left': ( blocks.extentByGroupName[name]) ? blocks.extentByGroupName[name]['style']['left'] : 0,
'top': (blocks.extentByGroupName[name]) ? blocks.extentByGroupName[name]['style']['top']: 0,
'position':'absolute',
Expand All @@ -168,7 +169,7 @@ export default observer(function Editor({ children }: EditorProps) {
}}>
{name}
</span>
}

<span
className='ReactTimeline__Editor--blocks--GroupBorder'
style={{// @ts-ignore
Expand All @@ -182,6 +183,10 @@ export default observer(function Editor({ children }: EditorProps) {
'position':'absolute'
}}
></span>
</>


}
</>
))}
</>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Timeline/Timeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default observer(function Timeline(props: TimelineProps) {
context.blocks.setGroupBy(undefined)
if (groupBy) {
context.blocks.setGroupBy(groupBy['fieldName'])
context.blocks.all.forEach((block)=>{ //@ts-ignore
context.blocks.all.forEach((block)=>{
block.setGroupName(undefined)
})
context.blocks.all.forEach((block)=>{ //@ts-ignore
Expand Down
6 changes: 6 additions & 0 deletions src/models/BlockState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ export default class BlockState {
this.proxy.setProjects_on_requiresProject(projects_on_requiresProject)
}

@computed
get projects_on_requiresProject() {
return this.proxy.projects_on_requiresProject;
}


@observable
groupName: string

Expand Down
135 changes: 105 additions & 30 deletions src/stores/BlocksStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,40 +164,115 @@ export default class BlockStore {
sortByGroup() {
const timelineBlockHeight = config.blockHeight; // px
const timelineRowPadding = config.rowPadding; // px
const timelineBlockGroupPadding = config.blockHeight * 4; // px

const timelineBlockGroupPadding = config.blockHeight * 3; // px
if (this.sortingPrevented) return;
if (this.groupBy){
const groupd: {[key:string]: BlockState[]} = this.sortDefault.reduce((reslt,blck)=>{
if (Object.keys(reslt).includes(blck[this.groupBy])) {
reslt[blck[this.groupBy]].push(blck)
} else {
blck.setGroupName(blck[this.groupBy])
reslt[blck[this.groupBy]] = [blck]
}
return reslt
}, {})
if (this.root.spaces.customSpaces && this.root.spaces.customSpaces.length > 0) {
this.root.spaces.customSpaces.forEach((spaceCustom)=>{
const space = spaceCustom['spaces']
let _i = 0
let _i_p = 0
Object.keys(space).forEach((spcValue, ii)=>{
const phaseBlocks = this.sortDefault.filter((block)=>{
//@ts-ignore
return block.proxy.project[spaceCustom['blockSpaceFieldName']] === spcValue
})

const phaseHeightLength = phaseBlocks.length;
const inGroupPhaseBlocks = phaseBlocks.filter((blk)=>{
return blk[this.groupBy] !== 'nan';
})

const outGroupPhaseBlocks = phaseBlocks.filter((blk)=>{
return blk[this.groupBy] === 'nan';
})
const ingroupLength = inGroupPhaseBlocks.length
const ungroupLength = outGroupPhaseBlocks.length
const groupd: {[key:string]: BlockState[]} = inGroupPhaseBlocks.reduce((reslt,blck)=>{
if (Object.keys(reslt).includes(blck[this.groupBy])) {
reslt[blck[this.groupBy]].push(blck)
} else {
blck.setGroupName(blck[this.groupBy])
reslt[blck[this.groupBy]] = [blck]
}
return reslt
}, {})



const sortedGroup = Object.keys(groupd)
// .sort((a:string, b:string)=> {
// // this is to make sure groups that have starting time earlier show up higher in the time line (requested by uncle TayTay)
// // if decided against it just make it a pure sort() here
// const a_first_block = Math.min(...groupd[a].map((blc)=>blc.timespan.start))
// const b_first_block = Math.min(...groupd[b].map((blc)=>blc.timespan.start))
// return (a_first_block > b_first_block) ? 1 : -1

let _i = 0
const sortedGroup = Object.keys(groupd).sort((a:string, b:string)=> {
// this is to make sure groups that have starting time earlier show up higher in the time line (requested by uncle TayTay)
// if decided against it just make it a pure sort() here
const a_first_block = Math.min(...groupd[a].map((blc)=>blc.timespan.start))
const b_first_block = Math.min(...groupd[b].map((blc)=>blc.timespan.start))
return (a_first_block > b_first_block) ? 1 : -1

}).reduce(function (result, key) {
result[key] = groupd[key];
return result;
}, {});

Object.keys(sortedGroup).forEach((grp, g_i)=>{
const grp_len = sortedGroup[grp].length
sortedGroup[grp].sort((a, b)=> this.sortBlocks(a, b)).forEach((block, i)=>{
block.setY((_i * (timelineBlockHeight + timelineRowPadding) )+ ((i ) * (timelineBlockHeight + timelineRowPadding)) + ((g_i ) * timelineBlockGroupPadding))
// })
.sort()
.reduce(function (result, key) {
result[key] = groupd[key];
return result;
}, {});
Object.keys(sortedGroup).forEach((grp, g_i)=>{
const grp_len = sortedGroup[grp].length
sortedGroup[grp].sort((a, b)=> this.sortBlocks(a, b)).forEach((block, i)=>{
block.setY(( _i * (timelineBlockHeight + timelineRowPadding) )+ ((i ) * (timelineBlockHeight + timelineRowPadding)) + ((_i_p + g_i) * timelineBlockGroupPadding))
})
_i = _i + grp_len
})
_i_p = _i_p + Object.keys(sortedGroup).length;
outGroupPhaseBlocks.sort((a, b)=> this.sortBlocks(a, b)).forEach((block, ui)=>{
block.setY( (_i * (timelineBlockHeight + timelineRowPadding) )+ (_i_p * timelineBlockGroupPadding) + ((ui) * (timelineBlockHeight + timelineRowPadding)))

})
_i_p = _i_p + 1
_i = _i + ungroupLength;
})



})
} else { // this is when there is a groupby but there is no custom spacing (phasing ...)
let _gi = 0
const groupd: {[key:string]: BlockState[]} = this.sortDefault.reduce((reslt,blck)=>{
if (Object.keys(reslt).includes(blck[this.groupBy])) {
reslt[blck[this.groupBy]].push(blck)
} else {
blck.setGroupName(blck[this.groupBy])
reslt[blck[this.groupBy]] = [blck]
}
return reslt
}, {})



const sortedGroup = Object.keys(groupd)
// .sort((a:string, b:string)=> {
// // this is to make sure groups that have starting time earlier show up higher in the time line (requested by uncle TayTay)
// // if decided against it just make it a pure sort() here
// const a_first_block = Math.min(...groupd[a].map((blc)=>blc.timespan.start))
// const b_first_block = Math.min(...groupd[b].map((blc)=>blc.timespan.start))
// return (a_first_block > b_first_block) ? 1 : -1

// })
.sort()
.reduce(function (result, key) {
result[key] = groupd[key];
return result;
}, {});
Object.keys(sortedGroup).forEach((grp, g_ig)=>{
const ggrp_len = sortedGroup[grp].length
sortedGroup[grp].sort((a, b)=> this.sortBlocks(a, b)).forEach((block, i__)=>{
block.setY(( _gi * (timelineBlockHeight + timelineRowPadding) )+ ((i__) * (timelineBlockHeight + timelineRowPadding)) + ((g_ig) * timelineBlockGroupPadding))
})
_gi = _gi + ggrp_len
})
_i = _i + grp_len
})


}

} else {
// if no groupby is passed just go by default
this.sortDefault.forEach((_block, __i)=>{
Expand Down
4 changes: 2 additions & 2 deletions src/stores/SpacesStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ export default class SpacesStore {
const offset = (this.root.ui.width / this.root.viewport.width / time.YEAR) * (1 - (time.YEAR - (viewport.left % time.YEAR)) / time.YEAR);

if (this.customSpaces) this.customSpaces.forEach((cs)=>{
Object.keys(cs).forEach((k,i)=>{
const time_span = cs[k]
Object.keys(cs['spaces']).forEach((k,i)=>{
const time_span = cs['spaces'][k]
const span_start_sec = (time_span[0] - this.startYear) * time.YEAR
const span_end_sec = (time_span[1] - this.startYear) * time.YEAR
const span_start_px = this.timeToPx(+span_start_sec)
Expand Down