Revision 0e2122e7
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/app.js | ||
---|---|---|
1 |
window.App = Ember.Application.create();
|
|
1 |
window.Snf = Ember.Application.create();
|
|
2 | 2 |
|
3 |
App.ApplicationAdapter = DS.FixtureAdapter; |
|
4 |
|
|
5 |
App.RawTransform = DS.Transform.extend({ |
|
6 |
deserialize: function(serialized) { |
|
7 |
return serialized; |
|
8 |
}, |
|
9 |
serialize: function(deserialized) { |
|
10 |
return deserialized; |
|
11 |
} |
|
12 |
}); |
|
3 |
Snf.ApplicationAdapter = DS.FixtureAdapter; |
/dev/null | ||
---|---|---|
1 |
App.DetailsContentComponent = Ember.Component.extend({ |
|
2 |
classNames: ['content'], |
|
3 |
tagName: 'section', |
|
4 |
}); |
/dev/null | ||
---|---|---|
1 |
App.EditablePropComponent = Ember.Component.extend({ |
|
2 |
|
|
3 |
tagName: 'div', |
|
4 |
classNames: ['editable'], |
|
5 |
layoutName: 'editable-prop', |
|
6 |
isEditable: false, |
|
7 |
|
|
8 |
actions: { |
|
9 |
allowEdit: function(){ |
|
10 |
this.set('isEditable', true); |
|
11 |
}, |
|
12 |
acceptEditableChanges: function(){ |
|
13 |
this.set('isEditable', false); |
|
14 |
this.sendAction('ok'); |
|
15 |
}, |
|
16 |
} |
|
17 |
|
|
18 |
}); |
/dev/null | ||
---|---|---|
1 |
App.NetworkElComponent = Ember.Component.extend({ |
|
2 |
tagName: 'section', |
|
3 |
}); |
/dev/null | ||
---|---|---|
1 |
App.RevealModalComponent = Ember.Component.extend({ |
|
2 |
classNames: ['inner-modal'], |
|
3 |
actions: { |
|
4 |
ok: function () { |
|
5 |
this.sendAction("ok", this.get('param')); |
|
6 |
$(this.$()[0]).foundation('reveal', 'close'); |
|
7 |
}, |
|
8 |
close: function () { |
|
9 |
$(this.$()[0]).foundation('reveal', 'close'); |
|
10 |
}, |
|
11 |
}, |
|
12 |
}); |
/dev/null | ||
---|---|---|
1 |
App.TagElComponent = Ember.Component.extend({ |
|
2 |
tagName: 'li', |
|
3 |
title:'tag1', |
|
4 |
color: 'yellow', |
|
5 |
style: function () { |
|
6 |
return 'background-color:'+this.color; |
|
7 |
}.property('color'), |
|
8 |
|
|
9 |
didInsertElement: function() { |
|
10 |
this.$().find('.tag').attr('data-tooltip',''); |
|
11 |
Foundation.libs.tooltips.init(); |
|
12 |
}, |
|
13 |
|
|
14 |
actions: { |
|
15 |
deleteTag: function() { |
|
16 |
this.sendAction('deleteTag', this.get('param')); |
|
17 |
}, |
|
18 |
}, |
|
19 |
|
|
20 |
}); |
/dev/null | ||
---|---|---|
1 |
App.ItemsItemController = Ember.ObjectController.extend({ |
|
2 |
|
|
3 |
codeName: 'vm', |
|
4 |
|
|
5 |
needs: [], |
|
6 |
|
|
7 |
hasViewCls: true, |
|
8 |
|
|
9 |
// i would like to get it from parent controller ???? |
|
10 |
icon: function () { |
|
11 |
var item = this.codeName; |
|
12 |
return 'snf-'+item+'-full'; |
|
13 |
}.property(), |
|
14 |
|
|
15 |
hasTags: true, |
|
16 |
|
|
17 |
hasConnect: false, |
|
18 |
|
|
19 |
codeNameParent: function() { |
|
20 |
return this.codeName+'s'; |
|
21 |
}.property(), |
|
22 |
|
|
23 |
codeNameChildInit: function() { |
|
24 |
return this.codeName+'init'; |
|
25 |
}.property(), |
|
26 |
|
|
27 |
actions : { |
|
28 |
saveModel: function(){ |
|
29 |
this.get('model').save(); |
|
30 |
}, |
|
31 |
|
|
32 |
} |
|
33 |
|
|
34 |
|
|
35 |
}); |
/dev/null | ||
---|---|---|
1 |
App.ItemsListController = Ember.ArrayController.extend({ |
|
2 |
|
|
3 |
codeName: '', |
|
4 |
|
|
5 |
// returns the same as codename, i.e. networks, serves as page title |
|
6 |
title: function () { |
|
7 |
return this.codeName; |
|
8 |
}.property(), |
|
9 |
|
|
10 |
// returns codename without an 's', i.e. network |
|
11 |
_item: function () { |
|
12 |
return this.codeName.substring(0, this.codeName.length - 1); |
|
13 |
}.property(), |
|
14 |
|
|
15 |
// returns codename without an 's', i.e. network |
|
16 |
itemController: function () { |
|
17 |
return this.get('_item'); |
|
18 |
}.property(), |
|
19 |
|
|
20 |
// returns snf-network-full |
|
21 |
iconCls: function () { |
|
22 |
return 'snf-'+this.get('_item')+'-full'; |
|
23 |
}.property(), |
|
24 |
|
|
25 |
// returns snf-network-create-full |
|
26 |
newIcon: function () { |
|
27 |
return 'snf-'+this.get('_item')+'-create-full'; |
|
28 |
}.property(), |
|
29 |
|
|
30 |
// returns Create new network |
|
31 |
newTxt: function () { |
|
32 |
return 'Create new '+this.get('_item'); |
|
33 |
}.property(), |
|
34 |
|
|
35 |
// enables grid/list view in action bar |
|
36 |
hasViewCls: true, |
|
37 |
|
|
38 |
// enables search functionality action bar |
|
39 |
hasSearch: true, |
|
40 |
|
|
41 |
// enables filtering in action bar |
|
42 |
hasFilter: true, |
|
43 |
|
|
44 |
codeNameParent: function () { |
|
45 |
return this.codeName; |
|
46 |
}.property(), |
|
47 |
|
|
48 |
codeNameChildInit: function () { |
|
49 |
return this.get('_item')+'init'; |
|
50 |
}.property(), |
|
51 |
|
|
52 |
}); |
|
53 |
|
|
54 |
|
|
55 |
App.NetworksController = App.ItemsListController.extend({ |
|
56 |
codeName : 'networks', |
|
57 |
}); |
|
58 |
|
|
59 |
|
|
60 |
App.VmsController = App.ItemsListController.extend({ |
|
61 |
codeName : 'vms', |
|
62 |
newIcon : 'snf-pc-create-full', |
|
63 |
iconCls : 'snf-pc-full', |
|
64 |
}); |
|
65 |
|
|
66 |
|
|
67 |
App.VolumesController = App.ItemsListController.extend({ |
|
68 |
codeName : 'volumes', |
|
69 |
}); |
|
70 |
|
|
71 |
App.TagsController = Ember.ArrayController.extend(); |
/dev/null | ||
---|---|---|
1 |
App.NetworkController = App.ItemsItemController.extend({ |
|
2 |
|
|
3 |
codeName: 'network', |
|
4 |
|
|
5 |
actionsMeta: function() { |
|
6 |
var enabledActions = this.get('model').get('enabledActions'); |
|
7 |
return _.map(enabledActions, function(val,key) { return actionsMetaNetwork[val]; }); |
|
8 |
}.property('model.enabledActions'), |
|
9 |
|
|
10 |
submenu: [ |
|
11 |
{ |
|
12 |
'link': 'network.info', |
|
13 |
'icon': 'snf-info-outline', |
|
14 |
}, |
|
15 |
{ |
|
16 |
'link': 'network.vm-connected', |
|
17 |
'icon': 'snf-pc-outline', |
|
18 |
}, |
|
19 |
], |
|
20 |
actions: { |
|
21 |
destroyNetwork: function(){ |
|
22 |
this.get('model').deleteRecord(); |
|
23 |
this.get('model').save(); |
|
24 |
this.transitionToRoute('networks.grid-view'); |
|
25 |
}, |
|
26 |
} |
|
27 |
}); |
/dev/null | ||
---|---|---|
1 |
App.TagController = Ember.ObjectController.extend({ |
|
2 |
actions: { |
|
3 |
createTag: function(data, model) { |
|
4 |
var tag = this.store.createRecord('tag', data); |
|
5 |
tag.save(); |
|
6 |
|
|
7 |
// model can be any model class instance which |
|
8 |
// shares the tags interface used below. |
|
9 |
if (model) { |
|
10 |
model.get('tags').addObject(tag); |
|
11 |
} |
|
12 |
} |
|
13 |
}, |
|
14 |
}); |
|
15 |
|
|
16 |
|
|
17 |
var _defaultNewTagColor = '#16C1E9'; |
|
18 |
|
|
19 |
App.AddTagController = App.TagController.extend({ |
|
20 |
newTagName: '', |
|
21 |
newTagColor: _defaultNewTagColor, |
|
22 |
closed: false, |
|
23 |
actions: { |
|
24 |
handleSubmit: function() { |
|
25 |
// resolve form params |
|
26 |
var tagDetails = { |
|
27 |
name: this.get('newTagName'), |
|
28 |
color: this.get('newTagColor') |
|
29 |
}; |
|
30 |
|
|
31 |
// validate ??? |
|
32 |
// failed validation messages ??? |
|
33 |
|
|
34 |
// do create tag |
|
35 |
this.send('createTag', tagDetails, this.get('model')); |
|
36 |
|
|
37 |
// hide form (view should use this attr) |
|
38 |
this.set('closed', true); |
|
39 |
|
|
40 |
// reset the newTagXXX shit |
|
41 |
this.set('newTagName', ''); |
|
42 |
this.set('newTagColor', _defaultNewTagColor); |
|
43 |
} |
|
44 |
} |
|
45 |
}); |
/dev/null | ||
---|---|---|
1 |
App.VmController =App.ItemsItemController.extend({ |
|
2 |
icon: 'snf-pc-full', |
|
3 |
|
|
4 |
hasConnect: true, |
|
5 |
|
|
6 |
actionsMeta: function() { |
|
7 |
var enabledActions = this.get('model').get('enabledActions'); |
|
8 |
return _.map(enabledActions, function(val,key) { return actionsMetaVm[val]; }); |
|
9 |
}.property('model.enabledActions'), |
|
10 |
|
|
11 |
submenu: [ |
|
12 |
{ |
|
13 |
'link': 'vm.info', |
|
14 |
'icon': 'snf-info-outline', |
|
15 |
}, |
|
16 |
{ |
|
17 |
'link': 'vm.disk-connected', |
|
18 |
'icon': 'snf-volume-outline', |
|
19 |
}, |
|
20 |
{ |
|
21 |
'link': 'vm.network-connected', |
|
22 |
'icon': 'snf-network-outline', |
|
23 |
} |
|
24 |
], |
|
25 |
|
|
26 |
actions: { |
|
27 |
|
|
28 |
deleteTag: function(tag) { |
|
29 |
this.get('model').get('tags').removeObject(tag); |
|
30 |
}, |
|
31 |
|
|
32 |
dettachVolume: function(volume){ |
|
33 |
volume.get('vm').get('volumes').removeObject(volume); |
|
34 |
}, |
|
35 |
|
|
36 |
rebootVm: function(){ |
|
37 |
this.get('model').set('status','rebooting'); |
|
38 |
var that = this; |
|
39 |
setTimeout(function(){ |
|
40 |
that.get('model').set('status','running'); |
|
41 |
},3000); |
|
42 |
}, |
|
43 |
|
|
44 |
destroyVm: function(){ |
|
45 |
this.get('model').deleteRecord(); |
|
46 |
this.get('model').save(); |
|
47 |
this.transitionToRoute('vms.grid-view'); |
|
48 |
}, |
|
49 |
|
|
50 |
shutdownVm: function(){ |
|
51 |
this.get('model').set('status','shutting'); |
|
52 |
var that = this; |
|
53 |
setTimeout(function(){ |
|
54 |
that.get('model').set('status','off'); |
|
55 |
},3000); |
|
56 |
}, |
|
57 |
|
|
58 |
startVm: function(){ |
|
59 |
this.get('model').set('status','running'); |
|
60 |
}, |
|
61 |
}, |
|
62 |
}); |
|
63 |
|
|
64 |
App.VmInfoController = App.VmController.extend(); |
|
65 |
|
|
66 |
App.VmDiskConnectedController = App.VmController.extend(); |
|
67 |
|
/dev/null | ||
---|---|---|
1 |
App.VolumeController = App.ItemsItemController.extend({ |
|
2 |
|
|
3 |
codeName: 'volume', |
|
4 |
|
|
5 |
actionsMeta: function() { |
|
6 |
var enabledActions = this.get('model').get('enabledActions'); |
|
7 |
return _.map(enabledActions, function(val,key) {return actionsMetaVolume[val]; }); |
|
8 |
}.property('model.enabledActions'), |
|
9 |
|
|
10 |
submenu: [ |
|
11 |
{ |
|
12 |
'link': 'volume.info', |
|
13 |
'icon': 'snf-info-outline', |
|
14 |
}, |
|
15 |
{ |
|
16 |
'link': 'volume.vm-connected', |
|
17 |
'icon': 'snf-pc-outline', |
|
18 |
}, |
|
19 |
], |
|
20 |
actions: { |
|
21 |
dettachVolume: function(volume){ |
|
22 |
volume.get('vm').get('volumes').removeObject(volume); |
|
23 |
}, |
|
24 |
destroyVolume: function(){ |
|
25 |
this.get('model').deleteRecord(); |
|
26 |
this.get('model').save(); |
|
27 |
this.transitionToRoute('volumes/grid-view'); |
|
28 |
}, |
|
29 |
} |
|
30 |
}); |
|
31 |
|
|
32 |
App.DettachVolumeModalController = Ember.Controller.extend(); |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/helpers/helpers.js | ||
---|---|---|
1 |
Ember.Handlebars.helper('status-to-text', function(value) { |
|
2 |
return statusText[value]; |
|
3 |
}, 'status'); |
|
4 |
|
|
5 |
Ember.Handlebars.registerHelper('myrender', function(name, contextString, options) { |
|
6 |
// controller option set ??? |
|
7 |
if (options.hash.controller) { |
|
8 |
// resolve string from current context |
|
9 |
var resolvedControllerName = Ember.Handlebars.get(options.contexts[0], options.hash.controller, options); |
|
10 |
if (resolvedControllerName) { |
|
11 |
options.hash.controller = resolvedControllerName; |
|
12 |
} |
|
13 |
} |
|
14 |
// call ember render helper |
|
15 |
return Ember.Handlebars.helpers.render.call(this, name, contextString, options); |
|
16 |
}); |
|
17 |
|
|
18 |
|
|
19 |
Ember.Handlebars.helper('bytes-to-human',function (value) { |
|
20 |
function humanFileSize(bytes, si) { |
|
21 |
var thresh = si ? 1000 : 1024; |
|
22 |
if(bytes < thresh) return bytes + ' B'; |
|
23 |
var units = si ? ['kB','MB','GB','TB','PB','EB','ZB','YB'] : ['KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB']; |
|
24 |
var u = -1; |
|
25 |
do { |
|
26 |
bytes /= thresh; |
|
27 |
++u; |
|
28 |
} while(bytes >= thresh); |
|
29 |
return bytes.toFixed(1)+' '+units[u]; |
|
30 |
} |
|
31 |
console.log(value); |
|
32 |
return humanFileSize(value,false); |
|
33 |
}, 'value'); |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/metadata.js | ||
---|---|---|
1 |
var actionsMetaNetwork = { |
|
2 |
'destroy': { |
|
3 |
title: 'destroy', |
|
4 |
act: 'destroy-network-modal', |
|
5 |
spanCls: 'snf-switch', |
|
6 |
controller: 'network' |
|
7 |
}, |
|
8 |
|
|
9 |
}; |
|
10 |
|
|
11 |
var actionsMetaVm = { |
|
12 |
'start': { |
|
13 |
title: 'start me now', |
|
14 |
act: 'start-vm-modal', |
|
15 |
spanCls: 'snf-switch', |
|
16 |
controller: 'vm', |
|
17 |
}, |
|
18 |
'destroy': { |
|
19 |
title: 'destroy', |
|
20 |
act: 'destroy-vm-modal', |
|
21 |
spanCls: 'snf-trash-outline', |
|
22 |
controller: 'vm', |
|
23 |
}, |
|
24 |
'reboot': { |
|
25 |
title: 'reboot', |
|
26 |
act: 'reboot-vm-modal', |
|
27 |
spanCls: 'snf-refresh-outline', |
|
28 |
controller: 'vm', |
|
29 |
}, |
|
30 |
'shutdown': { |
|
31 |
title: 'shutdown', |
|
32 |
act: 'shutdown-vm-modal', |
|
33 |
spanCls: 'snf-pc-broken-full', |
|
34 |
controller: 'vm', |
|
35 |
}, |
|
36 |
}; |
|
37 |
|
|
38 |
var actionsMetaVolume = { |
|
39 |
'destroy': { |
|
40 |
title: 'destroy', |
|
41 |
act: 'destroy-volume-modal', |
|
42 |
spanCls: 'snf-switch', |
|
43 |
controller: 'volume' |
|
44 |
}, |
|
45 |
}; |
|
46 |
|
|
47 |
|
|
48 |
var statusText ={ |
|
49 |
'off' : 'STOPPED', |
|
50 |
'error' : 'ERROR', |
|
51 |
'building' : 'BUILDING', |
|
52 |
'running' : 'RUNNING', |
|
53 |
'rebooting': 'REBOOTING', |
|
54 |
'starting' : 'STARTING', |
|
55 |
'shutting' : 'SHUTTING DOWN', |
|
56 |
}; |
|
57 |
|
|
58 |
|
|
59 |
var statusActionsVm = { |
|
60 |
'off' : { |
|
61 |
enabledActions : ['start', 'destroy'], |
|
62 |
}, |
|
63 |
'error' : { |
|
64 |
enabledActions : ['destroy'], |
|
65 |
}, |
|
66 |
'building' : { |
|
67 |
enabledActions : [], |
|
68 |
}, |
|
69 |
'running' : { |
|
70 |
enabledActions : ['reboot', 'shutdown', 'destroy'], |
|
71 |
}, |
|
72 |
'rebooting' : { |
|
73 |
enabledActions : ['destroy'], |
|
74 |
}, |
|
75 |
'starting' : { |
|
76 |
enabledActions : ['destroy'], |
|
77 |
}, |
|
78 |
'shutting' : { |
|
79 |
enabledActions : ['destroy'], |
|
80 |
}, |
|
81 |
}; |
|
82 |
|
|
83 |
|
|
84 |
var statusActionsNetwork = { |
|
85 |
'off' : { |
|
86 |
enabledActions : ['destroy'], |
|
87 |
}, |
|
88 |
'error' : { |
|
89 |
enabledActions : ['destroy'], |
|
90 |
}, |
|
91 |
'building' : { |
|
92 |
enabledActions : [], |
|
93 |
}, |
|
94 |
'running' : { |
|
95 |
enabledActions : ['destroy'], |
|
96 |
}, |
|
97 |
'starting' : { |
|
98 |
enabledActions : ['destroy'], |
|
99 |
}, |
|
100 |
'shutting' : { |
|
101 |
enabledActions : ['destroy'], |
|
102 |
}, |
|
103 |
}; |
|
104 |
|
|
105 |
|
|
106 |
var statusActionsVolume = { |
|
107 |
'off' : { |
|
108 |
enabledActions : ['destroy'], |
|
109 |
}, |
|
110 |
'error' : { |
|
111 |
enabledActions : ['destroy'], |
|
112 |
}, |
|
113 |
'building' : { |
|
114 |
enabledActions : [], |
|
115 |
}, |
|
116 |
'running' : { |
|
117 |
enabledActions : ['destroy'], |
|
118 |
}, |
|
119 |
'starting' : { |
|
120 |
enabledActions : ['destroy'], |
|
121 |
}, |
|
122 |
'shutting' : { |
|
123 |
enabledActions : ['destroy'], |
|
124 |
}, |
|
125 |
}; |
|
126 |
|
|
127 |
|
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/models/network.js | ||
---|---|---|
1 |
App.Network = DS.Model.extend({ |
|
2 |
|
|
3 |
name : DS.attr(), |
|
4 |
status : DS.attr(), |
|
5 |
ports : DS.hasMany('port', { async:true }), |
|
6 |
|
|
7 |
enabledActions: function() { |
|
8 |
return statusActionsNetwork[this.get('status')].enabledActions; |
|
9 |
}.property('status'), |
|
10 |
|
|
11 |
}); |
|
12 |
|
|
13 |
|
|
14 |
App.Network.FIXTURES = [ |
|
15 |
{ |
|
16 |
id: 1, |
|
17 |
name: 'Network 1', |
|
18 |
status: 'running', |
|
19 |
ports: [1,3,4,6], |
|
20 |
}, |
|
21 |
{ |
|
22 |
id: 2, |
|
23 |
name: 'Network 2', |
|
24 |
status: 'building', |
|
25 |
ports: [2,5], |
|
26 |
}, |
|
27 |
{ |
|
28 |
id: 3, |
|
29 |
name: 'Network 3', |
|
30 |
status: 'off', |
|
31 |
}, |
|
32 |
]; |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/models/port.js | ||
---|---|---|
1 |
App.Port = DS.Model.extend({ |
|
2 |
|
|
3 |
vm : DS.belongsTo('vm', {async:true}), |
|
4 |
network : DS.belongsTo('network', {async:true}), |
|
5 |
firewall : DS.attr(), |
|
6 |
|
|
7 |
// firewallState can be off or on |
|
8 |
firewallState: function() { |
|
9 |
var state = 'off'; |
|
10 |
if ( _.contains(['on','partial'], this.get('firewall')) ) { state='on'; } |
|
11 |
return state; |
|
12 |
}.property('firewall'), |
|
13 |
|
|
14 |
|
|
15 |
}); |
|
16 |
|
|
17 |
|
|
18 |
App.Port.FIXTURES = [ |
|
19 |
{ |
|
20 |
id: 1, |
|
21 |
vm: 1, |
|
22 |
network: 1, |
|
23 |
firewall: 'on', |
|
24 |
}, |
|
25 |
{ |
|
26 |
id: 2, |
|
27 |
vm: 1, |
|
28 |
network: 2, |
|
29 |
firewall: 'partial', |
|
30 |
}, |
|
31 |
{ |
|
32 |
id: 3, |
|
33 |
vm: 2, |
|
34 |
network: 1, |
|
35 |
firewall: 'off', |
|
36 |
}, |
|
37 |
{ |
|
38 |
id: 4, |
|
39 |
vm: 3, |
|
40 |
network: 1, |
|
41 |
firewall: 'on', |
|
42 |
}, |
|
43 |
{ |
|
44 |
id: 5, |
|
45 |
vm: 3, |
|
46 |
network: 1, |
|
47 |
firewall: 'on', |
|
48 |
}, |
|
49 |
{ |
|
50 |
id: 6, |
|
51 |
vm: 1, |
|
52 |
network: 1, |
|
53 |
firewall: 'on', |
|
54 |
}, |
|
55 |
]; |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/models/tag.js | ||
---|---|---|
1 |
App.Tag = DS.Model.extend({ |
|
2 |
|
|
3 |
name : DS.attr(), |
|
4 |
color : DS.attr(), |
|
5 |
vm : DS.belongsTo('vm', { async:true }), |
|
6 |
|
|
7 |
}); |
|
8 |
|
|
9 |
|
|
10 |
App.Tag.FIXTURES = [ |
|
11 |
{ |
|
12 |
id: 1, |
|
13 |
name: 'hacking', |
|
14 |
color: '#1E96FF', |
|
15 |
vm: 1, |
|
16 |
}, |
|
17 |
{ |
|
18 |
id: 2, |
|
19 |
name: 'movies', |
|
20 |
color: '#FFCB44', |
|
21 |
vm: 1, |
|
22 |
}, |
|
23 |
{ |
|
24 |
id: 3, |
|
25 |
name: 'dev', |
|
26 |
color: '#DF2F74', |
|
27 |
vm: 1, |
|
28 |
}, |
|
29 |
{ |
|
30 |
id: 4, |
|
31 |
name: 'var', |
|
32 |
color: '#F76720', |
|
33 |
vm: 2, |
|
34 |
}, |
|
35 |
{ |
|
36 |
id: 5, |
|
37 |
name: 'hacking', |
|
38 |
color: '#1E96FF', |
|
39 |
vm: 2, |
|
40 |
}, |
|
41 |
{ |
|
42 |
id: 6, |
|
43 |
name: 'movies', |
|
44 |
color: '#FFCB44', |
|
45 |
vm: 2, |
|
46 |
}, |
|
47 |
{ |
|
48 |
id: 7, |
|
49 |
name: 'dev', |
|
50 |
color: '#DF2F74', |
|
51 |
vm: 3, |
|
52 |
}, |
|
53 |
{ |
|
54 |
id: 8, |
|
55 |
name: 'dev', |
|
56 |
color: '#DF2F74', |
|
57 |
vm: 4, |
|
58 |
}, |
|
59 |
{ |
|
60 |
id: 9, |
|
61 |
name: 'dev', |
|
62 |
color: '#DF2F74', |
|
63 |
vm: 5, |
|
64 |
} |
|
65 |
]; |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/models/vm.js | ||
---|---|---|
1 |
App.Vm = DS.Model.extend({ |
|
2 |
|
|
3 |
name : DS.attr(), |
|
4 |
status : DS.attr(), |
|
5 |
os : DS.attr(), |
|
6 |
link : DS.attr(), |
|
7 |
created : DS.attr('date'), |
|
8 |
updated : DS.attr('date'), |
|
9 |
tags : DS.hasMany('tag', { async:true }), |
|
10 |
volumes : DS.hasMany('volume', { async:true}), |
|
11 |
ports : DS.hasMany('port', { async: true}), |
|
12 |
|
|
13 |
/*flavor : DS.attr('raw'),*/ |
|
14 |
|
|
15 |
enabledActions: function() { |
|
16 |
return statusActionsVm[this.get('status')].enabledActions; |
|
17 |
}.property('status'), |
|
18 |
|
|
19 |
}); |
|
20 |
|
|
21 |
|
|
22 |
App.Vm.FIXTURES = [ |
|
23 |
{ |
|
24 |
created: '2011-04-19T10:18:52.085737+00:00', |
|
25 |
id: 1, |
|
26 |
metadata: { foo: "bar"}, |
|
27 |
name: "The answer to everything", |
|
28 |
os: 'windows', |
|
29 |
status: "running", |
|
30 |
link: 'http://www.in.gr', |
|
31 |
updated: "2011-05-29T14:07:07.037602+00:00", |
|
32 |
tags: [1,2,3], |
|
33 |
volumes: [1,2], |
|
34 |
ports: [1,2,6], |
|
35 |
}, |
|
36 |
{ |
|
37 |
id: 2, |
|
38 |
name: 'My even cooler VM 2 that has a long name', |
|
39 |
status: 'error', |
|
40 |
os: 'unknown', |
|
41 |
link: 'http://www.in.gr', |
|
42 |
updated: "2011-05-29T14:07:07.037602+00:00", |
|
43 |
tags: [4,5,6], |
|
44 |
volumes: [3], |
|
45 |
ports: [3], |
|
46 |
}, |
|
47 |
{ |
|
48 |
id: 3, |
|
49 |
name: 'My cool VM 3', |
|
50 |
status: 'building', |
|
51 |
os: 'windows', |
|
52 |
link: 'http://www.in.gr', |
|
53 |
tags: [7], |
|
54 |
ports: [4,5], |
|
55 |
}, |
|
56 |
{ |
|
57 |
id: 4, |
|
58 |
name: 'So awesome VM 4', |
|
59 |
status: 'off', |
|
60 |
os: 'fedora', |
|
61 |
link: 'www.france24.fr', |
|
62 |
tags: [8], |
|
63 |
}, |
|
64 |
{ |
|
65 |
id: 5, |
|
66 |
name: 'olga', |
|
67 |
status: 'rebooting', |
|
68 |
os: 'kubuntu', |
|
69 |
link: 'http://www.in.gr', |
|
70 |
tags: [9], |
|
71 |
}, |
|
72 |
{ |
|
73 |
id: 6, |
|
74 |
name: 'athina', |
|
75 |
status: 'starting', |
|
76 |
os: 'kubuntu', |
|
77 |
link: 'http://www.in.gr', |
|
78 |
}, |
|
79 |
{ |
|
80 |
id: 7, |
|
81 |
name: 'kpap', |
|
82 |
status: 'shutting', |
|
83 |
os: 'kubuntu', |
|
84 |
link: 'http://www.in.gr', |
|
85 |
}, |
|
86 |
]; |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/models/volume.js | ||
---|---|---|
1 |
App.Volume = DS.Model.extend({ |
|
2 |
|
|
3 |
name : DS.attr(), |
|
4 |
status : DS.attr(), |
|
5 |
size : DS.attr('number'), |
|
6 |
storageType : DS.attr('string', {defaultValue: 'Archipelago'}), |
|
7 |
vm : DS.belongsTo('vm', { async:false }), |
|
8 |
|
|
9 |
enabledActions: function() { |
|
10 |
return statusActionsVolume[this.get('status')].enabledActions; |
|
11 |
}.property('state'), |
|
12 |
|
|
13 |
}); |
|
14 |
|
|
15 |
|
|
16 |
App.Volume.FIXTURES = [ |
|
17 |
{ |
|
18 |
id: 1, |
|
19 |
name: 'Ο αγαπημÎνος μου δίσκος', |
|
20 |
status: 'running', |
|
21 |
size: 10737418240, |
|
22 |
vm: 1, |
|
23 |
}, |
|
24 |
{ |
|
25 |
id: 2, |
|
26 |
name: 'Crypto', |
|
27 |
status: 'running', |
|
28 |
size: 2048, |
|
29 |
vm: 1, |
|
30 |
}, |
|
31 |
{ |
|
32 |
id: 3, |
|
33 |
name: 'Disk 3', |
|
34 |
status: 'running', |
|
35 |
size: 4096, |
|
36 |
storageType: 'drpd', |
|
37 |
vm: 3, |
|
38 |
}, |
|
39 |
]; |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/router.js | ||
---|---|---|
1 |
App.Router.map(function (argument) { |
|
2 |
|
|
3 |
this.resource('vms', { path: '/vms/:view_cls' }); |
|
4 |
this.resource('vminit', { path: '/vm'}); |
|
5 |
this.resource('vm', { path: '/vm/:vm_id' }, function () { |
|
6 |
this.route('info'); |
|
7 |
this.route('disk-connected'); |
|
8 |
this.route('network-connected'); |
|
9 |
}); |
|
10 |
|
|
11 |
this.resource('networks', {path: '/networks/:view_cls'}); |
|
12 |
this.resource('networkinit', { path: '/network'}); |
|
13 |
this.resource('network', { path: '/network/:network_id' }, function () { |
|
14 |
this.route('info'); |
|
15 |
this.route('vm-connected'); |
|
16 |
}); |
|
17 |
|
|
18 |
this.resource('volumes', {path: '/volumes/:view_cls'}); |
|
19 |
this.resource('volumeinit', { path: '/volume'}); |
|
20 |
this.resource('volume', { path: '/volume/:volume_id' }, function () { |
|
21 |
this.route('info'); |
|
22 |
this.route('vm-connected'); |
|
23 |
}); |
|
24 |
|
|
25 |
}); |
|
1 |
Snf.Router.map(function (argument) {}); |
/dev/null | ||
---|---|---|
1 |
App.ApplicationRoute = Ember.Route.extend({ |
|
2 |
actions: { |
|
3 |
openModal: function(modalName, controller, model) { |
|
4 |
|
|
5 |
this.controllerFor(controller).set("model", model); |
|
6 |
this.render('modals/'+modalName, { |
|
7 |
into: 'application', |
|
8 |
outlet: 'modal', |
|
9 |
controller: controller, |
|
10 |
}); |
|
11 |
$('#app-modal').foundation('reveal','open'); |
|
12 |
}, |
|
13 |
} |
|
14 |
}); |
|
15 |
|
|
16 |
|
/dev/null | ||
---|---|---|
1 |
App.ItemsListRoute = Ember.Route.extend({ |
|
2 |
|
|
3 |
modelName: '', |
|
4 |
|
|
5 |
model: function(params){ |
|
6 |
this.set( 'viewCls', params.view_cls ); |
|
7 |
var controller = this.get("controller"); |
|
8 |
|
|
9 |
// Ember checks if controller is already set, and if so, does not set it |
|
10 |
// up again. Hence, the following hack: |
|
11 |
if (controller) { |
|
12 |
controller.set("viewCls", params.view_cls); |
|
13 |
} |
|
14 |
|
|
15 |
// end of hack |
|
16 |
return this.store.find(this.modelName); |
|
17 |
}, |
|
18 |
|
|
19 |
renderTemplate: function() { |
|
20 |
this.render('items'); |
|
21 |
}, |
|
22 |
|
|
23 |
setupController: function(controller, model) { |
|
24 |
controller.set('model', model); |
|
25 |
controller.set("viewCls", this.get("viewCls")); |
|
26 |
controller.set('modelName', this.modelName); |
|
27 |
}, |
|
28 |
|
|
29 |
afterModel: function(model, transition ) { |
|
30 |
if (this.viewCls == 'first') { |
|
31 |
this.transitionTo(this.modelName, model.get('firstObject').id); |
|
32 |
} |
|
33 |
}, |
|
34 |
|
|
35 |
}); |
|
36 |
|
|
37 |
App.VmsRoute = App.ItemsListRoute.extend({ |
|
38 |
modelName: 'vm', |
|
39 |
}); |
|
40 |
|
|
41 |
App.NetworksRoute = App.ItemsListRoute.extend({ |
|
42 |
modelName: 'network', |
|
43 |
}); |
|
44 |
|
|
45 |
App.VolumesRoute = App.ItemsListRoute.extend({ |
|
46 |
modelName: 'volume', |
|
47 |
}); |
/dev/null | ||
---|---|---|
1 |
App.NetworkRoute = Ember.Route.extend({ |
|
2 |
|
|
3 |
renderTemplate: function() { |
|
4 |
|
|
5 |
this.render('details'); |
|
6 |
|
|
7 |
this.render('lt-bar', { |
|
8 |
into: 'details', |
|
9 |
outlet: 'lt-bar', |
|
10 |
controller: 'networks', |
|
11 |
}); |
|
12 |
}, |
|
13 |
}); |
|
14 |
|
|
15 |
App.NetworkinitRoute = Ember.Route.extend({ |
|
16 |
|
|
17 |
model: function(){ |
|
18 |
return this.store.find('network'); |
|
19 |
}, |
|
20 |
|
|
21 |
afterModel: function(model) { |
|
22 |
this.transitionTo('network', model.get('firstObject').id); |
|
23 |
}, |
|
24 |
|
|
25 |
}); |
|
26 |
|
|
27 |
App.NetworkInfoRoute = Ember.Route.extend({ |
|
28 |
renderTemplate: function() { |
|
29 |
this.render('details/info'); |
|
30 |
}, |
|
31 |
model: function () { |
|
32 |
return this.modelFor("network"); |
|
33 |
}, |
|
34 |
}); |
|
35 |
|
|
36 |
App.NetworkVmConnectedRoute = Ember.Route.extend({ |
|
37 |
renderTemplate: function() { |
|
38 |
this.render('details/network-vm-connected'); |
|
39 |
}, |
|
40 |
model: function () { |
|
41 |
return this.modelFor("network"); |
|
42 |
} |
|
43 |
}); |
/dev/null | ||
---|---|---|
1 |
App.VmRoute = Ember.Route.extend({ |
|
2 |
/* |
|
3 |
redirect: function() { |
|
4 |
this.transitionTo('vm.info'); |
|
5 |
},*/ |
|
6 |
|
|
7 |
renderTemplate: function() { |
|
8 |
|
|
9 |
this.render('details'); |
|
10 |
|
|
11 |
this.render('lt-bar', { |
|
12 |
into: 'details', |
|
13 |
outlet: 'lt-bar', |
|
14 |
controller: 'vms', |
|
15 |
}); |
|
16 |
}, |
|
17 |
}); |
|
18 |
|
|
19 |
|
|
20 |
App.VminitRoute = Ember.Route.extend({ |
|
21 |
|
|
22 |
model: function(){ |
|
23 |
return this.store.find('vm'); |
|
24 |
}, |
|
25 |
|
|
26 |
afterModel: function(model) { |
|
27 |
this.transitionTo('vm', model.get('firstObject').id); |
|
28 |
}, |
|
29 |
|
|
30 |
}); |
|
31 |
|
|
32 |
App.VmInfoRoute = Ember.Route.extend({ |
|
33 |
renderTemplate: function() { |
|
34 |
this.render('details/info'); |
|
35 |
}, |
|
36 |
model: function () { |
|
37 |
return this.modelFor("vm"); |
|
38 |
}, |
|
39 |
}); |
|
40 |
|
|
41 |
App.VmDiskConnectedRoute = Ember.Route.extend({ |
|
42 |
renderTemplate: function() { |
|
43 |
this.render('details/disk-connected'); |
|
44 |
}, |
|
45 |
model: function () { |
|
46 |
return this.modelFor("vm"); |
|
47 |
} |
|
48 |
}); |
|
49 |
|
|
50 |
App.VmNetworkConnectedRoute = Ember.Route.extend({ |
|
51 |
renderTemplate: function() { |
|
52 |
this.render('details/network-connected'); |
|
53 |
}, |
|
54 |
model: function () { |
|
55 |
return this.modelFor("vm"); |
|
56 |
} |
|
57 |
}); |
/dev/null | ||
---|---|---|
1 |
App.VolumeRoute = Ember.Route.extend({ |
|
2 |
|
|
3 |
|
|
4 |
renderTemplate: function() { |
|
5 |
|
|
6 |
this.render('details'); |
|
7 |
|
|
8 |
this.render('lt-bar', { |
|
9 |
into: 'details', |
|
10 |
outlet: 'lt-bar', |
|
11 |
controller: 'volumes', |
|
12 |
}); |
|
13 |
}, |
|
14 |
|
|
15 |
}); |
|
16 |
|
|
17 |
|
|
18 |
App.VolumeinitRoute = Ember.Route.extend({ |
|
19 |
|
|
20 |
model: function(){ |
|
21 |
return this.store.find('volume'); |
|
22 |
}, |
|
23 |
|
|
24 |
afterModel: function(model) { |
|
25 |
this.transitionTo('volume', model.get('firstObject').id); |
|
26 |
}, |
|
27 |
|
|
28 |
}); |
|
29 |
|
|
30 |
App.VolumeInfoRoute = Ember.Route.extend({ |
|
31 |
renderTemplate: function() { |
|
32 |
this.render('details/info'); |
|
33 |
}, |
|
34 |
model: function () { |
|
35 |
return this.modelFor("volume"); |
|
36 |
}, |
|
37 |
}); |
|
38 |
|
|
39 |
App.VolumeVmConnectedRoute = Ember.Route.extend({ |
|
40 |
renderTemplate: function() { |
|
41 |
this.render('details/volume-vm-connected'); |
|
42 |
}, |
|
43 |
model: function () { |
|
44 |
return this.modelFor("volume"); |
|
45 |
} |
|
46 |
}); |
/dev/null | ||
---|---|---|
1 |
<section class="actions-bar clearfix"> |
|
2 |
|
|
3 |
<h2> |
|
4 |
{{#if title}} |
|
5 |
{{title}} |
|
6 |
{{else}} |
|
7 |
{{#link-to codeNameParent 'grid-view'}}{{codeNameParent}}{{/link-to}}{{this.name}} |
|
8 |
{{/if}} |
|
9 |
</h2> |
|
10 |
|
|
11 |
{{#if hasViewCls}} |
|
12 |
<div class="rt-actions"> |
|
13 |
{{#link-to codeNameChildInit class="single"}}{{/link-to}} |
|
14 |
{{#link-to codeNameParent 'grid-view'}}<span class="snf-gridview current">{{/link-to}} |
|
15 |
{{#link-to codeNameParent 'list-view'}}<span class="snf-listview "></span>{{/link-to}} |
|
16 |
</div> |
|
17 |
{{/if}} |
|
18 |
|
|
19 |
{{#if hasFilter}} |
|
20 |
<div class="filter-menu"> |
|
21 |
<div><a class="filter" href="">Filter</a></div> |
|
22 |
<ul class="options"> |
|
23 |
<li><a href="">option 1</a></li> |
|
24 |
<li><a href="">option 2</a></li> |
|
25 |
<li><a href="">option 3</a></li> |
|
26 |
<li><a href="">option 4</a></li> |
|
27 |
</ul> |
|
28 |
</div> |
|
29 |
{{/if}} |
|
30 |
|
|
31 |
{{#if hasSearch}} |
|
32 |
<div id="hd-search" class="hd-search"> |
|
33 |
<form> |
|
34 |
<span class="hd-icon-search snf-search"></span> |
|
35 |
<input class="hd-search-input" placeholder="Enter your search term..." type="search" value="" name="search" id="search"> |
|
36 |
</form> |
|
37 |
</div> |
|
38 |
{{/if}} |
|
39 |
|
|
40 |
</section> |
/dev/null | ||
---|---|---|
1 |
<header class="header"> |
|
2 |
<nav> |
|
3 |
<ul class="icons-nav"> |
|
4 |
<li>{{#link-to 'vms' 'grid-view'}}<span class="snf-pc-outline"></span>{{/link-to}}</li> |
|
5 |
<li>{{#link-to 'networks' 'grid-view'}}<span class="snf-network-outline"></span>{{/link-to}}</li> |
|
6 |
<li>{{#link-to 'volumes' 'grid-view'}}<span class="snf-volume-outline"></span>{{/link-to}}</li> |
|
7 |
</ul> |
|
8 |
</nav> |
|
9 |
<div class="login"> |
|
10 |
<div class="wrap"> |
|
11 |
<a href="">user1@synnefo.org</a> |
|
12 |
<ul> |
|
13 |
<li><a href="">dashboard</a></li> |
|
14 |
<li><a href="">sign out</a></li> |
|
15 |
</ul> |
|
16 |
</div> |
|
17 |
</div> |
|
18 |
<div class="logo"> |
|
19 |
<a href="index.html"><img src="../images/synnefo-logo.png" alt="software logo"></a> |
|
20 |
</div> |
|
21 |
</header> |
/dev/null | ||
---|---|---|
1 |
<div class="img-wrap"> |
|
2 |
{{#link-to codeName this}} |
|
3 |
<span {{bind-attr class=":snf-font icon"}}></span> |
|
4 |
{{#if this.os}}<span {{bind-attr class=":os this.os"}}>{{this.os}}</span>{{/if}} |
|
5 |
{{/link-to}} |
|
6 |
</div> |
/dev/null | ||
---|---|---|
1 |
<div class="buttons"> |
|
2 |
<a href="" class="btn1 show-add-tag wrap-a" id="show-add-tag"><span>add new tag</span></a> |
|
3 |
</div> |
|
4 |
|
|
5 |
<div class="snf-color-picker"> |
|
6 |
<h3>Select color:</h3> |
|
7 |
<form action="#" method="post"> |
|
8 |
<div id="colorpicker"> |
|
9 |
<div class="farbtastic"> |
|
10 |
<div class="color" style="background-color: rgb(255, 0, 21);"></div> |
|
11 |
<div class="wheel"></div> |
|
12 |
<div class="overlay"></div> |
|
13 |
<div class="h-marker marker" style="left: 90px; top: 13px;"></div> |
|
14 |
<div class="sl-marker marker" style="left: 87px; top: 114px;"></div> |
|
15 |
</div> |
|
16 |
</div> |
|
17 |
|
|
18 |
<div class="form-item"> |
|
19 |
{{ input value=newTagColor class="color-preview" type="text" id="color" disabled="disabled"}} |
|
20 |
<span class="input"> |
|
21 |
{{ input value=newTagName class="tag_name" type="text" placeholder="My Tag" }} |
|
22 |
</span> |
|
23 |
</div> |
|
24 |
</form> |
|
25 |
<div class="btns"> |
|
26 |
<a class="btn1 wrap-a" href="" {{action 'handleSubmit'}}><span>OK</span></a> |
|
27 |
<a class="btn1 hide-add-tag wrap-a" href=""><span>CANCEL</span></a> |
|
28 |
</div> |
|
29 |
</div> |
b/snf-cyclades-app/synnefo/ui/new_ui/ui/app/templates/application.hbs | ||
---|---|---|
1 |
{{partial "header"}} |
|
2 |
<div id="app-modal" class="medium reveal-modal" data-reveal> |
|
3 |
{{outlet modal}} |
|
4 |
</div> |
|
5 |
|
|
6 |
<div class="body-wrapper"> |
|
7 |
{{outlet}} |
|
8 |
</div> |
|
1 |
Hello world! |
/dev/null | ||
---|---|---|
1 |
{{yield}} |
/dev/null | ||
---|---|---|
1 |
{{#unless isEditable}} |
|
2 |
<span class="prop">{{prop}}</span> |
|
3 |
{{/unless}} |
|
4 |
{{#if isEditable}} |
|
5 |
{{input value=prop focus-out="acceptEditableChanges" insert-newline="acceptEditableChanges"}} |
|
6 |
{{/if}} |
|
7 |
<span class="editbuttons"> |
|
8 |
{{#unless isEditable}} |
|
9 |
<a class="edit" {{action "allowEdit"}}><span class="snf-edit"></span></a> |
|
10 |
{{/unless}} |
|
11 |
{{#if isEditable}} |
|
12 |
<a class="save" {{action "acceptEditableChanges"}}><span class="snf-ok-sign"></span></a> |
|
13 |
{{/if}} |
|
14 |
</span> |
|
15 |
|
/dev/null | ||
---|---|---|
1 |
<section {{bind-attr class=":item item.status"}}> |
|
2 |
<div class="what"> |
|
3 |
<div class="img-wrap"> |
|
4 |
<span class="snf-network-full snf-font"></span> |
|
5 |
</div> |
|
6 |
<h4>{{item.name}}</h4> |
|
7 |
</div> |
|
8 |
<div class="clearfix"> |
|
9 |
<ul class="connections"> |
|
10 |
<li> |
|
11 |
<a href="#" class="act" data-reveal-id="disconnect-from-network"> </a> |
|
12 |
<div class="icon"><span class="snf-nic-full"></span></div> |
|
13 |
<div class="data"> |
|
14 |
<ul> |
|
15 |
<li> |
|
16 |
<h5 class="ip-data">IPv4</h5> |
|
17 |
<p>83.212.96.12</p> |
|
18 |
</li> |
|
19 |
</ul> |
|
20 |
</div> |
|
21 |
</li> |
|
22 |
<li> |
|
23 |
<a href="#" class="act" data-reveal-id="disconnect-from-network"> </a> |
|
24 |
<div class="icon"><span class="snf-nic-full"></span></div> |
|
25 |
<div class="data"> |
|
26 |
<ul> |
|
27 |
<li> |
|
28 |
<h5 class="ip-data">IPv4</h5> |
|
29 |
<p>83.212.96.12</p> |
|
30 |
</li> |
|
31 |
</ul> |
|
32 |
</div> |
|
33 |
</li> |
|
34 |
<li> |
|
35 |
<div class="icon"><span class="snf-nic-full"></span></div> |
|
36 |
<div class="data"> |
|
37 |
<ul> |
|
38 |
<li> |
|
39 |
<h5 class="ip-data">IPv6</h5> |
|
40 |
<p>2001:648:2ffc:1112:a80c:eaff:fe34:1234</p> |
|
41 |
</li> |
|
42 |
</ul> |
|
43 |
</div> |
|
44 |
</li> |
|
45 |
<div class="firewall" data-firewall="fully"> |
|
46 |
<p>Firewall <em>on</em></p> |
|
47 |
<ul class="more"> |
|
48 |
<li class="fully selected"> |
|
49 |
<a href="" class="radiobtn">Fully protected mode<span class="snf-radio-checked"></span></a> |
|
50 |
</li> |
|
51 |
<li class="basic"> |
|
52 |
<a href="" class="radiobtn">Basically protected mode<span class="snf-radio-unchecked"></span></a> |
|
53 |
</li> |
|
54 |
<li class="unprotected"> |
|
55 |
<a href="" class="radiobtn">Unprotected mode<span class="snf-radio-unchecked"></span></a> |
|
56 |
</li> |
|
57 |
</ul> |
|
58 |
</div> |
|
59 |
</ul> |
|
60 |
</div> |
|
61 |
</section> |
/dev/null | ||
---|---|---|
1 |
<a {{action 'deleteTag' }} class="act" data-reveal-id="detach-volume"> </a> |
/dev/null | ||
---|---|---|
1 |
{{!-- |
|
2 |
Is this necessary? |
|
3 |
{{#each tag in tags }} |
|
4 |
<{{ unbound entryTag}}> |
|
5 |
<a href="#" {{bind-attr title=tag.name style=style}} class="has-tip tag"> </a> |
|
6 |
<span>{{tag.name}}</span> |
|
7 |
<a class="delete" {{action 'deleteTag'}} title="remove this tag from this vm"><span class="snf-trash-outline"></span></a> |
|
8 |
</{{ unbound entryTag}}> |
|
9 |
{{/each}} |
|
10 |
--}} |
/dev/null | ||
---|---|---|
1 |
{{ yield }} |
|
2 |
|
|
3 |
{{#if hasButtons}} |
|
4 |
{{foo}} |
|
5 |
<p class="buttons"> |
|
6 |
<a href="" {{ action "ok" }} class="btn4"><span>Yes</span></a> |
|
7 |
<a href="" {{ action "close" }} class="btn4"><span>No</span></a> |
|
8 |
</p> |
|
9 |
{{/if}} |
|
10 |
|
|
11 |
<a class="close-reveal-modal has-tip" data-tooltip title="close window">x</a> |
/dev/null | ||
---|---|---|
1 |
<a href="#" {{bind-attr title=title style=style}} class="has-tip tag"> </a> |
|
2 |
<span>{{title}}</span> |
|
3 |
<a class="delete" {{action 'deleteTag'}} title="remove this tag from this vm"><span class="snf-trash-outline"></span></a> |
/dev/null | ||
---|---|---|
1 |
{{#reveal-modal id="destroy-vm-modal" hasButtons="true" ok="destroyVm" class="modal-reboot"}} |
|
2 |
<p>Are you sure you want to destroy the VM <strong>{{model.name}}</strong>?</p> |
|
3 |
{{/reveal-modal}} |
/dev/null | ||
---|---|---|
1 |
<ul> |
|
2 |
{{#each menu in this.submenu}} |
|
3 |
<li>{{#link-to menu.link title=menu.link}}<span {{bind-attr class="menu.icon"}}></span>{{/link-to}}</li> |
|
4 |
{{/each}} |
|
5 |
</ul> |
/dev/null | ||
---|---|---|
1 |
{{partial 'actions-bar'}} |
|
2 |
<section class="main row"> |
|
3 |
|
Also available in: Unified diff