瀏覽代碼

HUE-1368 [pig] Prettify main layout

Added unsaved notification on name and properties change
Simplified titles and gave access to run/stop from title bar
Subtle unsaved border on the editor menu
Enrico Berti 12 年之前
父節點
當前提交
f509c90

+ 90 - 63
apps/pig/src/pig/templates/app.mako

@@ -25,7 +25,7 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
 <div class="subnav subnav-fixed">
   <div class="container-fluid">
     <ul class="nav nav nav-pills">
-      <li class="active"><a href="#editor">${ _('Editor') }</a></li>
+      <li class="active"><a href="#editor" data-bind="css: { unsaved: isDirty }">${ _('Editor') }</a></li>
       <li><a href="#scripts">${ _('Scripts') }</a></li>
       <li><a href="#dashboard">${ _('Dashboard') }</a></li>
     </ul>
@@ -99,7 +99,6 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
   <div id="editor" class="row-fluid mainSection hide">
     <div class="span2">
       <div class="well sidebar-nav">
-        <form id="advancedSettingsForm" method="POST" class="form form-horizontal noPadding">
           <ul class="nav nav-list">
             <li class="nav-header">${_('Editor')}</li>
             <li data-bind="click: editScript" class="active" data-section="edit">
@@ -113,25 +112,20 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
                 <i class="icon-save"></i> ${ _('Save') }
               </a>
             </li>
+            ##<li class="nav-header">${_('UDF')}</li>
+            ##<li><a href="#createDataset">${ _('Python') }</a></li>
+            ##<li><a href="#createDataset">${ _('Ruby') }</a></li>
+            <li class="nav-header">${_('Actions')}</li>
             <li data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()">
               <a href="#" title="${ _('Run the script') }" rel="tooltip" data-placement="right">
                 <i class="icon-play"></i> ${ _('Run') }
               </a>
             </li>
             <li data-bind="click: showStopModal, visible: currentScript().isRunning()">
-              <a href="#" title="${ _('Run the script') }" rel="tooltip" data-placement="right" class="disabled">
+              <a href="#" title="${ _('Stop the script') }" rel="tooltip" data-placement="right" class="disabled">
                 <i class="icon-ban-circle"></i> ${ _('Stop') }
               </a>
             </li>
-            ##<li class="nav-header">${_('UDF')}</li>
-            ##<li><a href="#createDataset">${ _('Python') }</a></li>
-            ##<li><a href="#createDataset">${ _('Ruby') }</a></li>
-            <li class="nav-header">${_('Actions')}</li>
-            <li data-bind="click: confirmNewScript">
-              <a href="#" title="${ _('New script') }" rel="tooltip" data-placement="right">
-                <i class="icon-plus-sign"></i> ${ _('New script') }
-              </a>
-            </li>
             <li data-bind="visible: currentScript().id() != -1, click: copyScript">
               <a href="#" title="${ _('Copy the script') }" rel="tooltip" data-placement="right">
                 <i class="icon-copy"></i> ${ _('Copy') }
@@ -142,6 +136,11 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
                 <i class="icon-trash"></i> ${ _('Delete') }
               </a>
             </li>
+            <li data-bind="click: confirmNewScript">
+              <a href="#" title="${ _('New script') }" rel="tooltip" data-placement="right">
+                <i class="icon-plus-sign"></i> ${ _('New script') }
+              </a>
+            </li>
             <li class="nav-header">${_('Logs')}</li>
             <li data-bind="click: showScriptLogs" data-section="logs">
               <a href="#" title="${ _('Show Logs') }" rel="tooltip" data-placement="right">
@@ -159,7 +158,6 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
             </div>
             </li>
           </ul>
-        </form>
       </div>
     </div>
 
@@ -169,37 +167,51 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
       </div>
 
       <div id="edit" class="section">
