Skip to content

Commit 45073f2

Browse files
author
TimoPerplex
committed
Added start nodes in forms
1 parent 375e177 commit 45073f2

27 files changed

+1103
-175
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,4 @@ _Pvt_Extensions
234234

235235
# FAKE - F# Make
236236
.fake/
237+
/.svn
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div ng-controller="Perplex.FormsSecurity.EditController" id="perplex-forms-security-edit"></div>

Perplex.Umbraco.Forms/App_Plugins/PerplexUmbracoForms/backoffice/perplexForms/folder.html

+14-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
<div ng-controller="Perplex.Form.FolderController" class="perplex-folder">
1+
<div ng-controller="Perplex.Form.FolderController" class="perplex-folder">
22
<form novalidate ng-submit="update()">
3-
43
<div class="umb-panel-header">
54
<div class="row-fluid">
65
<div>
@@ -15,22 +14,28 @@
1514

1615
<div class="umb-panel-body umb-scrollable row-fluid">
1716
<div class="umb-pane perplex-sort perplex-folder">
18-
<p ng-if="folder && (folder.folder.length > 0 || folder.forms.length > 0)">
17+
<div ng-if="folder && !folder.disabled && (folder.folder.length > 0 || folder.forms.length > 0)">
1918
<h4>Reorder folders and forms using drag &amp; drop</h4>
2019
<hr />
21-
</p>
20+
</div>
2221

2322
<div ng-if="folder && folder.folders.length > 0">
2423
<h4 class="bold">Folders</h4>
25-
<ul class="folders" ui-sortable ng-model="folder.folders">
24+
<ul class="folders" ui-sortable ng-model="folder.folders" ng-if="!folder.disabled">
25+
<li ng-repeat="folder in folder.folders">
26+
<i class="icon umb-tree-icon sprTree icon-folder-close"></i><a href="#/forms/perplexForms/folder/{{ folder.id }}">{{ folder.name }}</a>
27+
</li>
28+
</ul>
29+
30+
<ul class="folders" ng-if="folder.disabled">
2631
<li ng-repeat="folder in folder.folders">
2732
<i class="icon umb-tree-icon sprTree icon-folder-close"></i><a href="#/forms/perplexForms/folder/{{ folder.id }}">{{ folder.name }}</a>
2833
</li>
2934
</ul>
35+
<br />
3036
</div>
31-
<br />
3237

33-
<div ng-if="folder && folder.forms.length > 0">
38+
<div ng-if="folder && !folder.disabled && folder.forms.length > 0">
3439
<h4 class="bold">Forms</h4>
3540
<ul class="folders" ui-sortable ng-model="folder.forms">
3641
<li ng-repeat="form in folder.forms">
@@ -40,7 +45,7 @@ <h4 class="bold">Forms</h4>
4045
</div>
4146
</div>
4247

43-
<div class="umb-tab-buttons" style="padding-left: 15px;">
48+
<div class="umb-tab-buttons" style="padding-left: 15px;" ng-if="!folder.disabled">
4449
<div class="btn-group">
4550
<button data-hotkey="ctrl+s" class="btn btn-success">
4651
<localize key="buttons_save" class="ng-isolate-scope ng-scope">Save</localize>
@@ -49,4 +54,5 @@ <h4 class="bold">Forms</h4>
4954
</div>
5055
</div>
5156
</form>
57+
5258
</div>

Perplex.Umbraco.Forms/App_Plugins/PerplexUmbracoForms/controllers/perplex.createfolder.controller.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
var folder = response.data;
99

1010
// Navigate to the created folder's path in the tree
11-
navigationService.syncTree({ tree: "form", path: folder.path, forceReload: true, activate: true });
11+
navigationService.syncTree({ tree: "form", path: folder.relativePath, forceReload: true, activate: true });
1212

1313
// Hide the tree
1414
navigationService.hideNavigation();

