Added delete feature for nodes.
This commit is contained in:
parent
39e7af6238
commit
79aadc85c2
|
@ -49,6 +49,7 @@
|
||||||
<script src="scripts/controllers/main.js"></script>
|
<script src="scripts/controllers/main.js"></script>
|
||||||
<script src="scripts/controllers/newNodeCtrl.js"></script>
|
<script src="scripts/controllers/newNodeCtrl.js"></script>
|
||||||
<script src="scripts/controllers/updateNodeCtrl.js"></script>
|
<script src="scripts/controllers/updateNodeCtrl.js"></script>
|
||||||
|
<script src="scripts/controllers/deleteNodeCtrl.js"></script>
|
||||||
|
|
||||||
<script src="scripts/services/nodeService.js"></script>
|
<script src="scripts/services/nodeService.js"></script>
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@
|
||||||
<script src="scripts/directives/nodeSaved.js"></script>
|
<script src="scripts/directives/nodeSaved.js"></script>
|
||||||
<script src="scripts/directives/tokenForm.js"></script>
|
<script src="scripts/directives/tokenForm.js"></script>
|
||||||
|
|
||||||
|
<script src="scripts/dialogs/confirmDeletionDialog.js"></script>
|
||||||
<script src="scripts/dialogs/outsideOfCommunityDialog.js"></script>
|
<script src="scripts/dialogs/outsideOfCommunityDialog.js"></script>
|
||||||
|
|
||||||
<script src="scripts/validation/constraints.js"></script>
|
<script src="scripts/validation/constraints.js"></script>
|
||||||
|
|
|
@ -25,6 +25,11 @@ angular.module('ffffng', [
|
||||||
controller: 'UpdateNodeCtrl',
|
controller: 'UpdateNodeCtrl',
|
||||||
title: 'Knotendaten ändern'
|
title: 'Knotendaten ändern'
|
||||||
})
|
})
|
||||||
|
.when('/delete', {
|
||||||
|
templateUrl: 'views/deleteNodeForm.html',
|
||||||
|
controller: 'DeleteNodeCtrl',
|
||||||
|
title: 'Knoten löschen'
|
||||||
|
})
|
||||||
.otherwise({
|
.otherwise({
|
||||||
redirectTo: '/'
|
redirectTo: '/'
|
||||||
});
|
});
|
||||||
|
@ -39,6 +44,9 @@ angular.module('ffffng', [
|
||||||
},
|
},
|
||||||
updateNode: function () {
|
updateNode: function () {
|
||||||
$location.url('/update');
|
$location.url('/update');
|
||||||
|
},
|
||||||
|
deleteNode: function () {
|
||||||
|
$location.url('/delete');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
26
app/scripts/controllers/deleteNodeCtrl.js
Normal file
26
app/scripts/controllers/deleteNodeCtrl.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ffffng')
|
||||||
|
.controller('DeleteNodeCtrl', function ($scope, Navigator, NodeService, config, ConfirmDeletionDialog) {
|
||||||
|
$scope.config = config;
|
||||||
|
$scope.token = undefined;
|
||||||
|
$scope.deleted = false;
|
||||||
|
|
||||||
|
$scope.onSubmitToken = function (token) {
|
||||||
|
$scope.token = token;
|
||||||
|
return NodeService.getNode(token)
|
||||||
|
.success(function (node) {
|
||||||
|
ConfirmDeletionDialog.open(node).result.then(function () {
|
||||||
|
NodeService.deleteNode(token)
|
||||||
|
.success(function () {
|
||||||
|
$scope.deleted = true;
|
||||||
|
$scope.hostname = node.hostname;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.cancel = function () {
|
||||||
|
Navigator.home();
|
||||||
|
};
|
||||||
|
});
|
|
@ -11,4 +11,8 @@ angular.module('ffffng')
|
||||||
$scope.updateNode = function () {
|
$scope.updateNode = function () {
|
||||||
Navigator.updateNode();
|
Navigator.updateNode();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.deleteNode = function () {
|
||||||
|
Navigator.deleteNode();
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
29
app/scripts/dialogs/confirmDeletionDialog.js
Normal file
29
app/scripts/dialogs/confirmDeletionDialog.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('ffffng')
|
||||||
|
.factory('ConfirmDeletionDialog', function ($uibModal, config) {
|
||||||
|
var ctrl = function ($scope, $uibModalInstance, node) {
|
||||||
|
$scope.node = node;
|
||||||
|
$scope.config = config;
|
||||||
|
|
||||||
|
$scope.proceed = function () {
|
||||||
|
$uibModalInstance.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.cancel = function () {
|
||||||
|
$uibModalInstance.dismiss('cancel');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
open: function (node) {
|
||||||
|
return $uibModal.open({
|
||||||
|
controller: ctrl,
|
||||||
|
templateUrl: 'views/dialogs/confirmDeletionDialog.html',
|
||||||
|
resolve: {
|
||||||
|
node: function () { return node; }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -33,7 +33,9 @@ angular.module('ffffng')
|
||||||
'templateUrl': 'views/directives/tokenForm.html',
|
'templateUrl': 'views/directives/tokenForm.html',
|
||||||
'scope': {
|
'scope': {
|
||||||
'onSubmit': '=fSubmit',
|
'onSubmit': '=fSubmit',
|
||||||
'onCancel': '=fCancel'
|
'onCancel': '=fCancel',
|
||||||
|
'submitIcon': '@fSubmitIcon',
|
||||||
|
'submitLabel': '@fSubmitLabel'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,10 @@ angular.module('ffffng')
|
||||||
return $http.put('/api/node/' + token, node);
|
return $http.put('/api/node/' + token, node);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'deleteNode': function (token) {
|
||||||
|
return $http.delete('/api/node/' + token);
|
||||||
|
},
|
||||||
|
|
||||||
'getNode': function (token) {
|
'getNode': function (token) {
|
||||||
return $http.get('/api/node/' + token);
|
return $http.get('/api/node/' + token);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,12 @@
|
||||||
@import "views/_main";
|
@import "views/_main";
|
||||||
@import "views/_newNodeForm";
|
@import "views/_newNodeForm";
|
||||||
@import "views/_updateNodeForm";
|
@import "views/_updateNodeForm";
|
||||||
|
@import "views/_deleteNodeForm";
|
||||||
@import "views/directives/_help";
|
@import "views/directives/_help";
|
||||||
@import "views/directives/_nodeForm";
|
@import "views/directives/_nodeForm";
|
||||||
@import "views/directives/_nodeSaved";
|
@import "views/directives/_nodeSaved";
|
||||||
@import "views/directives/_tokenForm";
|
@import "views/directives/_tokenForm";
|
||||||
|
@import "views/dialogs/_confirmDeletionDialog";
|
||||||
@import "views/dialogs/_outsideOfCommunityDialog";
|
@import "views/dialogs/_outsideOfCommunityDialog";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
|
44
app/styles/views/_deleteNodeForm.scss
Normal file
44
app/styles/views/_deleteNodeForm.scss
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
.delete-node-form {
|
||||||
|
@extend .container;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-deleted {
|
||||||
|
@extend .jumbotron, .container;
|
||||||
|
|
||||||
|
.summary, .actions {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token-hint {
|
||||||
|
font: {
|
||||||
|
weight: bold;
|
||||||
|
size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
.node {
|
||||||
|
@extend .well;
|
||||||
|
|
||||||
|
border: 3px dashed $gray;
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
margin: {
|
||||||
|
top: 30px;
|
||||||
|
bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-button {
|
||||||
|
@extend .btn, .btn-lg, .btn-info;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,11 +9,19 @@
|
||||||
bottom: 25px;
|
bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-node, .update-node {
|
.new-node, .update-node, .delete-node {
|
||||||
@extend .col-md-5;
|
@extend .col-md-4;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@extend .btn, .btn-lg, .btn-block;
|
@extend .btn, .btn-lg, .btn-block;
|
||||||
|
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
padding: {
|
||||||
|
left: 10px;
|
||||||
|
right: 10px;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +37,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.or {
|
.delete-node {
|
||||||
@extend .col-md-2;
|
button {
|
||||||
|
//@extend .btn-link;
|
||||||
text-align: center;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
33
app/styles/views/dialogs/_confirmDeletionDialog.scss
Normal file
33
app/styles/views/dialogs/_confirmDeletionDialog.scss
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
.confirm-deletion-dialog {
|
||||||
|
.modal-header {
|
||||||
|
h3 {
|
||||||
|
@extend .modal-title;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-icon {
|
||||||
|
@extend .fa, .fa-times;
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
top: 10px;
|
||||||
|
right: 0;
|
||||||
|
|
||||||
|
margin-left: 15px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
color: $gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.modal-footer {
|
||||||
|
.proceed {
|
||||||
|
@extend .btn;
|
||||||
|
|
||||||
|
margin-left: 5px;
|
||||||
|
|
||||||
|
&.proceed {
|
||||||
|
@extend .btn-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,8 @@
|
||||||
f-token-form {
|
f-token-form {
|
||||||
|
form {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.main-error {
|
.main-error {
|
||||||
@extend .alert, .alert-danger;
|
@extend .alert, .alert-danger;
|
||||||
}
|
}
|
||||||
|
|
56
app/views/deleteNodeForm.html
Normal file
56
app/views/deleteNodeForm.html
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<div class="delete-node-form" ng-if="!deleted">
|
||||||
|
<h2>Knoten löschen</h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
Um die Daten Deines Knotens zu löschen, benötigen wir den passenden Token (eine 16-stellige Folge aus
|
||||||
|
Ziffern und Buchstaben). Diesen hast Du beim ersten Anmelden Deines Knotens erhalten. Sinn des Tokens ist,
|
||||||
|
Dich davor zu schützen, dass Dritte unbefugt Deine Daten einsehen oder ändern können.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>
|
||||||
|
Solltest Du den Token nicht mehr haben, wende Dich einfach per E-Mail an
|
||||||
|
<a href="mailto:{{ config.community.contactEmail }}">{{ config.community.contactEmail }}</a>.
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
<f-token-form f-submit="onSubmitToken" f-cancel="cancel" f-submit-icon="fa-trash" f-submit-label="Knoten löschen"></f-token-form>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
Hinweis: Nach dem Löschen kann der Knoten ggf. weiterhin in der Knotenkarte angezeigt werden. Dies
|
||||||
|
ist dann der Fall, wenn der Knoten eingeschaltet ist und in Reichweite eines anderen aktiven Knotens
|
||||||
|
steht. Die angezeigten Daten sind dann die während der Einrichtung des Knotens im Config-Mode
|
||||||
|
(Konfigurationsoberfläche des Routers) hinterlegten.
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="node-deleted" ng-if="deleted">
|
||||||
|
<h1>Erledigt!</h1>
|
||||||
|
<p>
|
||||||
|
Die Daten Deines Freifunk-Knotens sind gelöscht worden. Es kann jetzt noch bis zu 20 Minuten dauern,
|
||||||
|
bis die Änderungen überall wirksam werden und sich im <a href="{{ config.map.graphUrl }}" target="_blank">Knotengraph</a>
|
||||||
|
und in der <a href="{{ config.map.mapUrl }}" target="_blank">Knotenkarte</a> auswirken.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="summary">
|
||||||
|
<span class="node">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
{{hostname}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<button class="back-button" ng-click="goHome()"><i class="fa fa-reply"></i> Zurück zum Anfang</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<em>
|
||||||
|
Hinweis: Nach dem Löschen kann der Knoten ggf. weiterhin in der Knotenkarte angezeigt werden. Dies
|
||||||
|
ist dann der Fall, wenn der Knoten eingeschaltet ist und in Reichweite eines anderen aktiven Knotens
|
||||||
|
steht. Die angezeigten Daten sind dann die während der Einrichtung des Knotens im Config-Mode
|
||||||
|
(Konfigurationsoberfläche des Routers) hinterlegten.
|
||||||
|
</em>
|
||||||
|
</p>
|
||||||
|
</div>
|
18
app/views/dialogs/confirmDeletionDialog.html
Normal file
18
app/views/dialogs/confirmDeletionDialog.html
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<div class="confirm-deletion-dialog">
|
||||||
|
<div class="modal-header">
|
||||||
|
<i class="cancel-icon" ng-click="cancel()"></i>
|
||||||
|
<h3>Soll der Knoten wirklich gelöscht werden?</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>
|
||||||
|
Soll der Knoten „{{node.hostname}}“ wirklich endgültig gelöscht werden?
|
||||||
|
Du kannst ihn selbstverständlich später jederzeit erneut anmelden!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="cancel" ng-click="cancel()">Abbrechen</button>
|
||||||
|
<button class="proceed" ng-click="proceed()">
|
||||||
|
<i class="fa fa-trash"></i> Knoten löschen
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -10,7 +10,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button class="submit" type="submit">
|
<button class="submit" type="submit">
|
||||||
<i class="fa fa-pencil"></i> Knotendaten ändern
|
<i class="fa {{submitIcon}}"></i> {{submitLabel}}
|
||||||
</button>
|
</button>
|
||||||
<button class="cancel" type="reset" ng-click="onCancel()">
|
<button class="cancel" type="reset" ng-click="onCancel()">
|
||||||
<i class="fa fa-times"></i> Abbrechen
|
<i class="fa fa-times"></i> Abbrechen
|
||||||
|
|
|
@ -2,22 +2,24 @@
|
||||||
<h1>Willkommen!</h1>
|
<h1>Willkommen!</h1>
|
||||||
<p>
|
<p>
|
||||||
Du hast einen neuen {{ config.community.name }} Router (Knoten), den Du in Betrieb nehmen möchtest? Du hast
|
Du hast einen neuen {{ config.community.name }} Router (Knoten), den Du in Betrieb nehmen möchtest? Du hast
|
||||||
schon einen Knoten in Betrieb und möchtest seine Daten ändern? Dann bist Du hier richtig!
|
schon einen Knoten in Betrieb und möchtest seine Daten ändern? Oder Du möchtest einen Knoten, der nicht mehr
|
||||||
|
in Betrieb ist löschen? Dann bist Du hier richtig!
|
||||||
</p>
|
</p>
|
||||||
<div class="select-action">
|
<div class="select-action">
|
||||||
<div class="new-node">
|
<div class="new-node">
|
||||||
<button ng-click="newNode()"><i class="fa fa-dot-circle-o"></i> Melde einen neuen Knoten an</button>
|
<button ng-click="newNode()">
|
||||||
|
<i class="fa fa-dot-circle-o"></i> Neuen Knoten anmelden
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="or">oder</div>
|
|
||||||
<div class="update-node">
|
<div class="update-node">
|
||||||
<button ng-click="updateNode()"><i class="fa fa-pencil"></i> Ändere die Daten Deines Knotens</button>
|
<button ng-click="updateNode()">
|
||||||
|
<i class="fa fa-pencil"></i> Knotendaten ändern
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="delete-node">
|
||||||
|
<button ng-click="deleteNode()">
|
||||||
|
<i class="fa fa-trash"></i> Knoten löschen
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>
|
|
||||||
<strong>
|
|
||||||
Hinweis:
|
|
||||||
Zum Entfernen von Knoten wende Dich bitte per E-Mail an
|
|
||||||
<a href="mailto:{{ config.community.contactEmail }}">{{ config.community.contactEmail }}</a>.
|
|
||||||
</strong>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<a href="mailto:{{ config.community.contactEmail }}">{{ config.community.contactEmail }}</a>.
|
<a href="mailto:{{ config.community.contactEmail }}">{{ config.community.contactEmail }}</a>.
|
||||||
</strong>
|
</strong>
|
||||||
</p>
|
</p>
|
||||||
<f-token-form f-submit="onSubmitToken" f-cancel="cancel"></f-token-form>
|
<f-token-form f-submit="onSubmitToken" f-cancel="cancel" f-submit-icon="fa-pencil" f-submit-label="Knotendaten ändern"></f-token-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div ng-if="hasData()">
|
<div ng-if="hasData()">
|
||||||
|
|
|
@ -80,6 +80,22 @@ angular.module('ffffng').factory('NodeResource', function (
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
delete: function (req, res) {
|
||||||
|
var data = getData(req);
|
||||||
|
|
||||||
|
var token = Strings.normalizeString(data.token);
|
||||||
|
if (!isValidToken(token)) {
|
||||||
|
return error(res, {data: 'Invalid token.', type: ErrorTypes.badRequest});
|
||||||
|
}
|
||||||
|
|
||||||
|
return NodeService.deleteNode(token, function (err) {
|
||||||
|
if (err) {
|
||||||
|
return error(res, err);
|
||||||
|
}
|
||||||
|
return success(res, {});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
get: function (req, res) {
|
get: function (req, res) {
|
||||||
var token = Strings.normalizeString(getData(req).token);
|
var token = Strings.normalizeString(getData(req).token);
|
||||||
if (!isValidToken(token)) {
|
if (!isValidToken(token)) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ angular.module('ffffng').factory('Router', function (app, NodeResource) {
|
||||||
init: function () {
|
init: function () {
|
||||||
app.post('/api/node', NodeResource.create);
|
app.post('/api/node', NodeResource.create);
|
||||||
app.put('/api/node/:token', NodeResource.update);
|
app.put('/api/node/:token', NodeResource.update);
|
||||||
|
app.delete('/api/node/:token', NodeResource.delete);
|
||||||
app.get('/api/node/:token', NodeResource.get);
|
app.get('/api/node/:token', NodeResource.get);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,6 +101,23 @@ angular.module('ffffng')
|
||||||
return callback(null, token, node);
|
return callback(null, token, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteNodeFile(token, callback) {
|
||||||
|
var files = findNodeFiles('*@*@*@' + token);
|
||||||
|
if (files.length !== 1) {
|
||||||
|
return callback({data: 'Node not found.', type: ErrorTypes.notFound});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.unlinkSync(files[0]);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
return callback({data: 'Could not delete node.', type: ErrorTypes.internalError});
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
function parseNodeFile(file, callback) {
|
function parseNodeFile(file, callback) {
|
||||||
var lines = fs.readFileSync(file).toString();
|
var lines = fs.readFileSync(file).toString();
|
||||||
|
|
||||||
|
@ -140,6 +157,10 @@ angular.module('ffffng')
|
||||||
writeNodeFile(true, token, node, callback);
|
writeNodeFile(true, token, node, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deleteNode: function (token, callback) {
|
||||||
|
deleteNodeFile(token, callback);
|
||||||
|
},
|
||||||
|
|
||||||
getNodeData: function (token, callback) {
|
getNodeData: function (token, callback) {
|
||||||
var files = findNodeFiles('*@*@*@' + token);
|
var files = findNodeFiles('*@*@*@' + token);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue