bryntum / support

An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
https://www.bryntum.com
53 stars 6 forks source link

Wrong scroll positioning on add task when stickyHeaders enabled #3827

Open chuckn0rris opened 2 years ago

chuckn0rris commented 2 years ago

Forum post

Open swimlanes demo, turn on stickyHeaders : true for a taskboard.

Add a task using "+" button. See that scroll gets wrong position and just added task is not visible.

maccuong2021 commented 2 years ago

In taskboard when I create new task, web page do not scroll to bottom, otherwise It scroll to top of the taskboard, I don't know what is the problem.

Please see me code below:

in HTML

 <bryntum-task-board   
                #taskboard
</bryntum-task-board>

in file .ts

@ViewChild(BryntumTaskBoardComponent, { static : false }) taskboardComponent: BryntumTaskBoardComponent;  
  private taskboard: TaskBoard;  

constructor(
    ) {              
      this.config();    
  }

 ngAfterViewInit(): void {    
     this.taskboard = this.taskboardComponent.instance;        
     this.taskboard.setConfig(this.taskBoardConfig);      
  }
config() {   
    var that = this;
    this.taskBoardConfig = {          
      useDomTransition : false,
      stickyHeaders : true,
      showCollapseInHeader : false,

  swimlanes : [
    // id is used to match tasks, text is displayed in swimlanes header
    { id : 'critical', text : 'Critical!!', color : 'red' },
    { id : 'high', text : 'High', color : 'deep-orange' },
    { id : 'medium', text : 'Medium', color : 'orange' },
    // Display more tasks per row in the Low lane
    { id : 'low', text : 'Low', color : 'light-green', tasksPerRow : 3 }
  ],

  swimlaneField : 'prio',

  features : {       
      columnDrag   : true,
      swimlaneDrag : true,
      taskTooltip  : true,
      columnToolbars : {
        // By default it displays a bottom toolbar (bbar) with an add button.
        // Here we also add a top toolbar with the same button
        topItems : {
            addTask : true
        },

        // Using processItems it is possible to affect the items at runtime.
        // We use it here to hide the add task button in the Done column
        processItems({ items, columnRecord, location }) {
            if (columnRecord.id === 'done') {
                items.addTask = false;
            }
        }
      },
      columnHeaderMenu : true,           
      taskMenu   : {
        items : {
          removeTask : null,
          resources : null,
          flagTask : {
              text : 'Flag task',
              icon : 'b-fa-fw b-fa-flag',
              onItem({ taskRecord }) {
                  taskRecord.flagged = true;
                  alert('flagTask');
              }
          },
          deleteTask : {
              text : 'Delete task',
              icon : 'b-fa-fw b-fa-flag',
              onItem({ taskRecord, source }) {                    
                  source.project.taskStore.remove(taskRecord);                   
              }
          },
            // Add a custom menu item with a color picker sub menu
            color : {
                icon   : 'b-fa-fw b-fa-square',
                // Adds a separator line above, for nicer look
                cls    : 'b-separator',
                text   : 'Color',
                // Move close to the top
                weight : 150,
                menu   : {
                    // Each color gets an item, the key is used as the items `ref` which on purpose matches a
                    // predefined color. Makes it easy to apply the color in the listener below
                    red           : { text : 'Red', icon : 'b-fa-fw b-fa-square b-taskboard-color-red' },
                    pink          : { text : 'Pink', icon : 'b-fa-fw b-fa-square b-taskboard-color-pink' },
                    purple        : { text : 'Purple', icon : 'b-fa-fw b-fa-square b-taskboard-color-purple' },
                    'deep-purple' : { text : 'Deep purple', icon : 'b-fa-fw b-fa-square b-taskboard-color-deep-purple' },
                    indigo        : { text : 'Indigo', icon : 'b-fa-fw b-fa-square b-taskboard-color-indigo' },
                    blue          : { text : 'Blue', icon : 'b-fa-fw b-fa-square b-taskboard-color-blue' },
                    'light-blue'  : { text : 'Light blue', icon : 'b-fa-fw b-fa-square b-taskboard-color-light-blue' },
                    cyan          : { text : 'Cyan', icon : 'b-fa-fw b-fa-square b-taskboard-color-cyan' },
                    teal          : { text : 'Teal', icon : 'b-fa-fw b-fa-square b-taskboard-color-teal' },
                    green         : { text : 'Green', icon : 'b-fa-fw b-fa-square b-taskboard-color-green' },
                    'light-green' : { text : 'Light green', icon : 'b-fa-fw b-fa-square b-taskboard-color-light-green' },
                    lime          : { text : 'Lime', icon : 'b-fa-fw b-fa-square b-taskboard-color-lime' },
                    yellow        : { text : 'Yellow', icon : 'b-fa-fw b-fa-square b-taskboard-color-yellow' },
                    amber         : { text : 'Amber', icon : 'b-fa-fw b-fa-square b-taskboard-color-amber' },
                    orange        : { text : 'Orange', icon : 'b-fa-fw b-fa-square b-taskboard-color-orange' },
                    'deep-orange' : { text : 'Deep orange', icon : 'b-fa-fw b-fa-square b-taskboard-color-deep-orange' }
                },
                // Apply picked color to the task
                onItem({ item, taskRecord }) {
                    taskRecord.eventColor = item.ref;
                }
            },
            // Add another custom item with a label picker
            labels : {
                icon   : 'b-fa-fw b-fa-tags',
                text   : 'Labels',
                // Create a sub menu with one item per label, starting unchecked
                menu   : that.availableLabels.map(label => ({ text : label, checked : false })),
                // Move below
                weight : 160,
                // When clicking an item, all checked items are collected and turned into a labels string applied
                // to the task record
                onItem({ item, taskRecord }) {
                    const checkedLabels = [];

                    // Iterate over all label items
                    item.parent.items.forEach(item => {
                        // Collecting the text of the checked ones
                        if (item.checked) {
                            checkedLabels.push(item.text);
                        }
                    });

                    // Convert the array from above into a comma separated labels string and update the record
                    // with it
                    taskRecord.labels = checkedLabels.join(',');
                }
            }
        },

        // Function called before showing the menu, allows modifying the items
        processItems({ taskRecord, columnRecord, items }) {

        }
      },       
      taskEdit       : {
        // edit task
        processItems({ items, taskRecord, columnRecord, swimlaneRecord }) {

            items.name.label = taskRecord.type === 'task' ? 'Task' : 'Issue';
            that.editingRecord = taskRecord;                
            that.openDialog(that.contentPopup);
            items.column = false;             
        },
        editorConfig : {
            // Will make it anchor to the task being edited
            centered : false,
            // Display it without masking the rest of the page
            modal    : false
        },
        items : {

        }
      }
  },
  headerItems : {
    menu : { type : 'taskMenu' }
  },

  footerItems : {
      resourceAvatars : null
  },     

  columns : [
      'todo',
      'doing',
      'done',
      'will'
  ],
  // configPanel: {

  // } ,
  // Field used to pair a task to a column
  //columnField : 'status',
  columnField : 'status',
  // bodyItems : {
  //     tags : { type : 'tags'  }
  // },

  // Project using inline data
  project : {
      validateResponse : true,
      autoLoad : true,         
      // taskStore : {
      //   fields : [
      //       { name : 'labels' },
      //       { name : 'category', defaultValue : 'Bug' },
      //       { name : 'description', defaultValue : 'No description yet' }
      //   ]
      // },         
      tasksData : [
        {
          "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"
      }            
      ],  

  },
  taskRenderer({ cardConfig, taskRecord }) {

  }

  }
  }