entries list display table layout

This commit is contained in:
Antelle 2015-11-21 17:55:42 +03:00
parent 7cf2f6634d
commit 898000c936
18 changed files with 187 additions and 37 deletions

View File

@ -8,7 +8,7 @@ Nov
- [x] trim history by rules
- [ ] custom icons, favicons
- [x] drag to trash
- [ ] switch view
- [x] switch view
- [x] option to check updates without install
## v0.5
@ -40,6 +40,7 @@ Feb
- [ ] generation templates
- [ ] entry templates
- [ ] drag entries across files
- [ ] customizable table view
- [ ] i18n
- [ ] allow to increase font size
- [ ] different storage options

View File

@ -16,7 +16,8 @@ var AppSettingsModel = Backbone.Model.extend({
clipboardSeconds: 0,
autoSave: true,
idleMinutes: 15,
minimizeOnClose: false
minimizeOnClose: false,
tableView: false
},
initialize: function() {

View File

@ -28,6 +28,7 @@ EntryPresenter.prototype = {
get created() { return this.entry ? Format.dtStr(this.entry.created) : undefined; },
get updated() { return this.entry ? Format.dtStr(this.entry.updated) : undefined; },
get expired() { return this.entry ? this.entry.expired : false; },
get tags() { return this.entry ? this.entry.tags : false; },
get description() {
if (!this.entry) {
return '[Group]';

View File

@ -4,6 +4,12 @@ var FeatureDetector = {
isMac: function() {
return navigator.platform.indexOf('Mac') >= 0;
},
isMobile: function() {
return typeof window.orientation !== 'undefined';
},
isDesktop: function() {
return !this.isMobile();
},
actionShortcutSymbol: function(formatting) {
return this.isMac() ? '⌘' : formatting ? '<span class="thin">ctrl + </span>' : 'ctrl-';
},

View File

@ -5,6 +5,7 @@ var Backbone = require('backbone'),
MenuView = require('../views/menu/menu-view'),
FooterView = require('../views/footer-view'),
ListView = require('../views/list-view'),
ListWrapView = require('../views/list-wrap-view'),
DetailsView = require('../views/details/details-view'),
GrpView = require('../views/grp-view'),
OpenView = require('../views/open-view'),
@ -37,8 +38,10 @@ var AppView = Backbone.View.extend({
this.views.menu = new MenuView({ model: this.model.menu });
this.views.menuDrag = new DragView('x');
this.views.footer = new FooterView({ model: this.model });
this.views.listWrap = new ListWrapView({ model: this.model });
this.views.list = new ListView({ model: this.model });
this.views.listDrag = new DragView('x');
this.views.list.dragView = this.views.listDrag;
this.views.details = new DetailsView();
this.views.details.appModel = this.model;
this.views.grp = new GrpView();
@ -55,7 +58,6 @@ var AppView = Backbone.View.extend({
this.listenTo(Backbone, 'show-file', this.showFileSettings);
this.listenTo(Backbone, 'open-file', this.toggleOpenFile);
this.listenTo(Backbone, 'save-all', this.saveAll);
this.listenTo(Backbone, 'switch-view', this.switchView);
this.listenTo(Backbone, 'toggle-settings', this.toggleSettings);
this.listenTo(Backbone, 'toggle-menu', this.toggleMenu);
this.listenTo(Backbone, 'toggle-details', this.toggleDetails);
@ -73,8 +75,9 @@ var AppView = Backbone.View.extend({
},
render: function () {
this.setTheme();
this.$el.html(this.template());
this.setTheme();
this.views.listWrap.setElement(this.$el.find('.app__list-wrap')).render();
this.views.menu.setElement(this.$el.find('.app__menu')).render();
this.views.menuDrag.setElement(this.$el.find('.app__menu-drag')).render();
this.views.footer.setElement(this.$el.find('.app__footer')).render();
@ -88,6 +91,7 @@ var AppView = Backbone.View.extend({
showOpenFile: function(filePath) {
this.views.menu.hide();
this.views.menuDrag.hide();
this.views.listWrap.hide();
this.views.list.hide();
this.views.listDrag.hide();
this.views.details.hide();
@ -119,6 +123,7 @@ var AppView = Backbone.View.extend({
showEntries: function() {
this.views.menu.show();
this.views.menuDrag.show();
this.views.listWrap.show();
this.views.list.show();
this.views.listDrag.show();
this.views.details.show();
@ -147,6 +152,7 @@ var AppView = Backbone.View.extend({
this.model.menu.setMenu('settings');
this.views.menu.show();
this.views.menuDrag.show();
this.views.listWrap.hide();
this.views.list.hide();
this.views.listDrag.hide();
this.views.details.hide();
@ -162,6 +168,7 @@ var AppView = Backbone.View.extend({
},
showEditGroup: function() {
this.views.listWrap.hide();
this.views.list.hide();
this.views.listDrag.hide();
this.views.details.hide();
@ -413,10 +420,6 @@ var AppView = Backbone.View.extend({
this.views.menu.switchVisibility();
},
switchView: function() {
Alerts.notImplemented();
},
toggleDetails: function(visible) {
this.$el.find('.app__list').toggleClass('app__list--details-visible', visible);
this.views.menu.switchVisibility(false);

View File

@ -8,12 +8,16 @@ var DragView = Backbone.View.extend({
},
initialize: function (coord) {
this.coord = coord;
this.offsetProp = 'page' + coord.toUpperCase();
this.setCoord(coord);
this.mouseDownTime = -1;
this.mouseDownCount = 0;
},
setCoord: function(coord) {
this.coord = coord;
this.offsetProp = 'page' + coord.toUpperCase();
},
render: function() {
$('<div/>').addClass('drag-handle__inner').appendTo(this.$el);
},

View File

@ -12,7 +12,6 @@ var FooterView = Backbone.View.extend({
events: {
'click .footer__db-item': 'showFile',
'click .footer__db-open': 'openFile',
'click .footer__btn-view': 'switchView',
'click .footer__btn-help': 'toggleHelp',
'click .footer__btn-settings': 'toggleSettings',
'click .footer__btn-generate': 'genPass',
@ -75,10 +74,6 @@ var FooterView = Backbone.View.extend({
Backbone.trigger('save-all');
},
switchView: function() {
Backbone.trigger('switch-view');
},
toggleHelp: function() {
Backbone.trigger('toggle-settings', 'help');
},

View File

@ -11,7 +11,6 @@ var Backbone = require('backbone'),
var ListView = Backbone.View.extend({
template: require('templates/list.html'),
itemTemplate: require('templates/list-item-short.html'),
emptyTemplate: require('templates/list-empty.html'),
events: {
@ -22,7 +21,9 @@ var ListView = Backbone.View.extend({
views: null,
minWidth: 200,
minHeight: 200,
maxWidth: 500,
maxHeight: 500,
itemsEl: null,
@ -41,6 +42,8 @@ var ListView = Backbone.View.extend({
this.listenTo(Backbone, 'filter', this.filterChanged);
this.listenTo(Backbone, 'entry-updated', this.entryUpdated);
this.listenTo(this.model.settings, 'change:tableView', this.setTableView);
this.items = [];
},
@ -49,6 +52,7 @@ var ListView = Backbone.View.extend({
this.$el.html(this.template());
this.itemsEl = this.$el.find('.list__items>.scroller');
this.views.search.setElement(this.$el.find('.list__header')).render();
this.setTableView();
this.scroll = baron({
root: this.$el.find('.list__items')[0],
@ -60,23 +64,43 @@ var ListView = Backbone.View.extend({
this.scrollerBarWrapper = this.$el.find('.scroller__bar-wrapper');
}
if (this.items.length) {
var itemTemplate = this.getItemTemplate();
var itemsTemplate = this.getItemsTemplate();
var presenter = new EntryPresenter(this.getDescField());
var itemsHtml = '';
this.items.forEach(function (item) {
presenter.present(item);
itemsHtml += this.itemTemplate(presenter);
itemsHtml += itemTemplate(presenter);
}, this);
this.itemsEl.html(itemsHtml).scrollTop(0);
var html = itemsTemplate({ items: itemsHtml });
this.itemsEl.html(html).scrollTop(0);
} else {
this.itemsEl.html(this.emptyTemplate());
}
if (typeof AppSettingsModel.instance.get('listViewWidth') === 'number') {
this.$el.width(AppSettingsModel.instance.get('listViewWidth'));
}
this.pageResized();
return this;
},
getItemsTemplate: function() {
if (this.model.settings.get('tableView')) {
return require('templates/list-table.html');
} else {
return this.renderPlainItems;
}
},
renderPlainItems: function(itemsHtml) {
return itemsHtml.items;
},
getItemTemplate: function() {
if (this.model.settings.get('tableView')) {
return require('templates/list-item-table.html');
} else {
return require('templates/list-item-short.html');
}
},
getDescField: function() {
return this.model.sort.replace('-', '');
},
@ -142,7 +166,31 @@ var ListView = Backbone.View.extend({
this.views.search.hide();
},
viewResized: _.throttle(function(size) {
setTableView: function() {
var isTable = this.model.settings.get('tableView');
this.dragView.setCoord(isTable ? 'y' : 'x');
this.setDefaultSize();
},
setDefaultSize: function() {
this.setSize(this.model.settings.get('listViewWidth'));
},
setSize: function(size) {
this.$el.css({ width: null, height: null });
if (size) {
this.$el.css('flex', '0 0 ' + size + 'px');
} else {
this.$el.css('flex', null);
}
},
viewResized: function(size) {
this.setSize(size);
this.throttleSetViewSizeSetting(size);
},
throttleSetViewSizeSetting: _.throttle(function(size) {
AppSettingsModel.instance.set('listViewWidth', size);
}, 1000),

View File

@ -0,0 +1,23 @@
'use strict';
var Backbone = require('backbone');
var ListWrapView = Backbone.View.extend({
events: {
},
initialize: function() {
this.listenTo(this.model.settings, 'change:tableView', this.setListLayout);
},
render: function() {
this.setListLayout();
},
setListLayout: function() {
var tableView = this.model.settings.get('tableView');
this.$el.toggleClass('app__list-wrap--table', tableView);
}
});
module.exports = ListWrapView;

View File

@ -7,6 +7,7 @@ var Backbone = require('backbone'),
AppSettingsModel = require('../../models/app-settings-model'),
UpdateModel = require('../../models/update-model'),
RuntimeInfo = require('../../comp/runtime-info'),
FeatureDetector = require('../../util/feature-detector'),
Links = require('../../const/links');
var SettingsGeneralView = Backbone.View.extend({
@ -20,6 +21,7 @@ var SettingsGeneralView = Backbone.View.extend({
'change .settings__general-clipboard': 'changeClipboard',
'change .settings__general-auto-save': 'changeAutoSave',
'change .settings__general-minimize': 'changeMinimize',
'change .settings__general-table-view': 'changeTableView',
'click .settings__general-update-btn': 'checkUpdate',
'click .settings__general-restart-btn': 'restartApp',
'click .settings__general-download-update-btn': 'downloadUpdate',
@ -51,6 +53,8 @@ var SettingsGeneralView = Backbone.View.extend({
devTools: Launcher && Launcher.devTools,
canAutoUpdate: !!Launcher,
canMinimizeOnClose: Launcher && Launcher.canMinimize(),
tableView: AppSettingsModel.instance.get('tableView'),
canSetTableView: FeatureDetector.isDesktop(),
autoUpdate: Updater.getAutoUpdateType(),
updateInProgress: Updater.updateInProgress(),
updateInfo: this.getUpdateInfo(),
@ -134,6 +138,12 @@ var SettingsGeneralView = Backbone.View.extend({
AppSettingsModel.instance.set('minimizeOnClose', minimizeOnClose);
},
changeTableView: function(e) {
var tableView = e.target.checked || false;
AppSettingsModel.instance.set('tableView', tableView);
Backbone.trigger('refresh');
},
restartApp: function() {
if (Launcher) {
Launcher.requestRestart();

View File

@ -25,13 +25,30 @@
}
}
&__list-wrap {
@include flex(1);
@include display(flex);
@include align-items(stretch);
@include flex-direction(row);
@include justify-content(flex-start);
&.app__list-wrap--table {
@include flex-direction(column);
}
}
&__menu-drag, &__list-drag {
@include drag-handle;
@include flex(0 0 auto);
width: 1px;
cursor: col-resize;
@include mobile {
display: none;
@include mobile { display: none; }
}
&__list-drag {
.app__list-wrap--table & {
width: auto;
height: 1px;
cursor: row-resize;
}
}
@ -40,12 +57,13 @@
}
&__list {
@include flex(0 0 auto);
@include flex(0 0 250px);
@include display(flex);
@include align-items(stretch);
@include flex-direction(column);
width: 250px;
overflow-y: auto;
.app__list-wrap--table & {
}
@include mobile {
width: 100vw;
&.app__list--details-visible {

View File

@ -73,18 +73,26 @@
}
}
&__table {
width: calc(100% - 1px);
td, th {
padding: $base-padding;
text-align: left;
}
}
&__item {
@include area-selectable(right);
padding: $base-padding-px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
height: 32px;
@include area-selectable(right);
&--active, &--active:hover {
@include nomobile {
@include area-selected(right);
}
@include nomobile { @include area-selected(right); }
}
&:not(.list__item--table) {
height: 32px;
}
&--expired {

View File

@ -2,9 +2,11 @@
<div class="app__body">
<div class="app__menu"></div>
<div class="app__menu-drag"></div>
<div class="app__list"></div>
<div class="app__list-drag"></div>
<div class="app__details"></div>
<div class="app__list-wrap">
<div class="app__list"></div>
<div class="app__list-drag"></div>
<div class="app__details"></div>
</div>
<div class="app__grp"></div>
</div>
<div class="app__footer"></div>

View File

@ -7,7 +7,6 @@
</div>
<% }); %>
<div class="footer__db footer__db--dimmed footer__db--expanded footer__db-open"><i class="fa fa-plus"></i> Open / New</div>
<!--<div class="footer__btn footer__btn-view"><i class="fa fa-list-ul"></i></div>-->
<div class="footer__btn footer__btn-help"><i class="fa fa-question"></i></div>
<div class="footer__btn footer__btn-settings">
<% if (updateAvailable) { %>

View File

@ -0,0 +1,9 @@
<tr class="list__item list__item--table <%= active ? 'list__item--active' : '' %> <%= expired ? 'list__item--expired' : '' %>" id="<%= id %>" draggable="true">
<td><% if (customIcon) { %><img src="data:image/png;base64,<%= customIcon %>" class="list__item-icon list__item-icon--custom <%= color || '' %>" /><% }
else { %><i class="fa fa-<%= icon %> <%= color ? color+'-color' : '' %> list__item-icon"></i><% } %></td>
<td><%- title || '(no title)' %></td>
<td><%- description %></td>
<td><%- url %></td>
<td><%- tags %></td>
<td><%- notes %></td>
</tr>

View File

@ -0,0 +1,15 @@
<table class="list__table">
<thead>
<tr>
<th></th>
<th>Title</th>
<th>User</th>
<th>Website</th>
<th>Tags</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<%= items %>
</tbody>
</table>

View File

@ -50,6 +50,12 @@
<input type="checkbox" class="settings__input input-base settings__general-expand" id="settings__general-expand" <%- expandGroups ? 'checked' : '' %> />
<label for="settings__general-expand">Show entries from all subgroups</label>
</div>
<% if (canSetTableView) { %>
<div>
<input type="checkbox" class="settings__input input-base settings__general-table-view" id="settings__general-table-view" <%- tableView ? 'checked' : '' %> />
<label for="settings__general-table-view">Entries list table view</label>
</div>
<% } %>
<h2>Function</h2>
<div>

View File

@ -1,8 +1,9 @@
Release notes
-------------
##### vNext
Locking, better Dropbox, security enhancements, bugfixes
Locking, better Dropbox, security enhancements, bugfixes
`+` lock flow, auto-lock
`+` entries list display table layout
`+` minimize to tray on windows
`+` desktop Dropbox
`+` Dropbox notification in self-hosted apps