This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-primate.git


The following commit(s) were added to refs/heads/master by this push:
     new 5ce14f6  components: reusable details settings and new fixes/features 
(#38)
5ce14f6 is described below

commit 5ce14f61b7e64d9b6d81d81c095a9999143517e4
Author: Rohit Yadav <[email protected]>
AuthorDate: Sat Nov 23 22:03:45 2019 +0530

    components: reusable details settings and new fixes/features (#38)
    
    - Reusable details settings component for VM and templates, with 
autocompletion of options
    - Instancegroup feature
    - split monitor into individual event and alert tabs, move alerts to infra
    - reimplement logo
    - project selection refactorings
    - use password input for relevant fields
    
    Signed-off-by: Rohit Yadav <[email protected]>
---
 docs/api/apis.primate.sh                           |   2 +-
 docs/api/apis.remaining                            |   1 -
 src/assets/cloudmonkey.png                         | Bin 30274 -> 0 bytes
 src/assets/logo.svg                                | 196 ++++++++++++++++----
 src/components/header/HeaderNotice.vue             |   2 +-
 src/components/header/Logo.vue                     |   7 +-
 src/components/header/ProjectMenu.vue              |  64 +++++--
 src/components/header/UserMenu.vue                 |   3 +
 src/components/view/DetailSettings.vue             | 203 +++++++++++++++++++++
 src/components/view/FormView.vue                   |  10 +-
 src/components/view/InfoCard.vue                   |  16 +-
 src/components/view/ListView.vue                   |   9 +
 src/components/view/SettingTable.vue               |  68 -------
 src/config/router.js                               |   5 +-
 src/config/section/compute.js                      |  38 +++-
 .../section/event.js}                              |  51 +++---
 src/config/section/iam.js                          |   2 +-
 src/config/section/image.js                        |   2 +-
 src/config/section/infra.js                        |  24 +++
 src/config/section/monitor.js                      |  78 --------
 src/views/AutogenView.vue                          |   9 +-
 src/views/auth/Login.vue                           |   4 +-
 src/views/image/TemplateSettings.vue               |  60 ------
 src/views/infra/InfraSummary.vue                   |  30 ++-
 24 files changed, 560 insertions(+), 324 deletions(-)

diff --git a/docs/api/apis.primate.sh b/docs/api/apis.primate.sh
index ed43739..b12d004 100644
--- a/docs/api/apis.primate.sh
+++ b/docs/api/apis.primate.sh
@@ -3,7 +3,7 @@ rm -f apis.txt
 grep api\( -R . | grep -v import | sed "s/.*api('//g" | sed "s/'.*//g" | grep 
-v '.vue' | sort | uniq >> apis.txt
 grep api -R config | sed "s/.*api: '//g" | sed "s/'.*//g" | grep -v \.js | 
sort | uniq >> apis.txt
 grep store.getters.apis -R . | sed "s/' in.*//g" | sed "s/').*//g" | grep "'" 
| sed "s/.*'//g" | grep -v ']' >> apis.txt
-grep 'permission:\ \[' -R config | sed "s/.*permission: \[ '//g" | grep -v .js 
| sed "s/', '/\\n/g" | sed "s/'.*//g" >> apis.txt
+grep 'permission:\ \[' -R config | sed "s/.*permission: \['//g" | grep -v .js 
| sed "s/', '/\\n/g" | sed "s/'.*//g" >> apis.txt
 cat apis.txt | sort | uniq > apis.uniq
 rm -f apis.txt
 mv apis.uniq ../docs/api/apis.txt
diff --git a/docs/api/apis.remaining b/docs/api/apis.remaining
index 2a80563..50fc784 100644
--- a/docs/api/apis.remaining
+++ b/docs/api/apis.remaining
@@ -62,7 +62,6 @@ deleteVpnCustomerGateway
 deleteVpnGateway
 findHostsForMigration
 findStoragePoolsForMigration
-getUploadParamsForTemplate
 importLdapUsers
 ldapCreateAccount
 linkDomainToLdap
diff --git a/src/assets/cloudmonkey.png b/src/assets/cloudmonkey.png
deleted file mode 100644
index 37928d5..0000000
Binary files a/src/assets/cloudmonkey.png and /dev/null differ
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
index 5c26e4e..095b866 100644
--- a/src/assets/logo.svg
+++ b/src/assets/logo.svg
@@ -5,11 +5,12 @@
    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";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
    xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
    xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
-   viewBox="0 0 449.99999 362.9483"
+   viewBox="0 0 1484.4133 362.9483"
    height="362.9483"
-   width="450"
+   width="1484.4133"
    xml:space="preserve"
    id="svg2"
    version="1.1"
@@ -23,68 +24,60 @@
      guidetolerance="10"
      inkscape:pageopacity="0"
      inkscape:pageshadow="2"
-     inkscape:window-width="1866"
-     inkscape:window-height="1017"
+     inkscape:window-width="1308"
+     inkscape:window-height="704"
      id="namedview93"
      showgrid="false"
-     inkscape:zoom="0.87885424"
-     inkscape:cx="-52.731547"
+     inkscape:zoom="0.41"
+     inkscape:cx="640.72071"
      inkscape:cy="181.47415"
-     inkscape:window-x="54"
-     inkscape:window-y="26"
+     inkscape:window-x="58"
+     inkscape:window-y="27"
      inkscape:window-maximized="1"
-     inkscape:current-layer="layer2" /><metadata
+     inkscape:current-layer="g116" /><metadata
      id="metadata8"><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></dc:title></cc:Work></rdf:RDF></metadata><defs
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; /><dc:title 
/></cc:Work></rdf:RDF></metadata><defs
      id="defs6"><marker
        inkscape:stockid="Arrow1Mend"
        orient="auto"
-       refY="0"
-       refX="0"
+       refY="0.0"
+       refX="0.0"
        id="Arrow1Mend"
-       style="overflow:visible"
+       style="overflow:visible;"
        inkscape:isstock="true"><path
          id="path913"
-         d="M 0,0 5,-5 -12.5,0 5,5 Z"
-         
style="fill:#5affff;fill-opacity:1;fill-rule:evenodd;stroke:#7787ff;stroke-width:1.00000003pt;stroke-opacity:1"
-         transform="matrix(-0.4,0,0,-0.4,-4,0)"
-         inkscape:connector-curvature="0" /></marker><clipPath
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         
style="fill-rule:evenodd;stroke:#7787ff;stroke-width:1pt;stroke-opacity:1;fill:#5affff;fill-opacity:1"
+         transform="scale(0.4) rotate(180) translate(10,0)" 
/></marker><clipPath
        id="clipPath18"
        clipPathUnits="userSpaceOnUse"><path
          id="path16"
-         d="M 0,2000 H 2000 V 0 H 0 Z"
-         inkscape:connector-curvature="0" /></clipPath><clipPath
+         d="M 0,2000 H 2000 V 0 H 0 Z" /></clipPath><clipPath
        id="clipPath90"
        clipPathUnits="userSpaceOnUse"><path
          id="path88"
-         d="m 1317.766,1308.723 v -15.945 h -0.107 c -1.215,2.153 -3.975,4.082 
-8.06,4.082 v 0 c -6.512,0 -12.028,-5.46 -11.973,-14.345 v 0 c 0,-8.111 
4.967,-13.573 11.419,-13.573 v 0 c 4.36,0 7.62,2.261 9.107,5.244 v 0 h 0.109 l 
0.218,-4.637 h 4.368 c -0.17,1.822 -0.227,4.523 -0.227,6.898 v 0 32.276 z m 
-15.23,-25.985 c 0,5.904 2.981,10.317 8,10.317 v 0 c 3.645,0 6.291,-2.535 
7.01,-5.628 v 0 c 0.164,-0.607 0.22,-1.435 0.22,-2.042 v 0 -4.632 c 0,-0.776 
-0.056,-1.437 -0.22,-2.099 v 0 c -0 [...]
-         inkscape:connector-curvature="0" /></clipPath><clipPath
+         d="m 1317.766,1308.723 v -15.945 h -0.107 c -1.215,2.153 -3.975,4.082 
-8.06,4.082 v 0 c -6.512,0 -12.028,-5.46 -11.973,-14.345 v 0 c 0,-8.111 
4.967,-13.573 11.419,-13.573 v 0 c 4.36,0 7.62,2.261 9.107,5.244 v 0 h 0.109 l 
0.218,-4.637 h 4.368 c -0.17,1.822 -0.227,4.523 -0.227,6.898 v 0 32.276 z m 
-15.23,-25.985 c 0,5.904 2.981,10.317 8,10.317 v 0 c 3.645,0 6.291,-2.535 
7.01,-5.628 v 0 c 0.164,-0.607 0.22,-1.435 0.22,-2.042 v 0 -4.632 c 0,-0.776 
-0.056,-1.437 -0.22,-2.099 v 0 c -0 [...]
        id="clipPath104"
        clipPathUnits="userSpaceOnUse"><path
          id="path102"
-         d="m 892.093,1318.587 h 744.665 v 1.564 H 892.093 Z"
-         inkscape:connector-curvature="0" /></clipPath><clipPath
+         d="m 892.093,1318.587 h 744.665 v 1.564 H 892.093 Z" 
/></clipPath><clipPath
        id="clipPath122"
        clipPathUnits="userSpaceOnUse"><path
          id="path120"
-         d="M 0,2000 H 2000 V 0 H 0 Z"
-         inkscape:connector-curvature="0" /></clipPath></defs><g
+         d="M 0,2000 H 2000 V 0 H 0 Z" /></clipPath></defs><g
      inkscape:groupmode="layer"
      id="layer2"
      inkscape:label="Layer 2"
-     style="display:inline"
-     transform="translate(0,-3.2226562e-6)"><path
-       
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:15;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke
 fill markers"
+     style="display:inline"><path
+       
style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:21;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:stroke
 fill markers"
        d="M 74.644451,333.81717 C 49.698347,322.45232 37.89043,305.98469 
37.89043,282.55906 c 0,-23.39691 7.977608,-37.44115 26.795419,-47.17222 
14.940601,-7.72609 51.524811,-8.91366 55.912041,-1.81499 2.13409,3.45303 
4.37116,3.47 7.78213,0.059 5.41915,-5.41914 -12.124,-27.19361 
-21.90923,-27.19361 -16.197294,0 -7.273924,-29.50548 15.35848,-50.78343 
18.73596,-17.6147 51.631,-21.18268 73.07972,-7.92664 31.16098,19.25854 
45.20833,67.48547 24.47251,84.01829 -16.44689,13.11323 -25.47165,29.1 [...]
        id="path97"
        inkscape:connector-curvature="0" /></g><g
      inkscape:groupmode="layer"
      id="layer1"
      inkscape:label="Layer 1"
-     style="display:inline"
-     transform="translate(0,-3.2226562e-6)"
-     sodipodi:insensitive="true"><g
+     style="display:inline"><g
        transform="matrix(1.3333333,0,0,-1.3333333,-309.27816,2052.7205)"
        id="g10"><g
    transform="translate(-317.59883,17.977292)"
@@ -186,6 +179,143 @@
          id="path82"
          style="fill:#b9e1f6;fill-opacity:1;fill-rule:nonzero;stroke:none"
          d="m 0,0 c 0,0 -2.887,5.018 0.984,8.986 0,0 5.068,1.737 5.206,5.665 
0,0 -1.398,6.182 1.491,8.342 0,0 4.789,3.286 5.406,-2.412 0,0 1.044,-5.282 
-0.676,-8.613 0,0 7.063,1.813 10.257,0 3.196,-1.814 4.302,-11.503 1.415,-16.522 
0,0 -3.44,-6.009 -13.086,-5.601 0,0 -8.601,-0.35 -8.786,5.895 0,0 -0.829,2.665 
-2.211,4.26"
-         inkscape:connector-curvature="0" /></g></g></g>
+         inkscape:connector-curvature="0" /></g></g></g><g
+   transform="matrix(0.8869744,0,0,0.961233,-132.31692,116.07227)"
+   id="g84"><g
+     clip-path="url(#clipPath90)"
+     id="g86"><g
+       id="g92"><g
+         transform="matrix(1008.8768,0,0,756.6576,710.18262,943.2384)"
+         id="g94"><image
+           id="image96"
+           
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAABHNCSVQICAgIfAhkiAAACP9JREFUeJzt2MGNQjEQBUEbkSdaAgMRqbnvEST8oasieNJcWjPHGGsAAJBx2j0AAIDPEoAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgA
 [...]
+           transform="matrix(1,0,0,-1,0,1)"
+           preserveAspectRatio="none"
+           style="image-rendering:optimizeSpeed"
+           height="1"
+           width="1" /></g></g></g></g><g
+   transform="matrix(0.8869744,0,0,0.961233,-132.31692,116.07227)"
+   id="g98"><g
+     clip-path="url(#clipPath104)"
+     id="g100"><g
+       id="g106"><g
+         transform="matrix(1014.016,0,0,750.59521,706.7168,947.9795)"
+         id="g108"><image
+           id="image110"
+           
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAABHNCSVQICAgIfAhkiAAACOVJREFUeJzt2LENg1AUBMGH5ZIRRSD3DB0gOeEHO1PBhavbZuYaAAAyPqsHAADwLgEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAECMAAQAiBGAAAAxAhAAIEYAAgDECEAAgBgBCAAQIwABAGIEIABAjAAEAIgRgAAAMQIQACBGAAIAxAhAAIAYAQgAECMAAQBiBCAAQIwABACIEYAAADECEAAgRgACAMQIQACAGAEIABAjAAEAYgQgAEC
 [...]
+           transform="matrix(1,0,0,-1,0,1)"
+           preserveAspectRatio="none"
+           style="image-rendering:optimizeSpeed"
+           height="1"
+           width="1" /></g></g></g></g><text
+   y="-1396.1345"
+   x="1380.2909"
+   id="text114"
+   
style="font-variant:normal;font-weight:bold;font-stretch:normal;font-size:11.77262306px;font-family:'Avenir
 LT Std 55 
Roman';-inkscape-font-specification:AvenirLTStd-Heavy;writing-mode:lr-tb;fill:#808181;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.92335749"
+   transform="scale(0.96059698,-1.0410193)"><tspan
+     id="tspan112"
+     y="-1396.1345"
+     x="1380.2909 1387.0483"
+     style="stroke-width:0.92335749">TM</tspan></text>
 
-</g></g></svg>
\ No newline at end of file
+
+<g
+   transform="translate(-317.59883,17.977292)"
+   id="g116"><g
+     clip-path="url(#clipPath122)"
+     id="g118"
+     transform="matrix(0.8869744,0,0,0.961233,185.28191,98.09498)"><g
+       transform="translate(833.8633,1358.5918)"
+       id="g124"><path
+         id="path126"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -1.158,0 -2.603,-0.051 -4.338,-0.153 -1.736,-0.102 
-3.404,-0.392 -5.002,-0.868 -1.599,-0.477 -2.96,-1.191 -4.083,-2.144 
-1.122,-0.953 -1.684,-2.28 -1.684,-3.98 0,-1.837 0.781,-3.2 2.348,-4.083 
1.564,-0.885 3.197,-1.327 4.899,-1.327 1.496,0 2.943,0.204 4.339,0.612 
1.393,0.409 2.636,0.986 3.725,1.735 1.088,0.749 1.955,1.701 2.603,2.858 
0.646,1.157 0.969,2.517 0.969,4.083 L 3.776,0 Z M 3.776,-15.515 H 3.572 c 
-1.701,-2.654 -3.965,-4.56 -6.787,-5.716 -2.825,-1.157 -5.803, [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(875.8135,1361.6538)"
+       id="g128"><path
+         id="path130"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c 0,-3.743 1.072,-6.772 3.215,-9.084 2.144,-2.314 
5.155,-3.471 9.034,-3.471 3.879,0 6.89,1.157 9.033,3.471 2.144,2.312 
3.216,5.341 3.216,9.084 0,3.742 -1.072,6.771 -3.216,9.084 -2.143,2.313 
-5.154,3.471 -9.033,3.471 -3.879,0 -6.89,-1.158 -9.034,-3.471 C 1.072,6.771 
0,3.742 0,0 M -14.086,24.804 H 0 v -6.533 h 0.204 c 0.613,0.884 1.412,1.787 
2.399,2.705 0.986,0.919 2.144,1.751 3.471,2.501 1.326,0.748 2.772,1.36 
4.338,1.837 1.564,0.476 3.231,0.715 5.001,0.715 3.675,0 7.008 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(950.939,1358.5918)"
+       id="g132"><path
+         id="path134"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -1.158,0 -2.603,-0.051 -4.338,-0.153 -1.736,-0.102 
-3.404,-0.392 -5.002,-0.868 -1.599,-0.477 -2.96,-1.191 -4.083,-2.144 
-1.122,-0.953 -1.684,-2.28 -1.684,-3.98 0,-1.837 0.781,-3.2 2.348,-4.083 
1.564,-0.885 3.197,-1.327 4.899,-1.327 1.496,0 2.943,0.204 4.339,0.612 
1.393,0.409 2.636,0.986 3.725,1.735 1.088,0.749 1.955,1.701 2.603,2.858 
0.646,1.157 0.969,2.517 0.969,4.083 L 3.776,0 Z M 3.776,-15.515 H 3.572 c 
-1.701,-2.654 -3.965,-4.56 -6.787,-5.716 -2.825,-1.157 -5.803, [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1010.9561,1370.4321)"
+       id="g136"><path
+         id="path138"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -0.75,1.088 -1.804,1.99 -3.164,2.705 -1.361,0.714 
-2.824,1.072 -4.389,1.072 -3.879,0 -6.89,-1.158 -9.033,-3.471 -2.144,-2.314 
-3.216,-5.343 -3.216,-9.084 0,-3.743 1.072,-6.772 3.216,-9.085 2.143,-2.314 
5.154,-3.47 9.033,-3.47 1.699,0 3.164,0.373 4.389,1.123 1.225,0.748 2.279,1.633 
3.164,2.653 l 10.105,-10.615 c -2.382,-2.45 -5.189,-4.169 -8.42,-5.155 
-3.234,-0.986 -6.313,-1.48 -9.238,-1.48 -3.812,0 -7.4,0.613 -10.769,1.837 
-3.368,1.225 -6.295,2.976 -8.778,5.257 -2.485 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1040.8633,1414.0176)"
+       id="g140"><path
+         id="path142"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 v -34.297 h 0.204 c 0.34,0.952 0.919,1.904 1.735,2.859 
0.818,0.952 1.802,1.801 2.96,2.551 1.157,0.748 2.518,1.361 4.083,1.837 
1.566,0.476 3.267,0.715 5.105,0.715 3.878,0 7.008,-0.597 9.391,-1.786 
2.38,-1.191 4.235,-2.842 5.562,-4.951 1.326,-2.11 2.229,-4.593 2.705,-7.451 
0.475,-2.858 0.715,-5.956 0.715,-9.289 V -77.167 H 17.148 v 24.293 c 0,1.429 
-0.051,2.909 -0.153,4.44 -0.101,1.531 -0.408,2.943 -0.918,4.236 -0.511,1.292 
-1.294,2.348 -2.348,3.164 -1.056,0.817 -2.57,1.2 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1117.1104,1367.2681)"
+       id="g144"><path
+         id="path146"
+         style="fill:#989898;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c 0.067,2.585 -0.783,4.797 -2.551,6.635 -1.771,1.837 
-4.051,2.756 -6.84,2.756 -1.701,0 -3.199,-0.273 -4.491,-0.817 C -15.176,8.028 
-16.28,7.332 -17.199,6.481 -18.117,5.63 -18.832,4.644 -19.342,3.521 
-19.854,2.398 -20.143,1.225 -20.21,0 Z m 12.963,-21.844 c -2.449,-3.131 
-5.547,-5.547 -9.288,-7.247 -3.743,-1.7 -7.622,-2.552 -11.636,-2.552 -3.812,0 
-7.4,0.613 -10.769,1.837 -3.369,1.225 -6.295,2.976 -8.778,5.257 -2.485,2.279 
-4.441,5.018 -5.869,8.217 -1.43,3.198 -2.144,6.7 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1174.2705,1370.4321)"
+       id="g148"><path
+         id="path150"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -0.75,1.088 -1.804,1.99 -3.164,2.705 -1.361,0.714 
-2.824,1.072 -4.389,1.072 -3.879,0 -6.89,-1.158 -9.033,-3.471 -2.144,-2.314 
-3.216,-5.343 -3.216,-9.084 0,-3.743 1.072,-6.772 3.216,-9.085 2.143,-2.314 
5.154,-3.47 9.033,-3.47 1.699,0 3.164,0.373 4.389,1.123 1.225,0.748 2.279,1.633 
3.164,2.653 l 10.105,-10.615 c -2.382,-2.45 -5.189,-4.169 -8.42,-5.155 
-3.234,-0.986 -6.313,-1.48 -9.238,-1.48 -3.812,0 -7.4,0.613 -10.769,1.837 
-3.368,1.225 -6.295,2.976 -8.778,5.257 -2.485 [...]
+         inkscape:connector-curvature="0" /></g><path
+       id="path152"
+       style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+       d="m 1189.071,1414.018 h 15.311 v -77.167 h -15.311 z"
+       inkscape:connector-curvature="0" /><g
+       transform="translate(1227.8584,1361.6538)"
+       id="g154"><path
+         id="path156"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c 0,-3.743 1.071,-6.772 3.215,-9.084 2.143,-2.314 
5.154,-3.471 9.033,-3.471 3.879,0 6.891,1.157 9.034,3.471 2.144,2.312 
3.215,5.341 3.215,9.084 0,3.742 -1.071,6.771 -3.215,9.084 -2.143,2.313 
-5.155,3.471 -9.034,3.471 -3.879,0 -6.89,-1.158 -9.033,-3.471 C 1.071,6.771 
0,3.742 0,0 m -15.311,0 c 0,3.946 0.714,7.519 2.143,10.718 1.43,3.198 
3.385,5.936 5.869,8.217 2.484,2.279 5.41,4.031 8.779,5.256 3.368,1.226 
6.957,1.838 10.768,1.838 3.811,0 7.4,-0.612 10.77,-1.838 3.368,-1. [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1323.3965,1336.8501)"
+       id="g158"><path
+         id="path160"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 h -14.698 v 6.737 h -0.204 c -0.545,-0.954 -1.243,-1.906 
-2.093,-2.858 -0.852,-0.954 -1.888,-1.804 -3.113,-2.552 -1.225,-0.75 
-2.621,-1.361 -4.185,-1.837 -1.566,-0.476 -3.267,-0.715 -5.103,-0.715 -3.879,0 
-7.028,0.597 -9.443,1.787 -2.416,1.189 -4.287,2.84 -5.613,4.95 -1.327,2.109 
-2.213,4.593 -2.654,7.451 -0.444,2.858 -0.665,5.954 -0.665,9.289 v 27.355 h 
15.312 V 25.314 c 0,-1.429 0.051,-2.909 0.153,-4.44 0.102,-1.531 0.409,-2.944 
0.919,-4.236 0.51,-1.294 1.292,-2.348 2 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1371.166,1361.6538)"
+       id="g162"><path
+         id="path164"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c 0,3.742 -1.071,6.771 -3.215,9.084 -2.143,2.313 
-5.155,3.471 -9.034,3.471 -3.878,0 -6.89,-1.158 -9.033,-3.471 -2.144,-2.313 
-3.215,-5.342 -3.215,-9.084 0,-3.743 1.071,-6.772 3.215,-9.084 2.143,-2.314 
5.155,-3.471 9.033,-3.471 3.879,0 6.891,1.157 9.034,3.471 C -1.071,-6.772 
0,-3.743 0,0 M 14.086,-24.804 H 0 v 6.533 h -0.204 c -0.612,-0.885 
-1.413,-1.786 -2.399,-2.705 -0.987,-0.919 -2.143,-1.753 -3.47,-2.501 
-1.327,-0.75 -2.791,-1.36 -4.389,-1.837 -1.6,-0.476 -3.251,-0.7 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1424.5498,1371.8613)"
+       id="g166"><path
+         id="path168"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -2.246,2.79 -5.206,4.185 -8.881,4.185 -1.293,0 
-2.552,-0.307 -3.776,-0.919 -1.226,-0.612 -1.838,-1.668 -1.838,-3.164 0,-1.225 
0.629,-2.128 1.889,-2.705 1.258,-0.579 2.858,-1.089 4.797,-1.531 1.939,-0.444 
4.014,-0.919 6.226,-1.429 2.211,-0.511 4.287,-1.311 6.227,-2.399 1.939,-1.089 
3.538,-2.569 4.797,-4.44 1.258,-1.872 1.889,-4.373 1.889,-7.502 0,-3.2 
-0.699,-5.836 -2.093,-7.911 -1.395,-2.077 -3.181,-3.743 -5.359,-5.002 
-2.179,-1.26 -4.628,-2.143 -7.349,-2.654 -2.722,- [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1476.5049,1374.209)"
+       id="g170"><path
+         id="path172"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 h -13.474 v -16.536 c 0,-1.362 0.067,-2.603 0.204,-3.726 
0.136,-1.122 0.442,-2.092 0.919,-2.909 0.475,-0.816 1.207,-1.446 2.195,-1.888 
0.985,-0.443 2.297,-0.664 3.929,-0.664 0.817,0 1.889,0.085 3.215,0.256 
1.327,0.169 2.33,0.561 3.012,1.174 v -12.76 c -1.702,-0.612 -3.471,-1.02 
-5.308,-1.224 -1.838,-0.205 -3.641,-0.307 -5.41,-0.307 -2.587,0 -4.968,0.273 
-7.145,0.817 -2.179,0.544 -4.083,1.412 -5.716,2.602 -1.633,1.19 -2.909,2.739 
-3.828,4.645 -0.918,1.904 -1.378,4.219 -1 [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1510.5967,1358.5918)"
+       id="g174"><path
+         id="path176"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -1.158,0 -2.603,-0.051 -4.338,-0.153 -1.735,-0.102 
-3.404,-0.392 -5.002,-0.868 -1.599,-0.477 -2.96,-1.191 -4.083,-2.144 
-1.123,-0.953 -1.684,-2.28 -1.684,-3.98 0,-1.837 0.782,-3.2 2.347,-4.083 
1.566,-0.885 3.198,-1.327 4.901,-1.327 1.496,0 2.942,0.204 4.338,0.612 
1.393,0.409 2.635,0.986 3.725,1.735 1.088,0.749 1.955,1.701 2.603,2.858 
0.646,1.157 0.969,2.517 0.969,4.083 L 3.776,0 Z M 3.776,-15.515 H 3.572 c 
-1.701,-2.654 -3.965,-4.56 -6.788,-5.716 -2.824,-1.157 -5.802, [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1570.6143,1370.4321)"
+       id="g178"><path
+         id="path180"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 c -0.75,1.088 -1.804,1.99 -3.164,2.705 -1.362,0.714 
-2.825,1.072 -4.39,1.072 -3.879,0 -6.889,-1.158 -9.033,-3.471 -2.143,-2.314 
-3.216,-5.343 -3.216,-9.084 0,-3.743 1.073,-6.772 3.216,-9.085 2.144,-2.314 
5.154,-3.47 9.033,-3.47 1.7,0 3.164,0.373 4.39,1.123 1.225,0.748 2.278,1.633 
3.164,2.653 l 10.105,-10.615 c -2.382,-2.45 -5.19,-4.169 -8.421,-5.155 
-3.233,-0.986 -6.313,-1.48 -9.238,-1.48 -3.811,0 -7.4,0.613 -10.768,1.837 
-3.368,1.225 -6.295,2.976 -8.779,5.257 -2.485,2. [...]
+         inkscape:connector-curvature="0" /></g><g
+       transform="translate(1585.2109,1414.0176)"
+       id="g182"><path
+         id="path184"
+         style="fill:#69afd8;fill-opacity:1;fill-rule:nonzero;stroke:none"
+         d="m 0,0 h 15.311 v -47.158 l 16.944,19.598 h 18.781 l -19.7,-22.354 
20.211,-27.253 H 32.255 l -16.74,25.109 H 15.311 V -77.167 H 0 Z"
+         inkscape:connector-curvature="0" /></g></g></g></g></g></svg>
\ No newline at end of file
diff --git a/src/components/header/HeaderNotice.vue 
b/src/components/header/HeaderNotice.vue
index c796a62..e807e9c 100644
--- a/src/components/header/HeaderNotice.vue
+++ b/src/components/header/HeaderNotice.vue
@@ -25,7 +25,7 @@
     overlayClassName="header-notice-popover">
     <template slot="content">
       <a-spin :spinning="loading">