-        <div class="alert alert-info"><h3>${ _('Edit') } '<span data-bind="text: currentScript().name"></span>'</h3></div>
+        <div class="alert alert-info">
+          <a class="mainAction" href="#" title="${ _('Run this script') }" data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()"><i class="icon-play"></i></a>
+          <a class="mainAction" href="#" title="${ _('Stop this script') }" data-bind="click: showStopModal, visible: currentScript().isRunning()"><i class="icon-stop"></i></a>
+          <h3><span data-bind="text: currentScript().name"></span></h3>
+        </div>
         <form id="queryForm">
           <textarea id="scriptEditor" data-bind="text:currentScript().script"></textarea>
         </form>
       </div>
 
       <div id="properties" class="section hide">
-        <div class="alert alert-info"><h3>${ _('Edit properties for') } '<span data-bind="text: currentScript().name"></span>'</h3></div>
-         <form class="form-inline" style="padding-left: 10px">
+        <div class="alert alert-info">
+          <a class="mainAction" href="#" title="${ _('Run this script') }" data-bind="click: runOrShowSubmissionModal, visible: !currentScript().isRunning()"><i class="icon-play"></i></a>
+          <a class="mainAction" href="#" title="${ _('Stop this script') }" data-bind="click: showStopModal, visible: currentScript().isRunning()"><i class="icon-stop"></i></a>
+          <h3><span data-bind="text: currentScript().name"></span></h3>
+        </div>
+        <form class="form-inline" style="padding-left: 10px">
           <label>
             ${ _('Script name') } &nbsp;
-            <input type="text" id="scriptName" class="input-xlarge" data-bind="value: currentScript().name" />
+            <input type="text" id="scriptName" class="input-xlarge" data-bind="value: currentScript().name, valueUpdate:'afterkeydown'" />
           </label>
 
           <br/>
           <br/>
 
-          <label>${ _('Parameters') } &nbsp; <i id="parameters-dyk" class="icon-question-sign"></i>
-            <div id="parameters-dyk-content" class="hide">
-              <ul style="text-align: left;">
-                <li>input /user/data</li>
-                <li>-param input=/user/data</li>
-                <li>-optimizer_off SplitFilter</li>
-                <li>-verbose</li>
-              </ul>
-            </div>
-            <button class="btn" data-bind="click: currentScript().addParameter, visible: currentScript().parameters().length == 0" style="margin-left: 4px">
-              <i class="icon-plus"></i> ${ _('Add') }
-            </button>
-          </label>
-          <div>
+          <h4>${ _('Parameters') } &nbsp; <i id="parameters-dyk" class="icon-question-sign"></i></h4>
+          <div id="parameters-dyk-content" class="hide">
+            <ul style="text-align: left;">
+              <li>input /user/data</li>
+              <li>-param input=/user/data</li>
+              <li>-optimizer_off SplitFilter</li>
+              <li>-verbose</li>
+            </ul>
+          </div>
+          <div class="parameterTableCnt">
+            <table class="parameterTable" data-bind="visible: currentScript().parameters().length == 0">
+              <tr>
+                <td>
+                  ${ _('There are currently no defined parameters.') }
+                  <button class="btn" data-bind="click: currentScript().addParameter" style="margin-left: 4px">
+                    <i class="icon-plus"></i> ${ _('Add') }
+                  </button>
+                </td>
+              </tr>
+            </table>
             <table data-bind="css: {'parameterTable': currentScript().parameters().length > 0}">
               <thead data-bind="visible: currentScript().parameters().length > 0">
                 <tr>
@@ -212,8 +224,10 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
                 <tr>
                   <td><input type="text" data-bind="value: name" class="input-xlarge" /></td>
                   <td>
