Merge branch 'dev'
CI/CD / deploy (push) Failing after 2m4s
Details
CI/CD / deploy (push) Failing after 2m4s
Details
This commit is contained in:
commit
8018acac2c
|
|
@ -45,6 +45,10 @@ class FolkTasksBoard extends HTMLElement {
|
|||
private _showColumnEditor = false;
|
||||
// Board labels (from server)
|
||||
private _boardLabels: string[] = [];
|
||||
// Inline workspace creation
|
||||
private _showCreateWs = false;
|
||||
// Inline delete confirmation
|
||||
private _confirmDeleteId: string | null = null;
|
||||
// ClickUp integration state
|
||||
private _cuConnected = false;
|
||||
private _cuTeamName = '';
|
||||
|
|
@ -434,12 +438,12 @@ class FolkTasksBoard extends HTMLElement {
|
|||
return '';
|
||||
}
|
||||
|
||||
private async createWorkspace() {
|
||||
const name = prompt("Workspace name:");
|
||||
private async createWorkspace(name: string) {
|
||||
if (!name?.trim()) return;
|
||||
if (this.isDemo) {
|
||||
const slug = name.trim().toLowerCase().replace(/\s+/g, "-");
|
||||
this.workspaces.push({ slug, name: name.trim(), icon: "\u{1F4CB}", task_count: 0, member_count: 1 });
|
||||
this._showCreateWs = false;
|
||||
this.render();
|
||||
return;
|
||||
}
|
||||
|
|
@ -450,7 +454,14 @@ class FolkTasksBoard extends HTMLElement {
|
|||
headers: this.authHeaders({ "Content-Type": "application/json" }),
|
||||
body: JSON.stringify({ name: name.trim() }),
|
||||
});
|
||||
if (res.ok) this.loadWorkspaces();
|
||||
if (res.ok) {
|
||||
this._showCreateWs = false;
|
||||
this.loadWorkspaces();
|
||||
} else {
|
||||
const data = await res.json().catch(() => ({}));
|
||||
this.error = data.error || `Failed to create workspace (${res.status})`;
|
||||
this.render();
|
||||
}
|
||||
} catch { this.error = "Failed to create workspace"; this.render(); }
|
||||
}
|
||||
|
||||
|
|
@ -494,7 +505,18 @@ class FolkTasksBoard extends HTMLElement {
|
|||
} catch { this.error = "Failed to update task"; this.render(); }
|
||||
}
|
||||
|
||||
private confirmDelete(taskId: string) {
|
||||
this._confirmDeleteId = taskId;
|
||||
this.render();
|
||||
}
|
||||
|
||||
private cancelDelete() {
|
||||
this._confirmDeleteId = null;
|
||||
this.render();
|
||||
}
|
||||
|
||||
private async deleteTask(taskId: string) {
|
||||
this._confirmDeleteId = null;
|
||||
if (this.isDemo) {
|
||||
this.tasks = this.tasks.filter(t => t.id !== taskId);
|
||||
if (this.detailTaskId === taskId) this.detailTaskId = null;
|
||||
|
|
@ -866,6 +888,22 @@ class FolkTasksBoard extends HTMLElement {
|
|||
.col-editor__add input { flex: 1; padding: 6px 8px; border-radius: 6px; border: 1px solid var(--rs-border-strong); background: var(--rs-bg-surface-sunken); color: var(--rs-text-primary); font-size: 12px; outline: none; }
|
||||
.col-editor__add button { padding: 6px 14px; border-radius: 6px; border: none; background: var(--rs-primary); color: #fff; cursor: pointer; font-size: 12px; font-weight: 600; }
|
||||
|
||||
/* Inline workspace create form */
|
||||
.ws-create-form { background: var(--rs-bg-surface); border: 1px solid var(--rs-primary); border-radius: 10px; padding: 14px; margin-bottom: 12px; display: flex; gap: 8px; align-items: center; }
|
||||
.ws-create-form input { flex: 1; padding: 8px 12px; border-radius: 6px; border: 1px solid var(--rs-border-strong); background: var(--rs-bg-surface-sunken); color: var(--rs-text-primary); font-size: 14px; outline: none; }
|
||||
.ws-create-form input:focus { border-color: var(--rs-primary-hover); }
|
||||
.ws-create-form button { padding: 8px 16px; border-radius: 6px; border: none; font-size: 13px; cursor: pointer; font-weight: 600; }
|
||||
.ws-create-submit { background: var(--rs-primary); color: #fff; }
|
||||
.ws-create-submit:hover { background: var(--rs-primary-hover); }
|
||||
.ws-create-cancel { background: transparent; color: var(--rs-text-muted); border: 1px solid var(--rs-border-strong) !important; }
|
||||
|
||||
/* Inline delete confirmation */
|
||||
.confirm-delete { display: flex; align-items: center; gap: 8px; padding: 6px 10px; background: #3b1111; border-radius: 6px; margin-top: 6px; }
|
||||
.confirm-delete span { font-size: 12px; color: #f87171; }
|
||||
.confirm-delete button { padding: 4px 10px; border-radius: 4px; border: none; font-size: 11px; cursor: pointer; font-weight: 600; }
|
||||
.confirm-yes { background: #f87171; color: #fff; }
|
||||
.confirm-no { background: transparent; color: var(--rs-text-muted); border: 1px solid var(--rs-border-strong) !important; }
|
||||
|
||||
/* Gear icon */
|
||||
.gear-btn { padding: 4px 8px; border-radius: 6px; border: 1px solid var(--rs-border-subtle); background: transparent; color: var(--rs-text-muted); cursor: pointer; font-size: 14px; }
|
||||
.gear-btn:hover { color: var(--rs-text-primary); border-color: var(--rs-border-strong); }
|
||||
|
|
@ -912,6 +950,13 @@ class FolkTasksBoard extends HTMLElement {
|
|||
<button class="rapp-nav__btn" id="create-ws">+ New Workspace</button>
|
||||
<button class="rapp-nav__btn" id="btn-tour" style="font-size:0.78rem;padding:4px 10px;opacity:0.7">Tour</button>
|
||||
</div>
|
||||
${this._showCreateWs ? `
|
||||
<div class="ws-create-form">
|
||||
<input type="text" id="ws-name-input" placeholder="Workspace name..." autofocus>
|
||||
<button class="ws-create-submit" id="ws-create-submit">Create</button>
|
||||
<button class="ws-create-cancel" id="ws-create-cancel">Cancel</button>
|
||||
</div>
|
||||
` : ''}
|
||||
${this.renderClickUpPanel()}
|
||||
${this.workspaces.length > 0 ? `<div class="workspace-grid">
|
||||
${this.workspaces.map(ws => `
|
||||
|
|
@ -1060,6 +1105,7 @@ class FolkTasksBoard extends HTMLElement {
|
|||
return `<span class="task-due${overdue ? ' overdue' : ''}">${fmt}</span>`;
|
||||
})();
|
||||
const labelFilter = this._filterLabel;
|
||||
const confirmingDelete = this._confirmDeleteId === task.id;
|
||||
return `
|
||||
<div class="task-card" draggable="${isEditing ? "false" : "true"}" data-task-id="${task.id}" data-collab-id="task:${task.id}">
|
||||
<button class="task-delete-btn" data-quick-delete="${task.id}" title="Delete">×</button>
|
||||
|
|
@ -1072,6 +1118,7 @@ class FolkTasksBoard extends HTMLElement {
|
|||
${dueDateBadge}
|
||||
${(task.labels || []).map((l: string) => `<span class="badge clickable${labelFilter === l ? ' filter-active' : ''}" data-filter-label="${l}">${this.esc(l)}</span>`).join("")}
|
||||
</div>
|
||||
${confirmingDelete ? `<div class="confirm-delete"><span>Delete?</span><button class="confirm-yes" data-confirm-yes="${task.id}">Yes</button><button class="confirm-no" data-confirm-no="${task.id}">No</button></div>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
|
@ -1133,7 +1180,9 @@ class FolkTasksBoard extends HTMLElement {
|
|||
<label>Updated</label>
|
||||
<span class="readonly">${task.updated_at ? new Date(task.updated_at).toLocaleString() : new Date(task.updatedAt || Date.now()).toLocaleString()}</span>
|
||||
</div>
|
||||
<button class="detail-delete" id="detail-delete">Delete Task</button>
|
||||
${this._confirmDeleteId === task.id
|
||||
? `<div class="confirm-delete"><span>Delete this task?</span><button class="confirm-yes" data-confirm-yes="${task.id}">Yes, delete</button><button class="confirm-no" data-confirm-no="${task.id}">Cancel</button></div>`
|
||||
: `<button class="detail-delete" id="detail-delete">Delete Task</button>`}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
|
@ -1169,7 +1218,25 @@ class FolkTasksBoard extends HTMLElement {
|
|||
this.render();
|
||||
});
|
||||
this.shadow.querySelector("#btn-tour")?.addEventListener("click", () => this.startTour());
|
||||
this.shadow.getElementById("create-ws")?.addEventListener("click", () => this.createWorkspace());
|
||||
this.shadow.getElementById("create-ws")?.addEventListener("click", () => {
|
||||
this._showCreateWs = !this._showCreateWs;
|
||||
this.render();
|
||||
if (this._showCreateWs) setTimeout(() => this.shadow.getElementById("ws-name-input")?.focus(), 0);
|
||||
});
|
||||
this.shadow.getElementById("ws-create-submit")?.addEventListener("click", () => {
|
||||
const input = this.shadow.getElementById("ws-name-input") as HTMLInputElement;
|
||||
if (input?.value?.trim()) this.createWorkspace(input.value.trim());
|
||||
});
|
||||
this.shadow.getElementById("ws-name-input")?.addEventListener("keydown", (e) => {
|
||||
if ((e as KeyboardEvent).key === "Enter") {
|
||||
const input = e.target as HTMLInputElement;
|
||||
if (input.value?.trim()) this.createWorkspace(input.value.trim());
|
||||
}
|
||||
if ((e as KeyboardEvent).key === "Escape") { this._showCreateWs = false; this.render(); }
|
||||
});
|
||||
this.shadow.getElementById("ws-create-cancel")?.addEventListener("click", () => {
|
||||
this._showCreateWs = false; this.render();
|
||||
});
|
||||
this.shadow.getElementById("create-task")?.addEventListener("click", () => {
|
||||
this.showCreateForm = !this.showCreateForm;
|
||||
this.render();
|
||||
|
|
@ -1344,7 +1411,7 @@ class FolkTasksBoard extends HTMLElement {
|
|||
});
|
||||
// Detail delete
|
||||
this.shadow.getElementById("detail-delete")?.addEventListener("click", () => {
|
||||
if (this.detailTaskId && confirm("Delete this task?")) this.deleteTask(this.detailTaskId);
|
||||
if (this.detailTaskId) this.confirmDelete(this.detailTaskId);
|
||||
});
|
||||
|
||||
// ── Quick delete on card hover ──
|
||||
|
|
@ -1352,7 +1419,22 @@ class FolkTasksBoard extends HTMLElement {
|
|||
el.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
const taskId = (el as HTMLElement).dataset.quickDelete!;
|
||||
if (confirm("Delete this task?")) this.deleteTask(taskId);
|
||||
this.confirmDelete(taskId);
|
||||
});
|
||||
});
|
||||
|
||||
// ── Inline delete confirmation ──
|
||||
this.shadow.querySelectorAll("[data-confirm-yes]").forEach(el => {
|
||||
el.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
const taskId = (el as HTMLElement).dataset.confirmYes!;
|
||||
this.deleteTask(taskId);
|
||||
});
|
||||
});
|
||||
this.shadow.querySelectorAll("[data-confirm-no]").forEach(el => {
|
||||
el.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
this.cancelDelete();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue