Skip to content

Commit 65ed95c

Browse files
authored
Merge pull request #76 from funktechno/dev
0.3.4 reorder page support
2 parents 8829850 + 18fd1dc commit 65ed95c

File tree

9 files changed

+229
-25
lines changed

9 files changed

+229
-25
lines changed

Asset/Javascript/wiki.js

+56
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,62 @@ jQuery(document).ready(function () {
3838

3939
// Don't do anything if dropping the same column we're dragging.
4040
if (dragSrcEl != this) {
41+
42+
let targetRoute;
43+
if(e.target.localName == "a"){
44+
targetRoute = e.target.href
45+
} else {
46+
targetRoute = e.target.querySelector("a").href
47+
}
48+
let targetParams = new URL(targetRoute)
49+
var targetProperties = {}
50+
for (const [key, value] of targetParams.searchParams.entries()) {
51+
targetProperties[key] = value
52+
}
53+
// console.log("targetProperties", targetProperties)
54+
55+
var srcParams = new URL(dragSrcEl.querySelector("a").href)
56+
var srcProperties = {}
57+
58+
for (const [key, value] of srcParams.searchParams.entries()) {
59+
srcProperties[key] = value
60+
}
61+
// console.log("srcProperties", srcProperties)
62+
63+
let project_id = srcProperties["project_id"]
64+
65+
// console.log("project_id", project_id)
66+
67+
let request = {
68+
"src_wiki_id": srcProperties["wiki_id"],
69+
"target_wiki_id": targetProperties["wiki_id"]
70+
}
71+
72+
console.log("request", request)
73+
74+
$.ajax({
75+
cache: false,
76+
url: $("#columns").data("reorder-url"),
77+
contentType: "application/json",
78+
type: "POST",
79+
processData: false,
80+
data: JSON.stringify(request),
81+
success: function(data) {
82+
// self.refresh(data);
83+
// self.savingInProgress = false;
84+
},
85+
error: function() {
86+
// self.app.hideLoadingIcon();
87+
// self.savingInProgress = false;
88+
},
89+
statusCode: {
90+
403: function(data) {
91+
window.alert(data.responseJSON.message);
92+
document.location.reload(true);
93+
}
94+
}
95+
});
96+
4197
// Set the source column's HTML to the HTML of the column we dropped on.
4298
//alert(this.outerHTML);
4399
//dragSrcEl.innerHTML = this.innerHTML;

ChangeLog

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Version 0.3.4
2+
Improvements:
3+
4+
* ability to reorder wiki pages
5+
6+
Bug fixes:
7+
8+
* Fix https://github.com/funktechno/kanboard-plugin-wiki/issues/28
9+
110
Version 0.3.3
211
Improvements:
312

Controller/WikiAjaxController.php

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace Kanboard\Plugin\Wiki\Controller;
4+
5+
use Exception;
6+
use Kanboard\Controller\BaseController;
7+
use Kanboard\Core\Controller\AccessForbiddenException;
8+
use Kanboard\Model\UserMetadataModel;
9+
10+
/**
11+
* Class WikiAjaxController
12+
*
13+
* @package Kanboard\Controller
14+
* @author lastlink
15+
*/
16+
class WikiAjaxController extends BaseController
17+
{
18+
/**
19+
* reorder for wikipages using src and target page moving src before target
20+
*/
21+
public function reorder()
22+
{
23+
$this->checkReusableGETCSRFParam();
24+
$project_id = $this->request->getIntegerParam('project_id');
25+
26+
if (! $project_id || ! $this->request->isAjax()) {
27+
throw new AccessForbiddenException();
28+
}
29+
30+
$values = $this->request->getJson();
31+
32+
if(!isset($values['src_wiki_id']) || !isset($values['target_wiki_id'])) {
33+
throw new AccessForbiddenException();
34+
}
35+
36+
// if (! $this->helper->projectRole->canMoveTask($project_id, $values['src_column_id'], $values['dst_column_id'])) {
37+
// throw new AccessForbiddenException(e("You don't have the permission to move this task"));
38+
// }
39+
40+
try {
41+
$result = $this->wiki->reorderPages($project_id, $values['src_wiki_id'], $values['target_wiki_id']);
42+
43+
if (!$result) {
44+
$this->response->status(400);
45+
} else {
46+
$this->response->status(200);
47+
}
48+
} catch (Exception $e) {
49+
$this->response->html('<div class="alert alert-error">'.$e->getMessage().'</div>');
50+
}
51+
}
52+
53+
}

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugin=Wiki
2-
version=0.3.3
2+
version=0.3.4
33
all:
44
@ echo "Build archive for plugin ${plugin} version=${version}"
55
@ git archive HEAD --prefix=${plugin}/ --format=zip -o ${plugin}-${version}.zip

Model/Wiki.php

+63-9
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,68 @@ public function getWikipages($project_id)
9898
// ->findOne();
9999
}
100100

101+
public function reorderPages($project_id, $src_wiki_id, $target_wiki_id){
102+
// retrieve wiki pages
103+
$wikiPages = $this->getWikipages($project_id);
104+
105+
// echo json_encode($wikiPages), true;
106+
107+
// echo "project_id: " . $project_id . " src_wiki_id: " . $src_wiki_id . " target_wiki_id: " . $target_wiki_id . "<br>";
108+
// change order of each in for loop, move matching id to one before target
109+
$orderColumn = 1;
110+
$targetColumn = 1;
111+
$oldSourceColumn = 1;
112+
for ($i=0; $i < count($wikiPages); $i++) {
113+
$oldOrderColumn = $wikiPages[$i]['ordercolumn'];
114+
$id = $wikiPages[$i]['id'];
115+
if($id == $target_wiki_id){
116+
// add additional order column
117+
$orderColumn++;
118+
$targetColumn = $orderColumn;
119+
}
120+
// echo " id: " . $id . " oldOrderColumn: " . $oldOrderColumn . " orderColumn: " . $orderColumn . "<br>";
121+
122+
if ($id == $src_wiki_id) {
123+
$oldSourceColumn = $oldOrderColumn;
124+
} else {
125+
if ($oldOrderColumn != $orderColumn) {
126+
// echo "updating ". $id ." column to ". $orderColumn . "<br>";
127+
$result = $this->savePagePosition($id, $orderColumn);
128+
if(!$result){
129+
return false;
130+
}
131+
}
132+
}
133+
$orderColumn++;
134+
}
135+
136+
// update moved src
137+
$targetColumn--;
138+
// echo "oldSourceColumn: " . $oldSourceColumn . " targetColumn: " . $targetColumn . "<br>";
139+
if($oldSourceColumn != $targetColumn){
140+
// echo "updating src ". $src_wiki_id . " column to ". $targetColumn -1 . "<br>";
141+
$result = $this->savePagePosition($src_wiki_id, $targetColumn);
142+
if(!$result){
143+
return false;
144+
}
145+
}
146+
147+
return true;
148+
}
149+
150+
public function savePagePosition($wiki_id, $orderColumn) {
151+
$result = $this->db->table(self::WIKITABLE)->eq('id', $wiki_id)->update(array(
152+
'ordercolumn' => $orderColumn
153+
));
154+
155+
if (! $result) {
156+
$this->db->cancelTransaction();
157+
return false;
158+
}
159+
160+
return true;
161+
}
162+
101163

102164

103165
/**
@@ -229,7 +291,7 @@ public function updatepage($paramvalues, $editions, $date = '')
229291
}
230292

231293
$wikiEventJob = new WikiEventJob($this->container);
232-
$wikiEventJob->executeWithId($paramvalues['id'], self::EVENT_DELETE);
294+
$wikiEventJob->executeWithId($paramvalues['id'], self::EVENT_UPDATE);
233295
// $wikiEventJob = new WikiEventJob($this->container);
234296
// $wikiEventJob->execute($paramvalues['title'], $paramvalues['project_id'], $values, self::EVENT_UPDATE);
235297
$this->db->table(self::WIKITABLE)->eq('id', $paramvalues['id'])->update($values);
@@ -421,14 +483,6 @@ public function restoreEdition($wiki_id, $edition)
421483
->eq('wikipage_id', $wiki_id)
422484
->findOne(); // this may possibly not support joins
423485

424-
// $values = array(
425-
// 'title' => $editionvalues['title'],
426-
// 'current_edition' => $edition,
427-
// 'content' => $editionvalues['title'],
428-
// 'date_modification' => $date ?: date('Y-m-d'),
429-
// 'modifier_id' => $this->userSession->getId(),
430-
// );
431-
432486
$values = [
433487
'title' => $editionvalues['title'],
434488
'current_edition' => $edition,

Plugin.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Plugin extends Base
1111
public function initialize()
1212
{
1313
$this->projectAccessMap->add('WikiController', '*', Role::PROJECT_MEMBER);
14+
$this->projectAccessMap->add('WikiAjaxController', '*', Role::PROJECT_MEMBER);
1415
$this->applicationAccessMap->add('WikiController', array('readonly','detail_readonly'), Role::APP_PUBLIC);
1516
$this->projectAccessMap->add('WikiFileController', '*', Role::PROJECT_MEMBER);
1617
$this->projectAccessMap->add('WikiFileViewController', '*', Role::PROJECT_MEMBER);
@@ -68,6 +69,9 @@ public function onStartup()
6869
public function getClasses()
6970
{
7071
return array(
72+
'Plugin\Wiki\Controller' => [
73+
'WikiAjaxController'
74+
],
7175
'Plugin\Wiki\Model' => array(
7276
'Wiki',
7377
'WikiFile'
@@ -92,7 +96,7 @@ public function getPluginAuthor()
9296

9397
public function getPluginVersion()
9498
{
95-
return '0.3.3';
99+
return '0.3.4';
96100
}
97101

98102
public function getPluginHomepage()

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ Note that you can only restore **saved** editions. So you if you have the global
7070
- [x] editions listing and restore
7171
- Related issues: [#9](https://github.com/kanboard/kanboard/issues/9)
7272
- [x] finish edit
73-
- [] ordering
74-
- [] drop down to switch
75-
- [] drag to move, require css magic
73+
- [x] ordering
74+
- [x] drop down to switch
75+
- [x] drag to move, require css magic
7676
- [] subpages and pagination
7777
- [x] fix wiki sidebar
7878
- use html template render properly to list wiki pages

Template/wiki/detail.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
</style>
3434
<div class="clearfix">
3535
<div class="sidebar column list">
36-
<ul id="columns">
36+
<ul id="columns" data-reorder-url="<?= $this->url->href('WikiAjaxController', 'reorder', array('plugin' => 'wiki', 'project_id' => $project['id'], 'csrf_token' => $this->app->getToken()->getReusableCSRFToken())) ?>">
3737
<?php if (!empty($wikipages)): ?>
3838
<?php foreach ($wikipages as $page): ?>
3939

40-
<li class="wikipage" <?php if (!$not_editable): ?>draggable="true"<?php endif ?>>
40+
<li class="wikipage" data-project-id="<?=$project['id']?>" data-page-id="<?=$page['id']?>" <?php if (!$not_editable): ?>draggable="true"<?php endif ?>>
4141
<?php if (!$not_editable): ?>
4242
<?=$this->url->link(t($page['title']), 'WikiController', 'detail', array('plugin' => 'wiki', 'project_id' => $project['id'], 'wiki_id' => $page['id']))?>
4343

Test/Model/WikiPageTest.php

+37-9
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ protected function setUp(): void
2323

2424
$plugin = new Loader($this->container);
2525
$plugin->scan();
26+
27+
$authManager = new AuthenticationManager($this->container);
28+
$authManager->register(new DatabaseAuth($this->container));
29+
30+
$_SESSION['user'] = array('id' => 1, 'username' => 'test', 'role' => 'app-admin');
2631
}
2732

2833
public function testCreation()
2934
{
30-
3135
$projectModel = new ProjectModel($this->container);
3236

3337
$this->assertEquals($projectModel->create(array('name' => 'UnitTest')), 1, 'Failed to create project');
@@ -36,8 +40,8 @@ public function testCreation()
3640

3741
$wikimodel = new Wiki($this->container);
3842
// create wiki pages
39-
$this->assertEquals($wikimodel->createpage($project['id'], "Security", "Some content", '2015-01-01'), 1, 'Failed to a create wiki page on project');
40-
$this->assertEquals($wikimodel->createpage($project['id'], "Conventions", 'More content'), 2, 'Failed to an additional create wiki page on project');
43+
$this->assertEquals(1, $wikimodel->createpage($project['id'], "Security", "Some content", '2015-01-01'), 'Failed to a create wiki page on project');
44+
$this->assertEquals(2, $wikimodel->createpage($project['id'], "Conventions", 'More content'), 'Failed to an additional create wiki page on project');
4145

4246
// grab editions for first wiki page
4347
$editions = $wikimodel->getEditions(1);
@@ -49,12 +53,6 @@ public function testCreation()
4953
];
5054

5155
// create wiki page edition
52-
53-
$authManager = new AuthenticationManager($this->container);
54-
$authManager->register(new DatabaseAuth($this->container));
55-
56-
$_SESSION['user'] = array('id' => 1, 'username' => 'test', 'role' => 'app-admin');
57-
5856
$this->assertTrue($this->container['userSession']->isLogged(), 'Failed to login');
5957

6058
$this->userSession = new UserSession($this->container);
@@ -68,4 +66,34 @@ public function testCreation()
6866
$this->assertEquals('Security', $editions[0]['title']);
6967
$this->assertEquals('Some content', $editions[0]['content']);
7068
}
69+
70+
public function testReOrder(){
71+
72+
$projectModel = new ProjectModel($this->container);
73+
74+
$this->assertEquals($projectModel->create(array('name' => 'reorder')), 1, 'Failed to create project');
75+
76+
$project = $projectModel->getById(1);
77+
78+
$wikimodel = new Wiki($this->container);
79+
80+
// create wiki pages
81+
$this->assertEquals(1, $wikimodel->createpage($project['id'], "Home", "", '2015-01-01'), 1, 'Failed to a create wiki page home on project');
82+
$this->assertEquals(2, $wikimodel->createpage($project['id'], "Page 2", ""), 'Failed to a create wiki page 2 on project');
83+
$this->assertEquals(3, $wikimodel->createpage($project['id'], "Page 3", ""), 'Failed to a create wiki page 3 on project');
84+
$this->assertEquals(4, $wikimodel->createpage($project['id'], "Page 4", ""), 'Failed to a create wiki page 4 on project');
85+
$this->assertEquals(5, $wikimodel->createpage($project['id'], "Page 5", ""), 'Failed to a create wiki page 5 on project');
86+
87+
// reorder
88+
$wikimodel->reorderPages($project['id'], 5, 3);
89+
// expected by id
90+
$expectedColumnOrders = [1,2,4,5,3];
91+
92+
$wikiPages = $wikimodel->getWikipages($project['id']);
93+
$this->assertEquals(count($expectedColumnOrders), count($wikiPages), 'expected column order count doesn\'t match pages');
94+
95+
for ($i=0; $i < count($expectedColumnOrders); $i++) {
96+
$this->assertEquals($expectedColumnOrders[$wikiPages[$i]['id']-1], $wikiPages[$i]['ordercolumn'], 'Failed to reorder page id:'. $wikiPages[$i]['id']);
97+
}
98+
}
7199
}

0 commit comments

Comments
 (0)