
From: samhenri <samuel.guimaraes@eldorado.org.br> Signed-off-by: samhenri <samuel.guimaraes@eldorado.org.br> --- src/wok/plugins/kimchi/ui/config/tab-ext.xml | 74 ++-- .../plugins/kimchi/ui/css/theme-default/host.css | 270 ------------- .../kimchi/ui/css/theme-default/report-add.css | 20 - .../kimchi/ui/css/theme-default/report-rename.css | 21 -- .../kimchi/ui/css/theme-default/repository-add.css | 25 -- .../ui/css/theme-default/repository-edit.css | 62 --- src/wok/plugins/kimchi/ui/js/src/kimchi.host.js | 35 +- src/wok/plugins/kimchi/ui/pages/host.html.tmpl | 188 ++++------ .../plugins/kimchi/ui/pages/report-add.html.tmpl | 46 +-- .../kimchi/ui/pages/report-rename.html.tmpl | 41 +- .../kimchi/ui/pages/repository-add.html.tmpl | 123 ++---- .../kimchi/ui/pages/repository-edit.html.tmpl | 137 +++---- ui/css/src/bootstrap-select.custom.scss | 1 + ui/css/src/modules/_menu-flat.scss | 6 +- ui/css/src/modules/_modal-flat.scss | 2 +- ui/css/src/modules/_navbar-flat.scss | 4 +- ui/css/src/wok.scss | 3 +- ui/css/theme-default/message.css | 46 --- ui/images/theme-default/Makefile.am | 2 +- ui/images/theme-default/logo-flat.svg | 43 +++ ui/images/theme-default/logo-white.png | Bin 9879 -> 7583 bytes ui/js/src/wok.grid.js | 416 +++++---------------- ui/js/src/wok.line-chart.js | 74 ++-- ui/js/src/wok.list.js | 281 ++++++++++++++ ui/js/src/wok.login.js | 9 +- ui/js/src/wok.main.js | 37 +- ui/js/src/wok.message.js | 38 +- ui/js/src/wok.window.js | 38 +- ui/pages/login.html.tmpl | 186 ++++----- ui/pages/wok-ui.html.tmpl | 219 ++++++----- 30 files changed, 1020 insertions(+), 1427 deletions(-) create mode 100644 ui/images/theme-default/logo-flat.svg create mode 100644 ui/js/src/wok.list.js diff --git a/src/wok/plugins/kimchi/ui/config/tab-ext.xml b/src/wok/plugins/kimchi/ui/config/tab-ext.xml index ee88c88..7ae8d39 100644 --- a/src/wok/plugins/kimchi/ui/config/tab-ext.xml +++ b/src/wok/plugins/kimchi/ui/config/tab-ext.xml @@ -1,38 +1,38 @@ <?xml version="1.0" encoding="utf-8"?> -<tabs-ext> - <tab> - <access role="admin" mode="admin"/> - <access role="user" mode="none"/> - - <title>Host</title> - <path>plugins/kimchi/host.html</path> - </tab> - <tab> - <access role="admin" mode="admin"/> - <access role="user" mode="byInstance"/> - - <title>Guests</title> - <path>plugins/kimchi/guests.html</path> - </tab> - <tab> - <access role="admin" mode="admin"/> - <access role="user" mode="none"/> - - <title>Templates</title> - <path>plugins/kimchi/templates.html</path> - </tab> - <tab> - <access role="admin" mode="admin"/> - <access role="user" mode="read-only"/> - - <title>Storage</title> - <path>plugins/kimchi/storage.html</path> - </tab> - <tab> - <access role="admin" mode="admin"/> - <access role="user" mode="read-only"/> - - <title>Network</title> - <path>plugins/kimchi/network.html</path> - </tab> -</tabs-ext> + <tabs-ext> + <tab> + <access role="admin" mode="admin" /> + <access role="user" mode="none" /> + <title>Host</title> + <class>host</class> + <path>plugins/kimchi/host.html</path> + </tab> + <tab> + <access role="admin" mode="admin" /> + <access role="user" mode="byInstance" /> + <title>Guests</title> + <class>guests</class> + <path>plugins/kimchi/guests.html</path> + </tab> + <tab> + <access role="admin" mode="admin" /> + <access role="user" mode="none" /> + <title>Templates</title> + <class>templates</class> + <path>plugins/kimchi/templates.html</path> + </tab> + <tab> + <access role="admin" mode="admin" /> + <access role="user" mode="read-only" /> + <title>Storage</title> + <class>storage</class> + <path>plugins/kimchi/storage.html</path> + </tab> + <tab> + <access role="admin" mode="admin" /> + <access role="user" mode="read-only" /> + <title>Network</title> + <class>network</class> + <path>plugins/kimchi/network.html</path> + </tab> + </tabs-ext> \ No newline at end of file diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/host.css b/src/wok/plugins/kimchi/ui/css/theme-default/host.css index a0cccb1..bb693cc 100644 --- a/src/wok/plugins/kimchi/ui/css/theme-default/host.css +++ b/src/wok/plugins/kimchi/ui/css/theme-default/host.css @@ -15,273 +15,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -.host-panel { - font-size: 12px; - margin-bottom: 100px; -} - -.host-panel .logo-container, .host-panel .info-container, -.host-panel .section-label, .host-panel .section-value { - display: inline-block; - vertical-align: top; -} - -.host-panel .section-label { - display: inline-block; - margin-right: 1em; - vertical-align: top; -} - -.host-panel .logo { - background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top; - height: 128px; - width: 128px; -} - -.host-panel .hostname { - text-decoration: underline; -} - -.host-panel .action-panel { - margin-top: 2em; - padding-left: 10px; -} - -.host-panel .button-icon { - background: url("../images/theme-default/host-icon-sprite.png") no-repeat - left top; - display: inline-block; - height: 12px; - width: 12px; -} - -.host-panel .action-icon-stop { - background-position: -14px 0; -} - -.host-panel .action-icon-restart { - background-position: -28px 0; -} - -.host-panel .action-icon-download { - background-position: -42px 0; -} - -.host-panel .action-icon-connect { - background-position: -56px 0; -} - -.host-panel .action-icon-add { - background-position: -70px 0; -} - -.host-panel .action-icon-edit { - background-position: -84px 0; -} - -.host-panel .action-icon-remove { - background-position: -98px 0; -} - -.host-panel button:disabled .action-icon-start { - background-position: 0 -14px; -} - -.host-panel button:disabled .action-icon-stop { - background-position: -14px -14px; -} - -.host-panel button:disabled .action-icon-restart { - background-position: -28px -14px; -} - -.host-panel button:disabled .action-icon-download { - background-position: -42px -14px; -} - -.host-panel button:disabled .action-icon-connect { - background-position: -56px -14px; -} - -.host-panel button:disabled .action-icon-add { - background-position: -70px -14px; -} - -.host-panel button:disabled .action-icon-edit { - background-position: -84px -14px; -} - -.host-panel button:disabled .action-icon-remove { - background-position: -98px -14px; -} - -.host-panel .info-container { - padding-top: 16px; - width: 890px; -} - -.host-panel .section-header { - background: #EEE; - border-radius: 5px; - cursor: pointer; - line-height: 2em; - margin: 1em 0 1em; - padding-left: 6px; -} - -.host-panel .section-header:hover { - background: #06f; - color: white; -} - -.host-panel .section-content { - padding-left: 1em; -} - -.host-panel .section-header .arrow { - border-color: transparent; - border-style: solid; - display: inline-block; - margin-right: 6px; - width: 0; -} - -.host-panel .section-header[aria-expanded="true"] .arrow { - border-top-color: black; - border-width: 8px 4px 0; - border-bottom: none; -} - -.host-panel .section-header[aria-expanded="true"]:hover .arrow { - border-top-color: white; -} - -.host-panel .section-header[aria-expanded="false"] .arrow { - border-left-color: black; - border-right: none; - border-width: 4px 0 4px 8px; -} - -.host-panel .section-header[aria-expanded="false"]:hover .arrow { - border-left-color: white; -} - -.host-panel .section-row { - line-height: 1.6em; - margin-bottom: 1em; -} - -.host-panel .section-label { - width: 100px; -} - -#frequency-textbox { - width: 20px; -} - -#container-chart-cpu, -#container-chart-memory, -#container-chart-disk-io, -#container-chart-network-io { - border: 1px solid white; - box-shadow: 2px 2px 2px gray, 2px -2px 2px gray, -2px -2px 2px gray, -2px - 2px 2px gray; - height: 100px; - width: 500px; -} - -#container-chart-disk-io .disk-write, -#container-chart-network-io .network-sent { - stroke: #f80; -} - -/* Debug Report */ -.cell-text-wrapper { - margin-left: 10px; -} - -.host-panel #available-reports-grid { - border-color: #ddd; - height: 400px; - width: 850px; -} - -.host-panel select#available-reports-list { - width: 300px; -} - -.host-panel select#available-reports-list option { - margin: .2em 1em; -} - -.debug-report-name, -.debug-report-time { - width: 424px; -} - -#id-debug-img { - background: url(../images/theme-default/kimchi-loading15x15.gif) 12px - center no-repeat; - padding-left: 23px; -} - -/* End of Debug Report */ - -/* Software Updates */ -.host-panel #software-updates-grid { - border-color: #ddd; - height: 300px; - width: 850px; -} - -.software-update-name, -.software-update-repos { - width: 224px; -} - -.software-update-version, -.software-update-arch { - width: 200px; -} - -.host-panel #software-updates-progress-textarea { - border: 1px solid #ddd; - box-sizing: border-box; - height: 100px; - padding: .2em .5em; - resize: vertical; - width: 852px; -} -/* End of Software Updates */ - -/* Repository */ -.host-panel #repositories-grid { - border-color: #ddd; - height: 200px; - width: 850px; -} - -.host-panel #repositories-grid .repository-id { - width: 120px; -} - -.host-panel #repositories-grid .repository-name { - width: 640px; -} - -.host-panel #repositories-grid .repository-enabled { - width: 88px; -} - -.host-panel #repositories-grid .repository-baseurl.deb { - width: 400px; -} - -.host-panel #repositories-grid .repository-enabled.deb { - width: 100px; -} - -.host-panel #repositories-grid .repository-gpgcheck.deb { - width: 150px; -} -/* End of Repository */ diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css index 8020182..3769daa 100644 --- a/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css +++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css @@ -15,23 +15,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#report-add-window { - height: 300px; - width: 400px; -} - -#report-add-window .field { - font-size: 12px; -} - -#report-name-textbox { - margin: 0; - width: 100%; -} - -.info-add-debug-report { - font-size: 12px; - color: #999999; - font-weight: lighter; - font-family: 'Helvetica Neue', Helvetica, Arial; -} \ No newline at end of file diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css index 2fb2698..48abeb9 100644 --- a/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css +++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css @@ -15,25 +15,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#report-rename-window { - height: 300px; - width: 400px; -} -#report-rename-window .field { - font-size: 12px; -} - -#report-name-textbox { - -moz-box-sizing: border-box; - box-sizing: border-box; - margin: 0; - width: 100%; -} - -.info-debug-report-rename { - font-size: 12px; - color: #999999; - font-weight: lighter; - font-family: 'Helvetica Neue', Helvetica, Arial; -} diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css index 4344569..2d9e4a2 100644 --- a/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css +++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css @@ -15,28 +15,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#repository-add-window { - height: 500px; - width: 1000px; -} - -#repository-add-window span.required { - color: red; - padding-left: 5px; - vertical-align: top; -} - -#repository-add-window .textbox-wrapper input[type="text"] { - box-sizing: border-box; - width: 100%; -} - -#repository-add-window .textbox-wrapper label { - vertical-align: middle; -} - -#isMirrorLabel { - font-size: 14px; - font-weight: lighter; - font-family: 'Helvetica Neue', Helvetica, Arial; -} \ No newline at end of file diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css index 383a7fe..d50bbc1 100644 --- a/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css +++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css @@ -15,68 +15,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -.yum div#repository-edit-window { - height: 680px; - width: 1000px; -} - -.deb div#repository-edit-window { - height: 480px; - width: 1000px; -} - - -.repository-edit-fieldset { - float: left; - padding: 0 30px; - width: 95%; -} - -.repository-edit-wrapper-label, .repository-edit-wrapper-controls { - display: inline-block; - height: 30px; - line-height: 30px; - font-size: 14px; - vertical-align: top; -} - -.repository-edit-wrapper-label { - margin-top: 10px; - width: 150px; -} - -.repository-edit-wrapper-controls label { - vertical-align: middle; -} - -.repository-edit-wrapper-controls { - width: 100%; -} - -.repository-edit-wrapper-controls input[type="text"] { - font-size: 16px; - height: 30px; - line-height: 30px; - padding: 0 10px; - width: 100%; - -moz-box-sizing: border-box; - box-sizing: border-box; - border: 1px solid #CCCCCC; -} - - -.repository-edit-wrapper-controls input[type="text"][readonly] { - color: #bbb; - background-color: #fafafa; -} - - -.repository-edit-wrapper-controls input[type="text"][disabled] { - color: #bbb; - background-color: #fafafa; - cursor: not-allowed; -} - .deb .yum{ display: none; diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js index c925fa1..31a4a6a 100644 --- a/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js +++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js @@ -31,15 +31,18 @@ kimchi.host_main = function() { gridFields=[{ name: 'repo_id', label: i18n['KCHREPO6004M'], - 'class': 'repository-id' + 'class': 'repository-id', + type: 'name' }, { name: 'config[display_repo_name]', label: i18n['KCHREPO6005M'], - 'class': 'repository-name' + 'class': 'repository-name', + type: 'description' }, { name: 'enabled', label: i18n['KCHREPO6009M'], - 'class': 'repository-enabled' + 'class': 'repository-enabled', + type: 'status' }]; } else if (repo_type == "deb") { @@ -47,11 +50,13 @@ kimchi.host_main = function() { name: 'baseurl', label: i18n['KCHREPO6006M'], makeTitle: true, - 'class': 'repository-baseurl deb' + 'class': 'repository-baseurl deb', + type: 'description' }, { name: 'enabled', label: i18n['KCHREPO6009M'], - 'class': 'repository-enabled deb' + 'class': 'repository-enabled deb', + type: 'status' }, { name: 'config[dist]', label: "dist", @@ -64,27 +69,31 @@ kimchi.host_main = function() { } else { gridFields=[{ - name: 'repo_id', - label: i18n['KCHREPO6004M'], - 'class': 'repository-id' + name: 'repo_id', + label: i18n['KCHREPO6004M'], + 'class': 'repository-id', + type: 'name' }, { name: 'enabled', label: i18n['KCHREPO6009M'], - 'class': 'repository-enabled' + 'class': 'repository-enabled', + type: 'status' }, { name: 'baseurl', label: i18n['KCHREPO6006M'], makeTitle: true, - 'class': 'repository-baseurl' + 'class': 'repository-baseurl', + type: 'description' }]; } - repositoriesGrid = new wok.widget.Grid({ + repositoriesGrid = new wok.widget.List({ container: 'repositories-grid-container', id: 'repositories-grid', title: i18n['KCHREPO6003M'], toolbarButtons: [{ id: 'repositories-grid-add-button', label: i18n['KCHREPO6012M'], + class: 'fa fa-plus-circle', onClick: function(event) { wok.window.open({url:'plugins/kimchi/repository-add.html', class: repo_type}); @@ -92,6 +101,7 @@ kimchi.host_main = function() { }, { id: 'repositories-grid-enable-button', label: i18n['KCHREPO6016M'], + class: 'fa fa-play-circle-o', disabled: true, onClick: function(event) { var repository = repositoriesGrid.getSelected(); @@ -108,6 +118,7 @@ kimchi.host_main = function() { }, { id: 'repositories-grid-edit-button', label: i18n['KCHREPO6013M'], + class: 'fa fa-pencil', disabled: true, onClick: function(event) { var repository = repositoriesGrid.getSelected(); @@ -121,6 +132,8 @@ kimchi.host_main = function() { }, { id: 'repositories-grid-remove-button', label: i18n['KCHREPO6014M'], + class: 'fa fa-minus-circle', + critical: true, disabled: true, onClick: function(event) { var repository = repositoriesGrid.getSelected(); diff --git a/src/wok/plugins/kimchi/ui/pages/host.html.tmpl b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl index d87debc..3c02a34 100644 --- a/src/wok/plugins/kimchi/ui/pages/host.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl @@ -31,145 +31,103 @@ <body> <div id="host-root-container"> <div class="toolbar"> - <div class="tools"> + <div class="container"> + <div class="tools pull-right"> + <a id="host-button-restart" href="javascript:void(0);"><i class="fa fa-refresh"></i><span>$_("Restart")</span></a> + <a id="host-button-shutdown" href="javascript:void(0);"><i class="fa fa-ban"></i><span>$_("Shut down")</span></a> + <!-- <a href="javascript:void(0);"><i class="fa fa-desktop"></i><span>$_("Connect")</span></a> --> + </div> </div> </div> <div id="host-content-container" class="empty-when-logged-off"></div> </div> <script id="host-tmpl" type="kimchi/template"> - <div class="host-panel"> - <div class="logo-container"> - <div class="logo" style="background-image: url({logo});"></div> - </div> - <div id="host-info-container" class="info-container"> - <h2 class="hostname">{hostname}</h2> - <div class="action-panel"> - <button id="host-button-shutdown" class="btn-normal-1 stop"> - <div class="button-icon action-icon-stop"></div> - $_("Shut down") - </button> - <button id="host-button-restart" class="btn-normal-1 restart"> - <div class="button-icon action-icon-restart"></div> - $_("Restart") - </button> - <button class="btn-normal-1 connect" disabled="disabled"> - <div class="button-icon action-icon-connect"></div> - $_("Connect") - </button> - </div> - <div class="host-section"> - <h3 class="section-header" - aria-expanded="false" - aria-controls="content-sys-info"> - $_("Basic Information") - </h3> - <div id="content-sys-info" class="section-content"> - <div class="section-row"> - <div class="section-label">$_("OS Distro")</div> - <div class="section-value">{os_distro}</div> - </div> - <div class="section-row"> - <div class="section-label">$_("OS Version")</div> - <div class="section-value">{os_version}</div> - </div> - <div class="section-row"> - <div class="section-label">$_("OS Code Name")</div> - <div class="section-value">{os_codename}</div> - </div> - <div class="section-row"> - <div class="section-label">$_("Processor")</div> - <div class="section-value">{cpu_model}</div> - </div> - <div class="section-row"> - <div class="section-label">$_("CPU(s)")</div> - <div class="section-value">{cpus}</div> - </div> - <div class="section-row"> - <div class="section-label">$_("Memory")</div> - <div class="section-value">{memory}</div> +<div class="host-dashboard"> + <div class="container"> + <div id="alert-container"></div> + <div id="content-sys-statistics" class="row"> + <div class="col-md-3"> + <div id="cpu-dashboard"> + <h3 class="section-label">$_("CPU")</h3> + <div class="section-value"> + <div id="container-chart-cpu" class="inline-block"></div> </div> </div> </div> - <div class="host-section"> - <h3 class="section-header" - aria-controls="content-sys-statistics"> - $_("System Statistics") - </h3> - <div id="content-sys-statistics" class="section-content"> - <div class="section-row"> - <div class="section-label">$_("CPU")</div> - <div class="section-value"> - <div id="container-chart-cpu" class="inline-block"></div> - </div> - </div> - <div class="section-row"> - <div class="section-label">$_("Memory")</div> - <div class="section-value"> - <div id="container-chart-memory" class="inline-block"></div> - </div> - </div> - <div class="section-row"> - <div class="section-label">$_("Disk I/O")</div> - <div class="section-value"> - <div id="container-chart-disk-io" class="inline-block"></div> - </div> - </div> - <div class="section-row"> - <div class="section-label">$_("Network I/O")</div> - <div class="section-value"> - <div id="container-chart-network-io" class="inline-block"></div> - </div> + <div class="col-md-3"> + <div id="memory-dashboard"> + <h3 class="section-label">$_("Memory")</h3> + <div class="section-value"> + <div id="container-chart-memory" class="inline-block"></div> </div> </div> </div> - <div id="software-update-section" class="host-section hidden"> - <h3 class="section-header" - aria-controls="content-software-update"> - $_("Software Updates") - </h3> - <div id="content-software-update" class="section-content"> - <div class="section-row"> - <div class="section-value"> - <div id="software-updates-grid-container"></div> - <div id="software-updates-progress-container" class="hidden"> - <label for="software-updates-progress-textarea">$_("Update Progress")</label> - <textarea id="software-updates-progress-textarea" readonly></textarea> - </div> - </div> + <div class="col-md-3"> + <div id="disk-dashboard"> + <h3 class="section-label">$_("Disk I/O")</h3> + <div class="section-value"> + <div id="container-chart-disk-io" class="inline-block"></div> </div> </div> </div> - <div id="repositories-section" class="host-section hidden"> - <h3 class="section-header" - aria-controls="content-repositories"> - $_("Repositories") - </h3> - <div id="content-repositories" class="section-content"> - <div class="section-row"> - <div class="section-value"> - <div id="repositories-grid-container"></div> - </div> + <div class="col-md-3"> + <div id="network-dashboard"> + <h3 class="section-label">$_("Network I/O")</h3> + <div class="section-value"> + <div id="container-chart-network-io" class="inline-block"></div> </div> </div> </div> - <div id="debug-report-section" class="host-section hidden"> - <h3 class="section-header" - aria-controls="content-sys-reports"> - $_("Debug Reports") - </h3> - <div id="content-sys-reports" class="section-content"> - <div class="section-row"> - <div class="section-value"> - <div id="available-reports-grid-container"></div> - </div> + </div> + </div> +</div> +<div class="host-panel"> + <div class="container"> + <div id="host-info-container" class="row"> + <div id="content-sys-info" class="panel panel-default col-md-4"> + <div class="panel-heading"> + <h3 class="panel-title">$_("Basic Information")</h3> + </div> + <div class="panel-body"> + <dl class="basic-information-list"> + <dt>{os_distro}</dt> + <dd>$_("OS Distro")</dd> + <dt>{os_version}</dt> + <dd>$_("OS Version")</dd> + <dt>{os_codename}</dt> + <dd>$_("OS Code Name")</dd> + <dt>{cpu_model}</dt> + <dd>$_("Processor")</dd> + <dt>{cpus}</dt> + <dd>$_("CPU(s)")</dd> + <dt>{memory}</dt> + <dd>$_("Memory")</dd> + </dl> + </div> + </div> + <div id="repositories-grid-container" class="col-md-4"></div> + <div id="available-reports-grid-container" class="col-md-4"></div> + </div> + <div class="row"> + <div id="software-update-section" class="panel panel-default col-md-12"> + <div class="panel-heading"> + <h3 class="panel-title">$_("Software Updates")</h3> + </div> + <div id="content-software-update" class="panel panel-default"> + <div id="software-updates-grid-container"></div> + <div id="software-updates-progress-container" class="hidden"> + <label for="software-updates-progress-textarea">$_("Update Progress")</label> + <textarea id="software-updates-progress-textarea" readonly></textarea> </div> </div> </div> </div> </div> +</div> </script> - +<div id="modalWindow" class="modal fade host-modal" tabindex="-1" role="dialog" aria-labelledby="hostsModalLabel" aria-hidden="true"> +</div> <script type="text/javascript"> kimchi.host_main(); </script> diff --git a/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl index 25bf0a9..6882f34 100644 --- a/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl @@ -22,35 +22,25 @@ #silent _ = t.gettext #silent _t = t.gettext <!DOCTYPE html> -<div id="report-add-window" class="window"> - <header> - <h1 class="title h1 grey">$_("Generate a New Debug Report")</h1> - </header> - <div class="content"> - <form id="form-report-add"> - <section class="form-section"> - <h2> - <label for="report-name-textbox">$_("Report Name")</label> - </h2> - <div class="field"> - <input type="text" class="text" id="report-name-textbox" name="name" /> - <span class="icon-info-circled light-grey c1"></span> - <span class="info-add-debug-report"> - $_("The name used to identify the report. If omitted, a name will be chosen based on current time. Name can contain: letters, digits, underscore (\"_\") and hyphen (\"-\").") - </span> - </div> - </section> - </form> - </div> - <footer> - <div class="btn-group"> - <button id="button-report-add" class="btn-normal"><span class="text">$_("Generate")</span></button> - <button id="button-report-cancel" class="btn-normal close" type="button"> - <span calss="text">$_("Cancel")</span> - </button> +<div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">$_("Generate a New Debug Report")</h4> + </div> + <div class="modal-body"> + <form id="form-report-add"> + <div class="form-group"> + <label for="report-name-textbox">$_("Report Name")</label> + <input type="text" class="form-control" id="report-name-textbox" name="name" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("The name used to identify the report. If omitted, a name will be chosen based on current time. Name can contain: letters, digits, underscore (\"_\") and hyphen (\"-\").") + </p> </div> - </footer> + </form> + </div> + <div class="modal-footer"> + <button type="button" id="button-report-add" class="btn btn-default" data-dismiss="modal">$_("Generate")</button> + <button type="button" id="button-report-cancel" class="btn btn-default" data-dismiss="modal">$_("Cancel")</button> + </div> </div> <script> kimchi.report_add_main(); -</script> +</script> \ No newline at end of file diff --git a/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl index 90a0a80..ef14d8b 100644 --- a/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl @@ -22,34 +22,25 @@ #silent _ = t.gettext #silent _t = t.gettext <!DOCTYPE html> -<div id="report-rename-window" class="window"> - <header> - <h1 class="title h1 grey">$_("Rename a Debug Report")</h1> - </header> - <div class="content"> +<div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">$_("Rename a Debug Report")</h4> + </div> + <div class="modal-body"> <form id="form-report-rename"> - <section class="form-section"> - <h2> - <label for="report-name-textbox">$_("Report Name")</label> - </h2> - <div class="field"> - <input type="text" class="text" id="report-name-textbox" name="name" /> - <span class="icon-info-circled light-grey c1"></span> - <span class="info-debug-report-rename"> - $_("The name used to identify the report. Name can contain: letters, digits and hyphen (\"-\").") - </span> - </div> - </section> + <div class="form-group"> + <label for="report-name-textbox">$_("Report Name")</label> + <input type="text" class="form-control" id="report-name-textbox" name="name" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("The name used to identify the report. Name can contain: letters, digits and hyphen (\"-\").") + </p> + </div> </form> </div> - <footer> - <div class="btn-group"> - <button id="button-report-rename" class="btn-normal"><span class="text">$_("Submit")</span></button> - <button id-"button-report-rename-cancel" class="btn-normal close" type="button"> - <span class="text">$_("Cancel")</span> - </button> - </div> - </footer> + <div class="modal-footer"> + <button type="button" id="button-report-rename" class="btn btn-default" data-dismiss="modal">$_("Submit")</button> + <button type="button" id- "button-report-rename-cancel" class="btn btn-default" type="button" data-dismiss="modal">$_("Cancel") + </button> + </div> </div> <script> kimchi.report_rename_main(); diff --git a/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl index 950252a..0ab2cc0 100644 --- a/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl @@ -21,92 +21,49 @@ #silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True) #silent _ = t.gettext #silent _t = t.gettext -<div id="repository-add-window" class="window"> - <form id="form-repository-add"> - <header class="window-header"> - <h1 class="title h1 grey">$_("Add a Repository")</h1> - </header> - <section> - <div class="content"> - <div class="form-section yum"> - <h2>$_("Identifier")</h2> - <div class="field"> - <div class="textbox-wrapper"> - <input type="text" class="text" name="repo_id" /> - </div> - <div class="icon-info-circled light-grey c1 help-inline"></div> - <p class="text-help help-inline"> - $_("Single word, unique identifier for the repository.") +<div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">$_("Add a Repository")</h4> + </div> + <div class="modal-body"> + <form id="form-repository-add"> + <div class="form-group yum"> + <label for="repo_id">$_("Identifier")</label> + <input type="text" class="form-control" name="repo_id" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("Single word, unique identifier for the repository.") </p> - </div> </div> - <section class="form-section yum"> - <h2>$_("Name")</h2> - <div class="field"> - <div class="textbox-wrapper"> - <input type="text" class="text" name="config[repo_name]" /> - </div> - <div class="icon-info-circled light-grey c1 help-inline"></div> - <p class="text-help help-inline"> - $_("Textual name for the repository.") + <div class="form-group yum"> + <label for="repo_name">$_("Name")</label> + <input type="text" class="form-control" id="repo_name" name="config[repo_name]" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("Textual name for the repository.") </p> - </div> - </section> - <section class="form-section"> - <h2>$_("URL")<span class="required" role="presentation" title='$_("Required Field")'>*</span></h2> - <div class="field"> - <div class="textbox-wrapper"> - <input type="text" class="text required" name="baseurl" /> - </div> - <div class="icon-info-circled light-grey c1 help-inline"></div> - <p class="text-help help-inline"> - $_("URL to the repository. Supported protocols are http, ftp, and file.") - </p> - </div> - <div class="field yum"> - <p class="yum"> - <input type="checkbox" name="isMirror" value="true" id="isMirror" /> - <label id="isMirrorLabel" for="isMirror">$_("Repository is a mirror")</label> - </p> - </div> - </section> - <section class="form-section repository-dist deb"> - <h2>$_("Distribution")</h2> - <div class="field"> - <div class="textbox-wrapper"> - <input type="text" class="text" name="config[dist]" /> - </div> - <div class="icon-info-circled light-grey c1 help-inline"></div> - <p class="text-help help-inline"> - $_("Distribution of the DEB repository.") - </p> - </div> - </section> - <section class="form-section repository-comps deb"> - <h2>$_("Components")</h2> - <div class="field"> - <div class="textbox-wrapper"> - <input type="text" class="text" name="config[comps]" /> - </div> - <div class="icon-info-circled light-grey c1 help-inline"></div> - <p class="text-help help-inline"> - $_("List of components in DEB repository.") - </p> - </div> - </section> - </div> - </section> - <footer> - <div class="btn-group"> - <button type="submit" id="button-repository-add" class="btn-normal" disabled="disabled"> - <span class="text">$_("Add")</span> - </button> - <button type="button" id="button-repository-close" class="btn-normal close"> - <span class="text">$("Cancel")</span> - </button> - </div> - </footer> - </form> + </div> + <div class="form-group"> + <label for="baseurl">$_("URL")<span class="required" role="presentation" title='$_("Required Field")'>*</span></label> + <input type="text" class="form-control required" id="baseurl" name="baseurl" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("URL to the repository. Supported protocols are http, ftp, and file.")</p> + </div> + <div class="checkbox yum"> + <label id="isMirrorLabel" for="isMirror"> + <input type="checkbox" name="isMirror" value="true" id="isMirror" /> $_("Repository is a mirror")</label> + </div> + <div class="form-group repository-dist deb"> + <label>$_("Distribution")</label> + <input type="text" class="form-control" name="config[dist]" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("Distribution of the DEB repository.")</p> + </div> + <div class="form-group repository-comps deb"> + <label>$_("Components")</label> + <input type="text" class="form-control" name="config[comps]" /> + <p class="help-block"><i class="fa fa-info-circle"></i> $_("List of components in DEB repository.")</p> + </div> + </form> + </div> + <div class="modal-footer"> + <button type="submit" id="button-repository-add" class="btn btn-default" disabled="disabled">$_("Add")</button> + <button type="button" id="button-repository-close" class="btn btn-default">$("Cancel")</button> + </div> </div> <script> kimchi.repository_add_main(); diff --git a/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl index e5a3cfb..d74d816 100644 --- a/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl +++ b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl @@ -21,96 +21,55 @@ #silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True) #silent _ = t.gettext #silent _t = t.gettext - -<div id="repository-edit-window" class="window"> - <form id="form-repository-edit"> - <header> - <h1 class="title h1 grey">$_("Edit Repository")</h1> - </header> - <div class="content"> - <section id="form-repository-edit"> - <fieldset class="repository-edit-fieldset"> - <div class="repository-id yum"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-id-textbox">$_("ID")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-id-textbox" name="repo_id" type="text" disabled="disabled" readonly="readonly"/> - </div> - </div> - <div class="repository-name yum"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-name-textbox">$_("Name")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-name-textbox" class="yum" name="config[repo_name]" type="text" /> - </div> - </div> - <div class="repository-url"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-baseurl-textbox">$_("URL")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" /> - </div> - </div> - <div class="repository-dist deb"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-urlargs-textbox">$_("Distribution")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-urlargs-textbox" class="deb" name="config[dist]" type="text" /> - </div> - </div> - <div class="repository-mirrorlist yum"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-urlargs-textbox" class="yum" name="config[mirrorlist]" type="text" /> - </div> - </div> - <div class="repository-comps deb"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-urlargs-textbox">$_("Components")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-urlargs-textbox" class="deb" name="config[comps]" type="text" /> - </div> - </div> - <div class="repository-gpgkey yum"> - <div class="repository-edit-wrapper-label"> - <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-gpgkey-textbox" class="yum" name="config[gpgkey]" type="text" /> - </div> - </div> - <div class="repository-gpgcheck yum"> - <div class="repository-edit-wrapper-label"> - <label>$_("GPG Check")</label> - </div> - <div class="repository-edit-wrapper-controls"> - <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" /> - <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label> - <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" /> - <label for="repository-edit-gpgcheck-radio-false">$_("No")</label> - </div> - </div> - </fieldset> - </section> - </div> - <footer> - <div class="btn-group"> - <button type="submit" id="repository-edit-button-save" class="btn-normal"> - <span class="text">$_("Save")</span> - </button> - <button type="button" id="repository-edit-button-cancel" class="close btn-normal"> - <span class="text">$_("Cancel")</span> - </button> +<div class="modal-content"> + <div class="modal-header"> + <h4 class="modal-title">$_("Edit Repository")</h4> + </div> + <div class="modal-body"> + <form id="form-repository-edit"> + <div class="form-group repository-id yum"> + <label for="repository-edit-id-textbox">$_("ID")</label> + <input id="repository-edit-id-textbox" class="form-control" name="repo_id" type="text" disabled="disabled" readonly="readonly" /> </div> - </footer> - </form> + <div class="form-group repository-name yum"> + <label for="repository-edit-name-textbox">$_("Name")</label> + <input id="repository-edit-name-textbox" class="form-control yum" name="config[repo_name]" type="text" /> + </div> + <div class="form-group repository-url"> + <label for="repository-edit-baseurl-textbox">$_("URL")</label> + <input id="repository-edit-baseurl-textbox" class="form-control" name="baseurl" type="text" /> + </div> + <div class="form-group repository-dist deb"> + <label for="repository-edit-urlargs-textbox">$_("Distribution")</label> + <input id="repository-edit-urlargs-textbox" class="form-control deb" name="config[dist]" type="text" /> + </div> + <div class="form-group repository-mirrorlist yum"> + <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label> + <input id="repository-edit-urlargs-textbox" class="form-control yum" name="config[mirrorlist]" type="text" /> + </div> + <div class="form-group repository-comps deb"> + <label for="repository-edit-urlargs-textbox">$_("Components")</label> + <input id="repository-edit-urlargs-textbox" class="form-control deb" name="config[comps]" type="text" /> + </div> + <div class="form-group repository-gpgkey yum"> + <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label> + <input id="repository-edit-gpgkey-textbox" class="form-control yum" name="config[gpgkey]" type="text" /> + </div> + <div class="form-group repository-gpgcheck yum"> + <label>$_("GPG Check")</label> + <label for="repository-edit-gpgcheck-radio-true" class="radio inline control-label"> + <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" /> $_("Yes") + </label> + <label for="repository-edit-gpgcheck-radio-false" class="radio inline control-label"> + <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" /> $_("No") + </label> + </div> + </form> + </div> + <div class="modal-footer"> + <button type="submit" id="repository-edit-button-save" class="btn btn-default">$_("Save")</button> + <button type="button" id="repository-edit-button-cancel" class="btn btn-default">$_("Cancel")</button> + </div> </div> <script type="text/javascript"> kimchi.repository_edit_main(); diff --git a/ui/css/src/bootstrap-select.custom.scss b/ui/css/src/bootstrap-select.custom.scss index 49f9bc2..dd895f2 100644 --- a/ui/css/src/bootstrap-select.custom.scss +++ b/ui/css/src/bootstrap-select.custom.scss @@ -25,6 +25,7 @@ &.btn-group { .btn { .caret { + position: absolute; top: 0; right: 40px; margin-top: 0; diff --git a/ui/css/src/modules/_menu-flat.scss b/ui/css/src/modules/_menu-flat.scss index 9d7036b..46ed21c 100644 --- a/ui/css/src/modules/_menu-flat.scss +++ b/ui/css/src/modules/_menu-flat.scss @@ -127,7 +127,7 @@ background-color: $menu-flat-dropdown-bg; border: 0; border-radius: 0; - @include box-shadow(none !important); + box-shadow: none !important; background-clip: padding-box; // Aligns the dropdown menu to right @@ -150,11 +150,11 @@ > li:first-child > a { border-top: 1px solid $menu-flat-dropdown-bg; - @include box-shadow(none); + box-shadow: none; } > li.critical:last-child > a { - @include box-shadow(none); + box-shadow: none; } // Links within the dropdown menu diff --git a/ui/css/src/modules/_modal-flat.scss b/ui/css/src/modules/_modal-flat.scss index 8265140..90ae44a 100644 --- a/ui/css/src/modules/_modal-flat.scss +++ b/ui/css/src/modules/_modal-flat.scss @@ -76,7 +76,7 @@ border-radius: 0; border: 3px solid #999; background-clip: padding-box; - @include box-shadow(none !important); + box-shadow: none !important; border-radius: 0; outline: 0; } diff --git a/ui/css/src/modules/_navbar-flat.scss b/ui/css/src/modules/_navbar-flat.scss index b54db68..47246a6 100644 --- a/ui/css/src/modules/_navbar-flat.scss +++ b/ui/css/src/modules/_navbar-flat.scss @@ -355,7 +355,7 @@ margin-right: 0; padding-top: 0; padding-bottom: 0; - @include box-shadow(none); + box-shadow: none; } } @@ -418,7 +418,7 @@ background-color: $menu-flat-dropdown-bg; border: 0; border-radius: 0; - @include box-shadow(none !important); + box-shadow: none !important; background-clip: padding-box; height: auto; max-height: 400px; diff --git a/ui/css/src/wok.scss b/ui/css/src/wok.scss index 9c0dee2..b9d9996 100755 --- a/ui/css/src/wok.scss +++ b/ui/css/src/wok.scss @@ -64,7 +64,8 @@ // Override panels .panel { - @include box-shadow(none); + box-shadow: none !important; + -webkit-box-shadow: none !important; } .panel-title { diff --git a/ui/css/theme-default/message.css b/ui/css/theme-default/message.css index 5775334..136e626 100644 --- a/ui/css/theme-default/message.css +++ b/ui/css/theme-default/message.css @@ -17,52 +17,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#messageField { - position: fixed; - margin: auto; - left: 0; - right: 0; - top: 0; - width: 1024px; - max-width: 100%; - z-index: 200; -} - -.message { - background-color: #FFF68F; - position: relative; - margin-bottom: 5px; -} - -.message.warn { - background-color: #FFF68F; -} - -.message.error { - background-color: #FFAEB9; -} - -.message.success { - background-color: #90EE90; -} - -.message .close { - position: absolute; - width: 30px; - height: 30px; - top: 0; - right: 0; - color: #545454; - font-size: 12px; - text-align: center; - line-height: 30px; - cursor: pointer; -} - -.message .content { - padding: 0 30px 0 10px; - line-height: 30px; -} .confirmbox { position: absolute; diff --git a/ui/images/theme-default/Makefile.am b/ui/images/theme-default/Makefile.am index 85fdf5f..7deb55f 100644 --- a/ui/images/theme-default/Makefile.am +++ b/ui/images/theme-default/Makefile.am @@ -19,4 +19,4 @@ imagedir = $(datadir)/wok/ui/images/theme-default -dist_image_DATA = *.png *.gif +dist_image_DATA = *.png *.gif *.svg diff --git a/ui/images/theme-default/logo-flat.svg b/ui/images/theme-default/logo-flat.svg new file mode 100644 index 0000000..dda5822 --- /dev/null +++ b/ui/images/theme-default/logo-flat.svg @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> + <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="387" height="366" id="svg2"> + <title id="title4148">Project Kimchi</title> + <metadata id="metadata20"> + <rdf:RDF> + <cc:Work rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title>Project Kimchi</dc:title> + <cc:license rdf:resource="http://www.apache.org/licenses/LICENSE-2.0" /> + <dc:date>2013 - 2015</dc:date> + <dc:creator> + <cc:Agent> + <dc:title>IBM, Corp.</dc:title> + </cc:Agent> + </dc:creator> + <dc:rights> + <cc:Agent> + <dc:title>IBM, Corp.</dc:title> + </cc:Agent> + </dc:rights> + <dc:publisher> + <cc:Agent> + <dc:title>IBM, Corp.</dc:title> + </cc:Agent> + </dc:publisher> + <dc:contributor> + <cc:Agent> + <dc:title>https://github.com/kimchi-project</dc:title> + </cc:Agent> + </dc:contributor> + <dc:description>An HTML5 management interface for KVM</dc:description> + </cc:Work> + </rdf:RDF> + </metadata> + <defs id="defs18" /> + <path fill="#D91F2F" d="M303.868,82.71c25.172-8.604,27.898-42.319,7.13-55.331c-1.923-1.04-16.93-10.998-43.506-11.999 c-39.783,1.486-71.632,13.167-92.662,62.139c-0.25,2.109-0.508,6.054,1.977,3.206c0,0,0.284-0.329,0.443-0.515 c15.153-23.034,69.707-29.756,88.572-8.681c0.625,0.72,1.297,1.634,2.003,2.274C276.457,82.654,293.688,86.191,303.868,82.71" id="path4" /> + <path fill="#F19125" d="M336.691,227.692c20.913,16.439,50.687,0.387,50.306-24.119c-0.174-2.18,0.018-20.188-13.601-43.033 c-22.892-32.571-50.019-52.939-102.551-43.944c-1.906,0.938-5.355,2.866-1.615,3.403c0,0,0.432,0.059,0.674,0.093 c27.571,0.183,62.889,42.3,55.469,69.596c-0.263,0.916-0.665,1.977-0.817,2.918C321.826,204.661,328.231,221.044,336.691,227.692" id="path6" /> + <path fill="#8CC643" d="M228.105,329.358c-4.421,26.23,23.926,44.686,45.259,32.619c1.831-1.197,17.731-9.65,31.27-32.543 c17.636-35.689,22.531-69.258-10.515-111.072c-1.737-1.225-5.082-3.33-3.762,0.211c0,0,0.152,0.406,0.24,0.637 c13.04,24.293-7.028,75.463-34.545,82.018c-0.932,0.207-2.055,0.361-2.955,0.68C241.207,305.282,229.893,318.749,228.105,329.358" id="path8" /> + <path fill="#27AEE4" d="M81.133,285.823c-25.04,8.973-27.272,42.725-6.314,55.43c1.939,1.01,17.088,10.746,43.677,11.357 c39.757-2.072,71.43-14.219,91.738-63.496c0.22-2.113,0.421-6.061-2.023-3.176c0,0-0.279,0.33-0.438,0.521 c-14.811,23.254-69.259,30.777-88.434,9.982c-0.637-0.711-1.321-1.615-2.038-2.246C108.544,285.476,91.262,282.192,81.133,285.823" id="path10" /> + <path fill="#06659E" d="M48.671,141.301c-21.969-14.995-50.596,3.023-48.569,27.447c0.321,2.165,1.34,20.143,16.463,42.022 c25.03,30.957,53.465,49.455,105.273,36.947c1.839-1.063,5.151-3.219,1.382-3.502c0,0-0.432-0.031-0.678-0.047 c-27.52,1.672-65.589-37.975-60.023-65.709c0.202-0.933,0.531-2.018,0.62-2.968C65.053,163.281,57.561,147.365,48.671,141.301" id="path12" /> + <path fill="#BA1E70" d="M164.882,38.837c6.497-25.793-20.29-46.448-42.516-36.122c-1.919,1.049-18.444,8.206-33.764,29.946 c-20.424,34.171-27.98,67.243,1.628,111.558c1.632,1.359,4.798,3.726,3.765,0.089c0,0-0.119-0.417-0.188-0.651 c-11.062-25.255,13.021-74.663,40.974-79.004c0.945-0.132,2.076-0.198,3-0.441C149.9,61.794,162.255,49.273,164.882,38.837" id="path14" /> + </svg> diff --git a/ui/images/theme-default/logo-white.png b/ui/images/theme-default/logo-white.png index 8ef8ae15aa40ceb7db5170c9806ac74b840eaa0f..f2630da0fd837573cd6ca69a46823260b899f9ac 100644 GIT binary patch literal 7583 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 BY-Rue literal 9879 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 JPDHLkV1gkP$2tH2 diff --git a/ui/js/src/wok.grid.js b/ui/js/src/wok.grid.js index 12f191c..0606bc6 100644 --- a/ui/js/src/wok.grid.js +++ b/ui/js/src/wok.grid.js @@ -18,106 +18,73 @@ * limitations under the License. */ wok.widget.Grid = function(opts) { + "use strict"; this.opts = $.extend({}, this.opts, opts); this.createDOM(); this.reload(); }; wok.widget.Grid.prototype = (function() { + "use strict"; var htmlStr = [ - '<div id="{id}" class="grid">', - '<div class="grid-content">', - '<div class="grid-header">', - '<div class="grid-frozen-header-view">', - '<table class="grid-frozen-header-container">', - '</table>', - '</div>', - '<div class="grid-header-view">', - '<div class="grid-header-wrapper">', - '<table class="grid-header-container">', - '</table>', - '</div>', - '</div>', - '</div>', - '<div class="grid-body">', - '<div class="grid-frozen-body-view">', - '<div class="grid-frozen-body-wrapper">', - '<table class="grid-frozen-body-container">', - '</table>', - '</div>', - '</div>', - '<div class="grid-body-view">', - '<div class="grid-body-wrapper">', - '<table class="grid-body-container">', - '</table>', - '</div>', - '</div>', + '<div id="{id}" class="grid wok-grid">', + '<div class="wok-grid-message hidden">', + '<div class="alert alert-danger fade in" role="alert">', + '<p><strong>{message}</strong> ', + '<span class="detailed-text"></span></p>', + '<p><button class="btn btn-primary btn-xs retry-button">', + '{buttonLabel}', + '</button></p>', '</div>', - '<div class="grid-resizer-leftmost hidden"></div>', - '<div class="grid-resizer hidden"></div>', '</div>', - '<div class="grid-footer"></div>', - '<div class="grid-mask hidden">', - '<div class="grid-loading">', - '<div class="grid-loading-icon"></div>', - '<div class="grid-loading-text">', - '{loading}', - '</div>', - '</div>', + '<div class="grid-content wok-grid-content">', + '<table class="wok-table table">', + '<thead class="wok-grid-header-container"></thead>', + '<tbody class="wok-grid-body-container">', + '</tbody>', + '</table>', '</div>', - '<div class="grid-message hidden">', - '<div class="grid-message-text">', - '{message}', - '<button class="retry-button btn-small">', - '{buttonLabel}', - '</button>', - '</div>', - '<div class="detailed-title">', - '{detailedLabel}', + '<div class="wok-grid-mask hidden">', + '<div class="wok-grid-loader-container">', + '<div class="wok-grid-loading">', + '<div class="wok-grid-loading-icon"></div>', + '<div class="wok-grid-loading-text">', + '{loading}', + '</div>', + '</div>', '</div>', - '<div class="detailed-text"></div>', '</div>', '</div>' ].join(''); - var CONTAINER_NORMAL = 0, CONTAINER_FROZEN = 1; - var setupHeaders = function(header, body, fields) { var colGroup = $('<colgroup></colgroup>').appendTo(header); - var headerHeader = $('<thead></thead>'); - var headerRow = $('<tr></tr>').appendTo(headerHeader); + var headerRow = $('<tr></tr>').appendTo(header); $.each(fields || [], function(i, field) { $('<col class="' + field['class'] + '"/>') .appendTo(colGroup); - $('<th><div class="cell-text-wrapper">' + + $('<th><div class="wok-text-header">' + field['label'] + '</div></th>').appendTo(headerRow); }); - headerHeader.appendTo(header); var totalWidth = 0; - $('col', colGroup).each(function(index, col) { - var width = $(col).width(); - totalWidth += width; - $(col).css('width', width + 'px'); - }); - $(body).append(colGroup.clone()); return totalWidth; }; var getValue = function(name, obj) { - var result=undefined; + var result; if(!Array.isArray(name)) { name=name.parseKey(); } - if(name.length!=0) { + if(name.length!==0) { var tmpName=name.shift(); - if(obj[tmpName]!=undefined) { + if(obj[tmpName]!==undefined) { result=obj[tmpName]; } - if(name.length!=0) { + if(name.length!==0) { result=getValue(name,obj[tmpName]); } } @@ -126,55 +93,18 @@ wok.widget.Grid.prototype = (function() { var fillBody = function(container, fields) { var data = this.data; - var tbody = ($('tbody', container).length && $('tbody', container)) - || $('<tbody></tbody>').appendTo(container); - tbody.empty(); $.each(data, function(i, row) { - var rowNode = $('<tr></tr>').appendTo(tbody); + var rowNode = $('<tr></tr>').appendTo(container); $.each(fields, function(fi, field) { var value = getValue(field['name'], row); - $('<td><div class="cell-text-wrapper"' + - (field['makeTitle'] === true - ? ' title="' + value + '"' - : '' - ) + '>' + value.toString() + '</div></td>' + $('<td><div class="wok-cell-text"' + (field['makeTitle'] === true ? ' title="' + value + '"' : '' ) + '>' + value.toString() + '</div></td>' ).appendTo(rowNode); }); }); }; - var fixTableLayout = function(style) { - $.each([ - this.frozenHeaderContainer, - this.headerContainer, - this.frozenBodyContainer, - this.bodyContainer - ], function(i, tableNode) { - $(tableNode).css('table-layout', style || 'fixed'); - }); - }; - - var initResizing = function(event) { - var resizer = event.data.resizer; - var pageX = event.pageX; - var tailPos = $(this).width() + $(this).offset()['left']; - var atResizer = Math.abs(pageX - tailPos) <= 2; - var isResizing = !$(resizer).hasClass('hidden'); - $('body')[(atResizer || isResizing) - ? 'addClass' - : 'removeClass' - ]('resizing'); - }; - - var clearResizing = function(event) { - $(event.data.resizer).hasClass('hidden') && - $('body').removeClass('resizing'); - }; - var stylingRow = function(row, className, add) { var index = $(row).index() + 1; - $('tr', this.frozenBodyContainer) - .removeClass(className); $('tr', this.bodyContainer) .removeClass(className); @@ -182,19 +112,18 @@ wok.widget.Grid.prototype = (function() { return; } - $('tr:nth-child(' + index + ')', this.frozenBodyContainer) - .addClass(className); $('tr:nth-child(' + index + ')', this.bodyContainer) .addClass(className); }; var setBodyListeners = function() { - if(this['opts']['rowSelection'] != 'disabled') { + if(this['opts']['rowSelection'] !== 'disabled') { $('tr', this.gridBody).on('mouseover', { grid: this }, function(event) { - if (! $(this).hasClass('no-hover')) + if (! $(this).hasClass('no-hover')) { stylingRow.call(event.data.grid, this, 'hover'); + } }); $('tr', this.gridBody).on('mouseout', { @@ -213,128 +142,16 @@ wok.widget.Grid.prototype = (function() { }); } - $('.grid-body-view', this.domNode).on('scroll', { - grid: this - }, function(event) { - var grid = event.data.grid; - $('.grid-header .grid-header-view', grid.domNode) - .prop('scrollLeft', this.scrollLeft); - $('.grid-body .grid-frozen-body-view', grid.domNode) - .prop('scrollTop', this.scrollTop); - }); }; var setData = function(data) { this.data = data; - fillBody.call(this, this.frozenBodyContainer, this['opts']['frozenFields']); fillBody.call(this, this.bodyContainer, this['opts']['fields']); setBodyListeners.call(this); }; var getSelected = function() { - return this.selectedIndex >= 0 - ? this.data[this.selectedIndex] - : null; - }; - - var startResizing = function(container, event) { - var grid = event.data.grid; - wok.widget.Grid.beingResized = grid; - if(!($('body').hasClass('resizing') - && $(grid.resizer).hasClass('hidden'))) { - return; - } - - grid.columnBeingResized = container; - var pageX = event.pageX; - var gridOffsetX = grid.domNode.offset()['left']; - var leftmostOffsetX = $(container).offset()['left'] - gridOffsetX; - var left = pageX - gridOffsetX; - var contentHeight = $('.grid-content', grid.domNode).height(); - $(grid.resizerLeftmost).css({ - left: leftmostOffsetX + 'px', - height: contentHeight + 'px' - }); - $(grid.resizer).css({ - left: left + 'px', - height: contentHeight + 'px' - }); - $(grid.resizerLeftmost).removeClass('hidden'); - $(grid.resizer).removeClass('hidden'); - event.preventDefault(); - }; - - var endResizing = function(event) { - var grid = wok.widget.Grid.beingResized; - if(!$('body').hasClass('resizing')) { - return; - } - $(grid.resizerLeftmost).addClass('hidden'); - $(grid.resizer).addClass('hidden'); - $('body').removeClass('resizing'); - var leftmostOffset = $(grid.columnBeingResized).offset()['left']; - var left = event.pageX; - if(leftmostOffset > left) { - return; - } - resizeColumnWidth.call( - grid, - $(grid.columnBeingResized).index(), - left - leftmostOffset - ); - fixTableLayout.call(grid); - grid.columnBeingResized = null; - wok.widget.Grid.beingResized = null; - }; - - var resizeColumnWidth = function(index, width) { - var width = Math.ceil(width); - var widthArray = []; - var totalWidth = 0; - var header = this.headerContainer; - var body = this.bodyContainer; - if(this.containerBeingResized === CONTAINER_FROZEN) { - header = this.frozenHeaderContainer; - body = this.frozenBodyContainer; - } - $('col', header).each(function(i, colNode) { - var w = index === i ? width : $(colNode).width(); - widthArray.push(w); - totalWidth += w; - }); - $.each([header, body], function(i, container) { - container.css({ - 'table-layout': 'fixed', - width: totalWidth + 'px' - }); - $('col:nth-child(' + (index + 1) + ')', container).css({ - width: width + 'px' - }); - }); - - if(this.containerBeingResized === CONTAINER_FROZEN) { - var headerView = $('.grid-header-view', this.domNode); - var bodyView = $('.grid-body-view', this.domNode); - $.each([headerView, bodyView], function(i, view) { - view.css({ - left: totalWidth + 'px' - }); - }); - } - }; - - var positionResizer = function(event) { - var grid = event.data.grid; - if($(grid.resizer).hasClass('hidden')) { - return; - } - - var pageX = event.pageX; - var gridOffsetX = $(grid.domNode).offset()['left']; - var leftMost = $(grid.resizerLeftmost).position()['left']; - var offsetX = pageX - gridOffsetX; - offsetX = offsetX >= leftMost ? offsetX : leftMost; - $(grid.resizer).css('left', offsetX + 'px'); + return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null; }; var showMessage = function(msg) { @@ -368,11 +185,6 @@ wok.widget.Grid.prototype = (function() { } }; - var destroy = function() { - $('body').off('mousemove.grid#' + this['opts']['id'], positionResizer); - $('body').off('mouseup.grid#' + this['opts']['id'], endResizing); - }; - var createDOM = function() { var containerID = this['opts']['container']; var container = $('#' + containerID); @@ -387,118 +199,91 @@ wok.widget.Grid.prototype = (function() { })).appendTo(container); this.domNode = domNode; + var theTable = $('.wok-table', domNode); + var theContainer = $('.wok-grid-content', domNode); + var headerContainer = $('.wok-grid-header-container', domNode); + var bodyContainer = $('.wok-grid-body-container', domNode); + setupHeaders(headerContainer, bodyContainer, this['opts']['fields']); + this.theTable = theTable; + this.theContainer = theContainer; + this.headerContainer = headerContainer; + this.bodyContainer = bodyContainer; + var height = domNode.height(); var width = domNode.width(); var title = this['opts']['title']; var titleNode = null; if(title) { - titleNode = $('<div class="grid-caption">' + title + '</div>') - .prependTo(domNode); + titleNode = $('<caption class="sr-only">' + title + '</caption>').prependTo(theTable); } var toolbarButtons = this['opts']['toolbarButtons']; var toolbarNode = null; + var btnHTML, dropHTML = []; if(toolbarButtons) { - toolbarNode = $('<div class="grid-toolbar"></div>'); - if(titleNode) { - titleNode.after(toolbarNode); - } - else { - toolbarNode.prependTo(domNode); + toolbarNode = $('<div class="btn-group"></div>'); + toolbarNode.prependTo(theContainer); + if(toolbarButtons.length > 1) { + dropHTML = ['<div class="dropdown menu-flat">', + '<button id="wok-dropdown-button-', containerID, '" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">', + '<span class="edit-alt"></span>Actions<span class="caret"></span>', + '</button>', + '<ul class="dropdown-menu"></ul>', + '</div>' + ].join(''); + $(dropHTML).appendTo(toolbarNode); + $.each(toolbarButtons, function(i, button) { + btnHTML = [ + '<li role="presentation"', button.critical === true ? ' class="critical"' : '', '><a data-toggle="modal"', + button.id ? (' id="' + button.id + '"') : '', + ' class="', button.disabled === true ? ' disabled' : '', '">', + button.class ? ('<i class="' + button.class) + '"></i>' : '', + button.label, + '</a></li>' + ].join(''); + var btnNode = $(btnHTML).appendTo(toolbarNode[0].children[0].children[1]); + button.onClick && btnNode.on('click', button.onClick); + }); + }else { + $.each(toolbarButtons, function(i, button) { + btnHTML = [ + '<button data-dismiss="modal" ', + button['id'] ? (' id="' + button['id'] + '"') : '', + ' class="btn btn-primary', + button['class'] ? (' ' + button['class']) : '', + '"', + button['disabled'] === true ? ' disabled' : '', + '>', + button['label'], + '</button>' + ].join(''); + var btnNode = $(btnHTML).appendTo(toolbarNode); + button['onClick'] && + btnNode.on('click', button['onClick']); + }); } - $.each(toolbarButtons, function(i, button) { - var btnHTML = [ - '<button', - button['id'] ? (' id="' + button['id'] + '"') : '', - ' class="grid-toolbar-button', - button['class'] ? (' ' + button['class']) : '', - '"', - button['disabled'] === true ? ' disabled' : '', - '>', - button['label'], - '</button>' - ].join(''); - var btnNode = $(btnHTML).appendTo(toolbarNode); - button['onClick'] && - btnNode.on('click', button['onClick']); - }); } - var frozenHeaderContainer = $('.grid-frozen-header-container', domNode); - var frozenBodyContainer = $('.grid-frozen-body-container', domNode); - var frozenWidth = setupHeaders( - frozenHeaderContainer, - frozenBodyContainer, - this['opts']['frozenFields'] - ); - this.frozenHeaderContainer = frozenHeaderContainer; - this.frozenBodyContainer = frozenBodyContainer; - - var headerContainer = $('.grid-header-container', domNode); - var bodyContainer = $('.grid-body-container', domNode); - setupHeaders(headerContainer, bodyContainer, this['opts']['fields']); - this.headerContainer = headerContainer; - this.bodyContainer = bodyContainer; - - fixTableLayout.call(this, 'auto'); + // var domHeight = domNode && $(domNode).height() || 0; + // var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0; + // var maskHeight = domHeight - toolbarHeight; - var gridContentNode = $('.grid-content', domNode); - var captionHeight = titleNode && $(titleNode).height() || 0; - var toolbarHeight = toolbarNode && $(toolbarNode).height() || 0; - gridContentNode.css('top', (captionHeight + toolbarHeight) + 'px'); + // var maskContainer = $('.wok-grid-loader-container',domNode); + // maskContainer.css({'top': toolbarHeight+'px', 'height': maskHeight+'px'}); + // this.maskContainer = maskContainer; - var maskNode = $('.grid-mask', domNode); - maskNode.css('top', captionHeight + 'px'); + var maskNode = $('.wok-grid-mask', domNode); this.maskNode = maskNode; - var messageNode = $('.grid-message', domNode); - messageNode.css('top', captionHeight + 'px'); + var messageNode = $('.wok-grid-message', domNode); this.messageNode = messageNode; - var headerView = $('.grid-header-view', domNode); - var bodyView = $('.grid-body-view', domNode); - headerView.css('left', (frozenWidth) + 'px'); - bodyView.css('left', (frozenWidth) + 'px'); + //fixTableLayout.call(this); - var bodyWidth = width - frozenWidth; - headerContainer.css('width', bodyWidth + 'px'); - bodyContainer.css('width', bodyWidth + 'px'); - - fixTableLayout.call(this); - - var gridBody = $('.grid-body', domNode); + var gridBody = $('.wok-grid-body', domNode); this.gridBody = gridBody; - this.resizerLeftmost = $('.grid-resizer-leftmost', domNode); - this.resizer = $('.grid-resizer', domNode); - var gridHeader = $('.grid-header', domNode); - $('th', gridHeader).on('mouseover mousemove', { - resizer: this.resizer - }, initResizing); - - $('th', gridHeader).on('mouseout', { - resizer: this.resizer - }, clearResizing); - - this.containerBeingResized = CONTAINER_NORMAL; - $('th', frozenHeaderContainer).on('mousedown', { - grid: this - }, function(event) { - event.data.grid.containerBeingResized = CONTAINER_FROZEN; - startResizing(this, event); - }); - $('th', headerContainer).on('mousedown', { - grid: this - }, function(event) { - event.data.grid.containerBeingResized = CONTAINER_NORMAL; - startResizing(this, event); - }); - - $('body').on('mousemove.grid#' + this['opts']['id'], { - grid: this - }, positionResizer); - $('body').on('mouseup.grid#' + this['opts']['id'], endResizing); var data = this['opts']['data']; @@ -517,14 +302,13 @@ wok.widget.Grid.prototype = (function() { onRowSelected: null, title: null, toolbarButtons: null, - frozenFields: null, fields: null }, createDOM: createDOM, setData: setData, getSelected: getSelected, reload: reload, - destroy: destroy, + //destroy: destroy, showMessage: showMessage }; -})(); +})(); \ No newline at end of file diff --git a/ui/js/src/wok.line-chart.js b/ui/js/src/wok.line-chart.js index 3c740e6..3eb3494 100644 --- a/ui/js/src/wok.line-chart.js +++ b/ui/js/src/wok.line-chart.js @@ -18,13 +18,15 @@ * limitations under the License. */ -/** +/* * new wok.widget.LineChart({ * node: 'line-chart-cpu', * id: 'line-chart', * type: 'value' * }); */ + + wok.widget.LineChart = function(params) { var container = $('#' + params['node']); container.addClass('chart-container'); @@ -82,6 +84,14 @@ wok.widget.LineChart = function(params) { } }); } + + var defs = [ + '<defs>', + '<pattern id="patternbg" x="0" y="0" width="6" height="6" patternUnits="userSpaceOnUse">', + '<rect x="0" y="0" width="3" height="6" style="stroke:none; fill: #eeeeee;"></rect>', + '</pattern>', + '</defs>' + ].join(''); var canvasNode = $('#' + canvasID); canvasNode.length && canvasNode.remove(); @@ -89,25 +99,10 @@ wok.widget.LineChart = function(params) { '<svg id="', canvasID, '" class="line-chart"', ' height="', height, '" width="', width, '"', '>', + defs, '<rect height="', height, '" width="', width, '" class="background" />' ]; - for(var x = linesOffset; x < width; x += linesSpace) { - htmlStr.push( - '<line x1="', x, '" y1="', 0, '" x2="', x, '" y2="', height, '" />' - ); - } - - linesOffset -= xFactor; - while(linesOffset < 0) { - linesOffset = linesSpace + linesOffset; - } - - for(var y = height - linesSpace; y > 0; y -= linesSpace) { - htmlStr.push( - '<line x1="', 0, '" y1="', y, '" x2="', width, '" y2="', y, '" />' - ); - } var maxValueLabel = i18n['KCHHOST6001M'] + ' ' + (type === 'value' @@ -124,12 +119,34 @@ wok.widget.LineChart = function(params) { chartVAxis.text(maxValueLabel); } + seriesNames = []; $.each(data, function(i, series) { var points = series['points']; var className = series['class']; var latestPoint = points.slice(-1).pop(); xStart = latestPoint['x'] - period; + htmlStr.push('<path', + ' class="series', className ? ' ' + className : '', '"', + ' d="M 0,92 ' + ); + var first = true; + $.each(points, function(i, point) { + if(first) { + first = false; + } + else { + htmlStr.push(' '); + } + + var x = xFactor * (point['x'] - xStart); + var y = height - yFactor * (type === 'value' ? + point['y'] * 100 / maxValue : + point['y'] + ); + htmlStr.push(x, ',', y); + }); + htmlStr.push(' 310,92z" />'); htmlStr.push('<polyline', ' class="series', className ? ' ' + className : '', '"', @@ -152,6 +169,7 @@ wok.widget.LineChart = function(params) { htmlStr.push(x, ',', y); }); htmlStr.push('" />'); + }); htmlStr.push('</svg>'); @@ -160,7 +178,7 @@ wok.widget.LineChart = function(params) { if(!chartLegend) { chartLegend = $('<div class="chart-legend-container"></div>'); - container.after(chartLegend); + container.before(chartLegend); } else { chartLegend.empty(); @@ -169,18 +187,15 @@ wok.widget.LineChart = function(params) { var wrapper = $('<div class="legend-wrapper"></div>') .appendTo(chartLegend); $([ - '<svg class="legend-icon" width="20" height="10">', - '<line x1="0" y1="5" x2="20" y2="5"/>', + '<svg class="legend-icon" width="5" height="40">', + '<rect width="5" height="40" />', '</svg>' ].join('')).appendTo(wrapper); - $('line', wrapper).css({ - stroke: $(polyline).css('stroke'), - 'stroke-width': $(polyline).css('stroke-width') + $('rect', wrapper).css({ + fill: $(polyline).css('stroke') }); var label = data[i]['legend']; var base = data[i]['base']; - $('<label class="legend-label">' + label + '</label>') - .appendTo(wrapper); var latestPoint = data[i]['points'].slice(-1).pop(); var latestValue = latestPoint['y']; if(type === 'value') { @@ -189,11 +204,12 @@ wok.widget.LineChart = function(params) { formatSettings ); } - else { - latestValue += '%'; + else { + latestValue = { v: latestValue, s: '%' }; } - $('<div class="latest-value">' + latestValue + '</div>') - .appendTo(wrapper); + $('<div class="latest-value"><span class="number">' + latestValue.v + '</span></div>').appendTo(wrapper); + $('<span class="legend-label">'+ latestValue.s +'</span><span class="legend-string">'+ label + '</span>').appendTo(wrapper[0].children[1]); + }); }; diff --git a/ui/js/src/wok.list.js b/ui/js/src/wok.list.js new file mode 100644 index 0000000..bee9254 --- /dev/null +++ b/ui/js/src/wok.list.js @@ -0,0 +1,281 @@ +/* + * Project Wok + * + * Copyright IBM, Corp. 2013-2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +wok.widget.List = function(opts) { + "use strict"; + this.opts = $.extend({}, this.opts, opts); + this.createDOM(); + this.reload(); +}; + +wok.widget.List.prototype = (function() { + "use strict"; + var htmlStr = [ + '<div id="{id}-section" class="panel panel-default">', + '<div class="panel-heading">', + '</div>', + '<div id="content-{id}" class="panel-body">', + '<div id="{id}-container">', + '<div class="wok-list-message clearfix hidden">', + '<div class="alert alert-danger fade in" role="alert">', + '<p><strong>{message}</strong> ', + '<span class="detailed-text"></span></p>', + '<p><button class="btn btn-primary btn-xs retry-button">', + '{buttonLabel}', + '</button></p>', + '</div>', + '</div>', + '<div id="{id}" class="row clearfix">', + '<div class="wok-list-content">', + '<table class="wok-list-table table table-striped" id="list">', + '</table>', + '</div>', + '</div>', + '<div class="wok-list-mask hidden">', + '<div class="wok-list-loader-container">', + '<div class="wok-list-loading">', + '<div class="wok-list-loading-icon"></div>', + '<div class="wok-list-loading-text">', + '{loading}', + '</div>', + '</div>', + '</div>', + '</div>', + '</div>', + '</div>', + '</div>' + ].join(''); + + var getValue = function(name, obj) { + var result; + if (!Array.isArray(name)) { + name = name.parseKey(); + } + if (name.length !== 0) { + var tmpName = name.shift(); + if (obj[tmpName] !== undefined) { + result = obj[tmpName]; + } + if (name.length !== 0) { + result = getValue(name, obj[tmpName]); + } + } + return (result); + }; + + var fillBody = function(container, fields) { + + var toolbarButtons = this.opts.toolbarButtons; + var actionDropdownHtml; + var data = this.data; + var tbody = ($('tbody', container).length && $('tbody', container)) || $('<tbody></tbody>').appendTo(container); + tbody.empty(); + $.each(data, function(i, row) { + var rowNode = $('<tr></tr>').appendTo(tbody); + var columnNodeHTML; + var columnData = ''; + var state = ''; + var styleClass = ''; + if (toolbarButtons) { + actionDropdownHtml = [ + '<td>', + '<div class="dropdown menu-flat">', + '<button id="wok-dropdown-button-', i, '" class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">', + '<span class="edit-alt"></span>Actions<span class="caret"></span>', + '</button>', + '<ul class="dropdown-menu" role="menu" aria-labelledby="action-dropdown-menu-', i, '">', + '</ul>', + '</div>', + '</td>' + ].join(''); + } + $.each(fields, function(fi, field) { + var value = getValue(field.name, row); + if (field.type === 'status' && field.name === 'enabled') { + styleClass = (value === true ? '' : ' disabled'); + state = [ + '<span class="wok-repository-status ', + value === true ? 'enabled' : 'disabled', + '"><i class="fa fa-power-off"></i></span>' + ].join(''); + } + columnData += (field.type === 'name') ? ('<span class="wok-list-name">' + value.toString() + '</span>') : (field.type !== 'status' ? '<span class="wok-list-description">' + value.toString() + '</span>' : ''); + + }); + columnNodeHTML = [ + '<td>', + '<div class="wok-list-cell', styleClass, '">', state, + columnData, + '</div>', + '</td>' + ].join(''); + $(columnNodeHTML).appendTo(rowNode); + + var actionMenuNode = $(actionDropdownHtml).appendTo(rowNode); + + $.each(toolbarButtons, function(i, button) { + var btnHTML = [ + '<li role="presentation"', button.critical === true ? ' class="critical"' : '', '>', + '<a role="menuitem" tabindex="-1" data-dismiss="modal"', (button.id ? (' id="' + button.id + '"') : ''), (button.disabled === true ? ' class="disabled"' : ''), + '>', + button.class ? ('<i class="' + button.class) + '"></i>' : '', + button.label, + '</a></li>' + ].join(''); + + var btnNode = $(btnHTML).appendTo($('.dropdown-menu', rowNode)); + button.onClick && btnNode.on('click', button.onClick); + + }); + + + }); + }; + + var stylingRow = function(row, className, add) { + console.log('stylingRow'); + var index = $(row).index() + 1; + $('tr', this.bodyContainer) + .removeClass(className); + if (add === false) { + return; + } + $('tr:nth-child(' + index + ')', this.bodyContainer) + .addClass(className); + }; + + var setBodyListeners = function() { + if (this['opts']['rowSelection'] != 'disabled') { + + $('tr', this.bodyContainer).on('click', { + grid: this + }, function(event) { + var grid = event.data.grid; + if ($(this).hasClass('selected')) { + console.log(this); + } + grid.selectedIndex = $(this).index(); + stylingRow.call(grid, this, 'selected'); + grid['opts']['onRowSelected'] && grid['opts']['onRowSelected'](); + }); + } + }; + + var setData = function(data) { + this.data = data; + fillBody.call(this, this.bodyContainer, this.opts.fields); + setBodyListeners.call(this); + }; + + var getSelected = function() { + return this.selectedIndex >= 0 ? this.data[this.selectedIndex] : null; + }; + + var showMessage = function(msg) { + $('.detailed-text', this.messageNode).text(msg); + $(this.messageNode).removeClass('hidden'); + }; + + var hideMessage = function() { + $(this.messageNode).addClass('hidden'); + }; + + var reload = function() { + var data = this.opts.data; + if (!data) { + return; + } + + if ($.isArray(data)) { + return this.setData(data); + } + + if ($.isFunction(data)) { + var loadData = data; + $(this.maskNode).removeClass('hidden'); + loadData($.proxy(function(data) { + this.setData(data); + $(this.maskNode).addClass('hidden'); + }, this)); + } + }; + + var createDOM = function() { + var containerID = this.opts.container; + var container = $('#' + containerID); + var gridID = this.opts.id; + var data = this.opts.data; + var rowSelection = this.opts.rowSelection || 'single'; + var domNode = $(wok.substitute(htmlStr, { + id: gridID, + loading: i18n.KCHGRD6001M, + message: i18n.KCHGRD6002M, + buttonLabel: i18n.KCHGRD6003M, + detailedLabel: i18n.KCHGRD6004 + })).appendTo(container); + this.domNode = domNode; + + + var titleContainer = $('.panel-heading', domNode); + this.titleContainer = titleContainer; + + var title = this.opts.title; + var titleNode = null; + + if (title) { + titleNode = $('<h3 class="panel-title">' + title + '</h3>').appendTo(titleContainer); + } + + var bodyContainer = $('.wok-list-table.table.table-striped', domNode); + this.bodyContainer = bodyContainer; + + var gridBody = $('.wok-list-content', domNode); + this.gridBody = gridBody; + + var maskNode = $('.wok-list-mask', domNode); + this.maskNode = maskNode; + + var messageNode = $('.wok-list-message', domNode); + this.messageNode = messageNode; + + $('.retry-button', domNode).on('click', { + grid: this + }, function(event) { + event.data.grid.reload(); + }); + + + }; + + return { + opts: { + container: null, + id: null, + rowSelection: 'single', + onRowSelected: null, + title: null, + toolbarButtons: null, + frozenFields: null, + fields: null + }, + createDOM: createDOM, + setData: setData, + getSelected: getSelected, + reload: reload, + showMessage: showMessage + }; +})(); diff --git a/ui/js/src/wok.login.js b/ui/js/src/wok.login.js index d9ccae6..13a1da0 100644 --- a/ui/js/src/wok.login.js +++ b/ui/js/src/wok.login.js @@ -18,9 +18,12 @@ * limitations under the License. */ wok.login_main = function() { - + "use strict"; var selectedLanguage = wok.lang.get(); $('#userLang').val(selectedLanguage); + $('#userLang option[value="'+selectedLanguage+'"]').attr("selected", "selected"); + $('#userLang').next().find('.selectpicker').attr('title',$('#userLang option[value="'+selectedLanguage+'"]').text()); + $('#userLang').next().children().find('.filter-option').text($('#userLang option[value="'+selectedLanguage+'"]').text()); $('#userLang').on('change', function() { wok.lang.set($(this).val()); @@ -29,7 +32,7 @@ wok.login_main = function() { var query = window.location.search; var error = /.*error=(.*?)(&|$)/g.exec(query); - if (error && error[1] == "sessionTimeout") { + if (error && error[1] === "sessionTimeout") { $("#messSession").show(); } @@ -59,7 +62,7 @@ wok.login_main = function() { var next_url = lastPage ? lastPage.replace(/\"/g,'') : "/"; } wok.cookie.set('roles',JSON.stringify(data.roles)); - window.location.replace(window.location.pathname.replace(/\/+login.html/, '') + next_url) + window.location.replace(window.location.pathname.replace(/\/+login.html/, '') + next_url); }, function() { $("#messUserPass").show(); $("#messSession").hide(); diff --git a/ui/js/src/wok.main.js b/ui/js/src/wok.main.js index 25fed31..af8695b 100644 --- a/ui/js/src/wok.main.js +++ b/ui/js/src/wok.main.js @@ -27,6 +27,7 @@ wok.main = function() { var tabsHtml = []; $(tabs).each(function(i, tab) { var title = tab['title']; + var cssClass = tab['css']; var path = tab['path']; var mode = tab['mode']; if (mode != 'none') { @@ -34,10 +35,10 @@ wok.main = function() { var disableHelp = (helpPath.length == 0 ? "disableHelp" : helpPath); tabsHtml.push( '<li>', - '<a class="item ', disableHelp,'" href="', path, '">', + '<a class="item ', disableHelp,' ',cssClass,'" href="', path, '">', title, '</a>', - '<input id="helpPathId" name="helpPath" value="' + helpPath + '" type="hidden"/>', + '<input id="helpPathId" name="helpPath" class="sr-only" value="' + helpPath + '" type="hidden"/>', '</li>' ); } @@ -51,6 +52,7 @@ wok.main = function() { var $tab = $(this); var titleKey = $tab.find('title').text(); var title = i18n[titleKey] ? i18n[titleKey] : titleKey; + var css = $tab.find('class').text(); var path = $tab.find('path').text(); var roles = wok.cookie.get('roles'); if (roles) { @@ -60,6 +62,7 @@ wok.main = function() { tabs.push({ title: title, path: path, + css: css, mode: mode }); } else { @@ -113,7 +116,8 @@ wok.main = function() { DEFAULT_HASH = defaultTabPath && defaultTabPath.substring(0, defaultTabPath.lastIndexOf('.')) } - $('#nav-menu').append(genTabs(tabs)); + $('#nav-menu ul.navbar-nav li.hostname').after(genTabs(tabs)); + wok.getHostname(); callback && callback(); }, function(data) { @@ -142,7 +146,7 @@ wok.main = function() { * point to the tab. If nothing found, inform user the URL is invalid * and clear location.hash to jump to home page. */ - var tab = $('#nav-menu a[href="' + url + '"]'); + var tab = $('#nav-menu ul li a[href="' + url + '"]'); if (tab.length === 0 && url!='wok-empty.html') { location.hash = ''; return; @@ -150,20 +154,14 @@ wok.main = function() { //Remove the tab arrow indicator for no plugin if(url=='wok-empty.html'){ - $('.menu-arrow').hide(); $('#main').html('No plugins installed currently.You can download the available plugins <a href="https://github.com/kimchi-project/kimchi">Kimchi</a> and <a href="https://github.com/kimchi-project/ginger">Ginger</a> from Github').addClass('noPluginMessage'); }else{ - // Animate arrow indicator. - var left = $(tab).parent().position().left; - var width = $(tab).parent().width(); - $('.menu-arrow').stop().animate({ - left : left + width / 2 - 10 - }); - + // Update the visual style of tabs; focus the selected one. - $('#nav-menu a').removeClass('current'); - $(tab).addClass('current'); + $('#nav-menu ul li').removeClass('active'); + $(tab).parent().addClass('active'); $(tab).focus(); + // Disable Help button according to selected tab if ($(tab).hasClass("disableHelp")) { $('#btn-help').css('cursor', "not-allowed"); @@ -240,7 +238,7 @@ wok.main = function() { * Register click listener of tabs. Replace the default reloading page * behavior of <a> with Ajax loading. */ - $('#nav-menu').on('click', 'a.item', function(event) { + $('#nav-menu ul li').on('click', 'a.item', function(event) { var href = $(this).attr('href'); // Remove file extension from 'href' location.hash = href.substring(0,href.lastIndexOf('.')) @@ -279,7 +277,7 @@ wok.main = function() { $('#peers').on('click', function() { // Check if any request is in progress - if ($('.popover', '#peers').is(':visible') || searchingPeers == true) + if ($('.dropdown', '#peers').is('.open') || searchingPeers == true) return $('#search-peers').show(); @@ -294,7 +292,7 @@ wok.main = function() { $('#no-peers').removeClass('hide-content'); for(var i=0; i<data.length; i++){ - $('.dropdown', '#peers').append("<a href='"+data[i]+"' target='_blank'>"+data[i]+"</a>"); + $('.dropdown-menu ', '#peers').append("<li><a href='"+data[i]+"' target='_blank'>"+data[i]+"</a></li>"); } searchingPeers = false; }); @@ -361,6 +359,11 @@ wok.checkHelpFile = function(path) { return url; }; +wok.getHostname = function(e) { + host = window.location.hostname; + $('span.host-location').text(host); + return host; +} wok.openHelp = function(e) { var tab = $('#nav-menu a.current'); diff --git a/ui/js/src/wok.message.js b/ui/js/src/wok.message.js index bd650e0..7af6468 100644 --- a/ui/js/src/wok.message.js +++ b/ui/js/src/wok.message.js @@ -18,31 +18,32 @@ * limitations under the License. */ wok.message = function(msg, level, node) { - var container = node || $('#messageField'); + "use strict"; + var container = node || $('#alert-fields'); if ($(container).size() < 1) { - container = $('<div id="messageField"/>').appendTo(document.body); + container = $('<div id="alert-fields"/>').appendTo($('#alert-container')); } - var message = '<div class="message ' + (level || '') + '" style="display: none;">'; + var message = '<div role="alert" class="alert ' + (level || '') + ' alert-dismissible fade in" style="display: none;">'; if(!node) { - message += '<div class="close">X</div>'; + message += '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true"><i class="fa fa-times-circle"></i></span></button>'; } - message += '<div class="content">' + msg + '</div>'; + message += msg; message += '</div>'; var $message = $(message); $(container).append($message); + $message.alert(); $message.fadeIn(100); setTimeout(function() { $message.fadeOut(2000, function() { + $message.alert('close'); $(this).remove(); + $(container).remove(); + if ($(container).children().length < 1) { + $(container).remove(); + } }); }, 4000); - - $(container).on("click", ".close", function(e) { - $(this).parent().fadeOut(200, function() { - $(this).remove(); - }); - }); }; /** @@ -64,6 +65,7 @@ wok.message = function(msg, level, node) { * The callback function of click the cancel and X button. */ wok.confirm = function(settings, confirmCallback, cancelCallback) { + "use strict"; if ($('#confirmbox-container ').size() < 1) { $(document.body).append('<div id="confirmbox-container" class="bgmask"></div>'); } @@ -104,15 +106,19 @@ wok.confirm = function(settings, confirmCallback, cancelCallback) { }; wok.message.warn = function(msg, node) { - wok.message(msg, 'warn', node); + "use strict"; + wok.message(msg, 'alert-warning', node); }; wok.message.error = function(msg, node) { - wok.message(msg, 'error', node); + "use strict"; + wok.message(msg, 'alert-danger', node); }; wok.message.error.code = function(code) { - msg = code + ": " + i18n[code] - wok.message(msg, 'error'); + "use strict"; + msg = code + ": " + i18n[code]; + wok.message(msg, 'alert-danger'); }; wok.message.success = function(msg, node) { - wok.message(msg, 'success', node); + "use strict"; + wok.message(msg, 'alert-success', node); }; diff --git a/ui/js/src/wok.window.js b/ui/js/src/wok.window.js index ef00a77..2c2a440 100644 --- a/ui/js/src/wok.window.js +++ b/ui/js/src/wok.window.js @@ -17,11 +17,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -wok.window = (function() { + wok.window = (function() { + "use strict"; var _windows = []; var _listeners = {}; var open = function(settings) { - var settings = jQuery.type(settings) === 'object' ? settings : { + settings = jQuery.type(settings) === 'object' ? settings : { url: settings }; @@ -33,14 +34,15 @@ wok.window = (function() { _windows.push(windowID); _listeners[windowID] = settings['close']; - var windowNode = $('<div></div>', { - id: windowID, - 'class': settings['class'] ? settings['class'] + ' bgmask remove-when-logged-off' : 'bgmask remove-when-logged-off' - }); + var windowNode = $('<div id="'+windowID+'" class="modal-dialog"></div>'); + + $('#modalWindow').modal('show'); - $(windowNode).css(settings['style'] || ''); + $('#modalWindow').on('hidden.bs.modal', function () { + wok.window.close(); + }); - $(windowNode).appendTo('body').on('click', '.window .close', function() { + $(windowNode).appendTo('#modalWindow').on('click', '.window .close', function() { wok.window.close(); }); @@ -53,20 +55,18 @@ wok.window = (function() { }; var close = function() { - var windowID = _windows.pop(); - if(_listeners[windowID]) { - _listeners[windowID](); - _listeners[windowID] = null; - } - delete _listeners[windowID]; - - $('#' + windowID).fadeOut(100, function() { - $(this).remove(); - }); + $('#modalWindow').removeData('bs.modal'); + var windowID = _windows.pop(); + if(_listeners[windowID]) { + _listeners[windowID](); + _listeners[windowID] = null; + } + delete _listeners[windowID]; + $('#' + windowID).remove(); }; return { open: open, close: close }; -})(); +})(); \ No newline at end of file diff --git a/ui/pages/login.html.tmpl b/ui/pages/login.html.tmpl index 2703d02..ee9d107 100644 --- a/ui/pages/login.html.tmpl +++ b/ui/pages/login.html.tmpl @@ -28,95 +28,109 @@ <!DOCTYPE html> <html lang="$lang.lang[0]"> <head> -<meta charset="UTF-8"> -<title>Kimchi</title> -<meta http-equiv="X-UA-Compatible" content="IE=edge"/> -<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> -<meta name="apple-mobile-web-app-capable" content="yes"> -<meta name="apple-mobile-web-app-title" content="Wok"> -<link href="images/apple-touch-icon-152.png" sizes="152x152" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-144.png" sizes="144x144" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-180x180.png" sizes="120x120" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-114x114.png" sizes="114x114" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-57x57.png" sizes="57x57" rel="apple-touch-icon-precomposed"> -<link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192"> -<!--[if IE lte 9]><link rel="shortcut icon" href="images/favicon.ico"><![endif]--> -<link rel="shortcut icon" href="images/favicon.png"> -<meta name="application-name" content="Wok"> -<meta name="msapplication-config" content="none" /> -<meta name="msapplication-TileColor" content="#4f4f4f"/> -<meta name="msapplication-square70x70logo" content="images/tiny.png"/> -<meta name="msapplication-square150x150logo" content="images/square.png"/> -<meta name="msapplication-wide310x150logo" content="images/wide.png"/> -<meta name="msapplication-square310x310logo" content="images/large.png"/> -<link rel="stylesheet" href="$href('libs/jquery-ui/themes/base/jquery-ui.min.css')"> -<link rel="stylesheet" href="$href('css/jquery-ui.custom.css')"> -<link rel="stylesheet" href="$href('css/theme-default.min.css')"> -<script src="$href('libs/jquery/jquery.min.js')"></script> -<script src="$href('libs/jquery-ui/jquery-ui.min.js')"></script> -<script src="$href('libs/jquery-ui/jquery-ui-i18n.min.js')"></script> -<script src="$href('js/wok.min.js')"></script> -<style type="text/css"> -.topbar select { - float: right; - margin-top: 12px; - margin-right: 10px; -} -.login-area { - margin: 120px auto 0; -} -#login-window { - width: 315px; -} -.err-area { - height: auto; - margin-bottom: 10px; -} -.err-mess { - color: #C85305; -} -</style> + <meta charset="UTF-8"> + <title>Kimchi</title> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-title" content="Wok"> + <link href="images/apple-touch-icon-152.png" sizes="152x152" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-144.png" sizes="144x144" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-180x180.png" sizes="120x120" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-114x114.png" sizes="114x114" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-57x57.png" sizes="57x57" rel="apple-touch-icon-precomposed"> + <link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192"> + <!--[if IE lte 9]><link rel="shortcut icon" href="images/favicon.ico"><![endif]--> + <link rel="shortcut icon" href="images/favicon.png"> + <meta name="application-name" content="Wok"> + <meta name="msapplication-config" content="none" /> + <meta name="msapplication-TileColor" content="#4f4f4f" /> + <meta name="msapplication-square70x70logo" content="images/tiny.png" /> + <meta name="msapplication-square150x150logo" content="images/square.png" /> + <meta name="msapplication-wide310x150logo" content="images/wide.png" /> + <meta name="msapplication-square310x310logo" content="images/large.png" /> + <link rel="stylesheet" href="$href('libs/jquery-ui/themes/base/jquery-ui.min.css')"> + <link rel="stylesheet" href="$href('css/jquery-ui.custom.css')"> + <link rel="stylesheet" href="$href('css/bootstrap.custom.css')"> + <link rel="stylesheet" href="$href('libs/bootstrap-select/dist/css/bootstrap-select.min.css')"> + <link rel="stylesheet" href="$href('css/fontawesome/fontawesome.css')"> + <link rel="stylesheet" href="$href('css/opensans/opensans.css')"> + <link rel="stylesheet" href="$href('css/bootstrap-select.custom.css')"> + <link rel="stylesheet" href="$href('css/wok.css')"> + <script src="$href('libs/es5-shim/es5-shim.min.js')"></script> + <script src="$href('libs/jquery/jquery.min.js')"></script> + <script src="$href('libs/jquery-ui/jquery-ui.min.js')"></script> + <script src="$href('libs/jquery-ui/jquery-ui-i18n.min.js')"></script> + <script src="$href('libs/jquery-i18n/jquery.i18n.min.js')"></script> + <script src="$href('libs/bootstrap/bootstrap.min.js')"></script> + <script src="$href('libs/bootstrap-select/dist/js/bootstrap-select.min.js')"></script> + <script src="$href('js/wok.min.js')"></script> </head> <body onload="wok.login_main()"> -<div class="container topbar"> - <span id="logo"><img alt="Project Wok" src="images/theme-default/logo-white.png"></span> - <select id="userLang"> - <option value="en_US">English (US)</option> - <option value="zh_CN">中文(简体)</option> - <option value="pt_BR">Português (Brasil)</option> - <option value="de_DE">Deutsch (Deutschland)</option> - <option value="es_ES">Español (España)</option> - <option value="fr_FR">Français (France)</option> - <option value="it_IT">Italiano (Italia)</option> - <option value="ja_JP">日本語 (日本)</option> - <option value="ko_KR">한국어 (대한민국)</option> - <option value="ru_RU">Русский (Россия)</option> - <option value="zh_TW">中文(繁體)</option> - </select> -</div> -<div id="login-window" class="login-area"> - <div class="err-area"> - <div id="messUserPass" class="err-mess" style="display: none;">$_("The username or password you entered is incorrect. Please try again.")</div> - <div id="messSession" class="err-mess" style="display: none;">$_("Session timeout, please re-login.")</div> + <div class="topbar"> + <nav class="navbar navbar-inverse"> + <div class="container"> + <div class="navbar-header"> + <a class="navbar-brand" href="#">Kimchi</a> + </div> + </div> + </nav> + <nav class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu" aria-expanded="false"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"><!-- Hamburguer button here --></span> + </button> + </div> + <div class="collapse navbar-collapse" id="nav-menu"> + <ul class="nav navbar-nav"> + <li class="hostname"><span class="host-location"></span></li> + </ul> + </div> + </div> + </nav> </div> - <form id="form-login" class="login-panel" method="post"> - <div class="row"> - <input type="text" id="username" name="username" required="required" placeholder="$_("User Name")" autofocus/> - <div id="username-msg" class="msg-required"></div> + <div class="content"> + <div id="login-window" class="login-area"> + <div class="err-area"> + <div id="messUserPass" class="alert alert-danger" style="display: none;">$_("The username or password you entered is incorrect. Please try again.")</div> + <div id="messSession" class="alert alert-danger" style="display: none;">$_("Session timeout, please re-login.")</div> + </div> + <form id="form-login" class="form-horizontal" method="post"> + <div class="form-group"> + <label for="username" class="sr-only">$_("User Name")</label> + <input type="text" class="form-control" id="username" name="username" required="required" placeholder="$_(" User Name ")" autofocus/> + <div id="username-msg" class="msg-required"></div> + </div> + <div class="form-group"> + <label for="password" class="sr-only">$_("Password")</label> + <input type="password" class="form-control" id="password" name="password" required="required" placeholder="$_(" Password ")" /> + <div id="password-msg" class="msg-required"></div> + </div> + <div class="form-group"> + <button id="btn-login" class="btn btn-login col-md-12 col-lg-12"> + <span id="login">$_("Log in")</span> + <span id="logging" style="display: none;">$_("Logging in...")</span> + </button> + </div> + <select id="userLang" class="selectpicker col-md-12 col-lg-12"> + <option value="en_US">English (US)</option> + <option value="zh_CN">中文(简体)</option> + <option value="pt_BR">Português (Brasil)</option> + <option value="de_DE">Deutsch (Deutschland)</option> + <option value="es_ES">Español (España)</option> + <option value="fr_FR">Français (France)</option> + <option value="it_IT">Italiano (Italia)</option> + <option value="ja_JP">日本語 (日本)</option> + <option value="ko_KR">한국어 (대한민국)</option> + <option value="ru_RU">Русский (Россия)</option> + <option value="zh_TW">中文(繁體)</option> + </select> + </form> </div> - <div class="row"> - <input type="password" id="password" name="password" required="required" placeholder="$_("Password")" /> - <div id="password-msg" class="msg-required"></div> - </div> - <div class="row"> - <button id="btn-login" class="btn-normal-1"> - <label id="login">$_("Log in")</label> - <label id="logging" style="display: none;">$_("Logging in...")</label> - </button> - </div> - </form> -</div> + </div> </body> </html> diff --git a/ui/pages/wok-ui.html.tmpl b/ui/pages/wok-ui.html.tmpl index 669ae29..59a7612 100644 --- a/ui/pages/wok-ui.html.tmpl +++ b/ui/pages/wok-ui.html.tmpl @@ -24,117 +24,134 @@ #silent _ = t.gettext #silent _t = t.gettext #from wok.config import get_version -<!DOCTYPE html> <html lang="$lang.lang[0]"> <head> -<meta charset="UTF-8"> -<title>Kimchi</title> -<meta http-equiv="X-UA-Compatible" content="IE=edge"/> -<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> -<meta name="apple-mobile-web-app-capable" content="yes"> -<meta name="apple-mobile-web-app-title" content="Wok"> -<link href="images/apple-touch-icon-152.png" sizes="152x152" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-144.png" sizes="144x144" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-180x180.png" sizes="120x120" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-114x114.png" sizes="114x114" rel="apple-touch-icon-precomposed"> -<link href="images/apple-touch-icon-57x57.png" sizes="57x57" rel="apple-touch-icon-precomposed"> -<link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192"> -<!--[if IE lte 9]><link rel="shortcut icon" href="images/favicon.ico"><![endif]--> -<link rel="shortcut icon" href="images/favicon.png"> -<meta name="application-name" content="Wok"> -<meta name="msapplication-config" content="none" /> -<meta name="msapplication-TileColor" content="#4f4f4f"/> -<meta name="msapplication-square70x70logo" content="images/tiny.png"/> -<meta name="msapplication-square150x150logo" content="images/square.png"/> -<meta name="msapplication-wide310x150logo" content="images/wide.png"/> -<meta name="msapplication-square310x310logo" content="images/large.png"/> -<link rel="stylesheet" href="$href('libs/jquery-ui/themes/base/jquery-ui.min.css')"> -<link rel="stylesheet" href="$href('css/jquery-ui.custom.css')"> -<link rel="stylesheet" href="$href('css/theme-default.min.css')"> -<script src="$href('base64/jquery.base64.js')"></script> -<script src="$href('libs/jquery/jquery.min.js')"></script> -<script src="$href('libs/jquery-ui/jquery-ui.min.js')"></script> -<script src="$href('libs/jquery-ui/jquery-ui-i18n.min.js')"></script> -<script src="$href('js/wok.min.js')"></script> + <meta charset="UTF-8"> + <title>Kimchi</title> + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-title" content="Wok"> + <link href="images/apple-touch-icon-152.png" sizes="152x152" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-144.png" sizes="144x144" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-76.png" sizes="76x76" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-72.png" sizes="72x72" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-180x180.png" sizes="120x120" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-114x114.png" sizes="114x114" rel="apple-touch-icon-precomposed"> + <link href="images/apple-touch-icon-57x57.png" sizes="57x57" rel="apple-touch-icon-precomposed"> + <link rel="icon" type="image/png" href="images/android-chrome-192x192.png" sizes="192x192"> + <!--[if IE lte 9]><link rel="shortcut icon" href="images/favicon.ico"><![endif]--> + <link rel="shortcut icon" href="images/favicon.png"> + <meta name="application-name" content="Wok"> + <meta name="msapplication-config" content="none" /> + <meta name="msapplication-TileColor" content="#4f4f4f" /> + <meta name="msapplication-square70x70logo" content="images/tiny.png" /> + <meta name="msapplication-square150x150logo" content="images/square.png" /> + <meta name="msapplication-wide310x150logo" content="images/wide.png" /> + <meta name="msapplication-square310x310logo" content="images/large.png" /> + <link rel="stylesheet" href="$href('libs/jquery-ui/themes/base/jquery-ui.min.css')"> + <link rel="stylesheet" href="$href('css/jquery-ui.custom.css')"> + <link rel="stylesheet" href="$href('css/bootstrap.custom.css')"> + <link rel="stylesheet" href="$href('libs/bootstrap-select/dist/css/bootstrap-select.min.css')"> + <link rel="stylesheet" href="$href('css/fontawesome/fontawesome.css')"> + <link rel="stylesheet" href="$href('css/opensans/opensans.css')"> + <link rel="stylesheet" href="$href('css/bootstrap-select.custom.css')"> + <link rel="stylesheet" href="$href('css/wok.css')"> + <script src="$href('libs/es5-shim/es5-shim.min.js')"></script> + <script src="$href('libs/jquery/jquery.min.js')"></script> + <script src="$href('libs/jquery-ui/jquery-ui.min.js')"></script> + <script src="$href('libs/jquery-ui/jquery-ui-i18n.min.js')"></script> + <script src="$href('libs/jquery-i18n/jquery.i18n.min.js')"></script> + <script src="$href('libs/bootstrap/bootstrap.min.js')"></script> + <script src="$href('libs/bootstrap-select/dist/js/bootstrap-select.min.js')"></script> + <script src="$href('js/wok.min.js')"></script> + <!-- This is used for detecting if the UI needs to be built --> + <style type="text/css"> + #buildme { + position: fixed; + background: rgba(0, 0, 0, 0.5); + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 10000; + } -<!-- This is used for detecting if the UI needs to be built --> -<style type="text/css"> -#buildme { - position: fixed; - background: rgba(0, 0, 0, 0.5); - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 10000; -} - -#buildme div { - background-color: #FFB2C0; - border-style: solid; - border-color: #FF0000; - padding: 30px; - width: 75%; - margin-left: auto; - margin-right: auto; - margin-top: 50px; - -moz-border-radius: 15px; - border-radius: 15px; -} -</style> -</head> + #buildme div { + background-color: #FFB2C0; + border-style: solid; + border-color: #FF0000; + padding: 30px; + width: 75%; + margin-left: auto; + margin-right: auto; + margin-top: 50px; + -moz-border-radius: 15px; + border-radius: 15px; + } + </style> + </head> <body onload="wok.main()"> -<div class="container"> -<header class="topbar"> - <h1 id="logo"><img alt="Project Wok" src="images/theme-default/logo-white.png"></h1> - <ul class="nav-top"> - <li> - <div id="peers" class="peers hide-content popable"> - <span>$_("Peers")</span> - <span class="arrow"></span> - <div class="dropdown popover right-side"> - <p id="search-peers">$_("Searching")...</p> - <p id="no-peers" class="hide-content">$_("No peers found.")</p> - </div> + <div class="topbar"> + <nav class="navbar navbar-inverse"> + <div class="container"> + <div class="navbar-header"> + <a id="logo" class="navbar-brand" href="#" title="Project Kimchi">Kimchi</a> </div> - </li> - <li> - <div id="user" class="popable"> - <span id="user-icon"></span> - <span id="user-name" class="empty-when-logged-off"></span> - <span class="arrow"></span> - <div class="action-panel popover right-side"> - <a id="btn-help" class="user-menu-item" href="javascript:void(0);">$_("Help")</a> - <br/> - <br/> - <a id="btn-about" class="user-menu-item" href="javascript:void(0);">$_("About")</a> - <br/> - <hr/> - <a id="btn-logout" class="user-menu-item" href="javascript: void(0);">$_("Log out")</a> - </div> + <ul class="nav navbar-nav navbar-right"> + <li class="dropdown hide-content peers" id="peers"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><span class="topbar-text">$_("Peers")</span><span class="caret"></span></a> + <ul class="dropdown-menu"> + <li id="search-peers"><span>$_("Searching")...</span></li> + <li id="no-peers" class="hide-content">$_("No peers found.")</li> + </ul> + </li> + <li class="dropdown" id="user"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> + <i class="fa fa-user" id="user-icon"></i><span class="topbar-text empty-when-logged-off" id="user-name"></span><span class="caret"></span> + </a> + <ul class="dropdown-menu"> + <li class="critical"><a id="btn-logout" href="javascript: void(0);"><i class="fa fa-ban"></i><span>$_("Log out")</span></a></li> + </ul> + </li> + <li class="dropdown"> + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><i class="fa fa-question-circle"></i><span class="topbar-text">$_("Help")</span><span class="caret"></span></a> + <ul class="dropdown-menu"> + <li><a id="btn-help" href="javascript: void(0);">$_("Help")</a></li> + <li><a id="btn-about" href="javascript:void(0);">$_("About")</a></li> + </ul> + </li> + </ul> + </div> + </nav> + <nav class="navbar navbar-default"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#nav-menu" aria-expanded="false"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"><!-- Hamburguer button here --></span> + </button> </div> - </li> - </ul> -</header> -<div class="content"> - <nav class="navbar"> - <ul id="nav-menu" class="nav-menu"> - <li class="menu-arrow"></li> - </ul> - </nav> - <div id="main"> + <div class="collapse navbar-collapse" id="nav-menu"> + <ul class="nav navbar-nav"> + <li class="hostname"><span class="host-location"></span></li> + </ul> + </div> + </div> + </nav> + </div> + <div class="content"> + <div id="main"> + </div> + </div> </div> -</div> -</div> -<div id="buildme"> - <div><p>Oops! It looks like I am running from a source tree and you forgot to build! + <div id="buildme" style="display:none"> + <div><p>Oops! It looks like I am running from a source tree and you forgot to build! Please run the following command from the wok and kimchi directories and reload this page:</p> - <p><code>make</code></p> + <p><code>make</code></p> + </div> </div> -</div> <script id="about-tmpl" type="wok/template"> <div class="window about-window"> -- 1.9.3