-        <a-list>
+        <a-list style="min-width: 200px">
           <a-list-item>
             <a-list-item-meta title="Notifications">
               <a-avatar :style="{backgroundColor: '#6887d0', verticalAlign: 
'middle'}" icon="notification" slot="avatar"/>
diff --git a/src/components/header/Logo.vue b/src/components/header/Logo.vue
index 3e5e72b..37e1e9c 100644
--- a/src/components/header/Logo.vue
+++ b/src/components/header/Logo.vue
@@ -18,17 +18,14 @@
 <template>
   <div class="logo">
     <img class="logo-image" src="~@/assets/logo.svg"/>
-    <project-menu></project-menu>
   </div>
 </template>
 
 <script>
-import ProjectMenu from './ProjectMenu'
 
 export default {
   name: 'Logo',
   components: {
-    ProjectMenu
   },
   props: {
     title: {
@@ -50,7 +47,6 @@ export default {
   height: 64px;
   position: relative;
   line-height: 64px;
-  padding-left: 12px;
   -webkit-transition: all .3s;
   transition: all .3s;
   background: #002140;
@@ -63,8 +59,7 @@ export default {
 }
 
 .logo-image {
-  width: 54px;
-  margin-right: 10px;
+  width: 256px;
   display: inline-block;
   vertical-align: middle;
 }
diff --git a/src/components/header/ProjectMenu.vue 
b/src/components/header/ProjectMenu.vue
index 35c0a55..5fa92c8 100644
--- a/src/components/header/ProjectMenu.vue
+++ b/src/components/header/ProjectMenu.vue
@@ -16,21 +16,43 @@
 // under the License.
 
 <template>
-  <span class="project-wrapper" :disabled="true">
-    <a-select
-      class="project-wrapper-select"
-      size="default"
-      defaultValue="Default View"
-      :value="selectedProject"
-      :disabled="isDisabled()"
-      :filterOption="filterProject"
-      @change="changeProject"
-      showSearch>
-      <a-select-option v-for="(project, index) in projects" :key="index">
-        {{ project.displaytext || project.name }}
-      </a-select-option>
-    </a-select>
-  </span>
+  <a-popover
+    class="project"
+    v-model="visible"
+    trigger="click"
+    placement="bottom"
+    :autoAdjustOverflow="true"
+    :arrowPointAtCenter="true">
+    <template slot="content">
+      <a-menu style="margin: -12px -16px">
+        <a-menu-item>
+          <a-icon class="project-icon" type="login" />
+          <a-select
+            class="project-select"
+            size="default"
+            defaultValue="Default View"
+            :value="selectedProject"
+            :disabled="isDisabled()"
+            :filterOption="filterProject"
+            @change="changeProject"
+            showSearch>
+            <a-select-option v-for="(project, index) in projects" :key="index">
+              {{ project.displaytext || project.name }}
+            </a-select-option>
+          </a-select>
+        </a-menu-item>
+        <a-menu-item>
+          <router-link :to="{ path: '/project' }">
+            <a-icon class="project-icon" type="project" />
+            {{ $t('Projects') }}
+          </router-link>
+        </a-menu-item>
+      </a-menu>
+    </template>
+    <span @click="visible = !visible" class="header-notice-opener">
+      <a-icon class="project-icon" type="project" />
+    </span>
+  </a-popover>
 </template>
 
 <script>
@@ -43,6 +65,7 @@ export default {
   name: 'ProjectMenu',
   data () {
     return {
+      visible: false,
       projects: [],
       selectedProject: 'Default View'
     }
@@ -105,9 +128,16 @@ export default {
 </script>
 
 <style lang="less" scoped>
-.project-wrapper {
+.project {
   &-select {
-    width: 165px;
+    width: 200px;
+  }
+
+  &-icon {
+    font-size: 20px;
+    line-height: 1;
+    padding-top: 5px;
+    padding-right: 5px;
   }
 }
 </style>
diff --git a/src/components/header/UserMenu.vue 
b/src/components/header/UserMenu.vue
index 0279934..f16482c 100644
--- a/src/components/header/UserMenu.vue
+++ b/src/components/header/UserMenu.vue
@@ -18,6 +18,7 @@
 <template>
   <div class="user-menu">
 
+    <project-menu class="action"/>
     <translation-menu class="action"/>
     <header-notice class="action"/>
     <a-dropdown>
@@ -59,12 +60,14 @@
 <script>
 import config from '@/config/settings'
 import HeaderNotice from './HeaderNotice'
+import ProjectMenu from './ProjectMenu'
 import TranslationMenu from './TranslationMenu'
 import { mapActions, mapGetters } from 'vuex'
 
 export default {
   name: 'UserMenu',
   components: {
+    ProjectMenu,
     TranslationMenu,
     HeaderNotice
   },
diff --git a/src/components/view/DetailSettings.vue 
b/src/components/view/DetailSettings.vue
new file mode 100644
index 0000000..c6adafb
--- /dev/null
+++ b/src/components/view/DetailSettings.vue
@@ -0,0 +1,203 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you 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.
+
+<template>
+  <a-spin :spinning="loading">
+    <div v-show="!showAddDetail">
+      <a-button type="dashed" style="width: 100%" icon="plus" 
@click="showAddDetail = true">Add Setting</a-button>
+    </div>
+    <div v-show="showAddDetail">
+      <a-auto-complete
+        style="width: 100%"
+        :value="newKey"
+        :dataSource="Object.keys(detailOptions)"
+        placeholder="Name"
+        @change="e => onAddInputChange(e, 'newKey')" />
+      <a-auto-complete
+        style="width: 100%"
+        :value="newValue"
+        :dataSource="detailOptions[newKey]"
+        placeholder="Value"
+        @change="e => onAddInputChange(e, 'newValue')" />
+      <a-button type="dashed" style="width: 50%" icon="close" 
@click="showAddDetail = false">Cancel</a-button>
+      <a-button type="primary" style="width: 50%" icon="plus" 
@click="addDetail">Add Setting</a-button>
+    </div>
+    <a-list size="large">
+      <a-list-item :key="index" v-for="(item, index) in details">
+        <a-list-item-meta>
+          <span slot="title">{{ item.name }}</span>
+          <span slot="description" style="word-break: break-all">
+            <span v-if="item.edit" style="display: flex">
+              <a-auto-complete
+                style="width: 100%"
+                :value="item.value"
+                :dataSource="detailOptions[item.name]"
+                @change="val => handleInputChange(val, index)"
+                @pressEnter="e => updateDetail(index)" />
+              <a-button shape="circle" size="small" 
@click="updateDetail(index)" style="margin: 2px">
+                <a-icon type="check-circle" theme="twoTone" 
twoToneColor="#52c41a" style="font-size: 24px"/>
+              </a-button>
+              <a-button shape="circle" size="small" 
@click="hideEditDetail(index)" style="margin: 2px">
+                <a-icon type="close-circle" theme="twoTone" 
twoToneColor="#eb2f96" style="font-size: 24px"/>
+              </a-button>
+            </span>
+            <span v-else>{{ item.value }}</span>
+          </span>
+        </a-list-item-meta>
+        <div slot="actions">
+          <a-button shape="circle" @click="showEditDetail(index)">
+            <a-icon type="edit" />
+          </a-button>
+        </div>
+        <div slot="actions">
+          <a-popconfirm
+            title="Delete setting?"
+            @confirm="deleteDetail(index)"
+            okText="Yes"
+            cancelText="No"
+            placement="left"
+          >
+            <a-button shape="circle">
+              <a-icon type="delete" theme="twoTone" twoToneColor="#f5222d" />
+            </a-button>
+          </a-popconfirm>
+        </div>
+      </a-list-item>
+    </a-list>
+  </a-spin>
+</template>
+
+<script>
+import { api } from '@/api'
+
+export default {
+  name: 'DetailSettings',
+  props: {
+    resource: {
+      type: Object,
+      required: true
+    }
+  },
+  data () {
+    return {
+      details: [],
+      detailOptions: {},
+      showAddDetail: false,
+      newKey: '',
+      newValue: '',
+      loading: false,
+      resourceType: 'UserVm'
+    }
+  },
+  watch: {
+    resource: function (newItem, oldItem) {
+      this.updateResource(newItem)
+    }
+  },
+  mounted () {
+    this.updateResource(this.resource)
+  },
+  methods: {
+    updateResource (resource) {
+      if (!resource) {
+        return
+      }
+      this.resource = resource
+      this.resourceType = this.$route.meta.resourceType
+      if (!resource.details) {
+        return
+      }
+      this.details = Object.keys(this.resource.details).map(k => {
+        return { name: k, value: this.resource.details[k], edit: false }
+      })
+      api('listDetailOptions', { resourcetype: this.resourceType, resourceid: 
this.resource.id }).then(json => {
+        this.detailOptions = 
json.listdetailoptionsresponse.detailoptions.details
+      })
+    },
+    showEditDetail (index) {
+      this.details[index].edit = true
+      this.details[index].originalValue = this.details[index].value
+      this.$set(this.details, index, this.details[index])
+    },
+    hideEditDetail (index) {
+      this.details[index].edit = false
+      this.details[index].value = this.details[index].originalValue
+      this.$set(this.details, index, this.details[index])
+    },
+    handleInputChange (val, index) {
+      this.details[index].value = val
+      this.$set(this.details, index, this.details[index])
+    },
+    onAddInputChange (val, obj) {
+      this[obj] = val
+    },
+    runApi () {
+      var apiName = ''
+      if (this.resourceType === 'UserVm') {
+        apiName = 'updateVirtualMachine'
+      } else if (this.resourceType === 'Template') {
+        apiName = 'updateTemplate'
+      }
+      if (!(apiName in this.$store.getters.apis)) {
+        this.$notification.error({
+          message: 'Failed to execute API: ' + apiName,
+          description: 'User is not permitted to use the API'
+        })
+        return
+      }
+
+      const params = { id: this.resource.id }
+      this.details.forEach(function (item, index) {
+        params['details[0].' + item.name] = item.value
+      })
+      this.loading = true
+      api(apiName, params).then(json => {
+        var details = {}
+        if (this.resourceType === 'UserVm') {
+          details = json.updatevirtualmachineresponse.virtualmachine.details
+        } else if (this.resourceType === 'Template') {
+          details = json.updatetemplateresponse.template.details
+        }
+        this.details = Object.keys(details).map(k => {
+          return { name: k, value: details[k], edit: false }
+        })
+      }).catch(error => {
+        this.$notification.error({
+          message: 'Failed to add setting',
+          description: error.response.headers['x-description']
+        })
+      }).finally(f => {
+        this.loading = false
+        this.showAddDetail = false
+        this.newKey = ''
+        this.newValue = ''
+      })
+    },
+    addDetail () {
+      this.details.push({ name: this.newKey, value: this.newValue })
+      this.runApi()
+    },
+    updateDetail (index) {
+      this.runApi()
+    },
+    deleteDetail (index) {
+      this.details.splice(index, 1)
+      this.runApi()
+    }
+  }
+}
+</script>
diff --git a/src/components/view/FormView.vue b/src/components/view/FormView.vue
index 1736e67..ef4e5a9 100644
--- a/src/components/view/FormView.vue
+++ b/src/components/view/FormView.vue
@@ -68,7 +68,15 @@
               :placeholder="field.description"
             />
           </span>
-          <span v-else>
+          <span v-else-if="field.name==='password'">
+            <a-input-password
+              v-decorator="[field.name, {
+                rules: [{ required: field.required, message: 'Please enter 
input' }]
+              }]"
+              :placeholder="field.description"
+            />
+          </span>
+          <span v-else">
             <a-input
               v-decorator="[field.name, {
                 rules: [{ required: field.required, message: 'Please enter 
input' }]
diff --git a/src/components/view/InfoCard.vue b/src/components/view/InfoCard.vue
index 8fde8d9..6d7438a 100644
--- a/src/components/view/InfoCard.vue
+++ b/src/components/view/InfoCard.vue
@@ -72,13 +72,6 @@
           <os-logo :osId="resource.ostypeid" :osName="resource.ostypename" 
size="lg" style="margin-left: -1px" />
           <span style="margin-left: 8px">{{ resource.ostypename }}</span>
         </div>
-        <div class="resource-detail-item" v-if="resource.keypair">
-          <a-icon type="key" />
-          <router-link :to="{ path: '/ssh/' + resource.keypair }">{{ 
resource.keypair }}</router-link>
-        </div>
-        <div class="resource-detail-item" v-if="resource.group">
-          <a-icon type="gold" />{{ resource.group }}
-        </div>
         <div class="resource-detail-item" v-if="(resource.cpunumber && 
resource.cpuspeed) || resource.cputotal">
           <a-icon type="appstore" />
           <span v-if="resource.cpunumber && resource.cpuspeed">{{ 
resource.cpunumber }} CPU x {{ parseFloat(resource.cpuspeed / 
1000.0).toFixed(2) }} Ghz</span>
@@ -218,6 +211,15 @@
           </slot>
         </div>
 
+        <div class="resource-detail-item" v-if="resource.groupid">
+          <a-icon type="gold" />
+          <router-link :to="{ path: '/vmgroup/' + resource.groupid }">{{ 
resource.group || resource.groupid }}</router-link>
+        </div>
+        <div class="resource-detail-item" v-if="resource.keypair">
+          <a-icon type="key" />
+          <router-link :to="{ path: '/ssh/' + resource.keypair }">{{ 
resource.keypair }}</router-link>
+        </div>
+
         <div class="resource-detail-item" v-if="resource.virtualmachineid">
           <a-icon type="desktop" />
           <router-link :to="{ path: '/vm/' + resource.virtualmachineid }">{{ 
resource.vmname || resource.vm || resource.virtualmachinename || 
resource.virtualmachineid }} </router-link>
diff --git a/src/components/view/ListView.vue b/src/components/view/ListView.vue
index a4b07a1..cccbccc 100644
--- a/src/components/view/ListView.vue
+++ b/src/components/view/ListView.vue
@@ -34,6 +34,9 @@
     </template>
 
     <a slot="name" slot-scope="text, record" href="javascript:;" 
style="display: inline-flex">
+      <span v-if="$route.path.startsWith('/project')" style="margin-right: 
5px">
+        <a-button type="dashed" size="small" shape="circle" icon="login" 
@click="changeProject(record)" />
+      </span>
       <console :resource="record" size="small" />
       <router-link :to="{ path: $route.path + '/' + record.id }" 
v-if="record.id">{{ text }}</router-link>
       <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ 
text }}</router-link>
@@ -129,6 +132,12 @@ export default {
     onSelectChange (selectedRowKeys) {
       console.log('selectedRowKeys changed: ', selectedRowKeys)
       this.selectedRowKeys = selectedRowKeys
+    },
+    changeProject (project) {
+      this.$store.dispatch('SetProject', project)
+      this.$store.dispatch('ToggleTheme', project.id === undefined ? 'light' : 
'dark')
+      this.$message.success(`Switched to "${project.name}"`)
+      this.$router.push({ name: 'dashboard' })
     }
   }
 }
diff --git a/src/components/view/SettingTable.vue 
b/src/components/view/SettingTable.vue
deleted file mode 100644
index 315c889..0000000
--- a/src/components/view/SettingTable.vue
+++ /dev/null
@@ -1,68 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-<template>
-  <div>
-    <a-button type="dashed" style="width: 100%" icon="plus" 
@click="addSettingForm()">Add Setting</a-button>
-    <a-list size="large">
-      <a-list-item :key="index" v-for="(item, index) in items">
-        <a-list-item-meta>
-          <span slot="title">{{ item.name }}</span>
-          <span slot="description" style="word-break: break-all">{{ item.value 
}}</span>
-        </a-list-item-meta>
-        <div slot="actions">
-          <a-button size="small" shape="circle">
-            <a-icon type="edit" />
-          </a-button>
-        </div>
-        <div slot="actions">
-          <a-button size="small" shape="circle">
-            <a-icon type="close" />
-          </a-button>
-        </div>
-      </a-list-item>
-    </a-list>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'SettingTable',
-  props: {
-    items: {
-      type: Array,
-      required: true
-    },
-    loading: {
-      type: Boolean,
-      default: false
-    }
-  },
-  data () {
-    return {
-    }
-  },
-  methods: {
-    addSettingForm () {
-      console.log('Add setting button clicked')
-    }
-  }
-}
-</script>
-
-<style scoped>
-</style>
diff --git a/src/config/router.js b/src/config/router.js
index 54038cf..ffd2fd5 100644
--- a/src/config/router.js
+++ b/src/config/router.js
@@ -24,7 +24,7 @@ import storage from '@/config/section/storage'
 import network from '@/config/section/network'
 import image from '@/config/section/image'
 import project from '@/config/section/project'
-import monitor from '@/config/section/monitor'
+import event from '@/config/section/event'
 import iam from '@/config/section/iam'
 import infra from '@/config/section/infra'
 import offering from '@/config/section/offering'
@@ -35,6 +35,7 @@ export function generateRouterMap (section) {
   var map = {
     name: section.name,
     path: '/' + section.name,
+    hidden: section.hidden,
     meta: { title: section.title, keepAlive: true, icon: section.icon },
     component: RouteView
   }
@@ -167,7 +168,7 @@ export const asyncRouterMap = [
       generateRouterMap(network),
       generateRouterMap(image),
       generateRouterMap(project),
-      generateRouterMap(monitor),
+      generateRouterMap(event),
       generateRouterMap(iam),
       generateRouterMap(infra),
       generateRouterMap(offering),
diff --git a/src/config/section/compute.js b/src/config/section/compute.js
index dfdf56a..f26f371 100644
--- a/src/config/section/compute.js
+++ b/src/config/section/compute.js
@@ -55,7 +55,7 @@ export default {
         component: () => import('@/views/compute/InstanceHardware.vue')
       }, {
         name: 'settings',
-        component: () => import('@/views/compute/InstanceSettings.vue')
+        component: () => import('@/components/view/DetailSettings')
       }],
       actions: [
         {
@@ -232,6 +232,42 @@ export default {
     },
     */
     {
+      name: 'vmgroup',
+      title: 'Instance Groups',
+      icon: 'gold',
+      permission: ['listInstanceGroups'],
+      columns: ['name', 'account', 'domain'],
+      details: ['name', 'id', 'account', 'domain', 'created'],
+      related: [{
+        name: 'vm',
+        title: 'Instances',
+        param: 'groupid'
+      }],
+      actions: [
+        {
+          api: 'createInstanceGroup',
+          icon: 'plus',
+          label: 'New Instance Group',
+          listView: true,
+          args: ['name']
+        },
+        {
+          api: 'updateInstanceGroup',
+          icon: 'edit',
+          label: 'Update Instance Group',
+          dataView: true,
+          args: ['name']
+        },
+        {
+          api: 'deleteInstanceGroup',
+          icon: 'delete',
+          label: 'Delete Instance Group',
+          dataView: true,
+          args: ['id']
+        }
+      ]
+    },
+    {
       name: 'ssh',
       title: 'SSH Key Pairs',
       icon: 'key',
diff --git a/src/views/compute/InstanceSettings.vue 
b/src/config/section/event.js
similarity index 56%
rename from src/views/compute/InstanceSettings.vue
rename to src/config/section/event.js
index 9587e3a..0e15e2b 100644
--- a/src/views/compute/InstanceSettings.vue
+++ b/src/config/section/event.js
@@ -15,33 +15,32 @@
 // specific language governing permissions and limitations
 // under the License.
 
-<template>
-  <div>
-    <setting-table
-      :loading="loading"
-      :items="Object.keys(resource.details).map(k => { return { name: k, 
value: resource.details[k] } })"
-    >
-    </setting-table>
-  </div>
-</template>
-
-<script>
-import SettingTable from '@/components/view/SettingTable'
-
 export default {
-  name: 'SettingsTab',
-  components: {
-    SettingTable
-  },
-  props: {
-    resource: {
-      type: Object,
-      required: true
+  name: 'event',
+  title: 'Events',
+  icon: 'schedule',
+  permission: ['listEvents'],
+  columns: ['username', 'description', 'state', 'level', 'type', 'account', 
'domain', 'created'],
+  details: ['username', 'id', 'description', 'state', 'level', 'type', 
'account', 'domain', 'created'],
+  related: [{
+    name: 'event',
+    title: 'Event Timeline',
+    param: 'startid'
+  }],
+  actions: [
+    {
+      api: 'archiveEvents',
+      icon: 'book',
+      label: 'Archive Event',
+      dataView: true,
+      args: ['ids']
     },
-    loading: {
-      type: Boolean,
-      default: false
+    {
+      api: 'deleteEvents',
+      icon: 'delete',
+      label: 'Delete Event',
+      dataView: true,
+      args: ['ids']
     }
-  }
+  ]
 }
-</script>
diff --git a/src/config/section/iam.js b/src/config/section/iam.js
index 07946ea..2792080 100644
--- a/src/config/section/iam.js
+++ b/src/config/section/iam.js
@@ -48,7 +48,7 @@ export default {
           icon: 'key',
           label: 'Change Password',
           dataView: true,
-          args: ['id', 'password', 'password']
+          args: ['id', 'currentpassword', 'password']
         },
         {
           api: 'registerUserKeys',
diff --git a/src/config/section/image.js b/src/config/section/image.js
index f6e164c..04fec8b 100644
--- a/src/config/section/image.js
+++ b/src/config/section/image.js
@@ -42,7 +42,7 @@ export default {
         component: () => import('@/views/image/TemplateZones.vue')
       }, {
         name: 'settings',
-        component: () => import('@/views/image/TemplateSettings.vue')
+        component: () => import('@/components/view/DetailSettings')
       }],
       actions: [
         {
diff --git a/src/config/section/infra.js b/src/config/section/infra.js
index b874640..7ffbdde 100644
--- a/src/config/section/infra.js
+++ b/src/config/section/infra.js
@@ -59,6 +59,30 @@ export default {
       icon: 'rocket',
       permission: ['listManagementServers'],
       columns: ['name', 'state', 'version']
+    },
+    {
+      name: 'alert',
+      title: 'Alerts',
+      icon: 'flag',
+      permission: ['listAlerts'],
+      columns: ['name', 'description', 'type', 'sent'],
+      details: ['name', 'id', 'type', 'sent', 'description'],
+      actions: [
+        {
+          api: 'archiveAlerts',
+          icon: 'book',
+          label: 'Archive Alert',
+          dataView: true,
+          args: ['ids']
+        },
+        {
+          api: 'deleteAlerts',
+          icon: 'delete',
+          label: 'Delete Alert',
+          dataView: true,
+          args: ['ids']
+        }
+      ]
     }
   ]
 }
diff --git a/src/config/section/monitor.js b/src/config/section/monitor.js
deleted file mode 100644
index aa6419c..0000000
--- a/src/config/section/monitor.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-export default {
-  name: 'monitor',
-  title: 'Monitor',
-  icon: 'compass',
-  permission: ['listEvents', 'listAlerts'],
-  children: [
-    {
-      name: 'event',
-      title: 'Events',
-      icon: 'schedule',
-      permission: ['listEvents'],
-      columns: ['username', 'description', 'state', 'level', 'type', 
'account', 'domain', 'created'],
-      details: ['username', 'id', 'description', 'state', 'level', 'type', 
'account', 'domain', 'created'],
-      related: [{
-        name: 'event',
-        title: 'Event Timeline',
-        param: 'startid'
-      }],
-      actions: [
-        {
-          api: 'archiveEvents',
-          icon: 'book',
-          label: 'Archive Event',
-          dataView: true,
-          args: ['ids']
-        },
-        {
-          api: 'deleteEvents',
-          icon: 'delete',
-          label: 'Delete Event',
-          dataView: true,
-          args: ['ids']
-        }
-      ]
-    },
-    {
-      name: 'alert',
-      title: 'Alerts',
-      icon: 'flag',
-      permission: ['listAlerts'],
-      columns: ['name', 'description', 'type', 'sent'],
-      details: ['name', 'id', 'type', 'sent', 'description'],
-      actions: [
-        {
-          api: 'archiveAlerts',
-          icon: 'book',
-          label: 'Archive Alert',
-          dataView: true,
-          args: ['ids']
-        },
-        {
-          api: 'deleteAlerts',
-          icon: 'delete',
-          label: 'Delete Alert',
-          dataView: true,
-          args: ['ids']
-        }
-      ]
-    }
-  ]
-}
diff --git a/src/views/AutogenView.vue b/src/views/AutogenView.vue
index c283562..a06bb5c 100644
--- a/src/views/AutogenView.vue
+++ b/src/views/AutogenView.vue
@@ -101,7 +101,6 @@
           v-if="!dataView"
           @search="onSearch"
         >
-          <a-icon slot="prefix" type="search" />
         </a-input-search>
       </a-col>
     </a-row>
@@ -174,6 +173,14 @@
                   :placeholder="field.description"
                 />
               </span>
+              <span v-else-if="field.name==='password' || 
field.name==='currentpassword'">
+                <a-input-password
+                  v-decorator="[field.name, {
+                    rules: [{ required: field.required, message: 'Please enter 
input' }]
+                  }]"
+                  :placeholder="field.description"
+                />
+              </span>
               <span v-else>
                 <a-input
                   v-decorator="[field.name, {
diff --git a/src/views/auth/Login.vue b/src/views/auth/Login.vue
index 00adfbc..144a6f6 100644
--- a/src/views/auth/Login.vue
+++ b/src/views/auth/Login.vue
@@ -49,7 +49,7 @@
         </a-form-item>
 
         <a-form-item>
-          <a-input
+          <a-input-password
             size="large"
             type="password"
             autocomplete="false"
@@ -60,7 +60,7 @@
             ]"
           >
             <a-icon slot="prefix" type="lock" :style="{ color: 
'rgba(0,0,0,.25)' }"/>
-          </a-input>
+          </a-input-password>
         </a-form-item>
 
         <a-form-item>
diff --git a/src/views/image/TemplateSettings.vue 
b/src/views/image/TemplateSettings.vue
deleted file mode 100644
index 1790a84..0000000
--- a/src/views/image/TemplateSettings.vue
+++ /dev/null
@@ -1,60 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you 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.
-
-<template>
-  <div>
-    <a-button style="margin-bottom: 15px; float: right">
-      Add Setting
-    </a-button>
-    <setting-table
-      :columns="[{
-        title: $t('name'),
-        dataIndex: 'name',
-        width: '40%'
-      },{
-        title: $t('value'),
-        dataIndex: 'value',
-        width: '40%',
-        scopedSlots: { customRender: 'value' }
-      }]"
-      :items="Object.keys(resource.details).map(k => { return { name: k, 
value: resource.details[k] } })"
-      :loading="loading"
-    >
-    </setting-table>
-  </div>
-</template>
-
-<script>
-import SettingTable from '@/components/view/SettingTable'
-
-export default {
-  name: 'SettingsTab',
-  components: {
-    SettingTable
-  },
-  props: {
-    resource: {
-      type: Object,
-      required: true
-    },
-    loading: {
-      type: Boolean,
-      default: false
-    }
-  }
-}
-</script>
diff --git a/src/views/infra/InfraSummary.vue b/src/views/infra/InfraSummary.vue
index 0000330..d918b2a 100644
--- a/src/views/infra/InfraSummary.vue
+++ b/src/views/infra/InfraSummary.vue
@@ -25,16 +25,11 @@
       :key="index">
       <chart-card :loading="loading">
         <div class="chart-card-inner">
-          <h2>{{ $t(routes[section].title) }}</h2>
-          <h1><a-icon :type="routes[section].icon" /> {{ stats[section] }}</h1>
+          <router-link :to="{ name: section.substring(0, section.length - 1) 
}">
+            <h2>{{ $t(routes[section].title) }}</h2>
+            <h1><a-icon :type="routes[section].icon" /> {{ stats[section] 
}}</h1>
+          </router-link>
         </div>
-        <template slot="footer">
-          <center>
-            <router-link :to="{ name: section.substring(0, section.length - 1) 
}">
-              <a-button style="margin-bottom: 3px">View {{ 
$t(routes[section].title) }}</a-button>
-            </router-link>
-          </center>
-        </template>
       </chart-card>
     </a-col>
     <!-- move refresh and ssl cert setup somewhere more friendly -->
@@ -43,17 +38,18 @@
       :style="{ marginBottom: '12px', marginTop: '12px' }">
       <a-card>
         <a-button
-          style="margin-right: 20px"
-          icon="safety-certificate">
-          {{ $t('SSL Certificate') }}
-        </a-button>
-        <a-button
+          style="width: 100%"
+          icon="reload"
           @click="fetchData()"
           :loading="loading"
-          type="primary"
-          icon="reload">
+          type="primary">
           {{ $t('Refresh') }}
         </a-button>
+        <a-button
+          style="width: 100%"
+          icon="safety-certificate">
+          {{ $t('SSL Certificate') }}
+        </a-button>
       </a-card>
     </a-col>
   </a-row>
@@ -73,7 +69,7 @@ export default {
   data () {
     return {
       loading: true,
-      sections: ['zones', 'pods', 'clusters', 'hosts', 'storagepools', 
'imagestores', 'systemvms', 'routers', 'cpusockets', 'managementservers'],
+      sections: ['zones', 'pods', 'clusters', 'hosts', 'storagepools', 
'imagestores', 'systemvms', 'routers', 'cpusockets', 'managementservers', 
'alerts'],
       routes: {},
       stats: {}
     }

Reply via email to