Loading portal/static/js/components/pieces/TaskList.mjs 0 → 100644 +104 −0 Changes for portal/static/js/components/pieces/TaskList.mjs: 104 added lines, 0 removed lines. Original line number Diff line number Diff line import { StatusPill } from "./StatusPill.mjs" export function createTaskList() { const state = { isEditable: false, isSaving: false, } return { view(vnode) { return m( "section.tasks.fancy.box", m("section.content", [ m("h2", vnode.attrs.title), getItems(vnode, state), ]), getAction(vnode, state), ) }, } } function getItems(vnode, state) { const { model, listTag = "ol" } = vnode.attrs if (!model.items) { return m("span.message", model.message) } if (model.items.length === 0) { return m("span.message", "Nichts.") } return m( listTag, model.items.map(item => m( "li", state.isEditable ? m( "div", item.name, item.taiga && m(StatusPill, { item, disabled: state.isSaving, }), ) : item.name, ), ), ) } function getAction(vnode, state) { const { model } = vnode.attrs const { isEditable, isSaving } = state if (isSaving) { return m( ".action.disabled", m("i.fa-solid.fa-circle-notch.fa-spin"), "Wird gespeichert...", ) } else if (isEditable) { return m( "a.action", { onclick: () => { if (model.changes.length === 0) { state.isEditable = false } else { save(vnode, state) } }, }, m("i.fa-solid.fa-floppy-disk"), model.changes.length > 0 ? "Speichern" : "Ohne Änderungen speichern", ) } else { return m( "a.action", { onclick: () => (state.isEditable = true) }, m("i.fa-solid.fa-pen-to-square"), "Bearbeiten", ) } } async function save(vnode, state) { const { model } = vnode.attrs state.isSaving = true try { await model.save() state.isEditable = false await vnode.attrs.onSaved?.() } finally { state.isSaving = false m.redraw() } } Loading
portal/static/js/components/pieces/TaskList.mjs 0 → 100644 +104 −0 Changes for portal/static/js/components/pieces/TaskList.mjs: 104 added lines, 0 removed lines. Original line number Diff line number Diff line import { StatusPill } from "./StatusPill.mjs" export function createTaskList() { const state = { isEditable: false, isSaving: false, } return { view(vnode) { return m( "section.tasks.fancy.box", m("section.content", [ m("h2", vnode.attrs.title), getItems(vnode, state), ]), getAction(vnode, state), ) }, } } function getItems(vnode, state) { const { model, listTag = "ol" } = vnode.attrs if (!model.items) { return m("span.message", model.message) } if (model.items.length === 0) { return m("span.message", "Nichts.") } return m( listTag, model.items.map(item => m( "li", state.isEditable ? m( "div", item.name, item.taiga && m(StatusPill, { item, disabled: state.isSaving, }), ) : item.name, ), ), ) } function getAction(vnode, state) { const { model } = vnode.attrs const { isEditable, isSaving } = state if (isSaving) { return m( ".action.disabled", m("i.fa-solid.fa-circle-notch.fa-spin"), "Wird gespeichert...", ) } else if (isEditable) { return m( "a.action", { onclick: () => { if (model.changes.length === 0) { state.isEditable = false } else { save(vnode, state) } }, }, m("i.fa-solid.fa-floppy-disk"), model.changes.length > 0 ? "Speichern" : "Ohne Änderungen speichern", ) } else { return m( "a.action", { onclick: () => (state.isEditable = true) }, m("i.fa-solid.fa-pen-to-square"), "Bearbeiten", ) } } async function save(vnode, state) { const { model } = vnode.attrs state.isSaving = true try { await model.save() state.isEditable = false await vnode.attrs.onSaved?.() } finally { state.isSaving = false m.redraw() } }