Perplex.Umbraco.Forms/App_Plugins/PerplexUmbracoForms/controllers/perplex.folder.controller.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@
1515
$scope.folder = response.data;
1616

1717
// Goto folder in tree
18-
navigationService.syncTree({ tree: "form", path: $scope.folder.path, forceReload: false, activate: true });
18+
navigationService.syncTree({ tree: "form", path: $scope.folder.relativePath, forceReload: false, activate: true });
19+
1920
}, function (error) { });
2021
});
2122

2223
$scope.update = function () {
2324
perplexFormResource.update($scope.folder).then(function (response) {
2425
// Reload folder
25-
navigationService.syncTree({ tree: "form", path: $scope.folder.path, forceReload: true }).then(function (syncArgs) {
26+
navigationService.syncTree({ tree: "form", path: $scope.folder.relativePath, forceReload: true }).then(function (syncArgs) {
2627
navigationService.reloadNode(syncArgs.node);
2728

2829
// Hide the tree
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
angular.module("umbraco").controller("Perplex.FormsSecurity.EditController",
2+
function ($scope, $controller, perplexFormResource, navigationService, treeService, formResource, $routeParams, notificationsService, $http, $compile) {
3+
$controller('UmbracoForms.Editors.Security.EditController', { $scope: $scope });
4+
5+
var defaultSave = $scope.save;
6+
7+
$scope.loading = true;
8+
$scope.folders = [];
9+
$scope.userId = $routeParams.id;
10+
$scope.startNodes = [];
11+
12+
// Fetch Umbraco's default edit view.
13+
$http.get('/App_Plugins/UmbracoForms/backoffice/FormSecurity/edit.html').success(function (template) {
14+
// Remove Umbraco's controller
15+
template = template.replace(/ng-controller\s*=\s*(["'])UmbracoForms.Editors.Security.EditController\1/, '');
16+
17+
// Add Form Start Nodes directive before the first umb-control-group
18+
template = template.replace(/(.*?)(<umb-control-group .*?)/, function(full, one, two) {
19+
return one + '<perplex-forms-start-nodes></perplex-forms-start-nodes>' + two
20+
});
21+
22+
$compile($("#perplex-forms-security-edit").html(template).contents())($scope);
23+
});
24+
25+
$scope.save = function () {
26+
defaultSave();
27+
saveStartNodes();
28+
}
29+
30+
function saveStartNodes() {
31+
perplexFormResource.setFormStartNodes($scope.userId, $scope.startNodes).then(function (response) {
32+
notificationsService.showNotification({ type: 0, header: "Start Nodes in Forms saved" });
33+
});
34+
}
35+
36+
// Load the start nodes for the selected user
37+
perplexFormResource.getFormStartNodes($scope.userId).then(function (response) {
38+
$scope.startNodes = _.pluck(response.data, 'id');
39+
40+
// Load folders
41+
perplexFormResource.getRootFolder().then(function (response) {
42+
if (response.data != null) {
43+
var rootFolder = response.data;
44+
45+
$scope.folders.push(rootFolder);
46+
initFolder(rootFolder);
47+
}
48+
49+
updateDisabledFolders();
50+
51+
$scope.loading = false;
52+
}, function (error) {
53+
// TODO: Handle error
54+
$scope.loading = false;
55+
});
56+
});
57+
58+
// Initialize a folder and its subfolders
59+
function initFolder(folder) {
60+
// If this folder is set as a startnode,
61+
// expand to this folder
62+
var isStartFolder = _.contains($scope.startNodes, folder.id);
63+
if (isStartFolder) {
64+
folder.selected = true;
65+
66+
// Expand all parent folders and the folder itself
67+
_.each(folder.path, function (folderId) {
68+
var ff = findFolder(folderId);
69+
if (ff != null) {
70+
ff.expanded = true;
71+
}
72+
});
73+
}
74+
75+
// Init subfolders
76+
_.each(folder.folders, function (subFolder) {
77+
initFolder(subFolder);
78+
})
79+
}
80+
81+
// Recusively find a folder inside a list of folders
82+
function findFolder(id, parent) {
83+
// No parent given, search through $scope.folders
84+
if (parent == null) {
85+
var folder = _.find($scope.folders, { id: id });
86+
if (folder != null) {
87+
return folder;
88+
}
89+
90+
// Search sub folders
91+
for (var i = 0; i < $scope.folders.length; i++) {
92+
folder = findFolder(id, $scope.folders[i]);
93+
if (folder != null) {
94+
return folder;
95+
}
96+
}
97+
} else {
98+
if (parent.id == id) {
99+
return parent;
100+
}
101+
102+
// Search sub folders
103+
for (var i = 0; i < parent.folders.length; i++) {
104+
folder = findFolder(id, parent.folders[i]);
105+
if (folder != null) {
106+
return folder;
107+
}
108+
}
109+
}
110+
}
111+
112+
$scope.toggleFolder = function (folder) {
113+
// Set expanded state
114+
folder.expanded = !folder.expanded;
115+
}
116+
117+
// Returns whether or not to show, does not actually show/hide
118+
$scope.showFolder = function (folder) {
119+
// Always show root
120+
if (folder.id === '-1') {
121+
return true;
122+
}
123+
124+
var parent = findFolder(folder.parentId);
125+
if (parent == null) {
126+
return false;
127+
}
128+
129+
return parent.expanded && $scope.showFolder(parent);
130+
}
131+
132+
$scope.selectFolder = function (folder) {
133+
folder.selected = !folder.selected;
134+
135+
if (folder.selected) {
136+
$scope.startNodes.push(folder.id);
137+
} else {
138+
var index = $scope.startNodes.indexOf(folder.id);
139+
$scope.startNodes.splice(index, 1);
140+
}
141+
142+
updateDisabledFolders();
143+
}
144+
145+
// Sets the disabled state of all folders based on
146+
// the currently selected startnodes
147+
function updateDisabledFolders() {
148+
_.each($scope.folders, updateDisabledFolder);
149+
}
150+
151+
function updateDisabledFolder(folder) {
152+
// No startnodes? Then everything is enabled
153+
if ($scope.startNodes.length === 0) {
154+
folder.disabled = false;
155+
} else {
156+
// Startnodes are not in folder's path, folder is disabled
157+
if(!_.any($scope.startNodes, function(sn) {
158+
return folder.path.indexOf(sn) > -1;
159+
})) {
160+
folder.disabled = true;
161+
} else {
162+
// Otherwise => enabled
163+
folder.disabled = false;
164+
}
165+
}
166+
167+
// And traverse children
168+
_.each(folder.folders, updateDisabledFolder);
169+
}
170+
171+
$scope.clear = function () {
172+
_.each($scope.startNodes, function (folderId) {
173+
var folder = findFolder(folderId);
174+
if (folder != null) {
175+
folder.selected = false;
176+
}
177+
});
178+
179+
$scope.startNodes = [];
180+
181+
updateDisabledFolders();
182+
}
183+
});

Perplex.Umbraco.Forms/App_Plugins/PerplexUmbracoForms/controllers/perplex.movefolder.controller.js

+32-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,34 @@
1010
// Add all folders to the flat list,
1111
// except the folder we are going to move
1212
addFolder(rootFolder);
13+
14+
// Since we added start folders, we have to tweak this list a bit more
15+
var enabledFolders = _.filter($scope.folders, { disabled: false });
16+
17+
// Find common ancestor
18+
var folderPaths = _.pluck(enabledFolders, 'path');
19+
20+
var commonAncestors = _.intersection.apply(this, folderPaths);
21+
22+
// Grab the last one (deepest in tree)
23+
var commonAncestor = commonAncestors[commonAncestors.length - 1];
24+
25+
// Since the Start Nodes were introduced, respect them
26+
// Filter out all disabled folders, but keep the common ancestor (which is disabled itself usually),
27+
// and any node between the common ancestor and a node which is not disabled
28+
$scope.folders = _.filter($scope.folders, function (folder) {
29+
return !folder.disabled || folder.id === commonAncestor ||
30+
(folder.path.indexOf(commonAncestor) > -1 && _.any(enabledFolders, function (f) { return f.path.indexOf(folder.id) > -1; }));
31+
});
32+
33+
// Fix depth
34+
var minDepthFolder = _.min($scope.folders, 'depth');
35+
var minDepth = minDepthFolder.depth;
36+
37+
$scope.folders = _.map($scope.folders, function (folder) {
38+
folder.depth = folder.depth - minDepth;
39+
return folder;
40+
});
1341
}
1442
}, function (error) {});
1543

@@ -37,7 +65,7 @@
3765
treeService.removeNode($scope.currentNode);
3866

3967
// Activate the form in its new location
40-
navigationService.syncTree({ tree: "form", path: movedFolder.path, forceReload: false, activate: true });
68+
navigationService.syncTree({ tree: "form", path: movedFolder.relativePath, forceReload: false, activate: true });
4169

4270
// Hide menu
4371
navigationService.hideNavigation();
@@ -46,6 +74,9 @@
4674
};
4775

4876
$scope.selectFolder = function (folder) {
77+
// Can't select disabled folders, sorry
78+
if (folder.disabled) return;
79+
4980
$scope.folderId = folder.id;
5081
};
5182

Perplex.Umbraco.Forms/App_Plugins/PerplexUmbracoForms/controllers/perplex.moveform.controller.js

+33-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,34 @@
99

1010
// Add all folders to the flat list
1111
addFolder(rootFolder);
12+
13+
// Since we added start folders, we have to tweak this list a bit more
14+
var enabledFolders = _.filter($scope.folders, { disabled: false });
15+
16+
// Find common ancestor
17+
var folderPaths = _.pluck(enabledFolders, 'path');
18+
19+
var commonAncestors = _.intersection.apply(this, folderPaths);
20+
21+
// Grab the last one (deepest in tree)
22+
var commonAncestor = commonAncestors[commonAncestors.length - 1];
23+
24+
// Since the Start Nodes were introduced, respect them
25+
// Filter out all disabled folders, but keep the common ancestor (which is disabled itself usually),
26+
// and any node between the common ancestor and a node which is not disabled
27+
$scope.folders = _.filter($scope.folders, function (folder) {
28+
return !folder.disabled || folder.id === commonAncestor ||
29+
(folder.path.indexOf(commonAncestor) > -1 && _.any(enabledFolders, function (f) { return f.path.indexOf(folder.id) > -1; }));
30+
});
31+
32+
// Fix depth
33+
var minDepthFolder = _.min($scope.folders, 'depth');
34+
var minDepth = minDepthFolder.depth;
35+
36+
$scope.folders = _.map($scope.folders, function (folder) {
37+
folder.depth = folder.depth - minDepth;
38+
return folder;
39+
});
1240
}
1341
}, function (error) { });
1442

@@ -26,7 +54,7 @@
2654
// response.data contains the new folder so we can sync the tree
2755
var newFolder = response.data;
2856

29-
var formPath = newFolder.path.concat([formId]);
57+
var formPath = newFolder.relativePath.concat([formId]);
3058

3159
// Remove the form from the tree
3260
treeService.removeNode($scope.currentNode);
@@ -39,7 +67,10 @@
3967
});
4068
};
4169

42-
$scope.selectFolder = function (folder) {
70+
$scope.selectFolder = function (folder) {
71+
// Can't select disabled folders, sorry
72+
if (folder.disabled) return;
73+
4374
$scope.folderId = folder.id;
4475
};
4576

0 commit comments

Comments
 (0)