Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Gutyán Gábor
/
circlestack
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
98577a78
authored
Aug 11, 2014
by
Kálmán Viktor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dashboard: js part of mass vm ops
parent
af03144a
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
104 additions
and
72 deletions
+104
-72
circle/dashboard/static/dashboard/vm-list.js
+65
-63
circle/dashboard/templates/dashboard/vm-list.html
+14
-6
circle/dashboard/views.py
+20
-3
circle/vm/models/instance.py
+5
-0
No files found.
circle/dashboard/static/dashboard/vm-list.js
View file @
98577a78
...
...
@@ -60,23 +60,6 @@ $(function() {
return
retval
;
});
$
(
'#vm-list-group-migrate'
).
click
(
function
()
{
// pass?
});
$
(
'.vm-list-details'
).
popover
({
'placement'
:
'auto'
,
'html'
:
true
,
'trigger'
:
'hover'
});
$
(
'.vm-list-connect'
).
popover
({
'placement'
:
'left'
,
'html'
:
true
,
'trigger'
:
'click'
});
$
(
'tbody a'
).
mousedown
(
function
(
e
)
{
// parent tr doesn't get selected when clicked
e
.
stopPropagation
();
...
...
@@ -89,43 +72,7 @@ $(function() {
}
});
/* rename */
$
(
"#vm-list-rename-button, .vm-details-rename-button"
).
click
(
function
()
{
$
(
"#vm-list-column-name"
,
$
(
this
).
closest
(
"tr"
)).
hide
();
$
(
"#vm-list-rename"
,
$
(
this
).
closest
(
"tr"
)).
css
(
'display'
,
'inline'
);
$
(
"#vm-list-rename-name"
,
$
(
this
).
closest
(
"tr"
)).
focus
();
});
/* rename ajax */
$
(
'.vm-list-rename-submit'
).
click
(
function
()
{
var
row
=
$
(
this
).
closest
(
"tr"
)
var
name
=
$
(
'#vm-list-rename-name'
,
row
).
val
();
var
url
=
'/dashboard/vm/'
+
row
.
children
(
"td:first-child"
).
text
().
replace
(
" "
,
""
)
+
'/'
;
$
.
ajax
({
method
:
'POST'
,
url
:
url
,
data
:
{
'new_name'
:
name
},
headers
:
{
"X-CSRFToken"
:
getCookie
(
'csrftoken'
)},
success
:
function
(
data
,
textStatus
,
xhr
)
{
$
(
"#vm-list-column-name"
,
row
).
html
(
$
(
"<a/>"
,
{
'class'
:
"real-link"
,
href
:
"/dashboard/vm/"
+
data
[
'vm_pk'
]
+
"/"
,
text
:
data
[
'new_name'
]
})
).
show
();
$
(
'#vm-list-rename'
,
row
).
hide
();
// addMessage(data['message'], "success");
},
error
:
function
(
xhr
,
textStatus
,
error
)
{
addMessage
(
"Error during renaming!"
,
"danger"
);
}
});
return
false
;
});
/* group actions */
/* select all */
...
...
@@ -143,17 +90,28 @@ $(function() {
return
false
;
});
/* mass vm delete */
$
(
'#vm-list-group-delete'
).
click
(
function
()
{
addModalConfirmation
(
massDeleteVm
,
{
'url'
:
'/dashboard/vm/mass-delete/'
,
'data'
:
{
'selected'
:
selected
,
'v'
:
collectIds
(
selected
)
}
/* mass operations */
$
(
"#vm-mass-ops"
).
on
(
'click'
,
'.mass-operation'
,
function
(
e
)
{
var
icon
=
$
(
this
).
children
(
"i"
).
addClass
(
'fa-spinner fa-spin'
);
params
=
"?a"
;
for
(
var
i
=
0
;
i
<
selected
.
length
;
i
++
)
{
params
+=
"&vm="
+
selected
[
i
].
vm
;
}
$
.
ajax
({
type
:
'GET'
,
url
:
$
(
this
).
attr
(
'href'
)
+
params
,
success
:
function
(
data
)
{
icon
.
removeClass
(
"fa-spinner fa-spin"
);
$
(
'body'
).
append
(
data
);
$
(
'#confirmation-modal'
).
modal
(
'show'
);
$
(
'#confirmation-modal'
).
on
(
'hidden.bs.modal'
,
function
()
{
$
(
'#confirmation-modal'
).
remove
();
});
$
(
"[title]"
).
tooltip
({
'placement'
:
"left"
});
}
);
}
);
return
false
;
});
...
...
@@ -181,8 +139,52 @@ $(function() {
$
(
".vm-list-table th a"
).
on
(
"click"
,
function
(
event
)
{
event
.
preventDefault
();
});
if
(
checkStatusUpdate
())
{
updateStatuses
(
1
);
}
});
function
checkStatusUpdate
()
{
if
(
$
(
"#vm-list-table tbody td.state i"
).
hasClass
(
"fa-spin"
))
{
return
true
;
}
}
function
updateStatuses
(
runs
)
{
$
.
get
(
"/dashboard/vm/list/?compact"
,
function
(
result
)
{
$
(
"#vm-list-table tbody tr"
).
each
(
function
()
{
vm
=
$
(
this
).
data
(
"vm-pk"
);
status_td
=
$
(
this
).
find
(
"td.state"
);
status_icon
=
status_td
.
find
(
"i"
);
status_text
=
status_td
.
find
(
"span"
);
if
(
vm
in
result
)
{
if
(
result
[
vm
].
in_status_change
)
{
if
(
!
status_icon
.
hasClass
(
"fa-spin"
))
{
status_icon
.
prop
(
"class"
,
"fa fa-spinner fa-spin"
);
}
}
else
{
status_icon
.
prop
(
"class"
,
"fa "
+
result
[
vm
].
icon
);
}
status_text
.
text
(
result
[
vm
].
status
);
}
else
{
$
(
this
).
remove
();
}
});
if
(
checkStatusUpdate
())
{
setTimeout
(
function
()
{
updateStatuses
(
runs
+
1
)},
1000
+
Math
.
exp
(
runs
*
0.05
)
);
}
});
}
function
isAlreadySelected
(
vm
)
{
for
(
var
i
=
0
;
i
<
selected
.
length
;
i
++
)
if
(
selected
[
i
].
vm
==
vm
)
...
...
circle/dashboard/templates/dashboard/vm-list.html
View file @
98577a78
...
...
@@ -23,13 +23,14 @@
</div>
</form>
</div>
<
p
>
<
div
id=
"vm-mass-ops"
>
{% for o in ops %}
<a
href=
"{{ o.get_url }}"
class=
"btn btn-xs btn-{{ o.effect }}"
title=
"{{ o.name }}"
>
<a
href=
"{{ o.get_url }}"
class=
"btn btn-xs btn-{{ o.effect }} mass-operation"
title=
"{{ o.name }}"
>
<i
class=
"fa fa-{{ o.icon }}"
></i>
</a>
{% endfor %}
</
p
>
</
div
>
<div
class=
"panel-body vm-list-group-control"
>
<p>
<strong>
{% trans "Group actions" %}
</strong>
...
...
@@ -41,7 +42,8 @@
</p>
</div>
<div
class=
"panel-body"
>
<table
class=
"table table-bordered table-striped table-hover vm-list-table"
>
<table
class=
"table table-bordered table-striped table-hover vm-list-table"
id=
"vm-list-table"
>
<thead><tr>
<th
data-sort=
"int"
class=
"orderable pk sortable vm-list-table-thin"
style=
"min-width: 50px;"
>
{% trans "ID" as t %}
...
...
@@ -68,7 +70,14 @@
<tr
class=
"{% cycle 'odd' 'even' %}"
data-vm-pk=
"{{ i.pk }}"
>
<td
class=
"pk"
><div
id=
"vm-{{i.pk}}"
>
{{i.pk}}
</div>
</td>
<td
class=
"name"
><a
class=
"real-link"
href=
"{% url "
dashboard
.
views
.
detail
"
i
.
pk
%}"
>
{{ i.name }}
</a>
</td>
<td
class=
"state"
>
{{ i.get_status_display }}
</td>
<td
class=
"state"
>
<i
class=
"fa
{% if i.is_in_status_change %}
fa-spin fa-spinner
{% else %}
{{ i.get_status_icon }}{% endif %}"
></i>
<span>
{{ i.get_status_display }}
</span>
</td>
<td>
{% include "dashboard/_display-name.html" with user=i.owner show_org=True %}
</td>
...
...
@@ -104,6 +113,5 @@
{% block extra_js %}
<script
src=
"{{ STATIC_URL}}dashboard/vm-list.js"
></script>
<script
src=
"{{ STATIC_URL}}dashboard/vm-common.js"
></script>
<script
src=
"{{ STATIC_URL}}dashboard/js/stupidtable.min.js"
></script>
{% endblock %}
circle/dashboard/views.py
View file @
98577a78
...
...
@@ -1648,6 +1648,24 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
def
get
(
self
,
*
args
,
**
kwargs
):
if
self
.
request
.
is_ajax
():
return
self
.
_create_ajax_request
()
else
:
return
super
(
VmList
,
self
)
.
get
(
*
args
,
**
kwargs
)
def
_create_ajax_request
(
self
):
if
self
.
request
.
GET
.
get
(
"compact"
)
is
not
None
:
instances
=
Instance
.
get_objects_with_level
(
"user"
,
self
.
request
.
user
)
.
filter
(
destroyed_at
=
None
)
statuses
=
{}
for
i
in
instances
:
statuses
[
i
.
pk
]
=
{
'status'
:
i
.
get_status_display
(),
'icon'
:
i
.
get_status_icon
(),
'in_status_change'
:
i
.
is_in_status_change
(),
}
return
HttpResponse
(
json
.
dumps
(
statuses
),
content_type
=
"application/json"
)
else
:
favs
=
Instance
.
objects
.
filter
(
favourite__user
=
self
.
request
.
user
)
.
values_list
(
'pk'
,
flat
=
True
)
instances
=
Instance
.
get_objects_with_level
(
...
...
@@ -1659,13 +1677,12 @@ class VmList(LoginRequiredMixin, FilterMixin, ListView):
'icon'
:
i
.
get_status_icon
(),
'host'
:
""
if
not
i
.
primary_host
else
i
.
primary_host
.
hostname
,
'status'
:
i
.
get_status_display
(),
'fav'
:
i
.
pk
in
favs
}
for
i
in
instances
]
'fav'
:
i
.
pk
in
favs
,
}
for
i
in
instances
]
return
HttpResponse
(
json
.
dumps
(
list
(
instances
)),
# instances is ValuesQuerySet
content_type
=
"application/json"
,
)
else
:
return
super
(
VmList
,
self
)
.
get
(
*
args
,
**
kwargs
)
def
get_queryset
(
self
):
logger
.
debug
(
'VmList.get_queryset() called. User:
%
s'
,
...
...
circle/vm/models/instance.py
View file @
98577a78
...
...
@@ -988,3 +988,8 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, OperatedMixin,
instance
=
self
,
succeeded
=
None
,
parent
=
None
)
.
latest
(
"started"
)
except
InstanceActivity
.
DoesNotExist
:
return
None
def
is_in_status_change
(
self
):
latest
=
self
.
get_latest_activity_in_progress
()
return
(
latest
and
latest
.
resultant_state
is
not
None
and
self
.
status
!=
latest
.
resultant_state
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment