[Bps-public-commit] rt-extension-lifecycleui branch, master, updated. fbe75c4506224d65d69b175d3ce1bd595fcdcd12

Shawn Moore shawn at bestpractical.com
Fri Sep 22 12:31:57 EDT 2017


The branch, master has been updated
       via  fbe75c4506224d65d69b175d3ce1bd595fcdcd12 (commit)
       via  1357eed198aa5ad3cf259da2bd0173375be61c7c (commit)
       via  d82527dd3e47b47d112333b68355b0948c9d948c (commit)
       via  bbb19fb136d0bffe19bea96a72288230bf07325c (commit)
       via  76f33941c26fd1cb9db1493766d81f04b7878f34 (commit)
       via  b17333184fe4c35b5c340b6f3d0ecd923a04bee9 (commit)
       via  39b64050f2d210abdf05d7ef75c1553b490ab9b7 (commit)
      from  ff59436438f799b87f03ecfaa8f971b92c107ee4 (commit)

Summary of changes:
 html/Elements/LifecycleInspectorCircle        | 79 +++++++++++++++------------
 html/Elements/LifecycleInspectorPolygon       | 14 ++++-
 html/Elements/LifecycleInspectorStatus        |  5 ++
 html/Elements/LifecycleInspectorTransition    | 32 ++++++++++-
 lib/RT/Extension/LifecycleUI.pm               |  1 +
 static/css/lifecycleui-editor.css             |  4 +-
 static/css/lifecycleui-viewer-interactive.css |  2 +-
 static/css/lifecycleui-viewer.css             |  4 +-
 static/js/lifecycleui-editor.js               | 42 +++++++++-----
 static/js/lifecycleui-model.js                | 13 +++++
 static/js/lifecycleui-viewer.js               | 69 +++++++++--------------
 11 files changed, 166 insertions(+), 99 deletions(-)

- Log -----------------------------------------------------------------
commit 39b64050f2d210abdf05d7ef75c1553b490ab9b7
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 15:54:01 2017 +0000

    Turn transition.right textbox into a combobox
    
    This is prepopulated with all the right names RT knows about

diff --git a/html/Elements/LifecycleInspectorTransition b/html/Elements/LifecycleInspectorTransition
index ad4ef62..701b441 100644
--- a/html/Elements/LifecycleInspectorTransition
+++ b/html/Elements/LifecycleInspectorTransition
@@ -7,7 +7,30 @@
 
           <tr>
             <td><&|/l&>Right</&>:</td>
-            <td><input type="text" name="right" value="{{transition.right}}"></td>
+            <td>
+%# taken from RT's /Widgets/ComboBox, except we can't know at Mason time which
+%# values to provide
+% my $z_index = 9999;
+% my $Class = "";
+% my $Name = "right";
+% my $Size = undef;
+% my $Default = "{{transition.right}}";
+% my $Rows = 5;
+              <nobr>
+                <div id="<% $Name %>_Container" class="combobox <%$Class%>" style="z-index: <%$z_index--%>">
+                  <input name="<% $Name %>" id="<% $Name %>" class="combo-text" value="<% $Default || '' %>" type="text" <% $Size ? "size='$Size'" : '' |n %> autocomplete="off" />
+                  <br style="display: none" />
+                  <span id="<% $Name %>_Button" class="combo-button">▼</span>
+                  <select name="List-<% $Name %>" id="<% $Name %>_List" class="combo-list" onchange="ComboBox_SimpleAttach(this, this.form[<% $Name |n,j%>]); " size="<% $Rows %>">
+% for my $map (map { $RT::ACE::RIGHTS{$_} } sort keys %RT::ACE::RIGHTS) {
+% for my $right (sort map { $_->{Name} } values %$map ) {
+                    <option value="<% $right %>"><% $right %></option>
+% }
+% }
+                  </select>
+                </div>
+              </nobr>
+            </td>
           </tr>
 
           <tr>
diff --git a/lib/RT/Extension/LifecycleUI.pm b/lib/RT/Extension/LifecycleUI.pm
index bac5221..df592a6 100644
--- a/lib/RT/Extension/LifecycleUI.pm
+++ b/lib/RT/Extension/LifecycleUI.pm
@@ -7,6 +7,7 @@ our $VERSION = '0.01';
 
 RT->AddJavaScript("d3.min.js");
 RT->AddJavaScript("handlebars-4.0.6.min.js");
