Commit 985466f4 authored by Big Pickle's avatar Big Pickle
Browse files

Add shared TaskList component

parent 1e3c3ce7
Loading
Loading
Loading
Loading
Loading
+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()
    }
}