-                    <input type="text" data-bind="value: value" class="input-xxlarge" />
-                    <button class="btn fileChooserBtn" data-bind="click: $root.showFileChooser">..</button>
+                    <div class="input-append">
+                      <input type="text" data-bind="value: value" class="input-xxlarge" />
+                      <button class="btn fileChooserBtn" data-bind="click: $root.showFileChooser">..</button>
+                    </div>
                   </td>
                   <td><button data-bind="click: viewModel.currentScript().removeParameter" class="btn"><i class="icon-trash"></i> ${ _('Remove') }</button></td>
                 </tr>
@@ -229,19 +243,24 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
           </div>
 
           <br/>
-
-          <label>${ _('Hadoop properties') } &nbsp; <i id="properties-dyk" class="icon-question-sign"></i>
-            <div id="properties-dyk-content" class="hide">
-              <ul style="text-align: left; word-wrap:break-word">
-                <li>mapred.job.queue.name production</li>
-                <li>mapred.map.tasks.speculative.execution false</li>
-              </ul>
-            </div>
-            <button class="btn" data-bind="click: currentScript().addHadoopProperties, visible: currentScript().hadoopProperties().length == 0" style="margin-left: 4px">
-              <i class="icon-plus"></i> ${ _('Add') }
-            </button>
-          </label>
-          <div>
+          <h4>${ _('Hadoop properties') } &nbsp; <i id="properties-dyk" class="icon-question-sign"></i></h4>
+          <div id="properties-dyk-content" class="hide">
+            <ul style="text-align: left; word-wrap:break-word">
+              <li>mapred.job.queue.name production</li>
+              <li>mapred.map.tasks.speculative.execution false</li>
+            </ul>
+          </div>
+          <div class="parameterTableCnt">
+            <table class="parameterTable" data-bind="visible: currentScript().hadoopProperties().length == 0">
+              <tr>
+                <td>
+                  ${ _('There are currently no defined Hadoop properties.') }
+                  <button class="btn" data-bind="click: currentScript().addHadoopProperties" style="margin-left: 4px">
+                    <i class="icon-plus"></i> ${ _('Add') }
+                  </button>
+                </td>
+              </tr>
+            </table>
             <table data-bind="css: {'parameterTable': currentScript().hadoopProperties().length > 0}">
               <thead data-bind="visible: currentScript().hadoopProperties().length > 0">
                 <tr>
@@ -254,8 +273,10 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
                 <tr>
                   <td><input type="text" data-bind="value: name" class="input-xlarge" /></td>
                   <td>
-                    <input type="text" data-bind="value: value" class="input-xxlarge" />
-                    <button class="btn fileChooserBtn" data-bind="click: $root.showFileChooser">..</button>
+                    <div class="input-append">
+                      <input type="text" data-bind="value: value" class="input-xxlarge" />
+                      <button class="btn fileChooserBtn" data-bind="click: $root.showFileChooser">..</button>
+                    </div>
                   </td>
                   <td><button data-bind="click: viewModel.currentScript().removeHadoopProperties" class="btn"><i class="icon-trash"></i> ${ _('Remove') }</button></td>
                 </tr>
@@ -272,17 +293,23 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
 
           <br/>
 
-          <label>${ _('Resources') } &nbsp; <i id="resources-dyk" class="icon-question-sign"></i>
-            <div id="resources-dyk-content" class="hide">
-              <ul style="text-align: left;">
-                <li>${ _("Path to a HDFS file or zip file to add to the workspace of the running script") }</li>
-              </ul>
-            </div>
-            <button class="btn" data-bind="click: currentScript().addResource, visible: currentScript().resources().length == 0" style="margin-left: 4px">
-              <i class="icon-plus"></i> ${ _('Add') }
-            </button>
-          </label>
-          <div>
+          <h4>${ _('Resources') } &nbsp; <i id="resources-dyk" class="icon-question-sign"></i></h4>
+          <div id="resources-dyk-content" class="hide">
+            <ul style="text-align: left;">
+              <li>${ _("Path to a HDFS file or zip file to add to the workspace of the running script") }</li>
+            </ul>
+          </div>
+          <div class="parameterTableCnt">
+            <table class="parameterTable" data-bind="visible: currentScript().resources().length == 0">
+              <tr>
+                <td>
+                  ${ _('There are currently no defined resources.') }
+                  <button class="btn" data-bind="click: currentScript().addResource" style="margin-left: 4px">
+                    <i class="icon-plus"></i> ${ _('Add') }
+                  </button>
+                </td>
+              </tr>
+            </table>
             <table data-bind="css: {'parameterTable': currentScript().resources().length > 0}">
               <thead data-bind="visible: currentScript().resources().length > 0">
                 <tr>
