diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties index bda93369c5e..6d761eafe7d 100644 --- a/client/WEB-INF/classes/resources/messages.properties +++ b/client/WEB-INF/classes/resources/messages.properties @@ -3,6 +3,10 @@ <<<<<<< HEAD <<<<<<< HEAD #new labels (begin) ********************************************************************************************** +message.specify.url=Please specify URL +label.select.instance.to.attach.volume.to=Select instance to attach volume to +label.upload=Upload +label.upload.volume=Upload volume label.virtual.routers=Virtual Routers label.primary.storage.count=Primary Storage Pools label.secondary.storage.count=Secondary Storage Pools diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index 057508f72d9..6b96310d837 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -7078,6 +7078,90 @@ div.panel.ui-dialog div.list-view div.fixed-header { display: none; } +/*Upload volume*/ +.upload-volume { +} + +.upload-volume .list-view { + margin-top: 5px !important; +} + +.upload-volume .listView-container { + background: #FFFFFF; + width: 823px; + margin: 71px 0px 20px 28px; + border: 1px solid #DADADA; + /*+border-radius:4px;*/ + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px 4px 4px 4px; +} + +.upload-volume div.list-view .data-table div.fixed-header { + top: 115px !important; + left: 56px !important; + background: #FFFFFF !important; +} + +.upload-volume .data-table table.body { + margin-top: 66px !important; + margin-left: 19px; +} + +.upload-volume .list-view .toolbar { + top: 118px; + width: 801px; + left: 43px; + background: transparent; + border: none; +} + +.upload-volume .top-fields { + float: left; + clear: none; + margin-left: 24px; +} + +.upload-volume .top-fields .field { + float: left; + margin-right: 50px; +} + +.upload-volume .top-fields input { + float: right; + /*+border-radius:3px;*/ + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -khtml-border-radius: 3px; + border-radius: 3px 3px 3px 3px; + padding: 2px; + width: 186px; +} + +.upload-volume .top-fields label, +.upload-volume .desc { + display: block; + float: left; + padding: 6px; + font-size: 12px; + color: #4C5D6C; + /*+text-shadow:0px 0px #FFFFFF;*/ + -moz-text-shadow: 0px 0px #FFFFFF; + -webkit-text-shadow: 0px 0px #FFFFFF; + -o-text-shadow: 0px 0px #FFFFFF; + text-shadow: 0px 0px #FFFFFF; +} + +.upload-volume .desc { + position: absolute; + width: 825px; + text-align: left; + top: 79px; + left: 32px; + border-top: 1px solid #CFCFCF; +} + /*Network detail chat*/ .network-chart { width: 100%; @@ -8885,3 +8969,11 @@ div.panel.ui-dialog div.list-view div.fixed-header { cursor: move !important; } +.uploadVolume .icon { + background-position: -232px -34px; +} + +.uploadVolume:hover .icon { + background-position: -230px -615px; +} + diff --git a/ui/images/sprites.png b/ui/images/sprites.png index 9cd07f23707..21ef1ad142c 100644 Binary files a/ui/images/sprites.png and b/ui/images/sprites.png differ diff --git a/ui/index.jsp b/ui/index.jsp index 63b9973087f..e1a30541f51 100644 --- a/ui/index.jsp +++ b/ui/index.jsp @@ -1639,6 +1639,7 @@ + @@ -1675,6 +1676,10 @@ dictionary = { 'message.edit.traffic.type': '', 'label.label': '', 'message.configure.all.traffic.types': '', +'message.specify.url': '', +'label.select.instance.to.attach.volume.to': '', +'label.upload': '', +'label.upload.volume': '', 'label.virtual.routers': '', 'label.primary.storage.count': '', 'label.secondary.storage.count': '', diff --git a/ui/scripts/storage.js b/ui/scripts/storage.js index 164b72fb528..f9033091924 100644 --- a/ui/scripts/storage.js +++ b/ui/scripts/storage.js @@ -171,8 +171,74 @@ notification: { poll: pollAsyncJobResult } - } + }, + uploadVolume: { + isHeader: true, + label: 'label.upload.volume', + messages: { + notification: function() { return 'label.upload.volume'; } + }, + notification: { poll: function(args) { args.complete(); } }, + action: { + custom: cloudStack.uiCustom.uploadVolume({ + listView: $.extend(true, {}, cloudStack.sections.instances, { + listView: { + filters: false, + dataProvider: function(args) { + var searchByArgs = args.filterBy.search.value && + args.filterBy.search.value.length ? + '&name=' + args.filterBy.search.value : ''; + $.ajax({ + url: createURL('listVirtualMachines' + searchByArgs), + data: { + page: args.page, + pageSize: pageSize, + listAll: true + }, + dataType: 'json', + async: true, + success: function(data) { + args.response.success({ + data: $.grep( + data.listvirtualmachinesresponse.virtualmachine ? + data.listvirtualmachinesresponse.virtualmachine : [], + function(instance) { + return $.inArray(instance.state, [ + 'Destroyed', 'Error', 'Stopping', 'Starting' + ]) == -1; + } + ) + }); + }, + error: function(data) { + args.response.error(parseXMLHttpResponse(data)); + } + }); + } + } + }), + action: function(args) { + $.ajax({ + url: createURL('uploadVolume'), + data: { + hypervisor: 'XenServer', // Replace with instances' hypervisor + format: 'VHD', // Replace with format of uploaded volume + name: args.data.name, + url: args.data.url, + zoneid: 1 // Replace with instances' zone ID + }, + success: function(json) { + args.response.success(); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + }) + } + } }, dataProvider: function(args) { diff --git a/ui/scripts/ui-custom/uploadVolume.js b/ui/scripts/ui-custom/uploadVolume.js new file mode 100644 index 00000000000..84d0235196d --- /dev/null +++ b/ui/scripts/ui-custom/uploadVolume.js @@ -0,0 +1,155 @@ +(function(cloudStack, $) { + cloudStack.uiCustom.uploadVolume = function(args) { + var listView = args.listView; + var action = args.action; + + var validate = function($uploadVolume) { + if (!$uploadVolume.find('input[type=text]').val()) { + cloudStack.dialog.notice({ message: _l('message.specify.url')}); + + return false; + } + + if (!$uploadVolume.find( + 'input[type=radio]:checked, input[type=checkbox]:checked' + ).size()) { + cloudStack.dialog.notice({ message: _l('message.select.instance')}); + + return false; + } + + return true; + }; + + return function(args) { + var $uploadVolume = $('
').addClass('upload-volume'); + var context = args.context; + var topFields = function() { + var $form = $('
').addClass('top-fields'); + var $urlLabel = $('