@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

When users hover over a column trigger menu, show a "preview" with the rules instead of a tooltip

Summary:
Ref T5474. The first rough cut of triggers showed some of the trigger rules in a tooltip when you hover over the "add/remove" trigger menu.

This isn't great since we don't have much room and it's a bit finnicky / hard to read.

Since we have a better way to show effects now in the drop preview, just use that instead. When you hover over the trigger menu, preview the trigger in the "drop effect" element, with a "Trigger: such-and-such" header.

Test Plan:
- This is pretty tough to screenshot.
- Hovered over menu, got a sensible preview of the trigger effects.
- Dragged a card over the menu, no preview.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T5474

Differential Revision: https://secure.phabricator.com/D20304

+215 -119
+37 -37
resources/celerity/map.php
··· 179 179 'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308', 180 180 'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98', 181 181 'rsrc/css/phui/workboards/phui-workcard.css' => '9e9eb0df', 182 - 'rsrc/css/phui/workboards/phui-workpanel.css' => 'e5461a51', 182 + 'rsrc/css/phui/workboards/phui-workpanel.css' => '4e4ec9f0', 183 183 'rsrc/css/sprite-login.css' => '18b368a6', 184 184 'rsrc/css/sprite-tokens.css' => 'f1896dc5', 185 185 'rsrc/css/syntax/syntax-default.css' => '055fc231', ··· 409 409 'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f', 410 410 'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', 411 411 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172', 412 - 'rsrc/js/application/projects/WorkboardBoard.js' => '2f893acd', 412 + 'rsrc/js/application/projects/WorkboardBoard.js' => '31766c31', 413 413 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', 414 414 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', 415 - 'rsrc/js/application/projects/WorkboardColumn.js' => 'c344eb3c', 415 + 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', 416 416 'rsrc/js/application/projects/WorkboardController.js' => '42c7a5a7', 417 - 'rsrc/js/application/projects/WorkboardDropEffect.js' => 'c808589e', 417 + 'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661', 418 418 'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d', 419 419 'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b', 420 420 'rsrc/js/application/projects/WorkboardOrderTemplate.js' => '03e8891f', 421 - 'rsrc/js/application/projects/behavior-project-boards.js' => 'cd7c9d4f', 421 + 'rsrc/js/application/projects/behavior-project-boards.js' => '8512e4ea', 422 422 'rsrc/js/application/projects/behavior-project-create.js' => '34c53422', 423 423 'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9', 424 424 'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68', ··· 664 664 'javelin-behavior-phuix-example' => 'c2c500a7', 665 665 'javelin-behavior-policy-control' => '0eaa33a9', 666 666 'javelin-behavior-policy-rule-editor' => '9347f172', 667 - 'javelin-behavior-project-boards' => 'cd7c9d4f', 667 + 'javelin-behavior-project-boards' => '8512e4ea', 668 668 'javelin-behavior-project-create' => '34c53422', 669 669 'javelin-behavior-quicksand-blacklist' => '5a6f6a06', 670 670 'javelin-behavior-read-only-warning' => 'b9109f8f', ··· 737 737 'javelin-view-renderer' => '9aae2b66', 738 738 'javelin-view-visitor' => '308f9fe4', 739 739 'javelin-websocket' => 'fdc13e4e', 740 - 'javelin-workboard-board' => '2f893acd', 740 + 'javelin-workboard-board' => '31766c31', 741 741 'javelin-workboard-card' => '0392a5d8', 742 742 'javelin-workboard-card-template' => '2a61f8d4', 743 - 'javelin-workboard-column' => 'c344eb3c', 743 + 'javelin-workboard-column' => 'c3d24e63', 744 744 'javelin-workboard-controller' => '42c7a5a7', 745 - 'javelin-workboard-drop-effect' => 'c808589e', 745 + 'javelin-workboard-drop-effect' => '8e0aa661', 746 746 'javelin-workboard-header' => '111bfd2d', 747 747 'javelin-workboard-header-template' => 'ebe83a6b', 748 748 'javelin-workboard-order-template' => '03e8891f', ··· 869 869 'phui-workboard-color-css' => 'e86de308', 870 870 'phui-workboard-view-css' => '74fc9d98', 871 871 'phui-workcard-view-css' => '9e9eb0df', 872 - 'phui-workpanel-view-css' => 'e5461a51', 872 + 'phui-workpanel-view-css' => '4e4ec9f0', 873 873 'phuix-action-list-view' => 'c68f183f', 874 874 'phuix-action-view' => 'aaa08f3b', 875 875 'phuix-autocomplete' => '8f139ef0', ··· 1178 1178 'phuix-autocomplete', 1179 1179 'javelin-mask', 1180 1180 ), 1181 - '2f893acd' => array( 1181 + '308f9fe4' => array( 1182 + 'javelin-install', 1183 + 'javelin-util', 1184 + ), 1185 + '31766c31' => array( 1182 1186 'javelin-install', 1183 1187 'javelin-dom', 1184 1188 'javelin-util', ··· 1190 1194 'javelin-workboard-card-template', 1191 1195 'javelin-workboard-order-template', 1192 1196 ), 1193 - '308f9fe4' => array( 1194 - 'javelin-install', 1195 - 'javelin-util', 1196 - ), 1197 1197 '32755edb' => array( 1198 1198 'javelin-install', 1199 1199 'javelin-util', ··· 1350 1350 'phuix-form-control-view', 1351 1351 'phuix-icon-view', 1352 1352 'javelin-behavior-phabricator-gesture', 1353 + ), 1354 + '4e4ec9f0' => array( 1355 + 'phui-workcard-view-css', 1353 1356 ), 1354 1357 '4e61fa88' => array( 1355 1358 'javelin-behavior', ··· 1591 1594 'javelin-dom', 1592 1595 'javelin-vector', 1593 1596 ), 1597 + '8512e4ea' => array( 1598 + 'javelin-behavior', 1599 + 'javelin-dom', 1600 + 'javelin-util', 1601 + 'javelin-vector', 1602 + 'javelin-stratcom', 1603 + 'javelin-workflow', 1604 + 'javelin-workboard-controller', 1605 + 'javelin-workboard-drop-effect', 1606 + ), 1594 1607 '87428eb2' => array( 1595 1608 'javelin-behavior', 1596 1609 'javelin-diffusion-locate-file-source', ··· 1635 1648 'phabricator-title', 1636 1649 'phabricator-shaped-request', 1637 1650 'conpherence-thread-manager', 1651 + ), 1652 + '8e0aa661' => array( 1653 + 'javelin-install', 1654 + 'javelin-dom', 1638 1655 ), 1639 1656 '8e2d9a28' => array( 1640 1657 'phui-theme-css', ··· 1940 1957 'javelin-dom', 1941 1958 'phuix-button-view', 1942 1959 ), 1943 - 'c344eb3c' => array( 1944 - 'javelin-install', 1945 - 'javelin-workboard-card', 1946 - 'javelin-workboard-header', 1947 - ), 1948 1960 'c3703a16' => array( 1949 1961 'javelin-behavior', 1950 1962 'javelin-aphlict', 1951 1963 'phabricator-phtize', 1952 1964 'javelin-dom', 1965 + ), 1966 + 'c3d24e63' => array( 1967 + 'javelin-install', 1968 + 'javelin-workboard-card', 1969 + 'javelin-workboard-header', 1953 1970 ), 1954 1971 'c687e867' => array( 1955 1972 'javelin-behavior', ··· 1978 1995 'javelin-util', 1979 1996 'phuix-icon-view', 1980 1997 'phabricator-busy', 1981 - ), 1982 - 'c808589e' => array( 1983 - 'javelin-install', 1984 - 'javelin-dom', 1985 1998 ), 1986 1999 'c8147a20' => array( 1987 2000 'javelin-behavior', ··· 2002 2015 'javelin-vector', 2003 2016 'javelin-magical-init', 2004 2017 ), 2005 - 'cd7c9d4f' => array( 2006 - 'javelin-behavior', 2007 - 'javelin-dom', 2008 - 'javelin-util', 2009 - 'javelin-vector', 2010 - 'javelin-stratcom', 2011 - 'javelin-workflow', 2012 - 'javelin-workboard-controller', 2013 - 'javelin-workboard-drop-effect', 2014 - ), 2015 2018 'cf32921f' => array( 2016 2019 'javelin-behavior', 2017 2020 'javelin-dom', ··· 2071 2074 'javelin-stratcom', 2072 2075 'javelin-dom', 2073 2076 'javelin-history', 2074 - ), 2075 - 'e5461a51' => array( 2076 - 'phui-workcard-view-css', 2077 2077 ), 2078 2078 'e562708c' => array( 2079 2079 'javelin-install',
+14 -19
src/applications/project/controller/PhabricatorProjectBoardViewController.php
··· 623 623 $drop_effects = $column->getDropEffects(); 624 624 $drop_effects = mpull($drop_effects, 'toDictionary'); 625 625 626 + $preview_effect = null; 627 + if ($column->canHaveTrigger()) { 628 + $trigger = $column->getTrigger(); 629 + if ($trigger) { 630 + $preview_effect = $trigger->getPreviewEffect() 631 + ->toDictionary(); 632 + } 633 + } 634 + 626 635 $column_templates[] = array( 627 636 'columnPHID' => $column_phid, 628 637 'effects' => $drop_effects, 629 638 'cardPHIDs' => $card_phids, 639 + 'triggerPreviewEffect' => $preview_effect, 630 640 ); 631 641 } 632 642 ··· 652 662 653 663 $properties = array(); 654 664 foreach ($all_tasks as $task) { 655 - $properties[$task->getPHID()] = array( 656 - 'points' => (double)$task->getPoints(), 657 - 'status' => $task->getStatus(), 658 - 'priority' => (int)$task->getPriority(), 659 - 'owner' => $task->getOwnerPHID(), 660 - ); 665 + $properties[$task->getPHID()] = 666 + PhabricatorBoardResponseEngine::newTaskProperties($task); 661 667 } 662 668 663 669 $behavior_config = array( ··· 1263 1269 $trigger_icon = 'fa-cogs grey'; 1264 1270 } 1265 1271 1266 - if ($trigger) { 1267 - $trigger_tip = array( 1268 - pht('%s: %s', $trigger->getObjectName(), $trigger->getDisplayName()), 1269 - $trigger->getRulesDescription(), 1270 - ); 1271 - $trigger_tip = implode("\n", $trigger_tip); 1272 - } else { 1273 - $trigger_tip = pht('No column trigger.'); 1274 - } 1275 - 1276 1272 $trigger_button = id(new PHUIIconView()) 1277 1273 ->setIcon($trigger_icon) 1278 1274 ->setHref('#') 1279 1275 ->addSigil('boards-dropdown-menu') 1280 - ->addSigil('has-tooltip') 1276 + ->addSigil('trigger-preview') 1281 1277 ->setMetadata( 1282 1278 array( 1283 1279 'items' => hsprintf('%s', $trigger_menu), 1284 - 'tip' => $trigger_tip, 1285 - 'size' => 300, 1280 + 'columnPHID' => $column->getPHID(), 1286 1281 )); 1287 1282 1288 1283 return $trigger_button;
+10 -4
src/applications/project/engine/PhabricatorBoardResponseEngine.php
··· 131 131 $card['headers'][$order_key] = $header; 132 132 } 133 133 134 - $card['properties'] = array( 135 - 'points' => (double)$object->getPoints(), 136 - 'status' => $object->getStatus(), 137 - ); 134 + $card['properties'] = self::newTaskProperties($object); 138 135 } 139 136 140 137 if ($card_phid === $object_phid) { ··· 157 154 158 155 return id(new AphrontAjaxResponse()) 159 156 ->setContent($payload); 157 + } 158 + 159 + public static function newTaskProperties($task) { 160 + return array( 161 + 'points' => (double)$task->getPoints(), 162 + 'status' => $task->getStatus(), 163 + 'priority' => (int)$task->getPriority(), 164 + 'owner' => $task->getOwnerPHID(), 165 + ); 160 166 } 161 167 162 168 private function buildTemplate($object) {
+22
src/applications/project/icon/PhabricatorProjectDropEffect.php
··· 7 7 private $color; 8 8 private $content; 9 9 private $conditions = array(); 10 + private $isTriggerEffect; 11 + private $isHeader; 10 12 11 13 public function setIcon($icon) { 12 14 $this->icon = $icon; ··· 40 42 'icon' => $this->getIcon(), 41 43 'color' => $this->getColor(), 42 44 'content' => hsprintf('%s', $this->getContent()), 45 + 'isTriggerEffect' => $this->getIsTriggerEffect(), 46 + 'isHeader' => $this->getIsHeader(), 43 47 'conditions' => $this->getConditions(), 44 48 ); 45 49 } ··· 56 60 57 61 public function getConditions() { 58 62 return $this->conditions; 63 + } 64 + 65 + public function setIsTriggerEffect($is_trigger_effect) { 66 + $this->isTriggerEffect = $is_trigger_effect; 67 + return $this; 68 + } 69 + 70 + public function getIsTriggerEffect() { 71 + return $this->isTriggerEffect; 72 + } 73 + 74 + public function setIsHeader($is_header) { 75 + $this->isHeader = $is_header; 76 + return $this; 77 + } 78 + 79 + public function getIsHeader() { 80 + return $this->isHeader; 59 81 } 60 82 61 83 }
+9 -30
src/applications/project/storage/PhabricatorProjectTrigger.php
··· 198 198 return $effects; 199 199 } 200 200 201 - public function getRulesDescription() { 202 - $rules = $this->getTriggerRules(); 203 - if (!$rules) { 204 - return pht('Does nothing.'); 205 - } 206 - 207 - $things = array(); 208 - 209 - $count = count($rules); 210 - $limit = 3; 211 - 212 - if ($count > $limit) { 213 - $show_rules = array_slice($rules, 0, ($limit - 1)); 214 - } else { 215 - $show_rules = $rules; 216 - } 217 - 218 - foreach ($show_rules as $rule) { 219 - $things[] = $rule->getDescription(); 220 - } 221 - 222 - if ($count > $limit) { 223 - $things[] = pht( 224 - '(Applies %s more actions.)', 225 - new PhutilNumber($count - $limit)); 226 - } 227 - 228 - return implode("\n", $things); 229 - } 230 - 231 201 public function newDropTransactions( 232 202 PhabricatorUser $viewer, 233 203 PhabricatorProjectColumn $column, ··· 265 235 return $trigger_xactions; 266 236 } 267 237 238 + public function getPreviewEffect() { 239 + $header = pht('Trigger: %s', $this->getDisplayName()); 240 + 241 + return id(new PhabricatorProjectDropEffect()) 242 + ->setIcon('fa-cogs') 243 + ->setColor('blue') 244 + ->setIsHeader(true) 245 + ->setContent($header); 246 + } 268 247 269 248 270 249 /* -( PhabricatorApplicationTransactionInterface )------------------------- */
-6
src/applications/project/trigger/PhabricatorProjectTriggerInvalidRule.php
··· 16 16 return $this->exception; 17 17 } 18 18 19 - public function getDescription() { 20 - return pht( 21 - 'Invalid rule (of type "%s").', 22 - $this->getRecord()->getType()); 23 - } 24 - 25 19 public function getSelectControlName() { 26 20 return pht('(Invalid Rule)'); 27 21 }
-8
src/applications/project/trigger/PhabricatorProjectTriggerManiphestStatusRule.php
··· 5 5 6 6 const TRIGGERTYPE = 'task.status'; 7 7 8 - public function getDescription() { 9 - $value = $this->getValue(); 10 - 11 - return pht( 12 - 'Changes status to "%s".', 13 - ManiphestTaskStatus::getTaskStatusName($value)); 14 - } 15 - 16 8 public function getSelectControlName() { 17 9 return pht('Change status to'); 18 10 }
+2 -2
src/applications/project/trigger/PhabricatorProjectTriggerRule.php
··· 37 37 return $this->getRecord()->getValue(); 38 38 } 39 39 40 - abstract public function getDescription(); 41 40 abstract public function getSelectControlName(); 42 41 abstract public function getRuleViewLabel(); 43 42 abstract public function getRuleViewDescription($value); ··· 111 110 } 112 111 113 112 final protected function newEffect() { 114 - return new PhabricatorProjectDropEffect(); 113 + return id(new PhabricatorProjectDropEffect()) 114 + ->setIsTriggerEffect(true); 115 115 } 116 116 117 117 final public function toDictionary() {
-6
src/applications/project/trigger/PhabricatorProjectTriggerUnknownRule.php
··· 5 5 6 6 const TRIGGERTYPE = 'unknown'; 7 7 8 - public function getDescription() { 9 - return pht( 10 - 'Unknown rule (of type "%s").', 11 - $this->getRecord()->getType()); 12 - } 13 - 14 8 public function getSelectControlName() { 15 9 return pht('(Unknown Rule)'); 16 10 }
+11
webroot/rsrc/css/phui/workboards/phui-workpanel.css
··· 201 201 text-overflow: ellipsis; 202 202 margin: 4px 8px; 203 203 color: {$greytext}; 204 + border-radius: 3px; 204 205 } 205 206 206 207 .workboard-drop-preview li .phui-icon-view { ··· 214 215 background: {$bluebackground}; 215 216 margin-right: 6px; 216 217 } 218 + 219 + .workboard-drop-preview .workboard-drop-preview-header { 220 + background: {$sky}; 221 + color: #fff; 222 + } 223 + 224 + .workboard-drop-preview .workboard-drop-preview-header .phui-icon-view { 225 + background: {$blue}; 226 + color: #fff; 227 + }
+89 -6
webroot/rsrc/js/application/projects/WorkboardBoard.js
··· 41 41 _cards: null, 42 42 _dropPreviewNode: null, 43 43 _dropPreviewListNode: null, 44 + _previewPHID: null, 45 + _hidePreivew: false, 44 46 45 47 getRoot: function() { 46 48 return this._root; ··· 141 143 142 144 this._columns[phid] = new JX.WorkboardColumn(this, phid, node); 143 145 } 146 + 147 + var on_over = JX.bind(this, this._showTriggerPreview); 148 + var on_out = JX.bind(this, this._hideTriggerPreview); 149 + JX.Stratcom.listen('mouseover', 'trigger-preview', on_over); 150 + JX.Stratcom.listen('mouseout', 'trigger-preview', on_out); 151 + }, 152 + 153 + _showTriggerPreview: function(e) { 154 + if (this._disablePreview) { 155 + return; 156 + } 157 + 158 + var target = e.getTarget(); 159 + var node = e.getNode('trigger-preview'); 160 + 161 + if (target !== node) { 162 + return; 163 + } 164 + 165 + var phid = JX.Stratcom.getData(node).columnPHID; 166 + var column = this._columns[phid]; 167 + 168 + // Bail out if we don't know anything about this column. 169 + if (!column) { 170 + return; 171 + } 172 + 173 + if (phid === this._previewPHID) { 174 + return; 175 + } 176 + 177 + this._previewPHID = phid; 178 + 179 + var effects = column.getDropEffects(); 180 + 181 + var triggers = []; 182 + for (var ii = 0; ii < effects.length; ii++) { 183 + if (effects[ii].getIsTriggerEffect()) { 184 + triggers.push(effects[ii]); 185 + } 186 + } 187 + 188 + if (triggers.length) { 189 + var header = column.getTriggerPreviewEffect(); 190 + triggers = [header].concat(triggers); 191 + } 192 + 193 + this._showEffects(triggers); 194 + }, 195 + 196 + _hideTriggerPreview: function(e) { 197 + if (this._disablePreview) { 198 + return; 199 + } 200 + 201 + var target = e.getTarget(); 202 + 203 + if (target !== e.getNode('trigger-preview')) { 204 + return; 205 + } 206 + 207 + this._removeTriggerPreview(); 208 + }, 209 + 210 + _removeTriggerPreview: function() { 211 + this._showEffects([]); 212 + this._previewPHID = null; 213 + }, 214 + 215 + _beginDrag: function() { 216 + this._disablePreview = true; 217 + this._showEffects([]); 218 + }, 219 + 220 + _endDrag: function() { 221 + this._disablePreview = false; 144 222 }, 145 223 146 224 _setupDragHandlers: function() { ··· 186 264 187 265 list.listen('didDrop', JX.bind(this, this._onmovecard, list)); 188 266 267 + list.listen('didBeginDrag', JX.bind(this, this._beginDrag)); 268 + list.listen('didEndDrag', JX.bind(this, this._endDrag)); 269 + 189 270 lists.push(list); 190 271 } 191 272 ··· 195 276 }, 196 277 197 278 _didChangeDropTarget: function(src_list, src_node, dst_list, dst_node) { 198 - var node = this._getDropPreviewNode(); 199 - 200 279 if (!dst_list) { 201 280 // The card is being dragged into a dead area, like the left menu. 202 - JX.DOM.remove(node); 281 + this._showEffects([]); 203 282 return; 204 283 } 205 284 206 285 if (dst_node === false) { 207 286 // The card is being dragged over itself, so dropping it won't 208 287 // affect anything. 209 - JX.DOM.remove(node); 288 + this._showEffects([]); 210 289 return; 211 290 } 212 291 ··· 217 296 var dst_column = this.getColumn(dst_phid); 218 297 219 298 var effects = []; 220 - 221 299 if (src_column !== dst_column) { 222 300 effects = effects.concat(dst_column.getDropEffects()); 223 301 } ··· 239 317 } 240 318 effects = visible; 241 319 320 + this._showEffects(effects); 321 + }, 322 + 323 + _showEffects: function(effects) { 324 + var node = this._getDropPreviewNode(); 325 + 242 326 if (!effects.length) { 243 327 JX.DOM.remove(node); 244 328 return; ··· 251 335 } 252 336 253 337 JX.DOM.setContent(this._getDropPreviewListNode(), items); 254 - 255 338 document.body.appendChild(node); 256 339 }, 257 340
+4
webroot/rsrc/js/application/projects/WorkboardColumn.js
··· 28 28 this._dropEffects = []; 29 29 }, 30 30 31 + properties: { 32 + triggerPreviewEffect: null 33 + }, 34 + 31 35 members: { 32 36 _phid: null, 33 37 _root: null,
+11 -1
webroot/rsrc/js/application/projects/WorkboardDropEffect.js
··· 11 11 icon: null, 12 12 color: null, 13 13 content: null, 14 + isTriggerEffect: false, 15 + isHeader: false, 14 16 conditions: [] 15 17 }, 16 18 ··· 20 22 .setIcon(map.icon) 21 23 .setColor(map.color) 22 24 .setContent(JX.$H(map.content)) 25 + .setIsTriggerEffect(map.isTriggerEffect) 26 + .setIsHeader(map.isHeader) 23 27 .setConditions(map.conditions || []); 24 28 } 25 29 }, ··· 31 35 .setColor(this.getColor()) 32 36 .getNode(); 33 37 34 - return JX.$N('li', {}, [icon, this.getContent()]); 38 + var attributes = {}; 39 + 40 + if (this.getIsHeader()) { 41 + attributes.className = 'workboard-drop-preview-header'; 42 + } 43 + 44 + return JX.$N('li', attributes, [icon, this.getContent()]); 35 45 }, 36 46 37 47 isEffectVisibleForCard: function(card) {
+6
webroot/rsrc/js/application/projects/behavior-project-boards.js
··· 108 108 for (jj = 0; jj < spec.cardPHIDs.length; jj++) { 109 109 column.newCard(spec.cardPHIDs[jj]); 110 110 } 111 + 112 + if (spec.triggerPreviewEffect) { 113 + column.setTriggerPreviewEffect( 114 + JX.WorkboardDropEffect.newFromDictionary( 115 + spec.triggerPreviewEffect)); 116 + } 111 117 } 112 118 113 119 var order_maps = config.orderMaps;