From b09e504e9e8b99cd46adcbe58d5b7e2b3461c0b5 Mon Sep 17 00:00:00 2001 From: antelle Date: Sat, 11 Jun 2016 17:18:11 +0300 Subject: [PATCH] customizable table view --- app/scripts/presenters/entry-presenter.js | 4 +- app/scripts/util/format.js | 3 ++ app/scripts/util/locale.js | 1 + app/scripts/views/dropdown-view.js | 5 +- app/scripts/views/list-view.js | 66 +++++++++++++++++++++-- app/templates/list-item-table.hbs | 12 +++-- app/templates/list-table.hbs | 8 ++- release-notes.md | 1 + 8 files changed, 83 insertions(+), 17 deletions(-) diff --git a/app/scripts/presenters/entry-presenter.js b/app/scripts/presenters/entry-presenter.js index 740cec3a..50eb6944 100644 --- a/app/scripts/presenters/entry-presenter.js +++ b/app/scripts/presenters/entry-presenter.js @@ -31,7 +31,9 @@ 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 tags() { return this.entry ? this.entry.tags : undefined; }, + get groupName() { return this.entry ? this.entry.groupName : undefined; }, + get fileName() { return this.entry ? this.entry.fileName : undefined; }, get description() { if (!this.entry) { return '[' + Locale.listGroup + ']'; diff --git a/app/scripts/util/format.js b/app/scripts/util/format.js index d4664d86..9d645f37 100644 --- a/app/scripts/util/format.js +++ b/app/scripts/util/format.js @@ -22,6 +22,9 @@ var Format = { }, dStr: function(dt) { return dt ? dt.getDate() + ' ' + Locale.monthsShort[dt.getMonth()] + ' ' + dt.getFullYear() : ''; + }, + capFirst: function(str) { + return str[0].toUpperCase() + str.substr(1); } }; diff --git a/app/scripts/util/locale.js b/app/scripts/util/locale.js index e7b9e20d..9a81a9a1 100644 --- a/app/scripts/util/locale.js +++ b/app/scripts/util/locale.js @@ -15,6 +15,7 @@ var Locale = { website: 'website', tags: 'tags', notes: 'notes', + group: 'group', noTitle: 'no title', or: 'or', notImplemented: 'Not Implemented', diff --git a/app/scripts/views/dropdown-view.js b/app/scripts/views/dropdown-view.js index a2ea21bd..e4d33e81 100644 --- a/app/scripts/views/dropdown-view.js +++ b/app/scripts/views/dropdown-view.js @@ -35,8 +35,9 @@ var DropdownView = Backbone.View.extend({ itemClick: function(e) { e.stopPropagation(); - var selected = $(e.target).closest('.dropdown__item').data('value'); - this.trigger('select', { item: selected }); + var el = $(e.target).closest('.dropdown__item'); + var selected = el.data('value'); + this.trigger('select', { item: selected, el: el }); } }); diff --git a/app/scripts/views/list-view.js b/app/scripts/views/list-view.js index b06683ce..56bfcdc2 100644 --- a/app/scripts/views/list-view.js +++ b/app/scripts/views/list-view.js @@ -4,9 +4,12 @@ var Backbone = require('backbone'), Resizable = require('../mixins/resizable'), Scrollable = require('../mixins/scrollable'), ListSearchView = require('./list-search-view'), + DropdownView = require('./dropdown-view'), EntryPresenter = require('../presenters/entry-presenter'), DragDropInfo = require('../comp/drag-drop-info'), - AppSettingsModel = require('../models/app-settings-model'); + AppSettingsModel = require('../models/app-settings-model'), + Locale = require('../util/locale'), + Format = require('../util/format'); var ListView = Backbone.View.extend({ template: require('templates/list.hbs'), @@ -27,6 +30,17 @@ var ListView = Backbone.View.extend({ itemsEl: null, + + tableColumns: [ + { val: 'title', name: 'title', enabled: true }, + { val: 'user', name: 'user', enabled: true }, + { val: 'url', name: 'website', enabled: true }, + { val: 'tags', name: 'tags', enabled: true }, + { val: 'notes', name: 'notes', enabled: true }, + { val: 'groupName', name: 'group', enabled: false }, + { val: 'fileName', name: 'file', enabled: false } + ], + initialize: function () { this.initScroll(); this.views = {}; @@ -65,12 +79,19 @@ var ListView = Backbone.View.extend({ var itemsTemplate = this.getItemsTemplate(); var noColor = AppSettingsModel.instance.get('colorfulIcons') ? '' : 'grayscale'; var presenter = new EntryPresenter(this.getDescField(), noColor, this.model.activeEntryId); + var columns = {}; + this.tableColumns.forEach(function(col) { + if (col.enabled) { + columns[col.val] = true; + } + }); + presenter.columns = columns; var itemsHtml = ''; this.items.forEach(function (item) { presenter.present(item); itemsHtml += itemTemplate(presenter); }, this); - var html = itemsTemplate({ items: itemsHtml }); + var html = itemsTemplate({ items: itemsHtml, columns: this.tableColumns }); this.itemsEl.html(html); } else { this.itemsEl.html(this.emptyTemplate()); @@ -209,8 +230,45 @@ var ListView = Backbone.View.extend({ DragDropInfo.dragObject = this.items.get(id); }, - tableOptionsClick: function() { - // TODO: show available columns list + tableOptionsClick: function(e) { + e.stopImmediatePropagation(); + if (this.views.optionsDropdown) { + this.hideOptionsDropdown(); + return; + } + var view = new DropdownView(); + this.listenTo(view, 'cancel', this.hideOptionsDropdown); + this.listenTo(view, 'select', this.optionsDropdownSelect); + var targetElRect = this.$el.find('.list__table-options')[0].getBoundingClientRect(); + var options = this.tableColumns.map(function(col) { + return { + value: col.val, + icon: col.enabled ? 'check-square-o' : 'square-o', + text: Format.capFirst(Locale[col.name]) + }; + }); + view.render({ + position: { + top: targetElRect.bottom, + left: targetElRect.left + }, + options: options + }); + this.views.optionsDropdown = view; + }, + + hideOptionsDropdown: function() { + if (this.views.optionsDropdown) { + this.views.optionsDropdown.remove(); + delete this.views.optionsDropdown; + } + }, + + optionsDropdownSelect: function(e) { + var col = _.find(this.tableColumns, function(c) { return c.val === e.item; }); + col.enabled = !col.enabled; + e.el.find('i:first').toggleClass('fa-check-square-o fa-square-o'); + this.render(); } }); diff --git a/app/templates/list-item-table.hbs b/app/templates/list-item-table.hbs index 36d0a215..047fced4 100644 --- a/app/templates/list-item-table.hbs +++ b/app/templates/list-item-table.hbs @@ -6,9 +6,11 @@ {{~/if~}} - {{#if title}}{{title}}{{else}}({{res 'noTitle'}}){{/if}} - {{user}} - {{url}} - {{tags}} - {{notes}} + {{#if columns.title}}{{#if title}}{{title}}{{else}}({{res 'noTitle'}}){{/if}}{{/if}} + {{#if columns.user}}{{user}}{{/if}} + {{#if columns.url}}{{url}}{{/if}} + {{#if columns.tags}}{{tags}}{{/if}} + {{#if columns.notes}}{{notes}}{{/if}} + {{#if columns.groupName}}{{groupName}}{{/if}} + {{#if columns.fileName}}{{fileName}}{{/if}} diff --git a/app/templates/list-table.hbs b/app/templates/list-table.hbs index 4af20855..fda85551 100644 --- a/app/templates/list-table.hbs +++ b/app/templates/list-table.hbs @@ -2,11 +2,9 @@ - {{Res 'title'}} - {{Res 'user'}} - {{Res 'website'}} - {{Res 'tags'}} - {{Res 'notes'}} + {{#each columns as |col|}} + {{#if col.enabled}}{{Res col.name}}{{/if}} + {{/each}} diff --git a/release-notes.md b/release-notes.md index 9b761b26..eb06dfd8 100644 --- a/release-notes.md +++ b/release-notes.md @@ -15,6 +15,7 @@ Auto-type, ui improvements `+` group info in entry details `+` logout from remote storages on disable `+` select file for new records +`+` customizable table view `*` don't check updates at startup `*` repos moved to github organization account `*` allow opening same file twice