@@ -325,7 +352,7 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
       </div>
 
       <div id="logs" class="section hide">
-          <div class="alert alert-info"><h3>${ _('Logs for') } '<span data-bind="text: currentScript().name"></span>'</h3></div>
+          <div class="alert alert-info"><h3><span data-bind="text: currentScript().name"></span></h3></div>
           <div data-bind="template: {name: 'logTemplate', foreach: currentScript().actions}"></div>
           <script id="logTemplate" type="text/html">
             <div data-bind="css:{'alert-modified': name != '', 'alert': name != '', 'alert-success': status == 'SUCCEEDED' || status == 'OK', 'alert-error': status != 'RUNNING' && status != 'SUCCEEDED' && status != 'OK' && status != 'PREP' && status != 'SUSPENDED'}">
@@ -338,7 +365,7 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
               </div>
             </div>
           </script>
-          <pre id="withoutLogs" class="hide">${ _('No available logs.') } <img src="/static/art/spinner.gif"/></pre>
+          <pre id="withoutLogs">${ _('No available logs.') } <img src="/static/art/spinner.gif"/></pre>
           <pre id="withLogs" class="hide scroll"></pre>
         </div>
 
@@ -820,7 +847,7 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
     $(window).on("resize", function () {
       window.clearTimeout(_resizeTimeout);
       _resizeTimeout = window.setTimeout(function () {
-        codeMirror.setSize("100%", $(window).height() - 250);
+        codeMirror.setSize("100%", $(window).height() - 190);
       }, 100);
     });
 
@@ -900,7 +927,7 @@ ${ commonheader(None, "pig", user, "100px") | n,unicode }
     function showMainSection(mainSection, includeGA) {
       window.setTimeout(function () {
         codeMirror.refresh();
-        codeMirror.setSize("100%", $(window).height() - 250);
+        codeMirror.setSize("100%", $(window).height() - 190);
       }, 100);
 
       if ($("#" + mainSection).is(":hidden")) {

+ 37 - 2
apps/pig/static/css/pig.css

@@ -29,6 +29,7 @@
   width: 100%;
   text-align: center;
   display: none;
+  z-index: 1000;
 }
 
 #logs .alert-modified {
@@ -41,8 +42,8 @@
   border-color: #DDD;
 }
 
-.parameterTable {
-  background-color: #eeeeee;
+.parameterTableCnt {
+  background-color: #F5F5F5;
 }
 
 .parameterTable td {
@@ -67,4 +68,38 @@
 
 .widget-content {
   padding: 10px;
+}
+
+.editable {
+  cursor: pointer;
+}
+
+.editable-container h3 {
+  display: none;
+}
+
+#properties h4 {
+  color: #3A87AD;
+}
+
+.mainAction {
+  float: right;
+  font-size: 48px;
+  opacity: 0.4;
+  color: #338bb8;
+  cursor: pointer;
+  margin-top: 6px;
+}
+
+.mainAction i {
+  cursor: pointer;
+}
+
+.mainAction:hover {
+  opacity: 0.88;
+  text-decoration: none;
+}
+
+.unsaved {
+  border-bottom: 1px solid #C63D37;
 }

+ 23 - 2
apps/pig/static/js/pig.ko.js

@@ -58,9 +58,11 @@ var PigScript = function (pigScript) {
   });
   self.addParameter = function () {
     self.parameters.push(new PigParameter({name: '', value: ''}));
+    self.updateParentModel();
   };
   self.removeParameter = function () {
     self.parameters.remove(this);
+    self.updateParentModel();
   };
   self.getParameters = function () {
     var params = {};
@@ -83,9 +85,11 @@ var PigScript = function (pigScript) {
   });
   self.addHadoopProperties = function () {
     self.hadoopProperties.push(new HadoopProperty({name: '', value: ''}));
+    self.updateParentModel();
   };
   self.removeHadoopProperties = function () {
     self.hadoopProperties.remove(this);
+    self.updateParentModel();
   };
 
   self.resources = ko.observableArray([]);
