Our flexible Kanban board for managing tasks with drag drop


Post by trail »

Hi,

Is it possible to load columns/swimlanes from an url like it is possible with tasks?
And if yes, is it possible to use one request for loading columns and tasks together?

Greetings


Post by tasnim »

Sure.

Example

async function main() {
    const response = await AjaxHelper.fetch('data/data.json');
    const { columns, swimlanes, tasks } = await response.json();

const taskBoard = new TaskBoard({
    appendTo : 'container',

    // Experimental, transition moving cards using the editor
    useDomTransition : true,

    features : {
        columnDrag   : true,
        swimlaneDrag : true,
        taskTooltip  : true
    },

    // columns
    columns,

    columnField : 'status',

    // swimlanes
    swimlanes,

    // Cards expand to fill available space if there are fewer than tasksPerRow
    stretchCards : true,

    swimlaneField : 'prio',

    tbar : [
        {
            type    : 'button',
            text    : 'Add swimlane',
            icon    : 'b-fa-plus-circle',
            onClick : 'up.onAddClick'
        },
        {
            type     : 'button',
            ref      : 'removeButton',
            text     : 'Remove swimlane',
            icon     : 'b-fa-trash',
            onClick  : 'up.onRemoveClick',
            disabled : true
        },
        '->',
        // Field for filtering swimlanes
        { type : 'swimlanefilterfield' },
        // Button for picking which swimlanes to show
        { type : 'swimlanepickerbutton' }
    ],

    taskRenderer({ taskRecord, cardConfig }) {
        const headerContent = cardConfig.children.header.children;

        // Header items are hidden in really small cards, make sure it exists before trying to update its text
        if (headerContent.text) {
            headerContent.text.text = `${taskRecord.hasGeneratedId ? '✻' : `#${taskRecord.id}`} ${taskRecord.name}`;
        }

        if (taskRecord.prio === 'critical') {
            headerContent.icon = {
                tag   : 'i',
                class : 'b-fa b-fa-exclamation-triangle'
            };
        }
    },

    project : {
        // tasks
        tasks : tasks.rows
    },

    onAddClick() {
        const id = taskBoard.swimlanes.count;

        taskBoard.swimlanes.add({ id, text : `Swimlane #${id}` });
        taskBoard.scrollToSwimlane(id);

        taskBoard.widgetMap.removeButton.disabled = false;
    },

    onRemoveClick() {
        taskBoard.swimlanes.last.remove();

        taskBoard.widgetMap.removeButton.disabled = taskBoard.swimlanes.count < 5;
    }
});
}

main();

And this is how the data looks like

{
  "success" : true,
  "columns" : ["todo", "doing", "revie", "done"],
  "swimlanes": [
      {
          "id": "critical",
          "text": "Critical!!",
          "color": "red"
      },
      {
          "id": "high",
          "text": "High",
          "color": "deep-orange"
      },
      {
          "id": "medium",
          "text": "Medium",
          "color": "orange"
      },
      {
          "id": "low",
          "text": "Low",
          "color": "light-green",
          "tasksPerRow": 3
      }
  ],
  "tasks"   : {
    "rows" : [
      {
        "id"          : 1,
        "name"        : "Bug with rendering",
        "description" : "Try it on any demo, reproduces easily",
        "status"      : "review",
        "prio"        : "medium"
      },
      {
        "id"          : 2,
        "name"        : "Add button to toolbar",
        "description" : "Should look like a proper button, must be clickable",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 3,
        "name"        : "Remove overflow",
        "description" : "It is overflowing everywhere, it should not",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 4,
        "name"        : "Test in Safari",
        "description" : "Also remember to test on IOS",
        "status"      : "doing",
        "prio"        : "low"
      },
      {
        "id"          : 5,
        "name"        : "Write tests",
        "description" : "Boss says we have to, better get started soon since test coverage is approximately 5%",
        "status"      : "done",
        "prio"        : "high"
      },
      {
        "id"          : 6,
        "name"        : "Refactor base class",
        "description" : "It is currently a mess, un-mess it please",
        "status"      : "todo",
        "prio"        : "low"
      },
      {
        "id"          : 7,
        "name"        : "Update themes",
        "description" : "All themes need an overhaul, marketing is not happy with their current state",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 8,
        "name"        : "De-nest CSS",
        "description" : "It is practically impossible to override any selector, needs a major de-nesting",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 9,
        "name"        : "Compile using esbuild",
        "description" : "So quick you will think it did not do anything...",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 10,
        "name"        : "Reconfigure grunt",
        "description" : "Better ask DevOps to handle it",
        "status"      : "doing",
        "prio"        : "high"
      },
      {
        "id"          : 11,
        "name"        : "Upgrade babel",
        "description" : "Need support for the latest syntax, devs go on and on about it",
        "status"      : "doing",
        "prio"        : "low"
      },
      {
        "id"          : 12,
        "name"        : "Install yarn",
        "description" : "Another task for DevOps",
        "status"      : "done",
        "prio"        : "medium"
      },
      {
        "id"          : 13,
        "name"        : "Replace var usages",
        "description" : "Makes us look old",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 14,
        "name"        : "Review PR",
        "description" : "Why?",
        "status"      : "todo",
        "prio"        : "high"
      },
      {
        "id"          : 15,
        "name"        : "Submit issue",
        "description" : "Which one? Have logged thousands",
        "status"      : "done",
        "prio"        : "medium"
      },
      {
        "id"          : 16,
        "name"        : "Fix xss vulnerabilities",
        "description" : "Really important this one",
        "status"      : "review",
        "prio"        : "critical"
      },
      {
        "id"          : 17,
        "name"        : "Apply destructuring",
        "description" : "Will shave 100k of our bundle, since we have many many vars",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 18,
        "name"        : "Remove deprecated API",
        "description" : "Josh says he deprecated it in last major, better verify it first",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 19,
        "name"        : "Upgrade ES5 syntax",
        "description" : "Really hard looping new devs in when they cant use the shiny new stuff",
        "status"      : "done",
        "prio"        : "high"
      },
      {
        "id"          : 20,
        "name"        : "Review package.json",
        "description" : "Should it really be 1000+ lines?",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 21,
        "name"        : "Try flutter",
        "description" : "It is trendy, lets try it",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 22,
        "name"        : "Evaluate WebFlow",
        "description" : "Our WordPress based site could use an upgrade",
        "status"      : "todo",
        "prio"        : "low"
      }
    ]
  }
}

Docs
https://bryntum.com/products/taskboard/docs/api/Core/helper/AjaxHelper#function-fetch-static


Post by trail »

Thank you, tasnim, but that is actually manual loading.
That's fine, that works, of course.

But what I meant is this nice auto-loading feature with readUrl,updateUrl etc...
So you can use a CrudManager to load and keep everything in sync automatically.


Post by tasnim »

Hi,

Sure. Here is how you could achieve it

Docs https://bryntum.com/products/taskboard/docs/api/TaskBoard/model/ProjectModel#function-addCrudStore

JS example

const taskBoard = new TaskBoard({
    appendTo : 'container',
    columnField : 'status',
    columns : {
        id        : 'columns',
        objectify : false
    },
    swimlaneField : 'prio',
    swimlanes : {
        id        : 'swimlanes',
        objectify : false
    },
    project : {
        loadUrl : 'data/data.json',
        autoLoad : true
    }
});

taskBoard.project.addCrudStore([taskBoard.columns, taskBoard.swimlanes]);

data

