Browse Source

Merge branch 'feature/optional-auto-width' of https://github.com/NadavTasher/wekan

Lauri Ojansivu 6 months ago
parent
commit
133dd55f4c

+ 8 - 0
client/components/boards/boardHeader.jade

@@ -23,6 +23,10 @@ template(name="boardHeaderBar")
               span
                 = currentBoard.stars
 
+          a.board-header-btn.js-auto-width-board(
+            title="{{#if isAutoWidth}}{{_ 'click-to-disable-auto-width'}}{{else}}{{_ 'click-to-enable-auto-width'}}{{/if}}")
+            i.fa(class="fa-solid fa-{{#if isAutoWidth}}compress{{else}}expand{{/if}}")
+
           a.board-header-btn(
             class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
             title="{{_ currentBoard.permission}}")
@@ -66,6 +70,10 @@ template(name="boardHeaderBar")
               span
                 = currentBoard.stars
 
+          a.board-header-btn.js-auto-width-board(
+            title="{{#if isAutoWidth}}{{_ 'click-to-disable-auto-width'}}{{else}}{{_ 'click-to-enable-auto-width'}}{{/if}}")
+            i.fa(class="fa-solid fa-{{#if isAutoWidth}}compress{{else}}expand{{/if}}")
+
           a.board-header-btn(
             class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
             title="{{_ currentBoard.permission}}")

+ 9 - 0
client/components/boards/boardHeader.js

