mirror of https://github.com/jumpserver/jumpserver
[Update] 支持拖拽更新
parent
5a0068d86a
commit
1018deda96
|
@ -19,7 +19,7 @@ from rest_framework.response import Response
|
|||
from rest_framework_bulk import BulkModelViewSet
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common.utils import get_logger
|
||||
from common.utils import get_logger, get_object_or_none
|
||||
from ..hands import IsSuperUser
|
||||
from ..models import Node
|
||||
from .. import serializers
|
||||
|
@ -29,6 +29,7 @@ logger = get_logger(__file__)
|
|||
__all__ = [
|
||||
'NodeViewSet', 'NodeChildrenApi',
|
||||
'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
|
||||
'NodeAddChildrenApi',
|
||||
]
|
||||
|
||||
|
||||
|
@ -75,6 +76,24 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
|
|||
return Response(response, status=200)
|
||||
|
||||
|
||||
class NodeAddChildrenApi(generics.UpdateAPIView):
|
||||
queryset = Node.objects.all()
|
||||
permission_classes = (IsSuperUser,)
|
||||
serializer_class = serializers.NodeAddChildrenSerializer
|
||||
instance = None
|
||||
|
||||
def put(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
nodes_id = request.data.get("nodes")
|
||||
children = [get_object_or_none(Node, id=pk) for pk in nodes_id]
|
||||
for node in children:
|
||||
if not node:
|
||||
continue
|
||||
node.parent = instance
|
||||
node.save()
|
||||
return Response("OK")
|
||||
|
||||
|
||||
class NodeAddAssetsApi(generics.UpdateAPIView):
|
||||
serializer_class = serializers.NodeAssetsSerializer
|
||||
queryset = Node.objects.all()
|
||||
|
|
|
@ -94,6 +94,10 @@ class Node(models.Model):
|
|||
else:
|
||||
return parent
|
||||
|
||||
@parent.setter
|
||||
def parent(self, parent):
|
||||
self.key = parent.get_next_child_key()
|
||||
|
||||
@property
|
||||
def ancestor(self):
|
||||
if self.parent == self.__class__.root():
|
||||
|
|
|
@ -65,4 +65,8 @@ class NodeAssetsSerializer(serializers.ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = Node
|
||||
fields = ['assets']
|
||||
fields = ['assets']
|
||||
|
||||
|
||||
class NodeAddChildrenSerializer(serializers.Serializer):
|
||||
nodes = serializers.ListField()
|
||||
|
|
|
@ -224,6 +224,7 @@ function editTreeNode() {
|
|||
if (!current_node){
|
||||
return
|
||||
}
|
||||
current_node.name = current_node.value;
|
||||
zTree.editName(current_node);
|
||||
}
|
||||
|
||||
|
@ -308,6 +309,44 @@ function selectQueryNode() {
|
|||
}
|
||||
}
|
||||
|
||||
function beforeDrag() {
|
||||
return true
|
||||
}
|
||||
|
||||
function beforeDrop() {
|
||||
return true
|
||||
}
|
||||
|
||||
function onDrag(event, treeId, treeNodes) {
|
||||
}
|
||||
|
||||
function onDrop(event, treeId, treeNodes, targetNode, moveType) {
|
||||
console.log("DROP");
|
||||
console.log(event);
|
||||
console.log(treeNodes);
|
||||
console.log(targetNode);
|
||||
console.log(moveType);
|
||||
|
||||
var treeNodesNames = [];
|
||||
var treeNodesIds = [];
|
||||
$.each(treeNodes, function (index, value) {
|
||||
treeNodesNames.push(value.value);
|
||||
treeNodesIds.push(value.id);
|
||||
});
|
||||
|
||||
var msg = "你想移动节点: `" + treeNodesNames.join(",") + "` 到 `" + targetNode.value + "` 下吗?";
|
||||
var the_url = "{% url 'api-assets:node-add-children' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", targetNode.id);
|
||||
var body = {nodes: treeNodesIds};
|
||||
if (confirm(msg)){
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
method: "PUT",
|
||||
body: JSON.stringify(body)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function initTree() {
|
||||
var setting = {
|
||||
view: {
|
||||
|
@ -319,11 +358,24 @@ function initTree() {
|
|||
enable: true
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
enable: true,
|
||||
showRemoveBtn: false,
|
||||
showRenameBtn: false,
|
||||
drag: {
|
||||
isCopy: true,
|
||||
isMove: true
|
||||
}
|
||||
},
|
||||
callback: {
|
||||
onRightClick: OnRightClick,
|
||||
beforeClick: beforeClick,
|
||||
onRename: onRename,
|
||||
onSelected: onSelected
|
||||
onSelected: onSelected,
|
||||
beforeDrag: beforeDrag,
|
||||
onDrag: onDrag,
|
||||
beforeDrop: beforeDrop,
|
||||
onDrop: onDrop
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -334,7 +386,8 @@ function initTree() {
|
|||
{#if (value["key"] === "0") {#}
|
||||
value["open"] = true;
|
||||
{# }#}
|
||||
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')'
|
||||
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
|
||||
value['value'] = value['value'];
|
||||
});
|
||||
zNodes = data;
|
||||
$.fn.zTree.init($("#assetTree"), setting, zNodes);
|
||||
|
|
|
@ -44,6 +44,7 @@ urlpatterns = [
|
|||
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
|
||||
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
|
||||
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'),
|
||||
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'),
|
||||
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
|
||||
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
|
||||
]
|
||||
|
|
|
@ -215,16 +215,6 @@ $(document).ready(function(){
|
|||
initTable();
|
||||
initTree();
|
||||
})
|
||||
.on('click', '.btn-create-asset', function () {
|
||||
var url = "{% url 'assets:asset-create' %}";
|
||||
var nodes = zTree.getSelectedNodes();
|
||||
var current_node;
|
||||
if (nodes && nodes.length ===1 ){
|
||||
current_node = nodes[0];
|
||||
url += "?node=" + current_node.id;
|
||||
}
|
||||
window.open(url, '_self');
|
||||
})
|
||||
.on('click', '.btn-del', function () {
|
||||
var $this = $(this);
|
||||
var uid = $this.data('uid');
|
||||
|
@ -241,7 +231,7 @@ $(document).ready(function(){
|
|||
current_node = nodes[0];
|
||||
url += "?node_id=" + current_node.id;
|
||||
}
|
||||
window.open(url);
|
||||
window.open(url, '_self');
|
||||
})
|
||||
|
||||
</script>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
极致的用户使用体验:拥有时尚外观是区别与以往版本和其他软件的铭牌,高雅的气质让你爱不释手;
|
||||
</p>
|
||||
<p>
|
||||
混合云环境下的堡垒机:怎么能容忍传统堡垒机的繁琐步骤,Jumpserver让你极致省力。
|
||||
混合云环境下的堡垒机:怎么能容忍传统堡垒机的繁琐步骤,Jumpserver让你极致省力;
|
||||
</p>
|
||||
<p>
|
||||
<small>改变世界,从一点点开始。</small>
|
||||
|
|
Loading…
Reference in New Issue