Implements the compact toggle

Signed-off-by: Michael Weimann <mail@michael-weimann.eu>
This commit is contained in:
Michael Weimann
2018-08-29 15:28:56 +02:00
parent 2c12a99020
commit e53c623759
12 changed files with 148 additions and 49 deletions

43
css/animations.scss Normal file
View File

@@ -0,0 +1,43 @@
/*
* @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu>
*
* @author 2018 Michael Weimann <mail@michael-weimann.eu>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
.compact-item.ng-enter,
.compact-item.ng-leave {
overflow: hidden;
transition: all 250ms linear;
}
.compact-item.ng-enter {
max-height: 0;
&.ng-enter-active {
max-height: 50px;
}
}
.compact-item.ng-leave {
max-height: 50px;
&.ng-leave-active {
max-height: 0;
}
}

41
css/compact-mode.scss Normal file
View File

@@ -0,0 +1,41 @@
/*
* @copyright Copyright (c) 2018 Michael Weimann <mail@michael-weimann.eu>
*
* @author 2018 Michael Weimann <mail@michael-weimann.eu>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
.compact-mode {
.card {
margin: $compact-board-item-margin;
&:last-child {
margin: $compact-board-last-item-margin;
}
}
.stack {
.as-sortable-placeholder {
margin: $compact-board-item-margin;
&:last-child {
margin: $compact-board-last-item-margin;
}
}
}
}

View File

@@ -40,3 +40,11 @@
.icon-badge { .icon-badge {
background-image: url('../../../core/img/places/calendar-dark.svg'); background-image: url('../../../core/img/places/calendar-dark.svg');
} }
.icon-toggle-compact-collapsed {
background-image: url('../img/toggle_view_expand.svg');
}
.icon-toggle-compact-expanded {
background-image: url('../img/toggle_view_collapse.svg');
}

View File

@@ -24,13 +24,23 @@
* *
*/ */
// colors
$color-warning-light: nc-lighten($color-warning, 15%); $color-warning-light: nc-lighten($color-warning, 15%);
$color-lightgrey: nc-darken($color-main-background, 4%); $color-lightgrey: nc-darken($color-main-background, 4%);
$color-grey: nc-darken($color-main-background, 7%); $color-grey: nc-darken($color-main-background, 7%);
$color-darkgrey: nc-darken($color-main-background, 32%); $color-darkgrey: nc-darken($color-main-background, 32%);
@import 'comp-appnav.scss'; // margins/paddings
@import 'icons.scss'; $board-item-margin: 10px 10px 20px 10px;
$board-last-item-margin: 10px;
$compact-board-item-margin: 5px 10px 10px 10px;
$compact-board-last-item-margin: 5px 10px 10px;
@import 'comp-appnav';
@import 'icons';
@import 'animations';
@import 'compact-mode';
/** /**
* General styles * General styles
@@ -338,7 +348,7 @@ input.input-inline {
flex-direction: column; flex-direction: column;
h3 { h3 {
padding: 10px 10px 8px; padding: 10px 10px 8px;;
margin: 0; margin: 0;
font-size: 12pt; font-size: 12pt;
font-weight: normal; font-weight: normal;
@@ -380,16 +390,16 @@ input.input-inline {
} }
.as-sortable-placeholder { .as-sortable-placeholder {
margin: 10px 10px 20px 10px; margin: $board-item-margin;
border: 1px dashed $color-darkgrey; border: 1px dashed $color-darkgrey;
min-height: 96px; min-height: 96px;
transition: margin 250ms linear;
&:last-child { &:last-child {
margin: 10px; margin: $board-last-item-margin;
} }
} }
> ul { > ul {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -397,17 +407,17 @@ input.input-inline {
} }
.card { .card {
background-color: $color-main-background; background-color: $color-main-background;
margin: 10px 10px 20px 10px; margin: $board-item-margin;
white-space: normal; white-space: normal;
position: relative; position: relative;
box-shadow: 0 0 3px $color-darkgrey; box-shadow: 0 0 3px $color-darkgrey;
border-radius: 3px; border-radius: 3px;
transition: margin 250ms linear;
&:last-child { &:last-child {
margin: 10px; margin: $board-last-item-margin;
} }
&.archived .card-upper { &.archived .card-upper {

View File

@@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -292.77)" display="none" stroke-width=".23666"><rect x=".28112" y="293.43" width="3.7042" height="1.1906" ry=".20225"/><rect x=".26458" y="295.15" width="3.7042" height="1.1906" ry=".20225"/></g><g transform="translate(0 -292.77)"><g transform="matrix(.040404 0 0 .040404 -3.0978 290.01)"><rect x="83.629" y="114.13" width="91.678" height="13.097" stroke-width="3.9049"/><path d="m155.25 81.388-26.194 26.194-26.194-26.154z" stroke-width="6.5484"/><path d="m155.25 159.97-26.194-26.194-26.194 26.154z" stroke-width="6.5484"/></g></g></svg>

After

Width:  |  Height:  |  Size: 671 B

View File

@@ -0,0 +1 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333 4.2333" xmlns="http://www.w3.org/2000/svg"><g transform="translate(0 -292.77)" display="none" stroke-width=".23666"><rect x=".28112" y="293.43" width="3.7042" height="1.1906" ry=".20225"/><rect x=".26458" y="295.15" width="3.7042" height="1.1906" ry=".20225"/></g><g transform="translate(0 -292.77)"><g transform="matrix(.040404 0 0 .040404 -3.0978 290.01)"><rect x="83.629" y="114.13" width="91.678" height="13.097" stroke-width="3.9049"/><path d="m155.25 107.58-26.194-26.194-26.194 26.154z" stroke-width="6.5484"/><path d="m155.25 133.78-26.194 26.194-26.194-26.154z" stroke-width="6.5484"/></g></g></svg>

After

Width:  |  Height:  |  Size: 671 B

View File

@@ -30,6 +30,7 @@ app.controller('AppController', function ($scope, $location, $http, $log, $rootS
$scope.sidebar = $rootScope.sidebar; $scope.sidebar = $rootScope.sidebar;
$scope.user = oc_current_user; $scope.user = oc_current_user;
$rootScope.config = JSON.parse($attrs.config); $rootScope.config = JSON.parse($attrs.config);
$rootScope.compactMode = false;
$scope.appNavigationHide = false; $scope.appNavigationHide = false;

View File

@@ -115,6 +115,10 @@ app.controller('BoardController', function ($rootScope, $scope, $stateParams, St
} }
}); });
$scope.toggleCompactMode = function() {
$rootScope.compactMode = !$rootScope.compactMode;
};
$scope.stacksData = StackService; $scope.stacksData = StackService;
$scope.stacks = []; $scope.stacks = [];
$scope.$watch('stacksData', function () { $scope.$watch('stacksData', function () {

41
js/package-lock.json generated
View File

@@ -2970,8 +2970,7 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@@ -2992,14 +2991,12 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@@ -3014,20 +3011,17 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@@ -3144,8 +3138,7 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@@ -3157,7 +3150,6 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@@ -3172,7 +3164,6 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@@ -3180,14 +3171,12 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.2.4", "version": "2.2.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.1", "safe-buffer": "^5.1.1",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@@ -3206,7 +3195,6 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@@ -3287,8 +3275,7 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@@ -3300,7 +3287,6 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@@ -3386,8 +3372,7 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.1", "version": "5.1.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@@ -3423,7 +3408,6 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@@ -3443,7 +3427,6 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@@ -3487,14 +3470,12 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.2", "version": "3.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true
"optional": true
} }
} }
}, },

View File

@@ -34,7 +34,13 @@ if (\OC_Util::getVersion()[0] < 14) {
} }
?> ?>
<div class="app app-deck" data-ng-app="Deck" ng-controller="AppController" ng-cloak config="<?php p(json_encode($_)); ?>" ng-class="{'app-navigation-hide': appNavigationHide}"> <div
class="app app-deck"
data-ng-app="Deck"
ng-controller="AppController"
ng-cloak
config="<?php p(json_encode($_)); ?>"
ng-class="{'app-navigation-hide': appNavigationHide, 'compact-mode': compactMode}">
<div id="app-navigation" data-ng-controller="ListController" ng-init="initSidebar()"> <div id="app-navigation" data-ng-controller="ListController" ng-init="initSidebar()">
<?php print_unescaped($this->inc('part.navigation')); ?> <?php print_unescaped($this->inc('part.navigation')); ?>

View File

@@ -21,6 +21,10 @@
<i class="icon icon-archive"></i> <i class="icon icon-archive"></i>
<span class="hidden-visually"><?php p($l->t('Hide archived cards')); ?></span> <span class="hidden-visually"><?php p($l->t('Hide archived cards')); ?></span>
</button> </button>
<button ng-click="toggleCompactMode()" title="<?php p($l->t('Toggle compact mode')); ?>">
<i class="icon" ng-class="{ 'icon-toggle-compact-collapsed': compactMode, 'icon-toggle-compact-expanded': !compactMode }"></i>
<span class="hidden-visually"><?php p($l->t('Toggle compact mode')); ?></span>
</button>
<button ui-sref="board.detail({ id: id, tab: 0})" title="<?php p($l->t('Board details')); ?>"> <button ui-sref="board.detail({ id: id, tab: 0})" title="<?php p($l->t('Board details')); ?>">
<i class="icon icon-settings"></i> <i class="icon icon-settings"></i>
<span class="hidden-visually"><?php p($l->t('Board details')); ?></span> <span class="hidden-visually"><?php p($l->t('Board details')); ?></span>

View File

@@ -81,16 +81,15 @@
autofocus-on-insert required maxlength="100" /> autofocus-on-insert required maxlength="100" />
</form> </form>
</h4> </h4>
<ul class="labels"> <ul class="labels compact-item" ng-if="!compactMode">
<li ng-repeat="label in cardservice.get(c.id).labels" <li ng-repeat="label in cardservice.get(c.id).labels"
ng-style="labelStyle(label.color)" title="{{ label.title }}"> ng-style="labelStyle(label.color)" title="{{ label.title }}">
<span>{{ label.title }}</span> <span>{{ label.title }}</span>
</li> </li>
</ul> </ul>
</div> </div>
<div class="card-controls"> <div class="card-controls compact-item" ng-if="!compactMode">
<i class="icon icon-filetype-text" ng-if="cardservice.get(c.id).description" title="{{ cardservice.get(c.id).description }}"></i> <i class="icon icon-filetype-text" ng-if="cardservice.get(c.id).description" title="{{ cardservice.get(c.id).description }}"></i>
<span class="due" ng-if="cardservice.get(c.id).duedate" ng-class="{'overdue': cardservice.get(c.id).overdue == 3, 'now': cardservice.get(c.id).overdue == 2, 'next': cardservice.get(c.id).overdue == 1 }" title="{{ cardservice.get(c.id).duedate }}"> <span class="due" ng-if="cardservice.get(c.id).duedate" ng-class="{'overdue': cardservice.get(c.id).overdue == 3, 'now': cardservice.get(c.id).overdue == 2, 'next': cardservice.get(c.id).overdue == 1 }" title="{{ cardservice.get(c.id).duedate }}">
<i class="icon icon-badge"></i> <i class="icon icon-badge"></i>