Commit fd008b434faa8f5a5832b2e33ed3d63cf41b5977

Authored by Brad Shuttleworth
1 parent 76ce69c5

re-enable notification-specification on workflows.


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@5967 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/widgets/forms.inc.php
... ... @@ -237,7 +237,10 @@ class KTForm {
237 237 return $this->renderContaining($sWidgets . ' ' . $sButtons);
238 238 }
239 239  
240   - function renderPage($sTitle, $sDescription = null) {
  240 + function renderPage($sTitle = null, $sDescription = null) {
  241 + if ($sTitle == null) {
  242 + $sTitle = $this->sLabel;
  243 + }
241 244 $pageval = $this->render();
242 245 $sHelpText = '';
243 246 if (!is_null($sDescription)) {
... ...
plugins/ktcore/KTCorePlugin.php
... ... @@ -139,6 +139,7 @@ class KTCorePlugin extends KTPlugin {
139 139 $this->registerWidget('KTCoreTransparentFieldsetWidget', 'ktcore.widgets.transparentfieldset', 'KTWidgets.php');
140 140 $this->registerWidget('KTCoreCollectionWidget', 'ktcore.widgets.collection', 'KTWidgets.php');
141 141 $this->registerWidget('KTCoreTreeMetadataWidget', 'ktcore.widgets.treemetadata', 'KTWidgets.php');
  142 + $this->registerWidget('KTDescriptorSelectionWidget', 'ktcore.widgets.descriptorselection', 'KTWidgets.php');
142 143  
143 144 $this->registerPage('collection', 'KTCoreCollectionPage', 'KTWidgets.php');
144 145  
... ... @@ -154,6 +155,7 @@ class KTCorePlugin extends KTPlugin {
154 155 $this->registerValidator('KTFieldsetValidator', 'ktcore.validators.fieldset', 'KTValidators.php');
155 156 $this->registerValidator('KTFileValidator', 'ktcore.validators.file', 'KTValidators.php');
156 157 $this->registerValidator('KTRequiredFileValidator', 'ktcore.validators.requiredfile', 'KTValidators.php');
  158 + $this->registerValidator('KTArrayValidator', 'ktcore.validators.array', 'KTValidators.php');
157 159  
158 160 // criterion
159 161 $this->registerCriterion('NameCriterion', 'ktcore.criteria.name', KT_LIB_DIR . '/browse/Criteria.inc');
... ...
plugins/ktcore/KTValidators.php
... ... @@ -397,4 +397,27 @@ class KTFileValidator extends KTValidator {
397 397 }
398 398 }
399 399  
  400 +
  401 +class KTArrayValidator extends KTValidator {
  402 + var $sNamespace = 'ktcore.validators.array';
  403 +
  404 + function validate($data) {
  405 + $results = array();
  406 + $errors = array();
  407 +
  408 + // very simple if we're required and not present, fail
  409 + // otherwise, its ok.
  410 + $val = KTUtil::arrayGet($data, $this->sInputVariable);
  411 + //var_dump($data); exit(0);
  412 + if ($this->bProduceOutput) {
  413 + $results[$this->sOutputVariable] = $val;
  414 + }
  415 +
  416 + return array(
  417 + 'errors' => $errors,
  418 + 'results' => $results,
  419 + );
  420 + }
  421 +}
  422 +
400 423 ?>
... ...
plugins/ktcore/KTWidgets.php
... ... @@ -272,6 +272,55 @@ class KTCoreEntitySelectionWidget extends KTCoreSelectionWidget {
272 272 }
273 273 }
274 274  
  275 +
  276 +class KTDescriptorSelectionWidget extends KTWidget {
  277 + var $sNamespace = 'ktcore.widgets.descriptorselection';
  278 + var $sTemplate = 'ktcore/forms/widgets/descriptor';
  279 +
  280 + var $aJavascript = array('resources/js/jsonlookup.js');
  281 +
  282 + function configure($aOptions) {
  283 + $res = parent::configure($aOptions);
  284 + if (PEAR::isError($res)) {
  285 + return $res;
  286 + }
  287 +
  288 +
  289 + }
  290 +
  291 + function getWidget() {
  292 + $oTemplating =& KTTemplating::getSingleton();
  293 + $oTemplate = $oTemplating->loadTemplate($this->sTemplate);
  294 +
  295 + $src_location = $this->aOptions['src'];
  296 + $sJS = sprintf("addLoadEvent(initJSONLookup(\"%s\", \"%s\"));", $this->sBasename, $src_location);
  297 +
  298 +
  299 + // its bad, but that's life.
  300 + $oPage =& $GLOBALS['main'];
  301 + $oPage->requireJSStandalone($sJS);
  302 +
  303 + $this->aOptions['multi'] = true;
  304 +
  305 + $aTemplateData = array(
  306 + "context" => $this,
  307 + "label" => $this->sLabel,
  308 + "description" => $this->sDescription,
  309 + "name" => $this->sName,
  310 + "required" => $this->bRequired,
  311 + "has_id" => ($this->sId !== null),
  312 + "id" => $this->sId,
  313 + "has_value" => ($this->value !== null),
  314 + "value" => $this->value,
  315 + "has_errors" => $bHasErrors,
  316 + "errors" => $this->aErrors,
  317 + 'short_name' => $this->sBasename,
  318 + "options" => $this->aOptions,
  319 + );
  320 + return $oTemplate->render($aTemplateData);
  321 + }
  322 +}
  323 +
275 324 class KTCoreTreeMetadataWidget extends KTWidget {
276 325 var $sNamespace = 'ktcore.widgets.treemetadata';
277 326 var $iFieldId;
... ...
plugins/ktcore/admin/workflowsv2.php
... ... @@ -1696,6 +1696,270 @@ class KTWorkflowAdminV2 extends KTAdminDispatcher {
1696 1696 exit(0);
1697 1697 }
1698 1698  
  1699 + function do_managenotifications() {
  1700 + $oTemplate =& $this->oValidator->validateTemplate("ktcore/workflow/admin/manage_notifications");
  1701 + $oTemplate->setData(array(
  1702 + 'context' => $this,
  1703 + 'states' => KTWorkflowState::getByWorkflow($this->oWorkflow),
  1704 + ));
  1705 + return $oTemplate->render();
  1706 + }
  1707 +
  1708 + function describeStateNotifications($oState) {
  1709 + $aAllowed = KTWorkflowUtil::getInformedForState($oState);
  1710 +
  1711 + $aUsers = array();
  1712 + $aGroups = array();
  1713 + $aRoles = array();
  1714 +
  1715 + foreach (KTUtil::arrayGet($aAllowed,'user',array()) as $iUserId) {
  1716 + $oU = User::get($iUserId);
  1717 + if (PEAR::isError($oU) || ($oU == false)) {
  1718 + continue;
  1719 + } else {
  1720 + $aUsers[] = $oU->getName();
  1721 + }
  1722 + }
  1723 +
  1724 + foreach (KTUtil::arrayGet($aAllowed,'group',array()) as $iGroupId) {
  1725 + $oG = Group::get($iGroupId);
  1726 + if (PEAR::isError($oG) || ($oG == false)) {
  1727 + continue;
  1728 + } else {
  1729 + $aGroups[] = $oG->getName();
  1730 + }
  1731 + }
  1732 +
  1733 + foreach (KTUtil::arrayGet($aAllowed,'role',array()) as $iRoleId) {
  1734 + $oR = Role::get($iRoleId);
  1735 + if (PEAR::isError($oR) || ($oR == false)) {
  1736 + continue;
  1737 + } else {
  1738 + $aRoles[] = $oR->getName();
  1739 + }
  1740 + }
  1741 +
  1742 + $sNotify = '';
  1743 + if (!empty($aUsers)) {
  1744 + $sNotify .= '<em>' . _kt('Users:') . '</em> ';
  1745 + $sNotify .= implode(', ', $aUsers);
  1746 + }
  1747 +
  1748 + if (!empty($aGroups)) {
  1749 + if (!empty($sNotify)) { $sNotify .= ' &mdash; '; }
  1750 + $sNotify .= '<em>' . _kt('Groups:') . '</em> ';
  1751 + $sNotify .= implode(', ', $aGroups);
  1752 + }
  1753 +
  1754 + if (!empty($aRoles)) {
  1755 + if (!empty($sNotify)) { $sNotify .= ' &mdash; '; }
  1756 + $sNotify .= '<em>' . _kt('Roles:') . '</em> ';
  1757 + $sNotify .= implode(', ', $aRoles);
  1758 + }
  1759 +
  1760 + if (empty($sNotify)) { $sNotify = _kt('No notifications.'); }
  1761 +
  1762 + return $sNotify;
  1763 + }
  1764 +
  1765 + function descriptorToJSON($aAllowed) {
  1766 + $values = array();
  1767 +
  1768 + foreach (KTUtil::arrayGet($aAllowed,'user',array()) as $oU) {
  1769 + if (!is_object($oU)) {
  1770 + $iUserId = $oU;
  1771 + $oU = User::get($iUserId);
  1772 + } else {
  1773 + $iUserId = $oU->getId();
  1774 + }
  1775 +
  1776 + if (PEAR::isError($oU) || ($oU == false)) {
  1777 + continue;
  1778 + } else {
  1779 + $values[sprintf("users[%d]", $iUserId)] = sprintf('User: %s', $oU->getName());
  1780 + }
  1781 + }
  1782 +
  1783 + foreach (KTUtil::arrayGet($aAllowed,'group',array()) as $oG) {
  1784 + if (!is_object($oG)) {
  1785 + $iGroupId = $oG;
  1786 + $oG = Group::get($iGroupId);
  1787 + } else {
  1788 + $iGroupId = $oG->getId();
  1789 + }
  1790 + if (PEAR::isError($oG) || ($oG == false)) {
  1791 + continue;
  1792 + } else {
  1793 + $values[sprintf("groups[%d]", $iGroupId)] = sprintf('Group: %s', $oG->getName());
  1794 + }
  1795 + }
  1796 +
  1797 + foreach (KTUtil::arrayGet($aAllowed,'role',array()) as $oR) {
  1798 + if (!is_object($oR)) {
  1799 + $iRoleId = $oR;
  1800 + $oR = Role::get($iRoleId);
  1801 + } else {
  1802 + $iRoleId = $oR->getId();
  1803 + }
  1804 +
  1805 + if (PEAR::isError($oR) || ($oR == false)) {
  1806 + continue;
  1807 + } else {
  1808 + $values[sprintf("roles[%d]", $iRoleId)] = sprintf('Role: %s', $oR->getName());
  1809 + }
  1810 + }
  1811 +
  1812 + return $values;
  1813 + }
  1814 +
  1815 + function form_editnotifications($oState) {
  1816 + $oForm = new KTForm;
  1817 + $oForm->setOptions(array(
  1818 + 'context' => $this,
  1819 + 'label' => _kt("Edit State Notifications."),
  1820 + 'identifier' => 'ktcore.workflow.notifications',
  1821 + 'submit_label' => _kt("Update Notifications"),
  1822 + 'cancel_action' => 'managenotifications',
  1823 + 'action' => 'savenotifications',
  1824 + 'fail_action' => 'editnotifications',
  1825 + ));
  1826 + $preval = KTWorkflowUtil::getInformedForState($oState);
  1827 + $oForm->setWidgets(array(
  1828 + array('ktcore.widgets.descriptorselection', array(
  1829 + 'label' => _kt("Users to inform"),
  1830 + 'description' => _kt("Select which users, groups and roles to be notified."),
  1831 + 'name' => 'users',
  1832 + 'src' => KTUtil::addQueryStringSelf($this->meldPersistQuery(array('json_action'=> 'notificationusers'), "json")),
  1833 + 'value' => $this->descriptorToJSON($preval),
  1834 + )),
  1835 + ));
  1836 + $oForm->setValidators(array(
  1837 + array('ktcore.validators.array', array(
  1838 + 'test' => 'users',
  1839 + 'output' => 'users',
  1840 + )),
  1841 + ));
  1842 + return $oForm;
  1843 + }
  1844 +
  1845 + function do_editnotifications() {
  1846 + $oForm = $this->form_editnotifications($this->oState);
  1847 + return $oForm->renderPage();
  1848 + }
  1849 +
  1850 + function do_savenotifications() {
  1851 +
  1852 +
  1853 + $oForm = $this->form_editnotifications($this->oState);
  1854 + $res = $oForm->validate();
  1855 +
  1856 + if (!empty($res['errors'])) {
  1857 + return $oForm->handleError();
  1858 + }
  1859 +
  1860 + $data = $res['results'];
  1861 + // now, an annoying problem is that we do *not* have the final set.
  1862 + // so we need to get the original, add the new ones, remove the old ones.
  1863 + //
  1864 + // because its not *really* isolated properly, we need to post-process
  1865 + // the data.
  1866 +
  1867 + // we need the old one
  1868 + $aAllowed = KTWorkflowUtil::getInformedForState($this->oState);
  1869 +
  1870 + $user_pattern = '|users\[(.*)\]|';
  1871 + $group_pattern = '|groups\[(.*)\]|';
  1872 + $role_pattern = '|roles\[(.*)\]|';
  1873 +
  1874 + $user = KTUtil::arrayGet($aAllowed, 'user', array());
  1875 + $group = KTUtil::arrayGet($aAllowed, 'group', array());
  1876 + $role = KTUtil::arrayGet($aAllowed, 'role', array());
  1877 +
  1878 + // do a quick overpass
  1879 + $newAllowed = array();
  1880 + if (!empty($user)) { $newAllowed['user'] = array_combine($user, $user); }
  1881 + else { $newAllowed['user'] = array(); }
  1882 + if (!empty($group)) { $newAllowed['group'] = array_combine($group, $group); }
  1883 + else { $newAllowed['group'] = array(); }
  1884 + if (!empty($role)) { $newAllowed['role'] = array_combine($role, $role); }
  1885 + else { $newAllowed['role'] = array(); }
  1886 +
  1887 + $added = explode(',', $data['users']['added']);
  1888 + $removed = explode(',', $data['users']['removed']);
  1889 +
  1890 + foreach ($added as $akey) {
  1891 + $matches = array();
  1892 + if (preg_match($user_pattern, $akey, $matches)) { $newAllowed['user'][$matches[1]] = $matches[1]; }
  1893 + else if (preg_match($group_pattern, $akey, $matches)) { $newAllowed['group'][$matches[1]] = $matches[1]; }
  1894 + else if (preg_match($role_pattern, $akey, $matches)) { $newAllowed['role'][$matches[1]] = $matches[1]; }
  1895 + }
  1896 +
  1897 + foreach ($removed as $akey) {
  1898 + $matches = array();
  1899 + if (preg_match($user_pattern, $akey, $matches)) { unset($newAllowed['user'][$matches[1]]); }
  1900 + else if (preg_match($group_pattern, $akey, $matches)) { unset($newAllowed['group'][$matches[1]]); }
  1901 + else if (preg_match($role_pattern, $akey, $matches)) { unset($newAllowed['role'][$matches[1]]); }
  1902 + }
  1903 +
  1904 + // FIXME check that these are all users.
  1905 +
  1906 + $res = KTWorkflowUtil::setInformedForState($this->oState, $newAllowed);
  1907 + if (PEAR::isError($res)) {
  1908 + return $oForm->handleError($res->getMessage());
  1909 + }
  1910 +
  1911 + $this->successRedirectTo("managenotifications", _kt("Notifications updated."));
  1912 + }
  1913 +
  1914 + function json_notificationusers() {
  1915 + $sFilter = KTUtil::arrayGet($_REQUEST, 'filter', false);
  1916 + if ($sFilter == false) {
  1917 + $values = array('off'=>'-- Please filter --'); // default
  1918 + }
  1919 + $sFilter = trim($sFilter);
  1920 + $values = array('off'=>'-- Please filter --'); // default
  1921 +
  1922 + if (!empty($sFilter)) {
  1923 + $allowed = array();
  1924 + $q = sprintf('name like "%%%s%%"', DBUtil::escapeSimple($sFilter));
  1925 +
  1926 + $aUsers = User::getList($q);
  1927 + $aGroups = Group::getList($q);
  1928 + $aRoles = Role::getList($q);
  1929 +
  1930 + $empty = true;
  1931 +
  1932 + if (!PEAR::isError($aUsers)) {
  1933 + $allowed['user'] = $aUsers;
  1934 + if (!empty($aUsers)) {
  1935 + $empty = false;
  1936 + }
  1937 + }
  1938 +
  1939 + if (!PEAR::isError($aGroups)) {
  1940 + $allowed['group'] = $aGroups;
  1941 + if (!empty($aGroups)) {
  1942 + $empty = false;
  1943 + }
  1944 + }
  1945 +
  1946 + if (!PEAR::isError($aRole)) {
  1947 + $allowed['role'] = $aRoles;
  1948 + if (!empty($aRoles)) {
  1949 + $empty = false;
  1950 + }
  1951 +
  1952 + }
  1953 +
  1954 + if ($empty) {
  1955 + $values = array('off'=>'-- No results --'); // default
  1956 + } else {
  1957 + $values = $this->descriptorToJSON($allowed);
  1958 + }
  1959 + }
  1960 +
  1961 + return $values;
  1962 + }
1699 1963 }
1700 1964  
1701 1965 ?>
... ...
resources/js/jsonlookup.js
... ... @@ -2,9 +2,9 @@ var _aLookupWidgets = {};
2 2  
3 3 function getJSONLookupWidget(name) {
4 4 if(!isUndefinedOrNull(_aLookupWidgets[name])) {
5   - return _aLookupWidgets[name];
  5 + return _aLookupWidgets[name];
6 6 } else {
7   - return false;
  7 + return false;
8 8 }
9 9 }
10 10  
... ... @@ -16,260 +16,260 @@ JSONLookupWidget.prototype = {
16 16 /* bind_add and bind_remove are functions to be called with the key:value's of selected items */
17 17  
18 18 'initialize' : function(name, action) {
19   - bindMethods(this);
  19 + bindMethods(this);
20 20  
21   - this.sName = name;
22   - this.sAction = action;
  21 + this.sName = name;
  22 + this.sAction = action;
23 23  
24   -
25   - this.oSelectAvail = $('select_' + name + '_avail');
26   - this.oSelectAssigned = $('select_' + name + '_assigned');
27   - this.oFilterAvail = $('filter_' + name + '_avail');
28   - this.oFilterAssigned = $('filter_' + name + '_assigned');
29   -
30   - this.savedFilter = this.oFilterAvail.value;
31   - this.savedSelector = this.oFilterAssigned.value;
32   - this.filterTimer = null;
33   -
34   - this.aItemsAdded = [];
35   - this.aItemsRemoved = [];
36   -
37   - connect(this.oFilterAvail, 'onkeyup', this, 'onchangeFilter');
38   - connect(this.oFilterAssigned, 'onkeyup', this, 'onchangeSelector');
39   - connect(name + '_add', 'onclick', this, 'onclickAdd');
40   - connect(name + '_remove', 'onclick', this, 'onclickRemove');
41   - connect(name + '_show_all', 'onclick', this, 'onclickShowAll');
42   -
43   - this.triggers = {};
44   - this.triggers['add'] = null;
45   - this.triggers['remove'] = null;
  24 +
  25 + this.oSelectAvail = $('select_' + name + '_avail');
  26 + this.oSelectAssigned = $('select_' + name + '_assigned');
  27 + this.oFilterAvail = $('filter_' + name + '_avail');
  28 + this.oFilterAssigned = $('filter_' + name + '_assigned');
  29 +
  30 + this.savedFilter = this.oFilterAvail.value;
  31 + this.savedSelector = this.oFilterAssigned.value;
  32 + this.filterTimer = null;
  33 +
  34 + this.aItemsAdded = [];
  35 + this.aItemsRemoved = [];
  36 +
  37 + connect(this.oFilterAvail, 'onkeyup', this, 'onchangeFilter');
  38 + connect(this.oFilterAssigned, 'onkeyup', this, 'onchangeSelector');
  39 + connect(name + '_add', 'onclick', this, 'onclickAdd');
  40 + connect(name + '_remove', 'onclick', this, 'onclickRemove');
  41 + connect(name + '_show_all', 'onclick', this, 'onclickShowAll');
  42 +
  43 + this.triggers = {};
  44 + this.triggers['add'] = null;
  45 + this.triggers['remove'] = null;
46 46  
47   - this.initialValuesLoaded = false;
48   - var d = this.getValues();
49   - d.addCallback(this.postInitialize);
  47 + this.initialValuesLoaded = false;
  48 + var d = this.getValues();
  49 + d.addCallback(this.postInitialize);
50 50 },
51 51  
52 52 'addTrigger' : function(event, func) {
53   - this.triggers[event] = func;
  53 + this.triggers[event] = func;
54 54 },
55 55  
56 56  
57 57 // values handling
58 58  
59 59 'getValues' : function(all) {
60   - var act = this.sAction;
61   - if(!isUndefinedOrNull(all)) {
62   - act += '&' + queryString({'filter' : '%'});
63   - } else if(this.savedFilter) {
64   - act += '&' + queryString({'filter' : this.savedFilter});
65   - } else if(!this.initialValuesLoaded) {
66   - act += '&' + queryString({'selected' : '1'});
67   - }
68   -
69   - var d = loadJSONDoc(act);
70   - d.addErrback(this.errGetValues);
71   - d.addCallback(checkKTError);
72   - d.addCallback(this.saveValues);
73   - d.addCallback(this.renderValues);
74   - return d;
  60 + var act = this.sAction;
  61 + if(!isUndefinedOrNull(all)) {
  62 + act += '&' + queryString({'filter' : '%'});
  63 + } else if(this.savedFilter) {
  64 + act += '&' + queryString({'filter' : this.savedFilter});
  65 + } else if(!this.initialValuesLoaded) {
  66 + act += '&' + queryString({'selected' : '1'});
  67 + }
  68 +
  69 + var d = loadJSONDoc(act);
  70 + d.addErrback(this.errGetValues);
  71 + d.addCallback(checkKTError);
  72 + d.addCallback(this.saveValues);
  73 + d.addCallback(this.renderValues);
  74 + return d;
75 75 },
76 76  
77 77 'errGetValues' : function(res) {
78   - alert('There was an error retrieving data. Please check connectivity and try again.');
79   - this.oValues = {'off':'-- Error fetching values --'};
80   - this.renderValues();
  78 + alert('There was an error retrieving data. Please check connectivity and try again.');
  79 + this.oValues = {'off':'-- Error fetching values --'};
  80 + this.renderValues();
81 81 },
82 82  
83 83 'saveValues' : function(res) {
84   - this.oValues = res;
85   - return res;
  84 + this.oValues = res;
  85 + return res;
86 86 },
87 87  
88 88 'renderValues' : function() {
89   - var aOptions = [];
90   - var bSelFound = false;
91   - for(var k in this.oValues) {
92   - var found = false;
93   - for(var i=0; i<this.oSelectAssigned.options.length; i++) {
94   - if(this.oSelectAssigned.options[i].value == k) {
95   - found = true; break;
96   - }
97   - }
98   -
99   - if(found) {
100   - continue;
101   - }
102   -
103   -
104   - var aParam = {'value':k};
105   - if(k == 'off') {
106   - aParam['disabled'] = 'disabled';
107   - }
108   -
109   - var val = this.oValues[k];
110   - var sDisp = val;
111   -
112   - if(!isUndefinedOrNull(val['display'])) {
113   - var sDisp = val['display'];
114   - if(!isUndefinedOrNull(val['selected']) && val['selected'] === true) {
115   - val['selected'] = undefined;
116   - aParam['selected'] = true;
117   - bSelFound = true;
118   - aParam['value'] = k;
119   - }
120   - }
121   - var oO = OPTION(aParam, sDisp);
122   - aOptions.push(oO);
123   - }
124   -
125   - replaceChildNodes(this.oSelectAvail, aOptions);
126   - if(bSelFound) {
127   - this.onclickAdd();
128   - }
  89 + var aOptions = [];
  90 + var bSelFound = false;
  91 + for(var k in this.oValues) {
  92 + var found = false;
  93 + for(var i=0; i<this.oSelectAssigned.options.length; i++) {
  94 + if(this.oSelectAssigned.options[i].value == k) {
  95 + found = true; break;
  96 + }
  97 + }
  98 +
  99 + if(found) {
  100 + continue;
  101 + }
  102 +
  103 +
  104 + var aParam = {'value':k};
  105 + if(k == 'off') {
  106 + aParam['disabled'] = 'disabled';
  107 + }
  108 +
  109 + var val = this.oValues[k];
  110 + var sDisp = val;
  111 +
  112 + if(!isUndefinedOrNull(val['display'])) {
  113 + var sDisp = val['display'];
  114 + if(!isUndefinedOrNull(val['selected']) && val['selected'] === true) {
  115 + val['selected'] = undefined;
  116 + aParam['selected'] = true;
  117 + bSelFound = true;
  118 + aParam['value'] = k;
  119 + }
  120 + }
  121 + var oO = OPTION(aParam, sDisp);
  122 + aOptions.push(oO);
  123 + }
  124 +
  125 + replaceChildNodes(this.oSelectAvail, aOptions);
  126 + if(bSelFound) {
  127 + this.onclickAdd();
  128 + }
129 129 },
130 130  
131 131 'postInitialize' : function(res) {
132   - if(!isUndefinedOrNull(this.triggers['postInitialize'])) {
133   - this.triggers['postInitialize']();
134   - }
  132 + if(!isUndefinedOrNull(this.triggers['postInitialize'])) {
  133 + this.triggers['postInitialize']();
  134 + }
135 135 },
136   -
  136 +
137 137  
138 138 'modItems' : function(type, value) {
139   - var aTarget = (type == 'add') ? 'aItemsAdded' : 'aItemsRemoved';
140   - var aOtherTarget = (type == 'remove') ? 'aItemsAdded' : 'aItemsRemoved';
141   -
142   - // check against other - if other has value, remove it from other, skip next bit
143   - var aNewOther = [];
144   - var exists = false;
145   - var i = 0;
146   - for(i=0; i<this[aOtherTarget].length; i++) {
147   - if(this[aOtherTarget][i]!=value) {
148   - aNewOther.push(this[aOtherTarget][i]);
149   - } else {
150   - exists = true;
151   - }
152   - }
153   - if(exists) {
154   - this[aOtherTarget] = aNewOther;
155   - var sHidden = this.sName + '_items_' + ((type == 'remove') ? 'added' : 'removed');
156   - $(sHidden).value = this[aOtherTarget].join(",");
157   - return;
158   - }
159   -
160   - exists = false;
161   - for(i=0; i<this[aTarget].length; i++) {
162   - if(this[aTarget][i] == value) {
163   - exists = true;
164   - break;
165   - }
166   - }
167   -
168   - if(!exists) {
169   - this[aTarget].push(value);
170   - var sHidden = this.sName + '_items_' + ((type == 'add') ? 'added' : 'removed');
171   - $(sHidden).value = this[aTarget].join(",");
172   - }
173   -
  139 + var aTarget = (type == 'add') ? 'aItemsAdded' : 'aItemsRemoved';
  140 + var aOtherTarget = (type == 'remove') ? 'aItemsAdded' : 'aItemsRemoved';
  141 +
  142 + // check against other - if other has value, remove it from other, skip next bit
  143 + var aNewOther = [];
  144 + var exists = false;
  145 + var i = 0;
  146 + for(i=0; i<this[aOtherTarget].length; i++) {
  147 + if(this[aOtherTarget][i]!=value) {
  148 + aNewOther.push(this[aOtherTarget][i]);
  149 + } else {
  150 + exists = true;
  151 + }
  152 + }
  153 + if(exists) {
  154 + this[aOtherTarget] = aNewOther;
  155 + var sHidden = this.sName + '_items_' + ((type == 'remove') ? 'added' : 'removed');
  156 + $(sHidden).value = this[aOtherTarget].join(",");
  157 + return;
  158 + }
  159 +
  160 + exists = false;
  161 + for(i=0; i<this[aTarget].length; i++) {
  162 + if(this[aTarget][i] == value) {
  163 + exists = true;
  164 + break;
  165 + }
  166 + }
  167 +
  168 + if(!exists) {
  169 + this[aTarget].push(value);
  170 + var sHidden = this.sName + '_items_' + ((type == 'add') ? 'added' : 'removed');
  171 + $(sHidden).value = this[aTarget].join(",");
  172 + }
  173 +
174 174 },
175   -
176   -
  175 +
  176 +
177 177 // signals handling
178 178  
179   - 'onchangeFilter' : function(e) {
180   - if(this.savedFilter != this.oFilterAvail.value) {
181   - this.savedFilter = this.oFilterAvail.value;
182   - if(!isUndefinedOrNull(this.filterTimer)) {
183   - this.filterTimer.canceller();
184   - }
185   - this.filterTimer = callLater(0.2, this.getValues);
186   - }
187   - return true;
  179 + 'onchangeFilter' : function(e) {
  180 + if(this.savedFilter != this.oFilterAvail.value) {
  181 + this.savedFilter = this.oFilterAvail.value;
  182 + if(!isUndefinedOrNull(this.filterTimer)) {
  183 + this.filterTimer.canceller();
  184 + }
  185 + this.filterTimer = callLater(0.2, this.getValues);
  186 + }
  187 + return true;
188 188 },
189 189  
190 190 'onchangeSelector' : function(e) {
191   - if(this.savedSelector != this.oFilterAssigned.value) {
192   - this.savedSelector = this.oFilterAssigned.value;
193   - forEach(this.oSelectAssigned.options, bind(function(o) {
194   - if(!this.savedSelector.length) {
195   - o.selected = false;
196   - } else {
197   - if(o.innerHTML.toLowerCase().search(this.savedSelector) != -1) {
198   - o.selected = true;
199   - } else {
200   - o.selected = false;
201   - }
202   - }
203   - }, this));
204   - }
  191 + if(this.savedSelector != this.oFilterAssigned.value) {
  192 + this.savedSelector = this.oFilterAssigned.value;
  193 + forEach(this.oSelectAssigned.options, bind(function(o) {
  194 + if(!this.savedSelector.length) {
  195 + o.selected = false;
  196 + } else {
  197 + if(o.innerHTML.toLowerCase().search(this.savedSelector) != -1) {
  198 + o.selected = true;
  199 + } else {
  200 + o.selected = false;
  201 + }
  202 + }
  203 + }, this));
  204 + }
205 205 },
206 206  
207 207 '_moveOptions' : function(dir) {
208 208 },
209 209  
210 210 'onclickAdd' : function(e) {
211   - var aCurOptions = extend([], this.oSelectAssigned.options);
212   - forEach(this.oSelectAvail.options, bind(
213   - function(o) {
214   - try {
215   - if(o.value == 'off') return;
216   - var a = o.selected;
217   - if(a == 'selected' || a === true) {
218   - this.modItems('add', o.value);
219   - try {
220   - o.selected = false;
221   - } catch(e) {
222   - o.setAttribute('selected', false);
223   - }
224   - aCurOptions.push(o);
225   -
226   - if(!isUndefinedOrNull(this.triggers['add'])) {
227   - this.triggers['add'](this.oValues[o.value]);
228   - }
229   - }
230   - } catch(e) {
231   - log('exception');
232   - // forEach(keys(e), function(k) { log(k,':', e[k]); });
233   - }
234   - }, this));
235   -
236   - aCurOptions.sort(keyComparator('innerHTML'));
237   - replaceChildNodes(this.oSelectAssigned, aCurOptions);
  211 + var aCurOptions = extend([], this.oSelectAssigned.options);
  212 + forEach(this.oSelectAvail.options, bind(
  213 + function(o) {
  214 + try {
  215 + if(o.value == 'off') return;
  216 + var a = o.selected;
  217 + if(a == 'selected' || a === true) {
  218 + this.modItems('add', o.value);
  219 + try {
  220 + o.selected = false;
  221 + } catch(e) {
  222 + o.setAttribute('selected', false);
  223 + }
  224 + aCurOptions.push(o);
  225 +
  226 + if(!isUndefinedOrNull(this.triggers['add'])) {
  227 + this.triggers['add'](this.oValues[o.value]);
  228 + }
  229 + }
  230 + } catch(e) {
  231 + log('exception');
  232 + // forEach(keys(e), function(k) { log(k,':', e[k]); });
  233 + }
  234 + }, this));
  235 +
  236 + aCurOptions.sort(keyComparator('innerHTML'));
  237 + replaceChildNodes(this.oSelectAssigned, aCurOptions);
238 238  
239 239 },
240 240  
241 241 'onclickRemove' : function(e) {
242   - var aOptions = [];
243   - forEach(this.oSelectAssigned.options, bind(function(o) {
244   - if(o.selected == 'selected' || o.selected === true) {
245   - this.modItems('remove', o.value);
246   - if(!isUndefinedOrNull(this.triggers['remove'])) {
247   - var obj = { 'type' : (o.value.substring(0,1) == 'g') ? 'group' : 'role',
248   - 'id' : o.value.substring(1) };
249   - this.triggers['remove'](obj);
250   - }
251   - } else {
252   - aOptions.push(o);
253   - }
254   - }, this));
255   - replaceChildNodes(this.oSelectAssigned, aOptions);
256   - this.renderValues();
  242 + var aOptions = [];
  243 + forEach(this.oSelectAssigned.options, bind(function(o) {
  244 + if(o.selected == 'selected' || o.selected === true) {
  245 + this.modItems('remove', o.value);
  246 + if(!isUndefinedOrNull(this.triggers['remove'])) {
  247 + var obj = { 'type' : (o.value.substring(0,1) == 'g') ? 'group' : 'role',
  248 + 'id' : o.value.substring(1) };
  249 + this.triggers['remove'](obj);
  250 + }
  251 + } else {
  252 + aOptions.push(o);
  253 + }
  254 + }, this));
  255 + replaceChildNodes(this.oSelectAssigned, aOptions);
  256 + this.renderValues();
257 257 },
258 258  
259 259 'onclickShowAll' : function(e) {
260   - this.oFilterAvail.value = '';
261   - this.savedFilter = '';
262   - this.getValues(true);
263   - e.stop();
  260 + this.oFilterAvail.value = '';
  261 + this.savedFilter = '';
  262 + this.getValues(true);
  263 + e.stop();
264 264 }
265 265 }
266 266  
267 267 function initJSONLookup(name, action) {
268 268 return function() {
269   - _aLookupWidgets[name] = new JSONLookupWidget();
270   - _aLookupWidgets[name].initialize(name, action);
  269 + _aLookupWidgets[name] = new JSONLookupWidget();
  270 + _aLookupWidgets[name].initialize(name, action);
271 271 }
272 272 }
273 273  
274 274  
275   -
276 275 \ No newline at end of file
  276 +
... ...
templates/ktcore/forms/widgets/descriptor.smarty 0 → 100644
  1 +
  2 +<table>
  3 +
  4 +<thead>
  5 + <tr>
  6 + <td style="width:45%"><label for="select_{$short_name}_avail">{i18n}Available{/i18n} {$user_name}</label></td>
  7 + <td style="width:10%">&nbsp;</td>
  8 + <td style="width:45%"><label for="select_{$short_name}_assigned">{i18n}Assigned{/i18n} {$user_name}</label></td>
  9 + </tr>
  10 +</thead>
  11 +
  12 +<tbody>
  13 + <tr>
  14 + <td style="vertical-align: top">
  15 +
  16 + <select name="select_{$short_name}_avail" id="select_{$short_name}_avail" {if $options.multi}multiple="true"{/if} {if $options.size}size="{$options.size}"{/if}>
  17 + {foreach item=lookup key=lookup_key from=$options.vocab}
  18 + <option value="{$lookup_key}" {if ($value == $lookup_key)}selected="selected"{/if}>{$lookup}</option>
  19 + {/foreach}
  20 + </select>
  21 +
  22 + <div><label for="filter_{$short_name}_avail">{i18n}Filter{/i18n}</label><input type="text" id="filter_{$short_name}_avail" /><br/><a href="#" id="{$short_name}_show_all">{i18n}Show All{/i18n}</a></div>
  23 + </td>
  24 +
  25 + <td>
  26 +
  27 + <input type="button" id="{$short_name}_add" value="&raquo;" />
  28 + <br /><br/>
  29 + <input type="button" id="{$short_name}_remove" value="&laquo;" />
  30 +
  31 + </td>
  32 +
  33 + <td style="vertical-align: top">
  34 +
  35 + <select name="{$name}[final]" id="select_{$short_name}_assigned" {if $options.multi}multiple="true"{/if} {if $options.size}size="{$options.size}"{/if}>
  36 + {foreach item=lookup key=lookup_key from=$value}
  37 + <option value="{$lookup_key}" {if ($value == $lookup_key)}selected="selected"{/if}>{$lookup}</option>
  38 + {/foreach}
  39 + </select>
  40 + <div><label for="filter_{$short_name}_assigned">Filter</label><input type="text" id="filter_{$short_name}_assigned" /></div>
  41 + </td>
  42 + </tr>
  43 +</tbody>
  44 +</table>
  45 +
  46 + <input name="{$name}[added]" id="{$short_name}_items_added" type="hidden" />
  47 + <input name="{$name}[removed]" id="{$short_name}_items_removed" type="hidden" />
... ...
templates/ktcore/workflow/admin/effects_overview.smarty
... ... @@ -8,5 +8,5 @@ with the role &quot;Reviewer&quot; on that document are informed.&lt;/p&gt;
8 8  
9 9 <ul class="descriptiveText">
10 10 <li><a href="{addQS context=$context}action=transitionactions{/addQS}">Transition Effects</a></li>
11   - <li><a href="{addQS context=$context}action=statenotifications{/addQS}">Notifications</a></li>
  11 + <li><a href="{addQS context=$context}action=managenotifications{/addQS}">Notifications</a></li>
12 12 </ul>
... ...