feat: enhance team planning and deployment
Test and publish / verify (push) Successful in 2m45s

This commit is contained in:
2026-07-29 12:09:21 +03:30
parent c3083b137f
commit eba6b3565c
10 changed files with 472 additions and 22 deletions
+46
View File
@@ -2,6 +2,24 @@
{{template "shell-start" .}}
<header class="page-head board-page-head">
<div><p class="eyebrow">SHARED WORKSPACE</p><h1>Team board</h1><p>Plan, assign, and move work forward together.</p></div>
<div class="board-head-actions">
<details class="tag-manager-panel">
<summary class="button secondary">◉ Manage tags</summary>
<div class="tag-manager">
<div><p class="eyebrow">BOARD LABELS</p><h2>Tag manager</h2><p>Create reusable labels for every card.</p></div>
<form method="post" action="/board/tags" class="tag-create-form">
<input type="hidden" name="csrf" value="{{.CSRF}}">
<label>Tag name<input name="name" required maxlength="40" placeholder="e.g. Backend"></label>
<label>Color<select name="color"><option value="green">Green</option><option value="blue">Blue</option><option value="red">Red</option><option value="amber">Amber</option><option value="purple">Purple</option><option value="slate">Slate</option></select></label>
<button class="button primary" type="submit">Add tag</button>
</form>
<div class="tag-manager-list">
{{range .BoardTags}}
<div><span class="board-tag {{.Color}}">{{.Name}}</span><details class="tag-delete"><summary>Delete</summary><form method="post" action="/board/tags/{{.ID}}/delete"><input type="hidden" name="csrf" value="{{$.CSRF}}"><button class="text-button" type="submit">Confirm</button></form></details></div>
{{else}}<p>No tags yet. Create the first one above.</p>{{end}}
</div>
</div>
</details>
<details class="new-task-panel" {{if .Error}}open{{end}}>
<summary class="button primary"> Add task</summary>
<form method="post" action="/board/tasks" class="new-task-form">
@@ -9,6 +27,21 @@
<div class="new-task-form-head"><div><p class="eyebrow">NEW CARD</p><h2>Add work to the board</h2></div></div>
<label>Task title<input name="title" required maxlength="160" autofocus placeholder="What needs to be done?"></label>
<label>Description <small>Optional</small><textarea name="description" rows="4" maxlength="4000" placeholder="Add context, acceptance criteria, or links…"></textarea></label>
<fieldset class="card-tag-picker">
<legend>Tags <small>Optional · select multiple</small></legend>
<div class="tag-options">
{{range .BoardTags}}<label><input type="checkbox" name="tag_ids" value="{{.ID}}"><span class="board-tag {{.Color}}">{{.Name}}</span></label>
{{else}}<p class="tag-picker-empty">No tags yet. Create the first one below.</p>{{end}}
</div>
<details class="inline-tag-creator">
<summary> Create a new tag</summary>
<div class="inline-tag-fields">
<label>Tag name<input name="new_tag_name" maxlength="40" placeholder="e.g. Backend"></label>
<label>Color<select name="new_tag_color"><option value="green">Green</option><option value="blue">Blue</option><option value="red">Red</option><option value="amber">Amber</option><option value="purple">Purple</option><option value="slate">Slate</option></select></label>
</div>
<small>The new tag will be created and added to this card.</small>
</details>
</fieldset>
<div class="form-row">
<label>Assignee<select name="assignee_id"><option value="">Unassigned</option>{{range .Users}}<option value="{{.ID}}">{{.DisplayName}}</option>{{end}}</select></label>
<label>Column<select name="status"><option value="backlog">Backlog</option><option value="in_progress">In progress</option><option value="blocked">Blocked</option><option value="done">Done</option></select></label>
@@ -17,6 +50,7 @@
<button class="button dark full" type="submit">Create task</button>
</form>
</details>
</div>
</header>
{{template "notice" .}}
@@ -29,7 +63,9 @@
</header>
<div class="kanban-cards" data-drop-zone="{{.Status}}">
{{range .Tasks}}
{{$task := .}}
<article class="kanban-card" draggable="true" data-task-id="{{.ID}}">
{{if .Tags}}<div class="card-tags">{{range .Tags}}<span class="board-tag {{.Color}}">{{.Name}}</span>{{end}}</div>{{end}}
<div class="card-topline"><span class="task-id">#{{.ID}}</span>{{if .DueDate}}<span class="task-due">Due {{dateFA .DueDate}}</span>{{end}}</div>
<h3>{{.Title}}</h3>
{{if .Description}}<p>{{.Description}}</p>{{end}}
@@ -37,6 +73,16 @@
{{if .AssigneeID.Valid}}<span class="task-assignee"><i class="avatar">{{initial .AssigneeName}}</i><span>{{.AssigneeName}}</span></span>{{else}}<span class="task-assignee unassigned"><i>?</i><span>Unassigned</span></span>{{end}}
<span class="task-creator">by {{.CreatorName}}</span>
</div>
{{if $.BoardTags}}
<details class="card-tag-editor">
<summary>Labels</summary>
<form method="post" action="/board/tasks/{{.ID}}/tags">
<input type="hidden" name="csrf" value="{{$.CSRF}}">
<div>{{range $.BoardTags}}<label><input type="checkbox" name="tag_ids" value="{{.ID}}" {{if hasTag $task.Tags .ID}}checked{{end}}><span class="board-tag {{.Color}}">{{.Name}}</span></label>{{end}}</div>
<button class="button primary full" type="submit">Save labels</button>
</form>
</details>
{{end}}
<div class="task-actions">
<form method="post" action="/board/tasks/{{.ID}}/move">
<input type="hidden" name="csrf" value="{{$.CSRF}}">
+1 -1
View File
@@ -17,7 +17,7 @@
<div class="calendar-grid days">
{{range .Calendar.Cells}}
{{if .InMonth}}
<a href="/day?date={{.Gregorian}}" class="day {{if .IsToday}}today{{end}} {{if .IsFriday}}friday{{end}} {{if .Holiday}}holiday{{end}}" title="View team details for this day">
<a href="/day?date={{.Gregorian}}&view=day" class="day {{if .IsToday}}today{{end}} {{if .IsFriday}}friday{{end}} {{if .Holiday}}holiday{{end}}" title="View team details for this day">
<span class="day-number">{{.Day}}</span>
{{if .Status}}<i class="status-dot {{.Status}}" title="{{.Status}}"></i>{{end}}
{{if .Holiday}}<small title="{{.Holiday}}">{{.Holiday}}</small>{{end}}
+5 -5
View File
@@ -8,11 +8,11 @@
</div>
<div class="day-view-controls">
<nav class="view-switch" aria-label="Schedule view">
<a href="/day?date={{.Day.Jalali}}" class="{{if not .Week.Enabled}}active{{end}}">Day</a>
<a href="/day?date={{.Day.Jalali}}&view=day" class="{{if not .Week.Enabled}}active{{end}}">Day</a>
<a href="/day?date={{.Day.Jalali}}&view=week" class="{{if .Week.Enabled}}active{{end}}">Week</a>
</nav>
<form method="get" action="/day" class="day-date-form">
{{if .Week.Enabled}}<input type="hidden" name="view" value="week">{{end}}
<input type="hidden" name="view" value="{{if .Week.Enabled}}week{{else}}day{{end}}">
<label>Persian date
<span class="jalali-field">
<input name="date" value="{{.Day.Jalali}}" data-jalali-picker required autocomplete="off" inputmode="numeric" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
@@ -43,7 +43,7 @@
<div class="week-grid">
{{range .Week.Days}}
<section class="week-day-column {{if .IsToday}}today{{end}} {{if eq .Weekday "Friday"}}friday{{end}}">
<a class="week-day-head" href="/day?date={{.Jalali}}">
<a class="week-day-head" href="/day?date={{.Jalali}}&view=day">
<span>{{.Weekday}}</span>
<strong>{{.Jalali}}</strong>
<small>{{.Gregorian}}{{if .DayNote}} · {{.DayNote}}{{end}}</small>
@@ -71,13 +71,13 @@
<div class="day-layout">
<section class="card day-summary-card">
<div class="day-date-nav">
<a href="/day?date={{.Day.Prev}}" aria-label="Previous day"></a>
<a href="/day?date={{.Day.Prev}}&view=day" aria-label="Previous day"></a>
<div>
<p class="eyebrow">PERSIAN CALENDAR</p>
<h2>{{.Day.Jalali}}</h2>
<span>{{.Day.Weekday}} · {{.Day.Gregorian}}{{if .Day.DayNote}} · {{.Day.DayNote}}{{end}}</span>
</div>
<a href="/day?date={{.Day.Next}}" aria-label="Next day"></a>
<a href="/day?date={{.Day.Next}}&view=day" aria-label="Next day"></a>
</div>
<div class="day-stats">
<div><i class="presence-mark present"></i><span><strong>{{.Day.Present}}</strong><small>Present</small></span></div>