mirror of https://github.com/keeweb/keeweb.git
fix #5: groups and entries arranging
This commit is contained in:
parent
f1d7cab271
commit
4b19f32bbc
2
TODO.md
2
TODO.md
|
@ -5,7 +5,7 @@
|
|||
- [x] improve open page UX
|
||||
- [x] provide engineer error details on file open
|
||||
- [ ] trash: groups/empty/untrash
|
||||
- [ ] move groups/entries
|
||||
- [x] move groups/entries
|
||||
- [ ] help/tips
|
||||
- [ ] switch view
|
||||
- [ ] optional auto-update
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var DragDropInfo = {
|
||||
dragObject: null
|
||||
};
|
||||
|
||||
module.exports = DragDropInfo;
|
|
@ -12,7 +12,9 @@ var GroupModel = MenuItemModel.extend({
|
|||
entries: null,
|
||||
filterKey: 'group',
|
||||
editable: true,
|
||||
top: false
|
||||
top: false,
|
||||
drag: true,
|
||||
drop: true
|
||||
}),
|
||||
|
||||
initialize: function() {
|
||||
|
@ -134,6 +136,28 @@ var GroupModel = MenuItemModel.extend({
|
|||
}
|
||||
this.parentGroup.removeGroup(this);
|
||||
this.trigger('delete');
|
||||
},
|
||||
|
||||
moveHere: function(object) {
|
||||
if (!object || object.id === this.id) {
|
||||
return;
|
||||
}
|
||||
if (object instanceof GroupModel) {
|
||||
if (this.group.groups.indexOf(object.group) >= 0) {
|
||||
return;
|
||||
}
|
||||
this.file.db.move(object.group, this.group);
|
||||
object.parentGroup.removeGroup(object);
|
||||
object.trigger('delete');
|
||||
this.addGroup(object);
|
||||
} else if (object instanceof EntryModel) {
|
||||
if (this.group.entries.indexOf(object.entry) >= 0) {
|
||||
return;
|
||||
}
|
||||
this.file.db.move(object.entry, this.group);
|
||||
object.group.removeEntry(object);
|
||||
this.addEntry(object);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -143,7 +167,7 @@ GroupModel.fromGroup = function(group, file, parentGroup) {
|
|||
if (parentGroup) {
|
||||
model.parentGroup = parentGroup;
|
||||
} else {
|
||||
model.set({ top: true }, { silent: true });
|
||||
model.set({ top: true, drag: false }, { silent: true });
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
|
|
@ -16,6 +16,8 @@ var MenuItemModel = Backbone.Model.extend({
|
|||
cls: null,
|
||||
disabled: false,
|
||||
visible: true,
|
||||
drag: false,
|
||||
drop: false,
|
||||
filterKey: null,
|
||||
filterValue: null
|
||||
},
|
||||
|
|
|
@ -5,6 +5,7 @@ var Backbone = require('backbone'),
|
|||
Scrollable = require('../mixins/scrollable'),
|
||||
ListSearchView = require('./list-search-view'),
|
||||
EntryPresenter = require('../presenters/entry-presenter'),
|
||||
DragDropInfo = require('../comp/drag-drop-info'),
|
||||
baron = require('baron');
|
||||
|
||||
var ListView = Backbone.View.extend({
|
||||
|
@ -13,7 +14,8 @@ var ListView = Backbone.View.extend({
|
|||
emptyTemplate: require('templates/list-empty.html'),
|
||||
|
||||
events: {
|
||||
'click .list__item': 'itemClick'
|
||||
'click .list__item': 'itemClick',
|
||||
'dragstart .list__item': 'itemDragStart'
|
||||
},
|
||||
|
||||
views: null,
|
||||
|
@ -144,6 +146,14 @@ var ListView = Backbone.View.extend({
|
|||
var scrollTop = this.itemsEl[0].scrollTop;
|
||||
this.render();
|
||||
this.itemsEl[0].scrollTop = scrollTop;
|
||||
},
|
||||
|
||||
itemDragStart: function(e) {
|
||||
e.stopPropagation();
|
||||
var id = $(e.target).closest('.list__item').attr('id');
|
||||
e.dataTransfer.setData('text/entry', id);
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
DragDropInfo.dragObject = this.items.get(id);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
var Backbone = require('backbone'),
|
||||
KeyHandler = require('../../comp/key-handler'),
|
||||
Keys = require('../../const/keys'),
|
||||
Alerts = require('../../comp/alerts');
|
||||
Alerts = require('../../comp/alerts'),
|
||||
DragDropInfo = require('../../comp/drag-drop-info');
|
||||
|
||||
var MenuItemView = Backbone.View.extend({
|
||||
template: require('templates/menu/menu-item.html'),
|
||||
|
@ -14,7 +15,11 @@ var MenuItemView = Backbone.View.extend({
|
|||
'click .menu__item-option': 'selectOption',
|
||||
'click': 'selectItem',
|
||||
'dblclick': 'expandItem',
|
||||
'click .menu__item-edit': 'editItem'
|
||||
'click .menu__item-edit': 'editItem',
|
||||
'dragstart': 'dragstart',
|
||||
'dragover': 'dragover',
|
||||
'dragleave': 'dragleave',
|
||||
'drop' : 'drop'
|
||||
},
|
||||
|
||||
iconEl: null,
|
||||
|
@ -99,8 +104,10 @@ var MenuItemView = Backbone.View.extend({
|
|||
},
|
||||
|
||||
mouseover: function(e) {
|
||||
this.$el.addClass('menu__item--hover');
|
||||
e.stopPropagation();
|
||||
if (!e.button) {
|
||||
this.$el.addClass('menu__item--hover');
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
|
||||
mouseout: function(e) {
|
||||
|
@ -146,6 +153,43 @@ var MenuItemView = Backbone.View.extend({
|
|||
e.stopPropagation();
|
||||
Backbone.trigger('edit-group', this.model);
|
||||
}
|
||||
},
|
||||
|
||||
dropAllowed: function(e) {
|
||||
return ['text/group', 'text/entry'].indexOf(e.dataTransfer.types[0]) >= 0;
|
||||
},
|
||||
|
||||
dragstart: function(e) {
|
||||
e.stopPropagation();
|
||||
if (this.model.get('drag')) {
|
||||
e.dataTransfer.setData('text/group', this.model.id);
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
DragDropInfo.dragObject = this.model;
|
||||
}
|
||||
},
|
||||
|
||||
dragover: function(e) {
|
||||
e.stopPropagation();
|
||||
if (this.model.get('drop') && this.dropAllowed(e)) {
|
||||
e.preventDefault();
|
||||
this.$el.addClass('menu__item--drag');
|
||||
}
|
||||
},
|
||||
|
||||
dragleave: function(e) {
|
||||
e.stopPropagation();
|
||||
if (this.model.get('drop') && this.dropAllowed(e)) {
|
||||
this.$el.removeClass('menu__item--drag');
|
||||
}
|
||||
},
|
||||
|
||||
drop: function(e) {
|
||||
e.stopPropagation();
|
||||
if (this.model.get('drop') && this.dropAllowed(e)) {
|
||||
this.$el.removeClass('menu__item--drag');
|
||||
this.model.moveHere(DragDropInfo.dragObject);
|
||||
Backbone.trigger('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -145,5 +145,11 @@
|
|||
.fa {
|
||||
margin-right: $base-padding-h / 2;
|
||||
}
|
||||
|
||||
&--drag {
|
||||
>.menu__item-body {
|
||||
@include th { color: action-color(); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="list__item <%= active ? 'list__item--active' : '' %> <%= expired ? 'list__item--expired' : '' %>" id="<%= id %>">
|
||||
<div class="list__item <%= active ? 'list__item--active' : '' %> <%= expired ? 'list__item--expired' : '' %>" id="<%= id %>" draggable="true">
|
||||
<i class="fa fa-<%= icon %> <%= color ? color+'-color' : '' %>"></i> <span
|
||||
class="list__item-title"><%- title || '(no title)' %></span><span class="list__item-descr thin"><%- description %></span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
disabled ? 'menu__item--disabled' : '' %> <%=
|
||||
options && options.length ? 'menu__item--with-options' : '' %> <%=
|
||||
cls ? cls : '' %>">
|
||||
<div class="menu__item-body">
|
||||
<div class="menu__item-body" <%= drag ? 'draggable="true"' : '' %>>
|
||||
<i class="menu__item-icon fa <%= icon ? 'fa-' + icon : 'menu__item-icon--no-icon' %>"></i><span
|
||||
class="menu__item-title"><%- title || '(no title)' %></span>
|
||||
<% if (options) { %>
|
||||
|
@ -17,5 +17,5 @@
|
|||
<% if (typeof editable !== 'undefined') { %>
|
||||
<i class="menu__item-edit fa fa-cog"></i>
|
||||
<% } %>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
Release notes
|
||||
-------------
|
||||
##### v0.2.0 (not released yet)
|
||||
Bugfixes and new features
|
||||
UX improvements, new features, bugfixes
|
||||
`+` improved open page ux
|
||||
`+` keyfiles from Dropbox
|
||||
`+` #17: option to hide entries from subgroups
|
||||
`+` #17: option to hide entries from subgroups
|
||||
`+` #5: groups and entries arranging
|
||||
`+` #13: increase max generated password length
|
||||
`+` #20: default http:// for urls without protocol
|
||||
`-` #12: cannot edit entries without title
|
||||
|
|
Loading…
Reference in New Issue