+RT->AddJavaScript("combobox.js");
 RT->AddJavaScript("lifecycleui-model.js");
 RT->AddJavaScript("lifecycleui-viewer.js");
 RT->AddJavaScript("lifecycleui-viewer-interactive.js");
diff --git a/static/js/lifecycleui-editor.js b/static/js/lifecycleui-editor.js
index 63348fa..a9b19e3 100644
--- a/static/js/lifecycleui-editor.js
+++ b/static/js/lifecycleui-editor.js
@@ -73,6 +73,10 @@ jQuery(function () {
             field.change(function (e) { toggle() });
             toggle();
         });
+
+        inspector.find(".combobox input.combo-text").each(function () {
+            ComboBox_Load(this.id);
+        });
     };
 
     Editor.prototype.bindInspectorEvents = function () {
@@ -81,16 +85,23 @@ jQuery(function () {
         var inspector = self.inspector;
 
         inspector.on('change', ':input', function () {
-            var field = this.name;
+            var node = jQuery(this);
             var value;
-            if (jQuery(this).is(':checkbox')) {
-                value = this.checked;
+
+            if (node.is('.combo-list')) {
+                value = node.val();
+                node = node.closest('.combobox').find('.combo-text');
+            }
+            else if (node.is(':checkbox')) {
+                value = node[0].checked;
             }
             else {
-                value = jQuery(this).val();
+                value = node.val();
             }
 
-            var action = jQuery(this).closest('li.action');
+            var field = node.attr('name');
+
+            var action = node.closest('li.action');
             if (action.length) {
                 var action = lifecycle.itemForKey(action.data('key'));
                 lifecycle.updateItem(action, field, value);

commit b17333184fe4c35b5c340b6f3d0ecd923a04bee9
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 15:54:44 2017 +0000

    Add custom rights added in this lifecycle window to combobox
    
    That way they're immediately available without a roundtrip to the server

diff --git a/html/Elements/LifecycleInspectorTransition b/html/Elements/LifecycleInspectorTransition
index 701b441..9235f47 100644
--- a/html/Elements/LifecycleInspectorTransition
+++ b/html/Elements/LifecycleInspectorTransition
@@ -22,11 +22,18 @@
                   <br style="display: none" />
                   <span id="<% $Name %>_Button" class="combo-button">▼</span>
                   <select name="List-<% $Name %>" id="<% $Name %>_List" class="combo-list" onchange="ComboBox_SimpleAttach(this, this.form[<% $Name |n,j%>]); " size="<% $Rows %>">
+                    <optgroup>
+{{#each (selectedRights lifecycle)}}
+                      <option value="{{this}}">{{this}}</option>
+{{/each}}
+                    </optgroup>
+                    <optgroup>
 % for my $map (map { $RT::ACE::RIGHTS{$_} } sort keys %RT::ACE::RIGHTS) {
 % for my $right (sort map { $_->{Name} } values %$map ) {
-                    <option value="<% $right %>"><% $right %></option>
+                      <option value="<% $right %>"><% $right %></option>
 % }
 % }
+                    </optgroup>
                   </select>
                 </div>
               </nobr>
diff --git a/static/js/lifecycleui-editor.js b/static/js/lifecycleui-editor.js
index a9b19e3..8a9d716 100644
--- a/static/js/lifecycleui-editor.js
+++ b/static/js/lifecycleui-editor.js
@@ -27,6 +27,10 @@ jQuery(function () {
             return lifecycle.hasTransition(fromStatus, toStatus);
         });
 
+        Handlebars.registerHelper('selectedRights', function(lifecycle) {
+            return lifecycle.selectedRights();
+        });
+
         Handlebars.registerHelper('truncate', function(text) {
             if (text.length > 15) {
                 text = text.substr(0, 15) + '…';
diff --git a/static/js/lifecycleui-model.js b/static/js/lifecycleui-model.js
index 86974b8..58264ba 100644
--- a/static/js/lifecycleui-model.js
+++ b/static/js/lifecycleui-model.js
@@ -799,6 +799,11 @@ jQuery(function () {
         return clone;
     };
 
+    Lifecycle.prototype.selectedRights = function () {
+        var rights = jQuery.map(this.transitions, function (transition) { return transition.right });
+        return jQuery.unique(rights.sort());
+    };
+
     RT.Lifecycle = Lifecycle;
 });
 

commit 76f33941c26fd1cb9db1493766d81f04b7878f34
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 15:55:21 2017 +0000

    Promote some oft-used rights to the top of the combobox

diff --git a/static/js/lifecycleui-model.js b/static/js/lifecycleui-model.js
index 58264ba..22bc8b3 100644
--- a/static/js/lifecycleui-model.js
+++ b/static/js/lifecycleui-model.js
@@ -801,6 +801,14 @@ jQuery(function () {
 
     Lifecycle.prototype.selectedRights = function () {
         var rights = jQuery.map(this.transitions, function (transition) { return transition.right });
+
+        if (this.type == 'ticket') {
+            rights = rights.concat(['ModifyTicket', 'DeleteTicket']);
+        }
+        else if (this.type == 'asset') {
+            rights = rights.concat(['ModifyAsset']);
+        }
+
         return jQuery.unique(rights.sort());
     };
 

commit bbb19fb136d0bffe19bea96a72288230bf07325c
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 16:04:23 2017 +0000

    Fix indentation in circle inspector

diff --git a/html/Elements/LifecycleInspectorCircle b/html/Elements/LifecycleInspectorCircle
index e38d7c2..8b2947d 100644
--- a/html/Elements/LifecycleInspectorCircle
+++ b/html/Elements/LifecycleInspectorCircle
@@ -1,42 +1,43 @@
 <script type="text/x-template" class="lifecycle-inspector-template" data-type="circle">
     <div class="circle">
-       <table>
-         <tr>
-           <td><&|/l&>Label</&>:</td>
-           <td><input type="text" name="label" value="{{circle.label}}" /></td>
-         </tr>
+        <table>
+          <tr>
+            <td><&|/l&>Label</&>:</td>
+            <td><input type="text" name="label" value="{{circle.label}}" /></td>
+          </tr>
 
-         <tr>
-           <td><&|/l&>Border</&>:</td>
-           <td>
-             <input type="checkbox" name="renderStroke" {{#if circle.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style">
-             <span class="color-control" data-field="stroke">
-               <span class="current-color" title="{{circle.stroke}}" style="background-color: {{circle.stroke}}"> </span>
-               <button class="change-color"><&|/l&>Change</&></button>
-             </span>
-           </td>
-         </tr>
+          <tr>
+            <td><&|/l&>Border</&>:</td>
+            <td>
+              <input type="checkbox" name="renderStroke" {{#if circle.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style">
+              <span class="color-control" data-field="stroke">
+                <span class="current-color" title="{{circle.stroke}}" style="background-color: {{circle.stroke}}"> </span>
+                <button class="change-color"><&|/l&>Change</&></button>
+              </span>
+            </td>
+          </tr>
 
-         <tr class="stroke-style">
-           <td><&|/l&>Style</&>:</td>
-           <td><select name="strokeStyle">
-             {{#select circle.strokeStyle}}
-             <option value="solid"><&|/l&>solid</&></option>
-             <option value="dashed"><&|/l&>dashed</&></option>
-             <option value="dotted"><&|/l&>dotted</&></option>
-             {{/select}}
-           </select></td>
-        </tr>
+          <tr class="stroke-style">
+            <td><&|/l&>Style</&>:</td>
+            <td><select name="strokeStyle">
+              {{#select circle.strokeStyle}}
+                <option value="solid"><&|/l&>solid</&></option>
+                <option value="dashed"><&|/l&>dashed</&></option>
+                <option value="dotted"><&|/l&>dotted</&></option>
+              {{/select}}
+            </select></td>
+          </tr>
 
-        <tr>
-          <td><&|/l&>Fill</&>:</td>
-          <td>
-            <input type="checkbox" name="renderFill" {{#if circle.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill]">
-            <span class="color-control" data-field="fill">
-              <span class="current-color" title="{{circle.fill}}" style="background-color: {{circle.fill}}"> </span>
-              <button class="change-color"><&|/l&>Change</&></button>
-            </span>
-          </td>
+          <tr>
+            <td><&|/l&>Fill</&>:</td>
+            <td>
+              <input type="checkbox" name="renderFill" {{#if circle.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill]">
+              <span class="color-control" data-field="fill">
+                <span class="current-color" title="{{circle.fill}}" style="background-color: {{circle.fill}}"> </span>
+                <button class="change-color"><&|/l&>Change</&></button>
+              </span>
+            </td>
+          </tr>
         </table>
 
         <button class="clone"><&|/l&>Clone Circle</&></button><br>

commit d82527dd3e47b47d112333b68355b0948c9d948c
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 16:10:54 2017 +0000

    Give color widgets their own row
    
    This way they aren't indented and overflow the inspector panel's
    boundary

diff --git a/html/Elements/LifecycleInspectorCircle b/html/Elements/LifecycleInspectorCircle
index 8b2947d..639ffea 100644
--- a/html/Elements/LifecycleInspectorCircle
+++ b/html/Elements/LifecycleInspectorCircle
@@ -9,13 +9,18 @@
           <tr>
             <td><&|/l&>Border</&>:</td>
             <td>
-              <input type="checkbox" name="renderStroke" {{#if circle.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style">
+              <input type="checkbox" name="renderStroke" {{#if circle.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style, tr.color-widget[data-field=stroke]">
               <span class="color-control" data-field="stroke">
                 <span class="current-color" title="{{circle.stroke}}" style="background-color: {{circle.stroke}}"> </span>
                 <button class="change-color"><&|/l&>Change</&></button>
               </span>
             </td>
           </tr>
+          <tr class="color-widget" data-field="stroke">
+            <td colspan="2">
+              <div class="color-picker"></div>
+            </td>
+          </tr>
 
           <tr class="stroke-style">
             <td><&|/l&>Style</&>:</td>
@@ -31,13 +36,18 @@
           <tr>
             <td><&|/l&>Fill</&>:</td>
             <td>
-              <input type="checkbox" name="renderFill" {{#if circle.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill]">
+              <input type="checkbox" name="renderFill" {{#if circle.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill], tr.color-widget[data-field=fill]">
               <span class="color-control" data-field="fill">
                 <span class="current-color" title="{{circle.fill}}" style="background-color: {{circle.fill}}"> </span>
                 <button class="change-color"><&|/l&>Change</&></button>
               </span>
             </td>
           </tr>
+          <tr class="color-widget" data-field="fill">
+            <td colspan="2">
+              <div class="color-picker"></div>
+            </td>
+          </tr>
         </table>
 
         <button class="clone"><&|/l&>Clone Circle</&></button><br>
diff --git a/html/Elements/LifecycleInspectorPolygon b/html/Elements/LifecycleInspectorPolygon
index 7914820..e315add 100644
--- a/html/Elements/LifecycleInspectorPolygon
+++ b/html/Elements/LifecycleInspectorPolygon
@@ -9,13 +9,18 @@
           <tr>
             <td><&|/l&>Border</&>:</td>
             <td>
-              <input type="checkbox" name="renderStroke" {{#if polygon.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style">
+              <input type="checkbox" name="renderStroke" {{#if polygon.renderStroke}}checked=checked{{/if}} data-show-hide=".color-control[data-field=stroke], .stroke-style, tr.color-widget[data-field=stroke]">
               <span class="color-control" data-field="stroke">
                 <span class="current-color" title="{{polygon.stroke}}" style="background-color: {{polygon.stroke}}"> </span>
                 <button class="change-color"><&|/l&>Change</&></button>
               </span>
             </td>
           </tr>
+          <tr class="color-widget" data-field="stroke">
+            <td colspan="2">
+              <div class="color-picker"></div>
+            </td>
+          </tr>
 
           <tr class="stroke-style">
             <td><&|/l&>Style</&>:</td>
@@ -31,13 +36,18 @@
           <tr>
             <td><&|/l&>Fill</&>:</td>
             <td>
-              <input type="checkbox" name="renderFill" {{#if polygon.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill]">
+              <input type="checkbox" name="renderFill" {{#if polygon.renderFill}}checked=checked{{/if}} data-show-hide=".color-control[data-field=fill], tr.color-widget[data-field=fill]">
               <span class="color-control" data-field="fill">
                 <span class="current-color" title="{{polygon.fill}}" style="background-color: {{polygon.fill}}"> </span>
                 <button class="change-color"><&|/l&>Change</&></button>
               </span>
             </td>
           </tr>
+          <tr class="color-widget" data-field="fill">
+            <td colspan="2">
+              <div class="color-picker"></div>
+            </td>
+          </tr>
         </table>
 
         <button class="clone"><&|/l&>Clone Polygon</&></button><br>
diff --git a/html/Elements/LifecycleInspectorStatus b/html/Elements/LifecycleInspectorStatus
index 60bda1d..abc687d 100644
--- a/html/Elements/LifecycleInspectorStatus
+++ b/html/Elements/LifecycleInspectorStatus
@@ -31,6 +31,11 @@
 	      </span>
 	    </td>
 	  </tr>
+          <tr class="color-widget" data-field="color">
+            <td colspan="2">
+              <div class="color-picker"></div>
+            </td>
+          </tr>
 	</table>
 
         <ul class="toplevel">
diff --git a/static/js/lifecycleui-editor.js b/static/js/lifecycleui-editor.js
index 8a9d716..8c3448a 100644
--- a/static/js/lifecycleui-editor.js
+++ b/static/js/lifecycleui-editor.js
@@ -121,17 +121,18 @@ jQuery(function () {
 
         inspector.on('click', 'button.change-color', function (e) {
             e.preventDefault();
-            var container = jQuery(this).closest('.color-control');
-            var field = container.data('field');
-            var picker = jQuery('<div class="color-picker"></div>');
-            jQuery(this).replaceWith(picker);
+            var inputContainer = jQuery(this).closest('.color-control');
+            var field = inputContainer.data('field');
+            var pickerContainer = jQuery('tr.color-widget[data-field="'+field+'"]');
+            var picker = pickerContainer.find('.color-picker');
+            jQuery(this).remove();
 
             var skipUpdateCallback = 0;
             var farb = jQuery.farbtastic(picker, function (newColor) {
                 if (skipUpdateCallback) {
                     return;
                 }
-                container.find('.current-color').val(newColor);
+                inputContainer.find('.current-color').val(newColor);
                 lifecycle.updateItem(self.inspectorNode, field, newColor, true);
                 self.renderDisplay();
             });
@@ -143,7 +144,7 @@ jQuery(function () {
             });
 
             var input = jQuery('<input class="current-color" size=8 maxlength=7>');
-            container.find('.current-color').replaceWith(input);
+            inputContainer.find('.current-color').replaceWith(input);
             input.on('input', function () {
                 var newColor = input.val();
                 if (newColor.match(/^#[a-fA-F0-9]{6}$/)) {

commit 1357eed198aa5ad3cf259da2bd0173375be61c7c
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 16:25:18 2017 +0000

    Make the primary status node a <g>
    
    This step one towards putting the label and the circle both in the same
    SVG element

diff --git a/static/css/lifecycleui-editor.css b/static/css/lifecycleui-editor.css
index 57c35b7..7126115 100644
--- a/static/css/lifecycleui-editor.css
+++ b/static/css/lifecycleui-editor.css
@@ -128,11 +128,11 @@
     left: 175px;
 }
 
-.lifecycle-ui .statuses text.hover {
+.lifecycle-ui .statuses .hover {
     opacity: 1;
 }
 
-.lifecycle-ui .statuses circle.hover,
+.lifecycle-ui .statuses .hover circle,
 .lifecycle-ui .transitions .hover,
 .lifecycle-ui .decorations :not(text).hover {
     opacity: 1;
diff --git a/static/css/lifecycleui-viewer-interactive.css b/static/css/lifecycleui-viewer-interactive.css
index e7c237b..aa92acd 100644
--- a/static/css/lifecycleui-viewer-interactive.css
+++ b/static/css/lifecycleui-viewer-interactive.css
@@ -48,7 +48,7 @@
     box-shadow: 2px 2px 8px -2px #999;
 }
 
-.lifecycle-ui .statuses circle.selected {
+.lifecycle-ui .statuses .selected circle {
     filter: url(#hover);
 }
 
diff --git a/static/css/lifecycleui-viewer.css b/static/css/lifecycleui-viewer.css
index 6e9fb50..9a621e5 100644
--- a/static/css/lifecycleui-viewer.css
+++ b/static/css/lifecycleui-viewer.css
@@ -75,11 +75,11 @@
     opacity: 1;
 }
 
-.lifecycle-ui .has-focus .statuses circle.focus {
+.lifecycle-ui .has-focus .statuses .focus circle {
     stroke-width: 6px;
 }
 
-.lifecycle-ui .has-focus .statuses circle.focus,
+.lifecycle-ui .has-focus .statuses .focus circle,
 .lifecycle-ui .has-focus .transitions .focus,
 .lifecycle-ui .has-focus .decorations :not(text).focus {
     filter: url(#focus);
diff --git a/static/js/lifecycleui-viewer.js b/static/js/lifecycleui-viewer.js
index c57b755..fd37790 100644
--- a/static/js/lifecycleui-viewer.js
+++ b/static/js/lifecycleui-viewer.js
@@ -69,36 +69,41 @@ jQuery(function () {
 
     Viewer.prototype.renderStatusNodes = function (initial) {
         var self = this;
-        var statuses = self.statusContainer.selectAll("circle")
+        var statuses = self.statusContainer.selectAll("g")
                                            .data(self.lifecycle.statusObjects(), function (d) { return d._key });
 
-        statuses.exit()
-              .classed("removing", true)
-              .transition().duration(200*self.animationFactor)
-                .attr("r", self.statusCircleRadius * .8)
-                .remove();
+        var exitStatuses = statuses.exit()
+                                   .classed("removing", true)
+                                   .transition().duration(200*self.animationFactor)
+                                     .remove();
 
-        var newStatuses = statuses.enter().append("circle")
-                            .attr("r", initial ? self.statusCircleRadius : self.statusCircleRadius * .8)
+        exitStatuses.select('circle')
+                    .attr("r", self.statusCircleRadius * .8);
+
+        var newStatuses = statuses.enter().append("g")
                             .attr("data-key", function (d) { return d._key })
                             .on("click", function (d) {
                                 d3.event.stopPropagation();
                                 self.clickedStatus(d);
                             })
                             .call(function (statuses) { self.didEnterStatusNodes(statuses) });
+        newStatuses.append("circle")
+                   .attr("r", initial ? self.statusCircleRadius : self.statusCircleRadius * .8)
 
         if (!initial) {
             newStatuses.transition().duration(200*self.animationFactor)
+                         .select("circle")
                          .attr("r", self.statusCircleRadius)
         }
 
         newStatuses.merge(statuses)
-                        .attr("cx", function (d) { return self.xScale(d.x) })
-                        .attr("cy", function (d) { return self.yScale(d.y) })
-                        .attr("fill", function (d) { return d.color })
                         .classed("focus", function (d) { return self.isFocused(d) })
                         .classed("focus-from", function (d) { return self.isFocusedTransition(d, true) })
-                        .classed("focus-to", function (d) { return self.isFocusedTransition(d, false) });
+                        .classed("focus-to", function (d) { return self.isFocusedTransition(d, false) })
+                   .select("circle")
+                        .attr("cx", function (d) { return self.xScale(d.x) })
+                        .attr("cy", function (d) { return self.yScale(d.y) })
+                        .attr("fill", function (d) { return d.color });
     };
 
     Viewer.prototype.clickedStatus = function (d) { };

commit fbe75c4506224d65d69b175d3ce1bd595fcdcd12
Author: Shawn M Moore <shawn at bestpractical.com>
Date:   Fri Sep 22 16:31:02 2017 +0000

    Put <text> node inside status <g>
    
    This way when you drag a status over another, we don't render both
    labels over top of both circles

diff --git a/static/js/lifecycleui-editor.js b/static/js/lifecycleui-editor.js
index 8c3448a..601b4fd 100644
--- a/static/js/lifecycleui-editor.js
+++ b/static/js/lifecycleui-editor.js
@@ -523,10 +523,6 @@ jQuery(function () {
         statuses.call(this._createDrag());
     };
 
-    Editor.prototype.didEnterStatusLabels = function (statuses) {
-        statuses.call(this._createDrag());
-    };
-
     Editor.prototype.didEnterTextDecorations = function (labels) {
         labels.call(this._createDrag());
     };
diff --git a/static/js/lifecycleui-viewer.js b/static/js/lifecycleui-viewer.js
index fd37790..a0751a2 100644
--- a/static/js/lifecycleui-viewer.js
+++ b/static/js/lifecycleui-viewer.js
@@ -60,7 +60,6 @@ jQuery(function () {
     };
 
     Viewer.prototype.didEnterStatusNodes = function (statuses) { };
-    Viewer.prototype.didEnterStatusLabels = function (labels) { };
     Viewer.prototype.didEnterTransitions = function (paths) { };
     Viewer.prototype.didEnterTextDecorations = function (labels) { };
     Viewer.prototype.didEnterPolygonDecorations = function (polygons) { };
@@ -87,23 +86,33 @@ jQuery(function () {
                                 self.clickedStatus(d);
                             })
                             .call(function (statuses) { self.didEnterStatusNodes(statuses) });
+
         newStatuses.append("circle")
                    .attr("r", initial ? self.statusCircleRadius : self.statusCircleRadius * .8)
 
+        newStatuses.append("text");
+
         if (!initial) {
             newStatuses.transition().duration(200*self.animationFactor)
                          .select("circle")
                          .attr("r", self.statusCircleRadius)
         }
 
-        newStatuses.merge(statuses)
+        var allStatuses = newStatuses.merge(statuses)
                         .classed("focus", function (d) { return self.isFocused(d) })
                         .classed("focus-from", function (d) { return self.isFocusedTransition(d, true) })
-                        .classed("focus-to", function (d) { return self.isFocusedTransition(d, false) })
-                   .select("circle")
-                        .attr("cx", function (d) { return self.xScale(d.x) })
-                        .attr("cy", function (d) { return self.yScale(d.y) })
-                        .attr("fill", function (d) { return d.color });
+                        .classed("focus-to", function (d) { return self.isFocusedTransition(d, false) });
+
+        allStatuses.select("circle")
+                     .attr("cx", function (d) { return self.xScale(d.x) })
+                     .attr("cy", function (d) { return self.yScale(d.y) })
+                     .attr("fill", function (d) { return d.color });
+
+        allStatuses.select("text")
+                      .attr("x", function (d) { return self.xScale(d.x) })
+                      .attr("y", function (d) { return self.yScale(d.y) })
+                      .attr("fill", function (d) { return d3.hsl(d.color).l > 0.35 ? '#000' : '#fff' })
+                      .text(function (d) { return d.name }).each(function () { self.truncateLabel(this) })
     };
 
     Viewer.prototype.clickedStatus = function (d) { };
@@ -121,34 +130,6 @@ jQuery(function () {
         }
     };
 
-    Viewer.prototype.renderStatusLabels = function (initial) {
-        var self = this;
-        var labels = self.statusContainer.selectAll("text")
-                                         .data(self.lifecycle.statusObjects(), function (d) { return d._key });
-
-        labels.exit()
-            .classed("removing", true)
-            .transition().duration(200*self.animationFactor)
-              .remove();
-
-        var newLabels = labels.enter().append("text")
-                          .attr("data-key", function (d) { return d._key })
-                          .on("click", function (d) {
-                              d3.event.stopPropagation();
-                              self.clickedStatus(d);
-                          })
-                          .call(function (labels) { self.didEnterStatusLabels(labels) });
-
-        newLabels.merge(labels)
-                      .attr("x", function (d) { return self.xScale(d.x) })
-                      .attr("y", function (d) { return self.yScale(d.y) })
-                      .attr("fill", function (d) { return d3.hsl(d.color).l > 0.35 ? '#000' : '#fff' })
-                      .text(function (d) { return d.name }).each(function () { self.truncateLabel(this) })
-                      .classed("focus", function (d) { return self.isFocused(d) })
-                      .classed("focus-from", function (d) { return self.isFocusedTransition(d, true) })
-                      .classed("focus-to", function (d) { return self.isFocusedTransition(d, false) });
-    };
-
     Viewer.prototype.transitionArc = function (d) {
       var from = this.lifecycle.statusObjectForName(d.from);
       var to = this.lifecycle.statusObjectForName(d.to);
@@ -403,7 +384,6 @@ jQuery(function () {
     Viewer.prototype.renderDisplay = function (initial) {
         this.renderTransitions(initial);
         this.renderStatusNodes(initial);
-        this.renderStatusLabels(initial);
         this.renderDecorations(initial);
     };
 

-----------------------------------------------------------------------


More information about the Bps-public-commit mailing list