{
  "success" : true,
  "tasks"   : {
    "rows" : [
      {
        "id"          : 1,
        "name"        : "Bug with rendering",
        "description" : "Try it on any demo, reproduces easily",
        "status"      : "review",
        "prio"        : "medium"
      },
      {
        "id"          : 2,
        "name"        : "Add button to toolbar",
        "description" : "Should look like a proper button, must be clickable",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 3,
        "name"        : "Remove overflow",
        "description" : "It is overflowing everywhere, it should not",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 4,
        "name"        : "Test in Safari",
        "description" : "Also remember to test on IOS",
        "status"      : "doing",
        "prio"        : "low"
      },
      {
        "id"          : 5,
        "name"        : "Write tests",
        "description" : "Boss says we have to, better get started soon since test coverage is approximately 5%",
        "status"      : "done",
        "prio"        : "high"
      },
      {
        "id"          : 6,
        "name"        : "Refactor base class",
        "description" : "It is currently a mess, un-mess it please",
        "status"      : "todo",
        "prio"        : "low"
      },
      {
        "id"          : 7,
        "name"        : "Update themes",
        "description" : "All themes need an overhaul, marketing is not happy with their current state",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 8,
        "name"        : "De-nest CSS",
        "description" : "It is practically impossible to override any selector, needs a major de-nesting",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 9,
        "name"        : "Compile using esbuild",
        "description" : "So quick you will think it did not do anything...",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 10,
        "name"        : "Reconfigure grunt",
        "description" : "Better ask DevOps to handle it",
        "status"      : "doing",
        "prio"        : "high"
      },
      {
        "id"          : 11,
        "name"        : "Upgrade babel",
        "description" : "Need support for the latest syntax, devs go on and on about it",
        "status"      : "doing",
        "prio"        : "low"
      },
      {
        "id"          : 12,
        "name"        : "Install yarn",
        "description" : "Another task for DevOps",
        "status"      : "done",
        "prio"        : "medium"
      },
      {
        "id"          : 13,
        "name"        : "Replace var usages",
        "description" : "Makes us look old",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 14,
        "name"        : "Review PR",
        "description" : "Why?",
        "status"      : "todo",
        "prio"        : "high"
      },
      {
        "id"          : 15,
        "name"        : "Submit issue",
        "description" : "Which one? Have logged thousands",
        "status"      : "done",
        "prio"        : "medium"
      },
      {
        "id"          : 16,
        "name"        : "Fix xss vulnerabilities",
        "description" : "Really important this one",
        "status"      : "review",
        "prio"        : "critical"
      },
      {
        "id"          : 17,
        "name"        : "Apply destructuring",
        "description" : "Will shave 100k of our bundle, since we have many many vars",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 18,
        "name"        : "Remove deprecated API",
        "description" : "Josh says he deprecated it in last major, better verify it first",
        "status"      : "todo",
        "prio"        : "medium"
      },
      {
        "id"          : 19,
        "name"        : "Upgrade ES5 syntax",
        "description" : "Really hard looping new devs in when they cant use the shiny new stuff",
        "status"      : "done",
        "prio"        : "high"
      },
      {
        "id"          : 20,
        "name"        : "Review package.json",
        "description" : "Should it really be 1000+ lines?",
        "status"      : "doing",
        "prio"        : "medium"
      },
      {
        "id"          : 21,
        "name"        : "Try flutter",
        "description" : "It is trendy, lets try it",
        "status"      : "done",
        "prio"        : "low"
      },
      {
        "id"          : 22,
        "name"        : "Evaluate WebFlow",
        "description" : "Our WordPress based site could use an upgrade",
        "status"      : "todo",
        "prio"        : "low"
      }
    ]
  },
  "columns" : {
    "rows" : [
      { "id" : "todo", "text" : "todo"},
      { "id" : "doing", "text" : "doing"},
      { "id" : "review", "text" : "review"},
      { "id" : "done", "text" : "done"}
    ]
  },
  "swimlanes" : {
    "rows" : [
      {
          "id": "critical",
          "text": "Critical!!",
          "color": "red"
      },
      {
          "id": "high",
          "text": "High",
          "color": "deep-orange"
      },
      {
          "id": "medium",
          "text": "Medium",
          "color": "orange"
      },
      {
          "id": "low",
          "text": "Low",
          "color": "light-green",
          "tasksPerRow": 3
      }
  ]
  }
}

And this is how it looks like

Screenshot 2023-10-30 135359.png
Screenshot 2023-10-30 135359.png (62.18 KiB) Viewed 779 times

Post Reply