X-Git-Url: http://git.datanom.net/omvzfs.git/blobdiff_plain/c6117b32379445101780af97836973ba9151cac7..9f2f49761f46d21417199cf1118b3d08084ae0fb:/gui/js/omv/module/admin/storage/zfs/Overview.js diff --git a/gui/js/omv/module/admin/storage/zfs/Overview.js b/gui/js/omv/module/admin/storage/zfs/Overview.js index f235799..3c0f25f 100644 --- a/gui/js/omv/module/admin/storage/zfs/Overview.js +++ b/gui/js/omv/module/admin/storage/zfs/Overview.js @@ -3,6 +3,40 @@ // require("js/omv/workspace/window/Grid.js") // require("js/omv/form/field/CheckboxGrid.js") +Ext.define("OMV.module.admin.storage.zfs.ShowDetails", { + extend: "OMV.workspace.window.Form", + requires: [ + "OMV.data.Store", + "OMV.data.Model", + "OMV.data.proxy.Rpc", + ], + + rpcService: "ZFS", + title: _("Object details"), + autoLoadData: true, + hideResetButton: true, + hideCancelButton: true, + width: 550, + height: 350, + layout: 'fit', + okButtonText: _("Ok"), + + getFormItems: function() { + var me = this; + + return [{ + xtype: "textareafield", + name: "details", + grow: true, + anchor: '100%', + readOnly: true, + preventScrollbars: true, + growMax: "2000" + }]; + + } +}); + Ext.define("OMV.module.admin.storage.zfs.AddPool", { extend: "OMV.workspace.window.Form", requires: [ @@ -63,6 +97,7 @@ Ext.define("OMV.module.admin.storage.zfs.AddPool", { break; case "raidz2": devicesField.minSelections = 4; + break; case "raidz3": devicesField.minSelections = 5; break; @@ -144,12 +179,23 @@ Ext.define("OMV.module.admin.storage.zfs.AddPool", { ptype: "fieldinfo", text: _("Optional mountpoint for the pool. Default is to use pool name.") }] + },{ + xtype: "checkbox", + name: "diskpath", + fieldLabel: _("Disk-by-path"), + plugins: [{ + ptype: "fieldinfo", + text: _("Use /dev/disk/by-path when creating the pool. Recommended.") + }] },{ xtype: "checkbox", name: "force", fieldLabel: _("Force creation"), checked: false, - boxLabel: _("Forces the creation of the pool even if errors are reported. Use with extreme caution!") + plugins: [{ + ptype: "fieldinfo", + text: _("Forces the creation of the pool even if errors are reported. Use with extreme caution!") + }] }]; }, @@ -185,32 +231,73 @@ Ext.define("OMV.module.admin.storage.zfs.AddObject", { getFormItems: function() { var me = this; + + var store = new Ext.data.ArrayStore({ + autoDestroy: true, + storeId: 'my_store', + fields: [ + {name: 'value', type: 'string'}, + {name: 'display', type: 'string'} + ] + }); + + var combodata; + if (me.parenttype === "Snapshot") { + combodata = [["clone","Clone"]]; + } else if (me.parenttype === "Volume") { + combodata = [["snapshot", "Snapshot"]]; + } else { + combodata = [["filesystem","Filesystem"], + ["volume","Volume"], + ["snapshot","Snapshot"]]; + } + store.loadData(combodata,false); + return [{ xtype: "combo", name: "type", fieldLabel: _("Object Type"), queryMode: "local", - store: [ - [ "filesystem", "Filesystem" ], - [ "snapshot", "Snapshot" ], - [ "volume", "Volume" ] - ], + store: store, allowBlank: true, editable: false, triggerAction: "all", - value: "filesystem", + valueField: "value", + displayField: "display", + value: combodata[0][0], listeners: { scope: me, change: function(combo, value) { var sizeField = this.findField("size"); + var cloneField = this.findField("clonename"); + var nameField = this.findField("name"); + var mountField = this.findField("mountpoint"); switch(value) { + case "filesystem": + sizeField.hide(); + sizeField.allowBlank = true; + cloneField.hide(); + nameField.show(); + mountField.show(); case "volume": sizeField.show(); - sizeField.allowBlank = false; + sizeField.allowBlank = false; + cloneField.hide(); + nameField.show(); + mountField.hide(); break; + case "clone": + sizeField.hide(); + sizeField.allowBlank = true; + cloneField.show(); + nameField.hide(); + mountField.hide(); default: sizeField.hide(); - sizeField.allowBlank = true; + sizeField.allowBlank = true; + cloneField.hide(); + nameField.show(); + mountField.hide(); break; } sizeField.validate(); @@ -221,19 +308,89 @@ Ext.define("OMV.module.admin.storage.zfs.AddObject", { name: "path", fieldLabel: _("Prefix"), allowBlank: false, - readOnly: true + readOnly: true, + value: me.path, + listeners: { + scope: me, + beforerender: function(e, eOpts) { + var pathField = this.findField("path"); + if (me.parenttype === "Snapshot") { + pathField.fieldLabel = _("Snapshot to clone"); + } else { + pathField.fieldLabel = _("Prefix"); + } + } + } },{ xtype: "textfield", name: "name", + id: "name", fieldLabel: _("Name"), allowBlank: false, plugins: [{ ptype: "fieldinfo", text: _("Name of the new object. Prefix will prepend the name. Please omit leading /") - }] + }], + listeners: { + scope: me, + beforerender: function(e, eOpts) { + var nameField = this.findField("name"); + if (me.parenttype === "Snapshot") { + nameField.hide(); + nameField.allowBlank = true; + } else { + nameField.show(); + nameField.allowBlank = false; + } + } + } + },{ + xtype: "textfield", + name: "mountpoint", + fieldLabel: _("Mountpoint"), + allowBlank: true, + plugins: [{ + ptype: "fieldinfo", + text: _("Optional mountpoint of the filesystem. If left blank parent mountpoint will be prepended to name of the filesystem.") + }], + listeners: { + scope: me, + beforerender: function(e, eOpts) { + var mountField = this.findField("mountpoint"); + if (combodata[0][0] === "filesystem") { + mountField.show(); + } else { + mountField.hide(); + } + } + } + },{ + xtype: "textfield", + name: "clonename", + id: "clonename", + fieldLabel: _("Clone name"), + allowBlank: false, + plugins: [{ + ptype: "fieldinfo", + text: _("Name of the new Clone. It can be placed anywhere within the ZFS hierarchy.") + }], + listeners: { + scope: me, + beforerender: function(e, eOpts) { + var cloneField = this.findField("clonename"); + if (me.parenttype === "Snapshot") { + cloneField.show(); + cloneField.allowBlank = false; + } else { + cloneField.hide(); + cloneField.allowBlank = true; + } + } + } },{ xtype: "textfield", name: "size", + id: "size", hidden: true, fieldLabel: _("Size"), allowBlank: true, @@ -245,6 +402,161 @@ Ext.define("OMV.module.admin.storage.zfs.AddObject", { } }); +Ext.define("OMV.module.admin.storage.zfs.ExpandPool", { + extend: "OMV.workspace.window.Form", + uses: [ + "OMV.data.Store", + "OMV.data.Model", + "OMV.data.proxy.Rpc", + "OMV.data.reader.RpcArray" + ], + + rpcService: "ZFS", + rpcSetMethod: "expandPool", + width: 550, + height: 350, + autoLoadData: true, + + getFormItems: function() { + var me = this; + return [{ + xtype: "textfield", + name: "name", + fieldLabel: _("Name"), + allowBlank: false, + readOnly: true, + value: me.name + },{ + xtype: "combo", + name: "vdevtype", + fieldLabel: _("Vdev type"), + queryMode: "local", + store: Ext.create("Ext.data.ArrayStore", { + fields: [ "value", "text" ], + data: [ + [ "basic", _("Basic") ], + [ "mirror", _("Mirror") ], + [ "raidz1", _("RAID-Z1") ], + [ "raidz2", _("RAID-Z2") ], + [ "raidz3", _("RAID-Z3") ] + ] + }), + displayField: "text", + valueField: "value", + allowBlank: false, + editable: false, + triggerAction: "all", + value: "raidz1", + listeners: { + scope: me, + change: function(combo, value) { + var devicesField = this.findField("devices"); + switch(value) { + case "basic": + devicesField.minSelections = 1; + break; + case "mirror": + devicesField.minSelections = 2; + break; + case "raidz1": + devicesField.minSelections = 3; + break; + case "raidz2": + devicesField.minSelections = 4; + break; + case "raidz3": + devicesField.minSelections = 5; + break; + default: + devicesField.minSelections = 2; + break; + } + devicesField.validate(); + } + } + },{ + xtype: "checkboxgridfield", + name: "devices", + fieldLabel: _("Devices"), + valueField: "devicefile", + minSelections: 3, // Min. number of devices for RAIDZ-1 + useStringValue: true, + height: 130, + store: Ext.create("OMV.data.Store", { + autoLoad: true, + model: OMV.data.Model.createImplicit({ + idProperty: "devicefile", + fields: [ + { name: "devicefile", type: "string" }, + { name: "size", type: "string" }, + { name: "vendor", type: "string" }, + { name: "serialnumber", type: "string" } + ] + }), + proxy: { + type: "rpc", + appendSortParams: false, + rpcData: { + service: "RaidMgmt", + method: "getCandidates" + } + }, + sorters: [{ + direction: "ASC", + property: "devicefile" + }] + }), + gridConfig: { + stateful: true, + stateId: "05c60750-5074-11e4-916c-0800200c9a66", + columns: [{ + text: _("Device"), + sortable: true, + dataIndex: "devicefile", + stateId: "devicefile", + flex: 1 + },{ + xtype: "binaryunitcolumn", + text: _("Capacity"), + sortable: true, + dataIndex: "size", + stateId: "size", + width: 50, + flex: 1 + },{ + text: _("Vendor"), + sortable: true, + dataIndex: "vendor", + stateId: "vendor", + flex: 1 + },{ + text: _("Serial Number"), + sortable: true, + dataIndex: "serialnumber", + stateId: "serialnumber", + flex: 1 + }] + } + },{ + xtype: "checkbox", + name: "diskpath", + fieldLabel: _("Disk-by-path"), + plugins: [{ + ptype: "fieldinfo", + text: _("Use /dev/disk/by-path when creating the vdev. Recommended.") + }] + },{ + xtype: "checkbox", + name: "force", + fieldLabel: _("Force creation"), + checked: false, + plugins: [{ + ptype: "fieldinfo", + text: _("Forces the creation of the Vdev even if errors are reported. Use with extreme caution!") + }] + }]; + } +}); Ext.define("OMV.module.admin.storage.zfs.EditProperties", { @@ -273,10 +585,7 @@ Ext.define("OMV.module.admin.storage.zfs.EditProperties", { e.record.set("modified", "true"); }, beforeedit: function(editor, e, eOpts) { - if (e.record.get("property") === "mountpoint") { - e.grid.getPlugin('rowEditing').editor.form.findField("value").disable(); - e.grid.getPlugin('rowEditing').editor.form.findField("property").disable(); - } else if (e.record.get("newproperty") === "false") { + if (e.record.get("newproperty") === "false") { e.grid.getPlugin('rowEditing').editor.form.findField("value").enable(); e.grid.getPlugin('rowEditing').editor.form.findField("property").disable(); } else { @@ -463,8 +772,8 @@ Ext.define("OMV.module.admin.storage.zfs.CreateShare", { xtype: "textfield", name: "mountpoint", fieldLabel: _("Path"), - allowBlank: false, - readOnly: true + allowBlank: true, + readOnly: false },{ xtype: "combo", name: "mode", @@ -532,19 +841,57 @@ Ext.define("OMV.module.admin.storage.zfs.Overview", { dataIndex: 'name', sortable: true, flex: 2, - stateId: 'name' + stateId: 'name', + renderer: function(value, p, r){ + if (r.data['origin'] === "n/a") { + return r.data['name']; + } else { + return r.data['name'] + ' (' + r.data['origin'] + ')'; + } + } },{ text: _("Type"), dataIndex: 'type', sortable: true, flex: 1, - stateId: 'type' + stateId: 'type', + renderer: function(value, p, r){ + if (r.data['origin'] === "n/a") { + return r.data['type']; + } else { + return 'Clone'; + } + } + },{ + text: _("Size"), + dataIndex: 'size', + sortable: true, + flex: 1, + stateId: 'size' },{ - text: _("Share"), + text: _("Used"), + dataIndex: 'used', + sortable: true, + flex: 1, + stateId: 'used' + },{ + text: _("Available"), + dataIndex: 'available', + sortable: true, + flex: 1, + stateId: 'available' + },{ + text: _("Mountpoint"), + dataIndex: 'mountpoint', + sortable: true, + flex: 1, + stateId: 'mountpoint' + },{ + text: _("Share folder"), xtype: 'actioncolumn', tooltip: 'Create shared folder', align: 'center', - icon: 'images/checkmark.png', + icon: 'images/share.png', handler: function(view, rowIndex, colIndex, item, e, record, row) { var me = this; Ext.create("OMV.module.admin.storage.zfs.CreateShare", { @@ -564,14 +911,23 @@ Ext.define("OMV.module.admin.storage.zfs.Overview", { return true; } } - - },{ text: _("Details"), xtype: 'actioncolumn', tooltip: 'Details', align: 'center', - icon: 'images/search.png' + icon: 'images/search.png', + handler: function(view, rowIndex, colIndex, item, e, record, row) { + var me = this; + Ext.create("OMV.module.admin.storage.zfs.ShowDetails", { + title: _("Object details"), + rpcGetMethod: "getObjectDetails", + rpcGetParams: { + name: record.get('path'), + type: record.get('type') + } + }).show(); + } },{ text: _("Shared"), dataIndex: 'shared', @@ -590,10 +946,16 @@ Ext.define("OMV.module.admin.storage.zfs.Overview", { fields: [ { name: "name", type: "string" }, { name: "type", type: "string" }, + { name: "size", type: "string" }, + { name: "used", type: "string" }, + { name: "available", type: "string" }, + { name: "mountpoint", type: "string" }, { name: "id", type: "string" }, { name: "path", type: "string" }, { name: "origin", type: "string", defaultValue: "none" }, - { name: "shared", type: "string", defaultValue: "false" } + { name: "shared", type: "string", defaultValue: "false" }, + { name: "pool_type", type: "string"}, + { name: "nr_disks", type: "string"} ] }), proxy: { @@ -628,11 +990,8 @@ Ext.define("OMV.module.admin.storage.zfs.Overview", { var record = records[0]; Ext.create("OMV.module.admin.storage.zfs.AddObject", { title: _("Add Object"), - rpcGetMethod: "passParam", - rpcGetParams: { - key: "path", - value: record.get('path') - }, + path: record.get("path"), + parenttype: record.get("type"), listeners: { scope: me, submit: function() { @@ -652,6 +1011,23 @@ Ext.define("OMV.module.admin.storage.zfs.Overview", { type: record.get("type") }).show(); }, + + onExpandPoolButton: function() { + var me = this; + var sm = me.getSelectionModel(); + var records = sm.getSelection(); + var record = records[0]; + Ext.create("OMV.module.admin.storage.zfs.ExpandPool", { + title: _("Expand Pool"), + name: record.get("path"), + listeners: { + scope: me, + submit: function() { + this.doReload(); + } + } + }).show(); + }, doDeletion: function(record) { var me = this;