Merge pull request #1040 from taigaio/enhancement/wiki-links-drag-and-drop

Enhancement #4339: Add wiki links drag and drop ordering
stable
David Barragán Merino 2016-06-15 14:00:14 +02:00 committed by GitHub
commit 8dcb79a033
7 changed files with 104 additions and 15 deletions

View File

@ -7,14 +7,14 @@
- Show a confirmation notice when you exit edit mode by pressing ESC in the markdown inputs. - Show a confirmation notice when you exit edit mode by pressing ESC in the markdown inputs.
- Add the tribe button to link stories from tree.taiga.io with gigs in tribe.taiga.io. - Add the tribe button to link stories from tree.taiga.io with gigs in tribe.taiga.io.
- Errors (not found, server error, permissions and blocked project) don't change the current url. - Errors (not found, server error, permissions and blocked project) don't change the current url.
- Attachments image slider - Neew Attachments image slider in preview mode.
- New admin area to edit the tag colors used in your project - New admin area to edit the tag colors used in your project.
- Display the current user (me) at first in assignment lightbox (thanks to [@mikaoelitiana](https://github.com/mikaoelitiana)) - Display the current user (me) at first in assignment lightbox (thanks to [@mikaoelitiana](https://github.com/mikaoelitiana))
- Add a new permissions to allow add comments instead of use the existent modify permission for this purpose. - Add a new permissions to allow add comments instead of use the existent modify permission for this purpose.
- Ability to edit comments, view edition history and redesign comments module UI - Ability to edit comments, view edition history and redesign comments module UI.
- Upvote and downvote issues from the issues list. - Upvote and downvote issues from the issues list.
- Divide dashboard in two columns in large screens - Divide dashboard in two columns in large screens,
- Drag & Drop ordering for wiki links.
### Misc ### Misc
- Lots of small and not so small bugfixes. - Lots of small and not so small bugfixes.

View File

@ -57,6 +57,7 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location, constructor: (@scope, @rootscope, @repo, @model, @confirm, @rs, @params, @q, @location,
@filter, @log, @appMetaService, @navUrls, @analytics, @translate, @errorHandlingService) -> @filter, @log, @appMetaService, @navUrls, @analytics, @translate, @errorHandlingService) ->
@scope.$on("wiki:links:move", @.moveLink)
@scope.projectSlug = @params.pslug @scope.projectSlug = @params.pslug
@scope.wikiSlug = @params.slug @scope.wikiSlug = @params.slug
@scope.wikiTitle = @scope.wikiSlug @scope.wikiTitle = @scope.wikiSlug
@ -156,6 +157,16 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
@repo.remove(@scope.wiki).then onSuccess, onError @repo.remove(@scope.wiki).then onSuccess, onError
moveLink: (ctx, item, itemIndex) =>
values = @scope.wikiLinks
r = values.indexOf(item)
values.splice(r, 1)
values.splice(itemIndex, 0, item)
_.each values, (value, index) ->
value.order = index
@repo.saveAll(values)
module.controller("WikiDetailController", WikiDetailController) module.controller("WikiDetailController", WikiDetailController)

View File

@ -38,7 +38,40 @@ module = angular.module("taigaWiki")
WikiNavDirective = ($tgrepo, $log, $location, $confirm, $analytics, $loading, $template, WikiNavDirective = ($tgrepo, $log, $location, $confirm, $analytics, $loading, $template,
$compile, $translate) -> $compile, $translate) ->
template = $template.get("wiki/wiki-nav.html", true) template = $template.get("wiki/wiki-nav.html", true)
link = ($scope, $el, $attrs) ->
linkDragAndDrop = ($scope, $el, $attrs) ->
oldParentScope = null
newParentScope = null
itemEl = null
tdom = $el.find(".sortable")
drake = dragula([tdom[0]], {
direction: 'vertical',
copySortSource: false,
copy: false,
mirrorContainer: tdom[0],
moves: (item) -> return $(item).is('li')
})
drake.on 'dragend', (item) ->
itemEl = $(item)
item = itemEl.scope().link
itemIndex = itemEl.index()
$scope.$emit("wiki:links:move", item, itemIndex)
scroll = autoScroll(window, {
margin: 20,
pixels: 30,
scrollWhenOutside: true,
autoScroll: () ->
return this.down && drake.dragging;
})
$scope.$on "$destroy", ->
$el.off()
drake.destroy()
linkWikiLinks = ($scope, $el, $attrs) ->
$ctrl = $el.controller() $ctrl = $el.controller()
if not $attrs.ngModel? if not $attrs.ngModel?
@ -130,9 +163,15 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $analytics, $loading, $t
$el.find(".new input").val('') $el.find(".new input").val('')
$el.find(".add-button").show() $el.find(".add-button").show()
bindOnce($scope, $attrs.ngModel, render) bindOnce($scope, $attrs.ngModel, render)
link = ($scope, $el, $attrs) ->
linkWikiLinks($scope, $el, $attrs)
linkDragAndDrop($scope, $el, $attrs)
$scope.$on "$destroy", ->
$el.off()
return {link:link} return {link:link}
module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgAnalytics", module.directive("tgWikiNav", ["$tgRepo", "$log", "$tgLocation", "$tgConfirm", "$tgAnalytics",

View File

@ -2,10 +2,10 @@ header
h1(translate="WIKI.NAVIGATION.SECTION_NAME") h1(translate="WIKI.NAVIGATION.SECTION_NAME")
nav nav
ul ul.sortable
<% _.each(wikiLinks, function(link, index) { %> li.wiki-link(ng-repeat="link in wikiLinks", data-id!="{{ $index }}", tg-bind-scope)
li.wiki-link(data-id!="<%- index %>") tg-svg.dragger(svg-icon="icon-drag")
a.link-title(title!="<%- link.title %>", href!="<%- link.url %>")<%- link.title %> a.link-title(title!="{{ link.title }}", href!="{{ link.url }}") {{ link.title }}
<% if (deleteWikiLinkPermission) { %> <% if (deleteWikiLinkPermission) { %>
a.js-delete-link.remove-wiki-page(title!="{{'WIKI.DELETE_LINK_TITLE' | translate}}") a.js-delete-link.remove-wiki-page(title!="{{'WIKI.DELETE_LINK_TITLE' | translate}}")
@ -15,9 +15,8 @@ nav
input.hidden( input.hidden(
type="text" type="text"
placeholder="{{'COMMON.FIELDS.NAME' | translate}}" placeholder="{{'COMMON.FIELDS.NAME' | translate}}"
value!="<%- link.title %>" value!="{{ link.title }}"
) )
<% }) %>
li.new.hidden li.new.hidden
input( input(

View File

@ -2,9 +2,10 @@
@include font-type(text); @include font-type(text);
align-items: center; align-items: center;
border-bottom: 1px solid $gray-light; border-bottom: 1px solid $gray-light;
cursor: move;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 1rem 0 1rem 1rem; padding: 1rem 0;
text-transform: uppercase; text-transform: uppercase;
&:hover { &:hover {
.remove-wiki-page { .remove-wiki-page {
@ -13,6 +14,20 @@
transition: opacity .2s linear; transition: opacity .2s linear;
transition-delay: .2s; transition-delay: .2s;
} }
.dragger {
cursor: move;
fill: $gray-light;
opacity: 1;
transition: opacity .2s linear;
transition-delay: .2s;
}
}
.dragger {
margin-right: .5rem;
opacity: 0;
svg {
@include svg-size(.9rem);
}
} }
.remove-wiki-page { .remove-wiki-page {
opacity: 0; opacity: 0;
@ -24,6 +39,7 @@
} }
.link-title { .link-title {
cursor: pointer; cursor: pointer;
flex-grow: 1;
} }
.icon-trash { .icon-trash {
fill: $gray-light; fill: $gray-light;

View File

@ -17,10 +17,17 @@ helper.links = function() {
return newLink; return newLink;
}, },
get: function() { get: function(index) {
if(index !== null && index !== undefined)
return el.$$(".wiki-link a.link-title").get(index)
return el.$$(".wiki-link a.link-title"); return el.$$(".wiki-link a.link-title");
}, },
getNameOf: async function(index) {
let item = await obj.get(index)
return item.getText()
},
deleteLink: async function(link){ deleteLink: async function(link){
link.click(); link.click();
await utils.lightbox.confirm.ok(); await utils.lightbox.confirm.ok();
@ -32,6 +39,12 @@ helper.links = function() {
return obj; return obj;
}; };
helper.dragAndDropLinks = async function(indexFrom, indexTo) {
let selectedLink = helper.links().get(indexFrom);
let newPosition = helper.links().get(indexTo);
return utils.common.drag(selectedLink, newPosition);
};
helper.editor = function(){ helper.editor = function(){
let el = $('.main.wiki'); let el = $('.main.wiki');

View File

@ -20,6 +20,17 @@ describe('wiki', function() {
await utils.common.takeScreenshot("wiki", "empty"); await utils.common.takeScreenshot("wiki", "empty");
}); });
it("drag & drop links", async function() {
let nameOld = await wikiHelper.links().getNameOf(0);
await wikiHelper.dragAndDropLinks(0, 1);
let nameNew = await wikiHelper.links().getNameOf(4);
expect(nameNew).to.be.equal(nameOld);
});
it('add link', async function(){ it('add link', async function(){
let timestamp = new Date().getTime(); let timestamp = new Date().getTime();
currentWiki.slug = "test-link" + timestamp; currentWiki.slug = "test-link" + timestamp;