project sub-timeline: event dots on bars, click to add event, + Event shortcut
This commit is contained in:
@@ -635,6 +635,24 @@
|
|||||||
font:italic 1rem/1.6 var(--serif); color:var(--paper);
|
font:italic 1rem/1.6 var(--serif); color:var(--paper);
|
||||||
}
|
}
|
||||||
.truth-item-text { flex:1; }
|
.truth-item-text { flex:1; }
|
||||||
|
/* Project bar event dots + click zone */
|
||||||
|
.tl-project-evt-dot {
|
||||||
|
position: absolute;
|
||||||
|
width: 9px; height: 9px;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 50%; transform: translate(-50%, -50%);
|
||||||
|
z-index: 3; cursor: pointer;
|
||||||
|
border: 1.5px solid rgba(23,21,19,.7);
|
||||||
|
transition: transform .1s;
|
||||||
|
}
|
||||||
|
.tl-project-evt-dot.light { background: var(--brass); }
|
||||||
|
.tl-project-evt-dot.dark { background: var(--rust); }
|
||||||
|
.tl-project-evt-dot:hover { transform: translate(-50%, -50%) scale(1.5); }
|
||||||
|
.tl-bar-add-overlay {
|
||||||
|
position: absolute; top: 0; bottom: 0;
|
||||||
|
z-index: 2; cursor: crosshair; background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.project-events {
|
.project-events {
|
||||||
margin-top:.8rem; padding-top:.8rem; border-top:1px solid var(--line);
|
margin-top:.8rem; padding-top:.8rem; border-top:1px solid var(--line);
|
||||||
}
|
}
|
||||||
@@ -830,7 +848,7 @@
|
|||||||
<div class="tl-sublabel">Projects</div>
|
<div class="tl-sublabel">Projects</div>
|
||||||
<div class="tl-rows">
|
<div class="tl-rows">
|
||||||
<template x-for="item in projects()" :key="item.id">
|
<template x-for="item in projects()" :key="item.id">
|
||||||
<div class="tl-row">
|
<div class="tl-row" style="height:26px">
|
||||||
<a
|
<a
|
||||||
class="tl-bar project-bar"
|
class="tl-bar project-bar"
|
||||||
:class="[item.mood || (game && game.mood), !item.end_date ? 'open-right' : '']"
|
:class="[item.mood || (game && game.mood), !item.end_date ? 'open-right' : '']"
|
||||||
@@ -841,6 +859,20 @@
|
|||||||
>
|
>
|
||||||
<span class="tl-bar-text" x-text="item.title"></span>
|
<span class="tl-bar-text" x-text="item.title"></span>
|
||||||
</a>
|
</a>
|
||||||
|
<!-- Crosshair zone: click to add event at that date (edit mode) -->
|
||||||
|
<div x-show="editMode"
|
||||||
|
class="tl-bar-add-overlay"
|
||||||
|
:style="`left:${posPercent(item.date)}%;width:${barWidth(item.date,item.end_date)}%`"
|
||||||
|
@click="openAddEventToProject(item, $event)"></div>
|
||||||
|
<!-- Event dots for this project -->
|
||||||
|
<template x-for="ev in eventsForProject(item.id)" :key="ev.id">
|
||||||
|
<a class="tl-project-evt-dot"
|
||||||
|
:class="ev.mood || (game && game.mood) || 'light'"
|
||||||
|
:style="`left:${posPercent(ev.date)}%`"
|
||||||
|
:href="'#entry-' + ev.id"
|
||||||
|
:title="ev.title + ' — ' + ev.date"
|
||||||
|
@click.stop></a>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -957,6 +989,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="entry-actions" x-show="editMode">
|
<div class="entry-actions" x-show="editMode">
|
||||||
|
<button class="btn sm" @click="openAddEventToProject(item, null)">+ Event</button>
|
||||||
<button class="btn sm ghost" @click="openEditItem(item)">Edit</button>
|
<button class="btn sm ghost" @click="openEditItem(item)">Edit</button>
|
||||||
<button class="btn sm danger" @click="deleteItem(item.id)">Delete</button>
|
<button class="btn sm danger" @click="deleteItem(item.id)">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -2075,6 +2108,29 @@
|
|||||||
return result.sort((a, b) => a.term.localeCompare(b.term))
|
return result.sort((a, b) => a.term.localeCompare(b.term))
|
||||||
},
|
},
|
||||||
|
|
||||||
|
openAddEventToProject(project, clickEvent) {
|
||||||
|
const env = this.randomEnv(project.discipline)
|
||||||
|
this.activeForm = {
|
||||||
|
type: 'event', title: '', description: '',
|
||||||
|
mood: project.mood || '', date: '', end_date: '',
|
||||||
|
status: 'active', discipline: project.discipline || '',
|
||||||
|
env, env_layout: env ? this.randomEnvLayout() : 'after',
|
||||||
|
project_id: project.id
|
||||||
|
}
|
||||||
|
// Calculate date from click position on the bar
|
||||||
|
if (clickEvent) {
|
||||||
|
const rect = clickEvent.currentTarget.getBoundingClientRect()
|
||||||
|
const pct = Math.max(0, Math.min(100, ((clickEvent.clientX - rect.left) / rect.width) * 100))
|
||||||
|
const start = new Date(project.date).getTime()
|
||||||
|
const end = new Date(project.end_date || (this.game && this.game.timeline_end)).getTime()
|
||||||
|
this.activeForm.date = new Date(Math.round(start + (pct / 100) * (end - start))).toISOString().split('T')[0]
|
||||||
|
}
|
||||||
|
this.editingId = null
|
||||||
|
this.formError = null
|
||||||
|
this.modalType = 'item'
|
||||||
|
this.showModal = true
|
||||||
|
},
|
||||||
|
|
||||||
eventsForProject(projectId) {
|
eventsForProject(projectId) {
|
||||||
return this.events().filter(e => e.project_id === projectId)
|
return this.events().filter(e => e.project_id === projectId)
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user