@@ -38,6 +38,12 @@ BlazeComponent.extendComponent({
     return user && user.hasStarred(boardId);
   },
 
+  isAutoWidth() {
+    const boardId = Utils.getCurrentBoardId();
+    const user = ReactiveCache.getCurrentUser();
+    return user && user.isAutoWidth(boardId);
+  },
+
   // Only show the star counter if the number of star is greater than 2
   showStarCounter() {
     const currentBoard = Utils.getCurrentBoard();
@@ -71,6 +77,9 @@ BlazeComponent.extendComponent({
         'click .js-star-board'() {
           ReactiveCache.getCurrentUser().toggleBoardStar(Session.get('currentBoard'));
         },
+        'click .js-auto-width-board'() {
+          ReactiveCache.getCurrentUser().toggleAutoWidth(Utils.getCurrentBoardId());
+        },
         'click .js-open-board-menu': Popup.open('boardMenu'),
         'click .js-change-visibility': Popup.open('boardChangeVisibility'),
         'click .js-watch-board': Popup.open('boardChangeWatch'),

+ 3 - 1
client/components/lists/list.css

@@ -7,11 +7,13 @@
   border-left: 1px solid #ccc;
   padding: 0;
   float: left;
-  flex: 1;
 }
 [id^="swimlane-"] .list:first-child {
   min-width: 20px;
 }
+.list.list-auto-width {
+  flex: 1;
+}
 .list:first-child {
   border-left: none;
   flex: none;

+ 2 - 2
client/components/lists/list.jade

@@ -1,7 +1,7 @@
 template(name='list')
   .list.js-list(id="js-list-{{_id}}"
-                style="{{#unless collapsed}}min-width:{{listWidth}}px;{{/unless}}"
-                class="{{#if collapsed}}list-collapsed{{/if}}")
+                style="{{#unless collapsed}}min-width:{{listWidth}}px;max-width:{{listConstraint}}px;{{/unless}}"
+                class="{{#if collapsed}}list-collapsed{{/if}} {{#if autoWidth}}list-auto-width{{/if}}")
     +listHeader
     +listBody
 

+ 12 - 0
client/components/lists/list.js

@@ -200,6 +200,18 @@ BlazeComponent.extendComponent({
     const list = Template.currentData();
     return user.getListWidth(list.boardId, list._id);
   },
+
+  listConstraint() {
+    const user = ReactiveCache.getCurrentUser();
+    const list = Template.currentData();
+    return user.getListConstraint(list.boardId, list._id);
+  },
+
+  autoWidth() {
+    const user = ReactiveCache.getCurrentUser();
+    const list = Template.currentData();
+    return user.isAutoWidth(list.boardId);
+  },
 }).register('list');
 
 Template.miniList.events({

+ 1 - 0
client/components/lists/listHeader.jade

@@ -191,6 +191,7 @@ template(name="setListWidthPopup")
     label {{_ 'set-list-width-value'}}
       p
         input.list-width-value(type="number" value="{{ listWidthValue }}" min="100")
+        input.list-constraint-value(type="number" value="{{ listConstraintValue }}" min="100")
         input.list-width-apply(type="submit" value="{{_ 'apply'}}")
         input.list-width-error
 

+ 14 - 2
client/components/lists/listHeader.js

@@ -347,14 +347,20 @@ BlazeComponent.extendComponent({
         .val(),
       10,
     );
+    const constraint = parseInt(
+      Template.instance()
+        .$('.list-constraint-value')
+        .val(),
+      10,
+    );
 
     // FIXME(mark-i-m): where do we put constants?
-    if (width < 100 || !width) {
+    if (width < 100 || !width || constraint < 100 || !constraint) {
       Template.instance()
         .$('.list-width-error')
         .click();
     } else {
-      Meteor.call('applyListWidth', board, list._id, width);
+      Meteor.call('applyListWidth', board, list._id, width, constraint);
       Popup.back();
     }
   },
@@ -365,6 +371,12 @@ BlazeComponent.extendComponent({
     return ReactiveCache.getCurrentUser().getListWidth(board, list._id);
   },
 
+  listConstraintValue() {
+    const list = Template.currentData();
+    const board = list.boardId;
+    return ReactiveCache.getCurrentUser().getListConstraint(board, list._id);
+  },
+
   events() {
     return [
       {

+ 6 - 4
imports/i18n/data/en.i18n.json

@@ -86,10 +86,10 @@
   "add-card": "Add Card",
   "add-card-to-top-of-list": "Add Card to Top of List",
   "add-card-to-bottom-of-list": "Add Card to Bottom of List",
-  "setListWidthPopup-title": "Set List Width",
-  "set-list-width": "Set Min Width",
-  "set-list-width-value": "Min Width (pixels)",
-  "list-width-error-message": "List width must be a positive integer",
+  "setListWidthPopup-title": "Set Widths",
+  "set-list-width": "Set Widths",
+  "set-list-width-value": "Set Min & Max Widths (pixels)",
+  "list-width-error-message": "List widths must be integers greater than 100",
   "setSwimlaneHeightPopup-title": "Set Swimlane Height",
   "set-swimlane-height": "Set Swimlane Height",
   "set-swimlane-height-value": "Swimlane Height (pixels)",
@@ -264,6 +264,8 @@
   "checklists": "Checklists",
   "click-to-star": "Click to star this board.",
   "click-to-unstar": "Click to unstar this board.",
+  "click-to-enable-auto-width": "Click to enable auto list width.",
+  "click-to-disable-auto-width": "Click to disable auto list width.",
   "clipboard": "Clipboard or drag & drop",
   "close": "Close",
   "close-board": "Close Board",

+ 61 - 2
models/users.js

@@ -417,6 +417,24 @@ Users.attachSchema(
       defaultValue: {},
       blackbox: true,
     },
+    'profile.listConstraints': {
+      /**
+       * User-specified constraint of each list (or nothing if default).
+       * profile[boardId][listId] = constraint;
+       */
+      type: Object,
+      defaultValue: {},
+      blackbox: true,
+    },
+    'profile.autoWidthBoards': {
+      /**
+       * User-specified flag for enabling auto-width for boards (false is the default).
+       * profile[boardId][listId] = constraint;
+       */
+      type: Object,
+      defaultValue: {},
+      blackbox: true,
+    },
     'profile.swimlaneHeights': {
       /**
        * User-specified heights of each swimlane (or nothing if default).
@@ -716,6 +734,11 @@ Users.helpers({
     return _.contains(starredBoards, boardId);
   },
 
+  isAutoWidth(boardId) {
+    const { autoWidthBoards = {} } = this.profile || {};
+    return autoWidthBoards[boardId] === true;
+  },
+
   invitedBoards() {
     const { invitedBoards = [] } = this.profile || {};
     return Boards.userBoards(
@@ -757,7 +780,7 @@ Users.helpers({
   },
 
   getListWidths() {
-    const { listWidths = {} } = this.profile || {};
+    const { listWidths = {}, } = this.profile || {};
     return listWidths;
   },
   getListWidth(boardId, listId) {
@@ -768,6 +791,18 @@ Users.helpers({
       return 270; //TODO(mark-i-m): default?
     }
   },
+  getListConstraints() {
+    const { listConstraints = {} } = this.profile || {};
+    return listConstraints;
+  },
+  getListConstraint(boardId, listId) {
+    const listConstraints = this.getListConstraints();
+    if (listConstraints[boardId] && listConstraints[boardId][listId]) {
+      return listConstraints[boardId][listId];
+    } else {
+      return 350;
+    }
+  },
 
   getSwimlaneHeights() {
     const { swimlaneHeights = {} } = this.profile || {};
@@ -974,6 +1009,15 @@ Users.mutations({
       },
     };
   },
+  toggleAutoWidth(boardId) {
+    const { autoWidthBoards = {} } = this.profile || {};
+    autoWidthBoards[boardId] = !autoWidthBoards[boardId];
+    return {
+      $set: {
+        'profile.autoWidthBoards': autoWidthBoards,
+      },
+    };
+  },
 
   addInvite(boardId) {
     return {
@@ -1148,6 +1192,19 @@ Users.mutations({
     };
   },
 
+  setListConstraint(boardId, listId, constraint) {
+    let currentConstraints = this.getListConstraints();
+    if (!currentConstraints[boardId]) {
+      currentConstraints[boardId] = {};
+    }
+    currentConstraints[boardId][listId] = constraint;
+    return {
+      $set: {
+        'profile.listConstraints': currentConstraints,
+      },
+    };
+  },
+
   setSwimlaneHeight(boardId, swimlaneId, height) {
     let currentHeights = this.getSwimlaneHeights();
     if (!currentHeights[boardId]) {
@@ -1199,12 +1256,14 @@ Meteor.methods({
     check(startDay, Number);
     ReactiveCache.getCurrentUser().setStartDayOfWeek(startDay);
   },
-  applyListWidth(boardId, listId, width) {
+  applyListWidth(boardId, listId, width, constraint) {
     check(boardId, String);
     check(listId, String);
     check(width, Number);
+    check(constraint, Number);
     const user = ReactiveCache.getCurrentUser();
     user.setListWidth(boardId, listId, width);
+    user.setListConstraint(boardId, listId, constraint);
   },
   applySwimlaneHeight(boardId, swimlaneId, height) {
     check(boardId, String);