@@ -94,10 +98,23 @@ var PigScript = function (pigScript) {
   });
   self.addResource = function () {
     self.resources.push(new Resource({type: 'file', value: ''}));
+    self.updateParentModel();
   };
   self.removeResource = function () {
     self.resources.remove(this);
+    self.updateParentModel();
   };
+
+  self.parentModel = pigScript.parentModel;
+  self.updateParentModel = function () {
+    if (typeof self.parentModel != "undefined" && self.parentModel != null) {
+      self.parentModel.isDirty(true);
+    }
+  }
+
+  self.name.subscribe(function (name) {
+    self.updateParentModel();
+  });
 }
 
 var Workflow = function (wf) {
@@ -158,7 +175,8 @@ var PigViewModel = function (props) {
     script: self.LABELS.NEW_SCRIPT_CONTENT,
     parameters: self.LABELS.NEW_SCRIPT_PARAMETERS,
     resources: self.LABELS.NEW_SCRIPT_RESOURCES,
-    hadoopProperties: self.LABELS.NEW_SCRIPT_HADOOP_PROPERTIES
+    hadoopProperties: self.LABELS.NEW_SCRIPT_HADOOP_PROPERTIES,
+    parentModel: self
   };
 
   self.currentScript = ko.observable(new PigScript(_defaultScript));
@@ -234,6 +252,7 @@ var PigViewModel = function (props) {
     $("#confirmModal").modal("hide");
     $(document).trigger("loadEditor");
     $(document).trigger("showEditor");
+    $(document).trigger("clearLogs");
   };
 
   self.editScript = function (script) {
@@ -274,7 +293,7 @@ var PigViewModel = function (props) {
     else {
       $("#nameModal").modal("hide");
       callSave(self.currentScript());
-      viewModel.isDirty(false);
+      self.isDirty(false);
     }
   };
 
@@ -326,6 +345,7 @@ var PigViewModel = function (props) {
   self.updateScripts = function () {
     $.getJSON(self.LIST_SCRIPTS, function (data) {
       self.scripts(ko.utils.arrayMap(data, function (script) {
+        script.parentModel = self;
         return new PigScript(script);
       }));
       self.filteredScripts(self.scripts());
@@ -501,6 +521,7 @@ var PigViewModel = function (props) {
           id: script.id()
         },
         function (data) {
+          data.parentModel = self;
           self.currentScript(new PigScript(data));
           $(document).trigger("loadEditor");
           self.updateScripts();

+ 1 - 1
desktop/core/src/desktop/templates/common_footer.html

@@ -140,7 +140,7 @@ limitations under the License.
       })();
 
       function trackOnGA(path) {
-        if (_gaq != undefined && _gaq != null){
+        if (typeof _gaq != "undefined" && _gaq != null){
           _gaq.push(['_trackPageview', '/remote/{{ version }}/' + path]);
         }
       }

+ 0 - 2
desktop/core/static/css/hue2.css

@@ -497,8 +497,6 @@ ul.errorlist li {
   position: fixed;
   top: 74px;
   right: -3px;
-  right: 20px\9; /* IE8 */
-  width: 125px\9; /* IE8 */
   z-index: 1001;
 }