Commit 38c18432432a0ea39d16fd110d481e31c14ef9ef
1 parent
33b4625b
- massively improve the workflow editing / management system
- fix html-error in listFieldsets - make the titlebar slightly less verbose to accommodate smaller screens better. git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@4699 c91229c3-7414-0410-bfa2-8a42b809f60b
Showing
19 changed files
with
866 additions
and
172 deletions
kthelp/.htaccess
0 โ 100644
kthelp/ktcore/EN/admin/workflow/overview.html
0 โ 100644
| 1 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
| 2 | +<html> | |
| 3 | +<head> | |
| 4 | + | |
| 5 | + | |
| 6 | + <title>Workflow Overview</title> | |
| 7 | +</head> | |
| 8 | + | |
| 9 | +<body> | |
| 10 | + | |
| 11 | +<h2>Workflow Overview</h2> | |
| 12 | + | |
| 13 | +<p>Workflow allows you to assign a series of steps to the document creation and | |
| 14 | +management process. For example, a "News" workflow might have documents which | |
| 15 | +go from <strong>Research</strong> to <strong>Draft</strong> to <strong>Under Review</strong> | |
| 16 | +to <strong>Published</strong>, | |
| 17 | +with different people participating in the document's | |
| 18 | +lifecycle at each stage. Naturally, not all documents have the | |
| 19 | +same needs in terms of workflow: Invoices (which must be <span style="font-weight: bold;">drawn up</span>, <span style="font-weight: bold;">maile</span>d, and then marked as <span style="font-weight: bold;">paid</span>) are very different from Marketing documents. </p> | |
| 20 | +<p>To facilitate this, KnowledgeTree™ allows the Administrator to | |
| 21 | +define a number of different workflows, each of which can be applied to | |
| 22 | +different documents as their organisation requires.</p> | |
| 23 | + | |
| 24 | +</body> | |
| 25 | +</html> | ... | ... |
lib/browse/BrowseColumns.inc.php
| ... | ... | @@ -72,7 +72,7 @@ class TitleColumn extends BrowseColumn { |
| 72 | 72 | function renderFolderLink($aDataRow) { |
| 73 | 73 | $outStr = '<a href="' . $this->buildFolderLink($aDataRow) . '">'; |
| 74 | 74 | $outStr .= $aDataRow["folder"]->getName(); |
| 75 | - $outStr .= '</a>'; | |
| 75 | + $outStr .= '</a> '; | |
| 76 | 76 | return $outStr; |
| 77 | 77 | } |
| 78 | 78 | ... | ... |
plugins/ktcore/KTDocumentActions.php
| ... | ... | @@ -585,7 +585,7 @@ class KTDocumentWorkflowAction extends KTDocumentAction { |
| 585 | 585 | |
| 586 | 586 | $oUser =& User::get($_SESSION['userID']); |
| 587 | 587 | $aTransitions = KTWorkflowUtil::getTransitionsForDocumentUser($oDocument, $oUser); |
| 588 | - $aWorkflows = KTWorkflow::getList(); | |
| 588 | + $aWorkflows = KTWorkflow::getList('start_state_id IS NOT NULL'); | |
| 589 | 589 | |
| 590 | 590 | $fieldErrors = null; |
| 591 | 591 | ... | ... |
plugins/ktcore/admin/workflows.php
| ... | ... | @@ -18,16 +18,232 @@ require_once(KT_LIB_DIR . '/search/savedsearch.inc.php'); |
| 18 | 18 | |
| 19 | 19 | require_once(KT_LIB_DIR . '/actions/documentaction.inc.php'); |
| 20 | 20 | |
| 21 | +require_once(KT_LIB_DIR . '/widgets/portlet.inc.php'); | |
| 22 | + | |
| 23 | +class WorkflowNavigationPortlet extends KTPortlet { | |
| 24 | + var $oWorkflow; | |
| 25 | + | |
| 26 | + function WorkflowNavigationPortlet($sTitle, $oWorkflow = null) { | |
| 27 | + $this->oWorkflow = $oWorkflow; | |
| 28 | + parent::KTPortlet($sTitle); | |
| 29 | + } | |
| 30 | + | |
| 31 | + function render() { | |
| 32 | + if (is_null($this->oWorkflow)) { return _('No Workflow Selected.'); } | |
| 33 | + | |
| 34 | + $aAdminPages = array(); | |
| 35 | + $aAdminPages[] = array('name' => _('Overview'), 'url' => $_SERVER['PHP_SELF'] . '?action=editWorkflow&fWorkflowId=' . $this->oWorkflow->getId()); | |
| 36 | + $aAdminPages[] = array('name' => _('States'), 'url' => $_SERVER['PHP_SELF'] . '?action=manageStates&fWorkflowId=' . $this->oWorkflow->getId()); | |
| 37 | + $aAdminPages[] = array('name' => _('Transitions'), 'url' => $_SERVER['PHP_SELF'] . '?action=manageTransitions&fWorkflowId=' . $this->oWorkflow->getId()); | |
| 38 | + $aAdminPages[] = array('name' => _('Actions'), 'url' => $_SERVER['PHP_SELF'] . '?action=manageActions&fWorkflowId=' . $this->oWorkflow->getId()); | |
| 39 | + | |
| 40 | + | |
| 41 | + $oTemplating = new KTTemplating; | |
| 42 | + $oTemplate = $oTemplating->loadTemplate("ktcore/workflow/admin_portlet"); | |
| 43 | + $aTemplateData = array( | |
| 44 | + "context" => $this, | |
| 45 | + "aAdminPages" => $aAdminPages, | |
| 46 | + ); | |
| 47 | + | |
| 48 | + return $oTemplate->render($aTemplateData); | |
| 49 | + } | |
| 50 | +} | |
| 51 | + | |
| 21 | 52 | class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 22 | 53 | var $bAutomaticTransaction = true; |
| 54 | + var $sHelpPage = 'ktcore/admin/workflow/overview.html'; | |
| 55 | + var $aWorkflowInfo; | |
| 56 | + var $oWorkflow; | |
| 23 | 57 | |
| 24 | - // {{{ WORKFLOW HANDLING | |
| 25 | - // {{{ do_main | |
| 26 | - function do_main () { | |
| 58 | + function check() { | |
| 27 | 59 | $this->aBreadcrumbs[] = array( |
| 28 | 60 | 'url' => $_SERVER['PHP_SELF'], |
| 29 | 61 | 'name' => _('Workflows'), |
| 30 | 62 | ); |
| 63 | + $this->oWorkflow =& KTWorkflow::get($_REQUEST['fWorkflowId']); | |
| 64 | + if (!PEAR::isError($this->oWorkflow)) { | |
| 65 | + $this->aBreadcrumbs[] = array( | |
| 66 | + 'url' => $_SERVER['PHP_SELF'], | |
| 67 | + 'query' => 'action=editWorkflow&fWorkflowId=' . $this->oWorkflow->getId(), | |
| 68 | + 'name' => $this->oWorkflow->getName(), | |
| 69 | + ); | |
| 70 | + $this->oPage->addPortlet(new WorkflowNavigationPortlet(_('Workflow'), $this->oWorkflow)); | |
| 71 | + } | |
| 72 | + | |
| 73 | + return true; | |
| 74 | + } | |
| 75 | + | |
| 76 | + // helper function to construct the set of workflow information | |
| 77 | + function buildWorkflowInfo($oWorkflow) { | |
| 78 | + if ($this->aWorkflowInfo != null) { return $this->aWorkflowInfo; } | |
| 79 | + | |
| 80 | + $aInfo = array(); | |
| 81 | + $aInfo['workflow'] = $oWorkflow; | |
| 82 | + | |
| 83 | + // roles | |
| 84 | + $aRoles = Role::getList(); | |
| 85 | + $aKeyRoles = array(); | |
| 86 | + foreach ($aRoles as $oRole) { $aKeyRoles[$oRole->getId()] = $oRole; } | |
| 87 | + $aInfo['roles'] = $aKeyRoles; | |
| 88 | + | |
| 89 | + // groups | |
| 90 | + $aGroups = Group::getList(); | |
| 91 | + $aKeyGroups = array(); | |
| 92 | + foreach ($aGroups as $oGroup) { $aKeyGroups[$oGroup->getId()] = $oGroup; } | |
| 93 | + $aInfo['groups'] = $aKeyGroups; | |
| 94 | + | |
| 95 | + // states. | |
| 96 | + $aStates = KTWorkflowState::getByWorkflow($oWorkflow); | |
| 97 | + $aKeyStates = array(); | |
| 98 | + foreach ($aStates as $oState) { $aKeyStates[$oState->getId()] = $oState; } | |
| 99 | + $aInfo['states'] = $aKeyStates; | |
| 100 | + | |
| 101 | + // transitions | |
| 102 | + $aTransitions = KTWorkflowTransition::getByWorkflow($oWorkflow); | |
| 103 | + $aKeyTransitions = array(); | |
| 104 | + foreach ($aTransitions as $oTransition) { $aKeyTransitions[$oTransition->getId()] = $oTransition; } | |
| 105 | + $aInfo['transitions'] = $aKeyTransitions; | |
| 106 | + | |
| 107 | + // permissions | |
| 108 | + $aPermissions = KTPermission::getList(); | |
| 109 | + $aKeyPermissions = array(); | |
| 110 | + foreach ($aPermissions as $oPermission) { $aKeyPermissions[$oPermission->getId()] = $oPermission; } | |
| 111 | + $aInfo['permissions'] = $aKeyPermissions; | |
| 112 | + | |
| 113 | + // actions | |
| 114 | + $aInfo['actions'] = KTDocumentActionUtil::getAllDocumentActions(); | |
| 115 | + $aKeyActions = array(); | |
| 116 | + foreach ($aInfo['actions'] as $oAction) { $aKeyActions[$oAction->getName()] = $oAction; } | |
| 117 | + $aInfo['actions_by_name'] = $aKeyActions; | |
| 118 | + | |
| 119 | + $aInfo['controlled_actions'] = KTWorkflowUtil::getControlledActionsForWorkflow($oWorkflow); | |
| 120 | + | |
| 121 | + /* | |
| 122 | + * now we need to do the crossmappings. | |
| 123 | + */ | |
| 124 | + | |
| 125 | + $aActionsByState = array(); | |
| 126 | + foreach ($aInfo['states'] as $oState) { | |
| 127 | + $aActionsByState[$oState->getId()] = KTWorkflowUtil::getEnabledActionsForState($oState);; | |
| 128 | + } | |
| 129 | + $aInfo['actions_by_state'] = $aActionsByState; | |
| 130 | + | |
| 131 | + // FIXME handle notified users and groups | |
| 132 | + $aTransitionsFromState = array(); | |
| 133 | + foreach ($aInfo['states'] as $oState) { | |
| 134 | + $aTransitionsFromState[$oState->getId()] = KTWorkflowUtil::getTransitionsFrom($oState); | |
| 135 | + } | |
| 136 | + $aInfo['transitions_from_state'] = $aTransitionsFromState; | |
| 137 | + | |
| 138 | + $aTransitionsToState = array(); | |
| 139 | + foreach ($aInfo['states'] as $oState) { | |
| 140 | + $aTransitionsToState[$oState->getId()] = KTWorkflowTransition::getByTargetState($oState); | |
| 141 | + } | |
| 142 | + $aInfo['transitions_to_state'] = $aTransitionsToState; | |
| 143 | + | |
| 144 | + $this->aWorkflowInfo = $aInfo; | |
| 145 | + | |
| 146 | + return $aInfo; | |
| 147 | + } | |
| 148 | + | |
| 149 | + | |
| 150 | + function getActionStringForState($oState) { | |
| 151 | + $aInfo = $this->aWorkflowInfo; | |
| 152 | + | |
| 153 | + // no controlled actions => all available | |
| 154 | + if (empty($aInfo['controlled_actions'])) { return _('All actions available.'); } | |
| 155 | + | |
| 156 | + | |
| 157 | + $aAlways = array(); | |
| 158 | + foreach ($aInfo['actions'] as $iActionId => $aAction) { | |
| 159 | + if (!array_key_exists($iActionId, $aInfo['controlled_actions'])) { | |
| 160 | + $aAlways[$iActionId] = $aAction; | |
| 161 | + } | |
| 162 | + } | |
| 163 | + | |
| 164 | + $aNamedActions = array(); | |
| 165 | + foreach ($aInfo['actions_by_state'][$oState->getId()] as $sName) { | |
| 166 | + $aNamedActions[] = $aInfo['actions_by_name'][$sName]; | |
| 167 | + } | |
| 168 | + | |
| 169 | + $aThese = array_merge($aAlways, $aNamedActions); | |
| 170 | + // some controlled. we need to be careful here: list actions that _are always_ available | |
| 171 | + if (empty($aThese)) { return _('No actions available.'); } | |
| 172 | + | |
| 173 | + // else | |
| 174 | + $aActions = array(); | |
| 175 | + foreach ($aThese as $oAction) { $aActions[] = $oAction->getDisplayName(); } | |
| 176 | + return implode(', ', $aActions); | |
| 177 | + } | |
| 178 | + | |
| 179 | + function getTransitionToStringForState($oState) { | |
| 180 | + $aInfo = $this->aWorkflowInfo; | |
| 181 | + //var_dump($aInfo['transitions_to_state'][$oState->getId()]); | |
| 182 | + if (($aInfo['workflow']->getStartStateId() != $oState->getId()) && (empty($aInfo['transitions_to_state'][$oState->getId()]))) { | |
| 183 | + return '<strong>' . _('This state is unreachable.') . '</strong>'; | |
| 184 | + } | |
| 185 | + | |
| 186 | + | |
| 187 | + if ($aInfo['workflow']->getStartStateId() == $oState->getId() && (empty($aInfo['transitions_to_state'][$oState->getId()]))) { | |
| 188 | + return '<strong>' . _('Documents start in this state') . '</strong>'; | |
| 189 | + } | |
| 190 | + $aT = array(); | |
| 191 | + if ($aInfo['workflow']->getStartStateId() == $oState->getId()) { | |
| 192 | + $aT[] = '<strong>' . _('Documents start in this state') . '</strong>'; | |
| 193 | + } | |
| 194 | + | |
| 195 | + foreach ($aInfo['transitions_to_state'][$oState->getId()] as $aTransition) { | |
| 196 | + $aT[] = sprintf('<a href="%s?action=editTransition&fWorkflowId=%d&fTransitionId=%d">%s</a>', $_SERVER['PHP_SELF'], $aInfo['workflow']->getId(), $aTransition->getId() ,$aTransition->getName()); | |
| 197 | + } | |
| 198 | + | |
| 199 | + return implode(', ',$aT); | |
| 200 | + } | |
| 201 | + | |
| 202 | + function getNotificationStringForState($oState) { | |
| 203 | + return _('No roles and groups notified.'); | |
| 204 | + } | |
| 205 | + | |
| 206 | + function transitionAvailable($oTransition, $oState) { | |
| 207 | + $aInfo = $this->aWorkflowInfo; | |
| 208 | + | |
| 209 | + $val = false; | |
| 210 | + foreach ($aInfo['transitions_from_state'][$oState->getId()] as $oT) { | |
| 211 | + if ($oTransition->getId() == $oT->getId()) { $val = true; } | |
| 212 | + } | |
| 213 | + | |
| 214 | + return $val; | |
| 215 | + } | |
| 216 | + | |
| 217 | + function actionAvailable($oAction, $oState) { | |
| 218 | + $aInfo = $this->aWorkflowInfo; | |
| 219 | + | |
| 220 | + $val = false; | |
| 221 | + | |
| 222 | + foreach ($aInfo['actions_by_state'][$oState->getId()] as $oA) { | |
| 223 | + | |
| 224 | + if ($oAction->getName() == $oA) { $val = true; } | |
| 225 | + } | |
| 226 | + | |
| 227 | + return $val; | |
| 228 | + } | |
| 229 | + | |
| 230 | + function getTransitionFromStringForState($oState) { | |
| 231 | + $aInfo = $this->aWorkflowInfo; | |
| 232 | + | |
| 233 | + if (empty($aInfo['transitions_from_state'][$oState->getId()])) { | |
| 234 | + return '<strong>' . _('No transitions available') . '</strong>'; | |
| 235 | + } | |
| 236 | + | |
| 237 | + $aT = array(); | |
| 238 | + foreach ($aInfo['transitions_from_state'][$oState->getId()] as $aTransition) { | |
| 239 | + $aT[] = sprintf('<a href="%s?action=editTransition&fWorkflowId=%d&fTransitionId=%d">%s</a>', $_SERVER['PHP_SELF'], $aInfo['workflow']->getId(), $aTransition->getId() ,$aTransition->getName()); | |
| 240 | + } | |
| 241 | + return implode(', ', $aT); | |
| 242 | + } | |
| 243 | + | |
| 244 | + // {{{ WORKFLOW HANDLING | |
| 245 | + // {{{ do_main | |
| 246 | + function do_main () { | |
| 31 | 247 | |
| 32 | 248 | $add_fields = array(); |
| 33 | 249 | $add_fields[] = new KTStringWidget(_('Name'),_('A human-readable name for the workflow.'), 'fName', null, $this->oPage, true); |
| ... | ... | @@ -42,69 +258,57 @@ class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 42 | 258 | return $oTemplate; |
| 43 | 259 | } |
| 44 | 260 | // }}} |
| 45 | - | |
| 261 | + | |
| 46 | 262 | // {{{ do_editWorkflow |
| 47 | 263 | function do_editWorkflow() { |
| 48 | 264 | |
| 49 | 265 | $oTemplate =& $this->oValidator->validateTemplate('ktcore/workflow/editWorkflow'); |
| 50 | 266 | $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); |
| 51 | 267 | |
| 52 | - $aStates = KTWorkflowState::getByWorkflow($oWorkflow); | |
| 53 | - $aPermissions = KTPermission::getList(); | |
| 268 | + | |
| 269 | + | |
| 270 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 271 | + | |
| 272 | + $aPermissions = $aInfo['permissions']; | |
| 273 | + $aStates = $aInfo['states']; | |
| 54 | 274 | |
| 55 | 275 | $edit_fields = array(); |
| 56 | 276 | $edit_fields[] = new KTStringWidget(_('Name'), _('A human-readable name for the workflow.'), 'fName', $oWorkflow->getName(), $this->oPage, true); |
| 57 | 277 | $aOptions = array(); |
| 58 | 278 | $vocab = array(); |
| 59 | - $vocab[0] = 'None'; | |
| 279 | + $vocab[0] = 'None - documents cannot use this workflow.'; | |
| 60 | 280 | foreach($aStates as $state) { |
| 61 | 281 | $vocab[$state->getId()] = $state->getName(); |
| 62 | 282 | } |
| 63 | - $aOptions['vocab'] = $vocab; | |
| 64 | - $edit_fields[] = new KTLookupWidget(_('Starting State'), _('When a document has this workflow applied to it, to which state should it initially be set'), 'fStartStateId', $oWorkflow->getStartStateId(), $this->oPage, false, null, null, $aOptions); | |
| 283 | + $aOptions['vocab'] = $vocab; | |
| 284 | + $edit_fields[] = new KTLookupWidget(_('Starting State'), _('When a document has this workflow applied to it, to which state should it initially be set. <strong>Note that workflows without a starting state cannot be applied to documents.</strong>'), 'fStartStateId', $oWorkflow->getStartStateId(), $this->oPage, false, null, null, $aOptions); | |
| 285 | + if (is_null($oWorkflow->getStartStateId())) { | |
| 286 | + $this->oPage->addInfo(_('This workflow is currently disabled. To enable it, please assign a starting state in the "Edit workflow properties" box.')); | |
| 287 | + } | |
| 65 | 288 | |
| 289 | + /* | |
| 66 | 290 | $add_state_fields = array(); |
| 67 | 291 | $add_state_fields[] = new KTStringWidget(_('Name'), _('A human-readable name for the state.'), 'fName', null, $this->oPage, true); |
| 68 | 292 | |
| 69 | 293 | |
| 70 | - $add_transition_fields = array(); | |
| 71 | - $add_transition_fields[] = new KTStringWidget(_('Name'), _('A human-readable name for the transition.'), 'fName', null, $this->oPage, true); | |
| 72 | - $aOptions = array(); | |
| 73 | - $vocab = array(); | |
| 74 | - foreach($aStates as $state) { | |
| 75 | - $vocab[$state->getId()] = $state->getName(); | |
| 76 | - } | |
| 77 | - $aOptions['vocab'] = $vocab; | |
| 78 | - $add_transition_fields[] = new KTLookupWidget(_('Destination State'), _('Once this transition is complete, which state should the document be in?'), 'fTargetStateId', $oWorkflow->getStartStateId(), $this->oPage, true, null, null, $aOptions); | |
| 79 | - $aOptions = array(); | |
| 80 | - $vocab = array(); | |
| 81 | - foreach($aPermissions as $permission) { | |
| 82 | - $vocab[$permission->getId()] = $permission->getHumanName(); | |
| 83 | - } | |
| 84 | - $aOptions['vocab'] = $vocab; | |
| 85 | - $add_transition_fields[] = new KTLookupWidget(_('Guard Permission.'), _('Which permission must the user have in order to follow this transition?'), 'fPermissionId', $oWorkflow->getStartStateId(), $this->oPage, true, null, null, $aOptions); | |
| 294 | + */ | |
| 295 | + | |
| 86 | 296 | |
| 87 | - $this->aBreadcrumbs[] = array( | |
| 88 | - 'url' => $_SERVER['PHP_SELF'], | |
| 89 | - 'name' => _('Workflows'), | |
| 90 | - ); | |
| 91 | - $this->aBreadcrumbs[] = array( | |
| 92 | - 'url' => $_SERVER['PHP_SELF'], | |
| 93 | - 'query' => 'action=editWorkflow&fWorkflowId=' . $oWorkflow->getId(), | |
| 94 | - 'name' => $oWorkflow->getName(), | |
| 95 | - ); | |
| 96 | 297 | $oTemplate->setData(array( |
| 298 | + 'context' => $this, | |
| 97 | 299 | 'oWorkflow' => $oWorkflow, |
| 300 | + | |
| 98 | 301 | 'aStates' => $aStates, |
| 99 | - 'aTransitions' => KTWorkflowTransition::getByWorkflow($oWorkflow), | |
| 302 | + 'aTransitions' => $aInfo['transitions'], | |
| 100 | 303 | 'aPermissions' => $aPermissions, |
| 101 | - 'aActions' => KTDocumentActionUtil::getAllDocumentActions(), | |
| 102 | - 'aActionsSelected' => KTWorkflowUtil::getControlledActionsForWorkflow($oWorkflow), | |
| 304 | + 'aActions' => $aInfo['actions'], | |
| 305 | + 'aActionsSelected' => $aInfo['controlled_actions'], | |
| 306 | + | |
| 307 | + // info | |
| 308 | + 'workflow_info' => $aInfo, | |
| 103 | 309 | |
| 104 | - // fields | |
| 310 | + // subform | |
| 105 | 311 | 'edit_fields' => $edit_fields, |
| 106 | - 'add_state_fields' => $add_state_fields, | |
| 107 | - 'add_transition_fields' => $add_transition_fields, | |
| 108 | 312 | )); |
| 109 | 313 | return $oTemplate; |
| 110 | 314 | } |
| ... | ... | @@ -168,6 +372,137 @@ class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 168 | 372 | } |
| 169 | 373 | // }}} |
| 170 | 374 | |
| 375 | + function do_manageActions() { | |
| 376 | + $oTemplate =& $this->oValidator->validateTemplate('ktcore/workflow/manageActions'); | |
| 377 | + $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); | |
| 378 | + | |
| 379 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 380 | + | |
| 381 | + $oTemplate->setData(array( | |
| 382 | + 'context' => $this, | |
| 383 | + 'oWorkflow' => $oWorkflow, | |
| 384 | + | |
| 385 | + 'aActions' => $aInfo['actions'], | |
| 386 | + 'aActionsSelected' => $aInfo['controlled_actions'], | |
| 387 | + | |
| 388 | + // info | |
| 389 | + 'workflow_info' => $aInfo, | |
| 390 | + )); | |
| 391 | + return $oTemplate; | |
| 392 | + | |
| 393 | + } | |
| 394 | + | |
| 395 | + function do_manageStates() { | |
| 396 | + $oTemplate =& $this->oValidator->validateTemplate('ktcore/workflow/manageStates'); | |
| 397 | + $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); | |
| 398 | + | |
| 399 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 400 | + | |
| 401 | + $add_fields = array(); | |
| 402 | + $add_fields[] = new KTStringWidget(_('Name'), _('A human-readable name for the state.'), 'fName', null, $this->oPage, true); | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + $oTemplate->setData(array( | |
| 407 | + 'context' => $this, | |
| 408 | + 'oWorkflow' => $oWorkflow, | |
| 409 | + | |
| 410 | + // info | |
| 411 | + 'workflow_info' => $aInfo, | |
| 412 | + | |
| 413 | + // subform | |
| 414 | + 'add_fields' => $add_fields, | |
| 415 | + )); | |
| 416 | + return $oTemplate; | |
| 417 | + } | |
| 418 | + | |
| 419 | + function do_manageTransitions() { | |
| 420 | + $oTemplate =& $this->oValidator->validateTemplate('ktcore/workflow/manageTransitions'); | |
| 421 | + $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); | |
| 422 | + | |
| 423 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 424 | + | |
| 425 | + $add_transition_fields = array(); | |
| 426 | + $add_transition_fields[] = new KTStringWidget(_('Name'), _('A human-readable name for the transition.'), 'fName', null, $this->oPage, true); | |
| 427 | + $aOptions = array(); | |
| 428 | + $vocab = array(); | |
| 429 | + foreach($aInfo['states'] as $state) { | |
| 430 | + $vocab[$state->getId()] = $state->getName(); | |
| 431 | + } | |
| 432 | + $aOptions['vocab'] = $vocab; | |
| 433 | + $add_transition_fields[] = new KTLookupWidget(_('Destination State'), _('Once this transition is complete, which state should the document be in?'), 'fTargetStateId', $oWorkflow->getStartStateId(), $this->oPage, true, null, null, $aOptions); | |
| 434 | + $aOptions = array(); | |
| 435 | + $vocab = array(); | |
| 436 | + foreach($aInfo['permissions'] as $permission) { | |
| 437 | + $vocab[$permission->getId()] = $permission->getHumanName(); | |
| 438 | + } | |
| 439 | + $aOptions['vocab'] = $vocab; | |
| 440 | + $add_transition_fields[] = new KTLookupWidget(_('Guard Permission.'), _('Which permission must the user have in order to follow this transition?'), 'fPermissionId', $oWorkflow->getStartStateId(), $this->oPage, true, null, null, $aOptions); | |
| 441 | + | |
| 442 | + $oTemplate->setData(array( | |
| 443 | + 'context' => $this, | |
| 444 | + 'oWorkflow' => $oWorkflow, | |
| 445 | + | |
| 446 | + // info | |
| 447 | + 'workflow_info' => $aInfo, | |
| 448 | + | |
| 449 | + // subform | |
| 450 | + 'add_fields' => $add_transition_fields, | |
| 451 | + )); | |
| 452 | + return $oTemplate; | |
| 453 | + } | |
| 454 | + | |
| 455 | + function do_setTransitionAvailability() { | |
| 456 | + $oTemplate =& $this->oValidator->validateTemplate('ktcore/workflow/editWorkflow'); | |
| 457 | + $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); | |
| 458 | + | |
| 459 | + $transitionMap = (array) KTUtil::arrayGet($_REQUEST, 'fTransitionAvailability'); | |
| 460 | + | |
| 461 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 462 | + | |
| 463 | + $this->startTransaction(); | |
| 464 | + foreach ($aInfo['states'] as $oState) { | |
| 465 | + | |
| 466 | + $a = (array) $transitionMap[$oState->getId()]; | |
| 467 | + $transitions = array(); | |
| 468 | + foreach ($a as $tid => $on) { $transitions[] = $tid; } | |
| 469 | + | |
| 470 | + $res = KTWorkflowUtil::saveTransitionsFrom($oState, $transitions); | |
| 471 | + if (PEAR::isError($res)) { | |
| 472 | + $this->errorRedirectTo('manageTransitions', _('Error updating transitions:') . $res->getMessage(), sprintf('fWorkflowId=%d', $oWorkflow->getId())); | |
| 473 | + } | |
| 474 | + } | |
| 475 | + $this->commitTransaction(); | |
| 476 | + | |
| 477 | + $this->successRedirectTo('manageTransitions', _('Availability updated.'), sprintf('fWorkflowId=%d', $oWorkflow->getId())); | |
| 478 | + } | |
| 479 | + | |
| 480 | + | |
| 481 | + function do_updateActionAvailability() { | |
| 482 | + $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); | |
| 483 | + | |
| 484 | + $actionMap = (array) KTUtil::arrayGet($_REQUEST, 'fAvailableActions'); | |
| 485 | + | |
| 486 | + $aInfo = $this->buildWorkflowInfo($oWorkflow); | |
| 487 | + | |
| 488 | + $this->startTransaction(); | |
| 489 | + foreach ($aInfo['states'] as $oState) { | |
| 490 | + | |
| 491 | + $a = (array) $actionMap[$oState->getId()]; | |
| 492 | + $actions = array_keys($a); | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + $res = KTWorkflowUtil::setEnabledActionsForState($oState, $actions); | |
| 497 | + if (PEAR::isError($res)) { | |
| 498 | + $this->errorRedirectTo('manageActions', _('Error updating actions:') . $res->getMessage(), sprintf('fWorkflowId=%d', $oWorkflow->getId())); | |
| 499 | + } | |
| 500 | + } | |
| 501 | + $this->commitTransaction(); | |
| 502 | + | |
| 503 | + $this->successRedirectTo('manageActions', _('Action availability updated.'), sprintf('fWorkflowId=%d', $oWorkflow->getId())); | |
| 504 | + } | |
| 505 | + | |
| 171 | 506 | // {{{ do_setWorkflowActions |
| 172 | 507 | function do_setWorkflowActions() { |
| 173 | 508 | $oWorkflow =& $this->oValidator->validateWorkflow($_REQUEST['fWorkflowId']); |
| ... | ... | @@ -247,9 +582,14 @@ class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 247 | 582 | 'query' => 'action=editWorkflow&fWorkflowId=' . $oWorkflow->getId(), |
| 248 | 583 | 'name' => $oWorkflow->getName(), |
| 249 | 584 | ); |
| 250 | - $this->oPage->setBreadcrumbDetails(_('state') . ': ' . $oState->getName()); | |
| 585 | + $this->oPage->setBreadcrumbDetails(_('State') . ': ' . $oState->getName()); | |
| 251 | 586 | |
| 252 | 587 | $aInformed = KTWorkflowUtil::getInformedForState($oState); |
| 588 | + | |
| 589 | + | |
| 590 | + $editForm = array(); | |
| 591 | + $editForm[] = new KTStringWidget(_('Name'), _('A human-readable name for this state. This is shown on the "Browse" page, as well as on the user\'s workflow page.'), 'fName', $oState->getName(), $this->oPage, true); | |
| 592 | + | |
| 253 | 593 | $oTemplate->setData(array( |
| 254 | 594 | 'oWorkflow' => $oWorkflow, |
| 255 | 595 | 'oState' => $oState, |
| ... | ... | @@ -263,6 +603,7 @@ class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 263 | 603 | 'aRoles' => Role::getList(), |
| 264 | 604 | 'aUsers' => User::getList(), |
| 265 | 605 | 'aInformed' => $aInformed, |
| 606 | + 'editForm' => $editForm, | |
| 266 | 607 | )); |
| 267 | 608 | return $oTemplate; |
| 268 | 609 | } |
| ... | ... | @@ -402,7 +743,7 @@ class KTWorkflowDispatcher extends KTAdminDispatcher { |
| 402 | 743 | 'redirect_to' => array('editWorkflow', 'fWorkflowId=' . $oWorkflow->getId()), |
| 403 | 744 | 'message' => _('Could not create workflow transition'), |
| 404 | 745 | )); |
| 405 | - $this->successRedirectTo('editWorkflow', _('Workflow transition created'), 'fWorkflowId=' . $oWorkflow->getId()); | |
| 746 | + $this->successRedirectTo('editTransition', _('Workflow transition created'), sprintf('fWorkflowId=%d&fTransitionId=%d', $oWorkflow->getId(), $res->getId())); | |
| 406 | 747 | exit(0); |
| 407 | 748 | } |
| 408 | 749 | // }}} | ... | ... |
resources/css/kt-framing.css
| ... | ... | @@ -103,6 +103,11 @@ body |
| 103 | 103 | { |
| 104 | 104 | border-bottom: 1px solid white; |
| 105 | 105 | } |
| 106 | + | |
| 107 | +.ktLoggedInUser { | |
| 108 | + font-weight: bold; | |
| 109 | +} | |
| 110 | + | |
| 106 | 111 | /* |
| 107 | 112 | a.main_nav_item { |
| 108 | 113 | background: transparent url(../../resources/graphics/home-navbar.gif) center left no-repeat; |
| ... | ... | @@ -580,9 +585,9 @@ a.main_nav_item { |
| 580 | 585 | .ktInfo |
| 581 | 586 | { |
| 582 | 587 | padding: 0 1em; |
| 583 | - border: 1px solid #ffc21e; | |
| 588 | + border: 1px solid #c5c5c5; | |
| 584 | 589 | margin: 0.5em 0; |
| 585 | - background: #ffdd80; | |
| 590 | + background: #dedede; | |
| 586 | 591 | } |
| 587 | 592 | |
| 588 | 593 | .ktInfo p { |
| ... | ... | @@ -655,6 +660,8 @@ The text will be hidden for screen view. The generic fahrner-ish approach comes |
| 655 | 660 | |
| 656 | 661 | /* =========== standard listings. */ |
| 657 | 662 | |
| 663 | + | |
| 664 | + | |
| 658 | 665 | .listing td { |
| 659 | 666 | padding: 0.5em; |
| 660 | 667 | vertical-align: top; | ... | ... |
resources/css/workflow-admin.css
0 โ 100644
| 1 | +#workflow-states-list { | |
| 2 | + list-style-type: none; | |
| 3 | + margin-left: 0; | |
| 4 | + padding-left: 0; | |
| 5 | +} | |
| 6 | + | |
| 7 | +#workflow-states-list ul { | |
| 8 | + list-style-type: none; | |
| 9 | + margin-left: 0; | |
| 10 | + padding-left: 1em; | |
| 11 | + border-top: 1px solid #dedede; | |
| 12 | + margin-top: 0.5em; | |
| 13 | + margin-bottom: 1.5em; | |
| 14 | +} | |
| 15 | + | |
| 16 | +.workflow_element { | |
| 17 | + font-weight: bold; | |
| 18 | +} | |
| 0 | 19 | \ No newline at end of file | ... | ... |
templates/kt3/standard_page.smarty
| ... | ... | @@ -64,9 +64,7 @@ |
| 64 | 64 | |
| 65 | 65 | <!-- user menu --> |
| 66 | 66 | <li class="pref">{if ($page->user)} |
| 67 | - Logged in as <strong>{$page->user->getName()}</strong> | |
| 68 | - {else} | |
| 69 | - FIXME: page does not set user. | |
| 67 | + <span class="ktLoggedInUser">{$page->user->getName()}</span> | |
| 70 | 68 | {/if} |
| 71 | 69 | · |
| 72 | 70 | ... | ... |
templates/ktcore/help_with_edit.smarty
| 1 | -<p><a href="{$rootUrl}/admin.php/misc/helpmanagement?action=customise&name={$target_name}">Edit this help page.</a></p> | |
| 2 | 1 | {if (!$help_body)} |
| 3 | 2 | <div class="ktError"><p>No content specified for this help file yet. <strong>Edit it first.</strong></p></div> |
| 4 | 3 | {else} |
| 5 | 4 | {$help_body} |
| 6 | -{/if} | |
| 7 | 5 | \ No newline at end of file |
| 6 | +{/if} | |
| 7 | + | |
| 8 | +<hr /> | |
| 9 | +<p><a href="{$rootUrl}/admin.php/misc/helpmanagement?action=customise&name={$target_name}" class="ktAction ktEdit" style="float: | |
| 10 | +left; padding-right: 0.5em;">{i18n}Edit this help page.{/i18n}</a><a href="{$rootUrl}/admin.php/misc/helpmanagement?action=customise&name={$target_name}">{i18n}Edit this help page.{/i18n}</a></p> | |
| 8 | 11 | \ No newline at end of file | ... | ... |
templates/ktcore/metadata/listFieldsets.smarty
templates/ktcore/workflow/admin_portlet.smarty
0 โ 100644
templates/ktcore/workflow/createState.smarty
0 โ 100644
| 1 | +<h2>{i18n}New State{/i18n}</h2> | |
| 2 | + | |
| 3 | +<p class="descriptiveText">As documents move through their lifecycle, they | |
| 4 | +are placed in certain <strong>states</strong>. For example, an invoice | |
| 5 | +which has been mailed might be in the "Pending" <strong>state</strong> after | |
| 6 | +the "sent" <strong>transition</strong> has been performed by a user.</p> | |
| 7 | + | |
| 8 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 9 | +<fieldset> | |
| 10 | +<legend>{i18n}Edit state properties{/i18n}</legend> | |
| 11 | +<input type="hidden" name="action" value="saveState" /> | |
| 12 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 13 | +<input type="hidden" name="fStateId" value="{$oState->getId()}" /> | |
| 14 | +{foreach item=oWidget from=$editForm} | |
| 15 | + {$oWidget->render()} | |
| 16 | +{/foreach} | |
| 17 | +<div class="form_actions"> | |
| 18 | + <input type="submit" name="submit" value="{i18n}Save{/i18n}" /> | |
| 19 | +</div> | |
| 20 | +</fieldset> | |
| 21 | +</form> | |
| 22 | + | |
| 23 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 24 | +<input type="hidden" name="action" value="saveInform" /> | |
| 25 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 26 | +<input type="hidden" name="fStateId" value="{$oState->getId()}" /> | |
| 27 | + | |
| 28 | +<fieldset> | |
| 29 | +<legend>{i18n}Inform Which Users?{/i18n}</legend> | |
| 30 | +<p class="descriptiveText">{i18n}Please select which roles or groups should be | |
| 31 | +informed when this state is reached.{/i18n}</p> | |
| 32 | + | |
| 33 | + | |
| 34 | +{if $aRoles} | |
| 35 | +<h3>{i18n}Roles{/i18n}</h3> | |
| 36 | +{entity_checkboxes entities=$aRoles name="fRoleIds" multiple="true" selected=$aInformed.role assign=aBoxes} | |
| 37 | +{foreach from=$aBoxes item=sBox} | |
| 38 | +{$sBox}<br /> | |
| 39 | +{/foreach} | |
| 40 | +{/if} | |
| 41 | + | |
| 42 | +<h3>{i18n}Groups{/i18n}</h3> | |
| 43 | +{entity_checkboxes entities=$aGroups name="fGroupIds" multiple="true" selected=$aInformed.group assign=aBoxes} | |
| 44 | +{foreach from=$aBoxes item=sBox} | |
| 45 | +{$sBox}<br /> | |
| 46 | +{/foreach} | |
| 47 | + | |
| 48 | +{* | |
| 49 | +<h3>{i18n}Users{/i18n}</h3> | |
| 50 | +{entity_checkboxes entities=$aUsers name="fUserIds" multiple="true" selected=$aInformed.user assign=aBoxes} | |
| 51 | +{foreach from=$aBoxes item=sBox} | |
| 52 | +{$sBox}<br /> | |
| 53 | +{/foreach} | |
| 54 | +<input type="submit" name="submit" value="{i18n}Save{/i18n}" /> | |
| 55 | + | |
| 56 | +</form> | |
| 57 | +*} | |
| 58 | + | |
| 59 | +</fieldset> | |
| 60 | + | |
| 61 | + | |
| 62 | +{* | |
| 63 | +<h3>{i18n}Assigned Permissions{/i18n}</h3> | |
| 64 | +<p class="descriptiveText">{i18n}While in this workflow state, additional permissions | |
| 65 | +may be given. This is done either to expose the document to more users | |
| 66 | +or to allow a particular role to be fulfilled before a workflow | |
| 67 | +transition can be accomplished.{/i18n}</p> | |
| 68 | +*} | |
| 69 | + | |
| 70 | + | |
| 71 | +<fieldset> | |
| 72 | +<legend>{i18n}Transitions{/i18n}</legend> | |
| 73 | + | |
| 74 | +<p class="descriptiveText">{i18n}Transitions are how documents move from one | |
| 75 | +state to another. Typically, most transitions can only be performed by people | |
| 76 | +with a specific <strong>role</strong> (e.g. Manager) or part of a specific group | |
| 77 | +(e.g. Marketing Department).{/i18n}</p> | |
| 78 | + | |
| 79 | +{if $aTransitionsTo} | |
| 80 | +<h3>{i18n}Transitions to this state{/i18n}</h3> | |
| 81 | +{if (!empty($aTransitionsTo))} | |
| 82 | +<ul> | |
| 83 | +{foreach from=$aTransitionsTo item=oTransition} | |
| 84 | + <li><a | |
| 85 | +href="?action=editTransition&fWorkflowId={$oWorkflow->getId()}&fTransitionId={$oTransition->getId()}" | |
| 86 | +title="Transition | |
| 87 | +{$oTransition->getId()}">{$oTransition->getName()|escape}</a></li> | |
| 88 | +{/foreach} | |
| 89 | +</ul> | |
| 90 | + | |
| 91 | +{/if} | |
| 92 | +{else} | |
| 93 | +<div class="ktInfo"><p>{i18n}No transitions lead to this state.{/i18n}</p></div> | |
| 94 | +{/if} | |
| 95 | + | |
| 96 | +<h3>{i18n}Transitions from this state{/i18n}</h3> | |
| 97 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 98 | +<input type="hidden" name="action" value="saveTransitions" /> | |
| 99 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 100 | +<input type="hidden" name="fStateId" value="{$oState->getId()}" /> | |
| 101 | + | |
| 102 | +{if (!empty($aTransitions))} | |
| 103 | +{entity_checkboxes entities=$aTransitions name="fTransitionIds" multiple="true" selected=$aTransitionsSelected separator="<br />"} | |
| 104 | +<div class="form_actions"> | |
| 105 | +<input type="submit" name="submit" value="{i18n}Save{/i18n}" /> | |
| 106 | +</div> | |
| 107 | +{else} | |
| 108 | +<div class="ktInfo"><p>{i18n}No transitions have been defined for this workflow.{/i18n}</p></div> | |
| 109 | +{/if} | |
| 110 | +</form> | |
| 111 | +</fieldset> | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 117 | +<fieldset> | |
| 118 | +<legend>Actions allowed</legend> | |
| 119 | + | |
| 120 | +<input type="hidden" name="action" value="setStateActions" /> | |
| 121 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 122 | +<input type="hidden" name="fStateId" value="{$oState->getId()}" /> | |
| 123 | + | |
| 124 | +{if (!empty($aActions))} | |
| 125 | +<ul> | |
| 126 | +{entity_checkboxes name="fActions" entities=$aActions idmethod="getName" method="getDisplayName" assign="aCheckboxes" selected="$aActionsSelected"} | |
| 127 | +{foreach from=$aCheckboxes item=sCheckbox} | |
| 128 | +<li>{$sCheckbox}</li> | |
| 129 | +{/foreach} | |
| 130 | +</ul> | |
| 131 | +<div class="form_actions"> | |
| 132 | + <input type="submit" name="submit" value="Set allowed actions" /> | |
| 133 | +</div> | |
| 134 | +{else} | |
| 135 | +No actions defined. | |
| 136 | +{/if} | |
| 137 | +</fieldset> | |
| 138 | +</form> | |
| 139 | + | ... | ... |
templates/ktcore/workflow/documentWorkflow.smarty
| ... | ... | @@ -25,7 +25,7 @@ lifecycle of the document.{/i18n} |
| 25 | 25 | </form> |
| 26 | 26 | {else} |
| 27 | 27 | <h3>{i18n}No defined workflows{/i18n}</h3> |
| 28 | -<div class="ktError"> | |
| 28 | +<div class="ktInfo"> | |
| 29 | 29 | <p>{i18n}There are no defined workflows which can be started on this |
| 30 | 30 | document. An administrator can create workflows to map the lifecycle of |
| 31 | 31 | a document. Contact your administrator to discuss | ... | ... |
templates/ktcore/workflow/editState.smarty
| 1 | 1 | <h2>{i18n}State{/i18n}: {$oState->getName()|escape}</h2> |
| 2 | 2 | |
| 3 | +<p class="descriptiveText">As documents move through their lifecycle, they | |
| 4 | +are placed in certain <strong>states</strong>. For example, an invoice | |
| 5 | +which has been mailed might be in the "Pending" <strong>state</strong> after | |
| 6 | +the "sent" <strong>transition</strong> has been performed by a user.</p> | |
| 7 | + | |
| 3 | 8 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| 4 | 9 | <fieldset> |
| 5 | 10 | <legend>{i18n}Edit state properties{/i18n}</legend> |
| 6 | 11 | <input type="hidden" name="action" value="saveState" /> |
| 7 | 12 | <input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> |
| 8 | 13 | <input type="hidden" name="fStateId" value="{$oState->getId()}" /> |
| 9 | -<input type="textbox" name="fName" value="{$oState->getName()|escape}" /> | |
| 14 | +{foreach item=oWidget from=$editForm} | |
| 15 | + {$oWidget->render()} | |
| 16 | +{/foreach} | |
| 10 | 17 | <div class="form_actions"> |
| 11 | 18 | <input type="submit" name="submit" value="{i18n}Save{/i18n}" /> |
| 12 | 19 | </div> |
| 13 | 20 | </fieldset> |
| 14 | 21 | </form> |
| 15 | - | |
| 22 | +{* | |
| 16 | 23 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| 17 | 24 | <input type="hidden" name="action" value="saveInform" /> |
| 18 | 25 | <input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> |
| ... | ... | @@ -32,25 +39,20 @@ informed when this state is reached.{/i18n}</p> |
| 32 | 39 | {/foreach} |
| 33 | 40 | {/if} |
| 34 | 41 | |
| 42 | +{if $aGroups} | |
| 35 | 43 | <h3>{i18n}Groups{/i18n}</h3> |
| 36 | 44 | {entity_checkboxes entities=$aGroups name="fGroupIds" multiple="true" selected=$aInformed.group assign=aBoxes} |
| 37 | 45 | {foreach from=$aBoxes item=sBox} |
| 38 | 46 | {$sBox}<br /> |
| 39 | 47 | {/foreach} |
| 48 | +{/if} | |
| 40 | 49 | |
| 41 | -{* | |
| 42 | -<h3>{i18n}Users{/i18n}</h3> | |
| 43 | -{entity_checkboxes entities=$aUsers name="fUserIds" multiple="true" selected=$aInformed.user assign=aBoxes} | |
| 44 | -{foreach from=$aBoxes item=sBox} | |
| 45 | -{$sBox}<br /> | |
| 46 | -{/foreach} | |
| 47 | -<input type="submit" name="submit" value="{i18n}Save{/i18n}" /> | |
| 48 | - | |
| 49 | -</form> | |
| 50 | -*} | |
| 50 | +{if (empty($aGroups) && empty($aRoles))} | |
| 51 | +<div class="ktInfo"><p>{i18n}No groups or roles are defined in the DMS.{/i18n}</p></div> | |
| 52 | +{/if} | |
| 51 | 53 | |
| 52 | 54 | </fieldset> |
| 53 | - | |
| 55 | +*} | |
| 54 | 56 | |
| 55 | 57 | {* |
| 56 | 58 | <h3>{i18n}Assigned Permissions{/i18n}</h3> |
| ... | ... | @@ -63,9 +65,13 @@ transition can be accomplished.{/i18n}</p> |
| 63 | 65 | |
| 64 | 66 | <fieldset> |
| 65 | 67 | <legend>{i18n}Transitions{/i18n}</legend> |
| 66 | -{if $aTransitionsTo} | |
| 67 | 68 | |
| 69 | +<p class="descriptiveText">{i18n}Transitions are how documents move from one | |
| 70 | +state to another. Typically, most transitions can only be performed by people | |
| 71 | +with a specific <strong>role</strong> (e.g. Manager) or part of a specific group | |
| 72 | +(e.g. Marketing Department).{/i18n}</p> | |
| 68 | 73 | |
| 74 | +{if $aTransitionsTo} | |
| 69 | 75 | <h3>{i18n}Transitions to this state{/i18n}</h3> |
| 70 | 76 | {if (!empty($aTransitionsTo))} |
| 71 | 77 | <ul> |
| ... | ... | @@ -76,11 +82,11 @@ title="Transition |
| 76 | 82 | {$oTransition->getId()}">{$oTransition->getName()|escape}</a></li> |
| 77 | 83 | {/foreach} |
| 78 | 84 | </ul> |
| 79 | -{else} | |
| 80 | -{i18n}No transitions lead to this state.{/i18n} | |
| 81 | -{/if} | |
| 82 | 85 | |
| 83 | 86 | {/if} |
| 87 | +{else} | |
| 88 | +<div class="ktInfo"><p>{i18n}No transitions lead to this state.{/i18n}</p></div> | |
| 89 | +{/if} | |
| 84 | 90 | |
| 85 | 91 | <h3>{i18n}Transitions from this state{/i18n}</h3> |
| 86 | 92 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| ... | ... | @@ -89,12 +95,12 @@ title="Transition |
| 89 | 95 | <input type="hidden" name="fStateId" value="{$oState->getId()}" /> |
| 90 | 96 | |
| 91 | 97 | {if (!empty($aTransitions))} |
| 92 | -{entity_checkboxes entities=$aTransitions name="fTransitionIds" multiple="true" selected=$aTransitionsSelected} | |
| 98 | +{entity_checkboxes entities=$aTransitions name="fTransitionIds" multiple="true" selected=$aTransitionsSelected separator="<br />"} | |
| 93 | 99 | <div class="form_actions"> |
| 94 | 100 | <input type="submit" name="submit" value="{i18n}Save{/i18n}" /> |
| 95 | 101 | </div> |
| 96 | 102 | {else} |
| 97 | -{i18n}No transitions defined.{/i18n} | |
| 103 | +<div class="ktInfo"><p>{i18n}No transitions have been defined for this workflow.{/i18n}</p></div> | |
| 98 | 104 | {/if} |
| 99 | 105 | </form> |
| 100 | 106 | </fieldset> |
| ... | ... | @@ -102,6 +108,8 @@ title="Transition |
| 102 | 108 | |
| 103 | 109 | |
| 104 | 110 | |
| 111 | + | |
| 112 | +{if (!empty($aActions))} | |
| 105 | 113 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| 106 | 114 | <fieldset> |
| 107 | 115 | <legend>Actions allowed</legend> |
| ... | ... | @@ -110,7 +118,6 @@ title="Transition |
| 110 | 118 | <input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> |
| 111 | 119 | <input type="hidden" name="fStateId" value="{$oState->getId()}" /> |
| 112 | 120 | |
| 113 | -{if (!empty($aActions))} | |
| 114 | 121 | <ul> |
| 115 | 122 | {entity_checkboxes name="fActions" entities=$aActions idmethod="getName" method="getDisplayName" assign="aCheckboxes" selected="$aActionsSelected"} |
| 116 | 123 | {foreach from=$aCheckboxes item=sCheckbox} |
| ... | ... | @@ -120,9 +127,11 @@ title="Transition |
| 120 | 127 | <div class="form_actions"> |
| 121 | 128 | <input type="submit" name="submit" value="Set allowed actions" /> |
| 122 | 129 | </div> |
| 123 | -{else} | |
| 124 | -No actions defined. | |
| 125 | -{/if} | |
| 126 | 130 | </fieldset> |
| 127 | 131 | </form> |
| 132 | +{else} | |
| 133 | +<div class="ktInfo"><p>No actions are controlled by this workflow, so all actions are available when | |
| 134 | +documents are in this state.</p></div> | |
| 135 | +{/if} | |
| 136 | + | |
| 128 | 137 | ... | ... |
templates/ktcore/workflow/editWorkflow.smarty
| 1 | -<h2>{i18n}Workflow{/i18n}: {$oWorkflow->getName()|escape}</h2> | |
| 2 | - | |
| 1 | +{$context->oPage->requireCSSResource('resources/css/workflow-admin.css')} | |
| 3 | 2 | |
| 3 | +<h2>{i18n}Workflow Overview{/i18n}: {$oWorkflow->getName()|escape}</h2> | |
| 4 | 4 | |
| 5 | 5 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| 6 | 6 | <fieldset> |
| ... | ... | @@ -18,98 +18,34 @@ |
| 18 | 18 | </fieldset> |
| 19 | 19 | </form> |
| 20 | 20 | |
| 21 | -<h3>States</h3> | |
| 22 | -<p class="descriptiveText"><strong>FIXME</strong> insert intelligent help.</p> | |
| 23 | -<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 24 | -<fieldset> | |
| 25 | -<legend>{i18n}Create a new state{/i18n}</legend> | |
| 26 | -<input type="hidden" name="action" value="newState" /> | |
| 27 | -<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 28 | - | |
| 29 | - | |
| 30 | -{foreach item=oWidget from=$add_state_fields} | |
| 31 | - {$oWidget->render()} | |
| 32 | -{/foreach} | |
| 33 | - | |
| 34 | -<div class="form_actions"> | |
| 35 | -<input type="submit" name="submit" value="{i18n}Create state{/i18n}" /> | |
| 36 | -</div> | |
| 37 | -</fieldset> | |
| 38 | -</form> | |
| 39 | - | |
| 40 | -{if $aStates} | |
| 41 | -<h4>{i18n}Existing states{/i18n}</h4> | |
| 42 | -<p class="descriptiveText">{i18n}Select a state to update its properties.{/i18n}</p> | |
| 43 | -<ul> | |
| 44 | -{foreach from=$aStates item=oState} | |
| 45 | - <li><a | |
| 46 | -href="?action=editState&fWorkflowId={$oWorkflow->getId()}&fStateId={$oState->getId()}" | |
| 47 | -title="State {$oState->getId()}">{$oState->getName()|escape}</a></li> | |
| 48 | -{/foreach} | |
| 49 | -</ul> | |
| 50 | -{/if} | |
| 51 | - | |
| 52 | - | |
| 53 | - | |
| 54 | - | |
| 55 | -{* check that there are states, and, if not, don't show transitions *} | |
| 56 | -{if $aStates} | |
| 57 | - | |
| 58 | -<h3>{i18n}Transitions{/i18n}</h3> | |
| 59 | - | |
| 60 | -<p class="descriptiveText"><strong>FIXME</strong> insert intelligent help.</p> | |
| 61 | - | |
| 62 | -<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 63 | -<fieldset> | |
| 64 | -<legend>{i18n}Create a new transition{/i18n}</legend> | |
| 65 | -<input type="hidden" name="action" value="newTransition" /> | |
| 66 | -<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 67 | - | |
| 68 | - | |
| 69 | -{foreach item=oWidget from=$add_transition_fields} | |
| 70 | - {$oWidget->render()} | |
| 71 | -{/foreach} | |
| 72 | - | |
| 73 | -<div class="form_actions"> | |
| 74 | -<input type="submit" name="submit" value="{i18n}Create transition{/i18n}" /> | |
| 75 | -</div> | |
| 76 | -</fieldset> | |
| 77 | -</form> | |
| 78 | - | |
| 79 | - | |
| 80 | -{if $aTransitions} | |
| 81 | -<h3>{i18n}Existing transitions{/i18n}</h3> | |
| 82 | - | |
| 83 | -<ul> | |
| 84 | -{foreach from=$aTransitions item=oTransition} | |
| 85 | - <li><a | |
| 86 | -href="?action=editTransition&fWorkflowId={$oWorkflow->getId()}&fTransitionId={$oTransition->getId()}" | |
| 87 | -title="Transition {$oTransition->getId()}">{$oTransition->getName()|escape}</a></li> | |
| 21 | +<p class="descriptiveText">{i18n}This page allows you to get a quick overview of the | |
| 22 | +workflow. To modify items, either select them from the overview below, | |
| 23 | +or use the "Workflow" menu on the left to create new ones.{/i18n}</p> | |
| 24 | + | |
| 25 | +{if (empty($aStates))} | |
| 26 | +<div class="ktInfo"><p>This workflow does not define any states. Please use the | |
| 27 | +Workflow menu (on the left) to create new states.</p></div> | |
| 28 | +{else} | |
| 29 | +<ul id="workflow-states-list"> | |
| 30 | +{foreach item=oState from=$aStates} | |
| 31 | + <li><span class="workflow_element">State:</span> <a href="{$smarty.server.PHP_SELF}?action=editState&fStateId={$oState->getId()}&fWorkflowId={$oWorkflow->getId()}" class="workflow_label">{$oState->getName()}</a> | |
| 32 | + <ul> | |
| 33 | + <li>{i18n}Notified groups & roles:{/i18n} | |
| 34 | + {$context->getNotificationStringForState($oState)} | |
| 35 | + </li> | |
| 36 | + <li>{i18n}Actions available: {/i18n} | |
| 37 | + {$context->getActionStringForState($oState)} | |
| 38 | + </li> | |
| 39 | + | |
| 40 | + <li>{i18n}Transitions available: {/i18n} | |
| 41 | + {$context->getTransitionFromStringForState($oState)} | |
| 42 | + </li> | |
| 43 | + | |
| 44 | + <li>{i18n}Transitions to this state: {/i18n} | |
| 45 | + {$context->getTransitionToStringForState($oState)} | |
| 46 | + </li> | |
| 47 | + </ul> | |
| 48 | + </li> | |
| 88 | 49 | {/foreach} |
| 89 | 50 | </ul> |
| 90 | -{/if} | |
| 91 | - | |
| 92 | -{/if} | |
| 93 | - | |
| 94 | - | |
| 95 | - | |
| 96 | -<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 97 | -<fieldset> | |
| 98 | -<legend>{i18n}Actions controlled{/i18n}</legend> | |
| 99 | - | |
| 100 | -<p class="descriptiveText"><strong>FIXME</strong> be helpful</p> | |
| 101 | - | |
| 102 | -<input type="hidden" name="action" value="setWorkflowActions" /> | |
| 103 | -<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 104 | - | |
| 105 | -<ul> | |
| 106 | -{entity_checkboxes name="fActions" entities=$aActions idmethod="getName" method="getDisplayName" assign="aCheckboxes" selected="$aActionsSelected"} | |
| 107 | -{foreach from=$aCheckboxes item=sCheckbox} | |
| 108 | -<li>{$sCheckbox}</li> | |
| 109 | -{/foreach} | |
| 110 | -</ul> | |
| 111 | -<div class="form_actions"> | |
| 112 | - <input type="submit" name="submit" value="{i18n}Set controlled actions{/i18n}" /> | |
| 113 | -</div> | |
| 114 | -</fieldset> | |
| 115 | -</form> | |
| 51 | +{/if} | |
| 116 | 52 | \ No newline at end of file | ... | ... |
templates/ktcore/workflow/listWorkflows.smarty
| 1 | -<h2>{i18n}Workflow{/i18n}</h2> | |
| 1 | +<h2>{i18n}Workflows{/i18n}</h2> | |
| 2 | + | |
| 3 | +<p class="descriptiveText">{i18n}Workflow is a description of a document's lifecycle. It is made up of | |
| 4 | +workflow states, which describe where in the lifecycle the document is, | |
| 5 | +and workflow transitions, which describe the next steps within the | |
| 6 | +lifecycle of the document.{/i18n}</p> | |
| 2 | 7 | |
| 3 | 8 | <form action="{$smarty.server.PHP_SELF}" method="POST"> |
| 4 | 9 | <fieldset> | ... | ... |
templates/ktcore/workflow/manageActions.smarty
0 โ 100644
| 1 | +{$context->oPage->requireCSSResource('resources/css/workflow-admin.css')} | |
| 2 | +<h2>{i18n}Manage Actions{/i18n}</h2> | |
| 3 | + | |
| 4 | +<p class="descriptiveText">{i18n}An important part of workflow is controlling which | |
| 5 | +actions are available to users at various stages. For example, it may be | |
| 6 | +necessary to prevent the "Edit Metadata" action from being used when a document | |
| 7 | +is "published". Doing this is a two step process: first, you need to specify | |
| 8 | +that "Edit Metadata" is an action you wish to control within this workflow; second, | |
| 9 | +you need to specify that the action is <strong>not</strong> to be made available | |
| 10 | +when documents are in the "published" state.{/i18n}</p> | |
| 11 | + | |
| 12 | +<form> | |
| 13 | +<fieldset><legend>{i18n}Specify Controlled Actions{/i18n}</legend> | |
| 14 | +<p class="descriptiveText">{i18n}Select the actions you want this workflow | |
| 15 | +to control from the list below. Actions you do not specify will be available no | |
| 16 | +matter what the state of the document.{/i18n}</p> | |
| 17 | + | |
| 18 | +<input type="hidden" name="action" value="setWorkflowActions" /> | |
| 19 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 20 | + | |
| 21 | + | |
| 22 | +{entity_checkboxes name="fActions" entities="$aActions" idmethod="getName" method="getDisplayName" assign="aCheckboxes" selected="$aActionsSelected" separator="<br />"} | |
| 23 | +{foreach from=$aCheckboxes item=sCheckbox} | |
| 24 | +{$sCheckbox} | |
| 25 | +{/foreach} | |
| 26 | + | |
| 27 | +<div class="form_actions"> | |
| 28 | + <input type="submit" name="submit" value="{i18n}Set controlled actions{/i18n}" /> | |
| 29 | +</div> | |
| 30 | + | |
| 31 | +</fieldset> | |
| 32 | +</form> | |
| 33 | + | |
| 34 | +<h3>Assign Actions to States</h3> | |
| 35 | + | |
| 36 | +<p class="descriptiveText">The table below lists the actions you have specified | |
| 37 | +as controlled by this workflow, and all the states within the workflow. From here | |
| 38 | +you can assign those actions to the various states in this workflow.</p> | |
| 39 | + | |
| 40 | +{if (empty($aActionsSelected))} | |
| 41 | +<div class="ktInfo"><p>{i18n}No actions are controlled by this workflow. All actions | |
| 42 | +will be available at all states.{/i18n}</p></div> | |
| 43 | +{else} | |
| 44 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 45 | +<input type="hidden" name="action" value="updateActionAvailability" /> | |
| 46 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 47 | +<table class="kt_collection" style="width: auto;"> | |
| 48 | +<thead> | |
| 49 | + <tr> | |
| 50 | + <th> </th> | |
| 51 | + {foreach from=$aActions item=oAction} | |
| 52 | + <th>{$oAction->getDisplayName()}</th> | |
| 53 | + {/foreach} | |
| 54 | + </tr> | |
| 55 | +</thead> | |
| 56 | +<tbody> | |
| 57 | +{foreach item=oState from=$workflow_info.states} | |
| 58 | + <tr class='{cycle values="odd,even"}'> | |
| 59 | + <td>{$oState->getName()}</td> | |
| 60 | + {foreach item=oAction from=$aActions} | |
| 61 | + <td><input type="checkbox" name="fAvailableActions[{$oState->getId()}][{$oAction->getName()}]" {if ($context->actionAvailable($oAction, $oState))}checked="true"{/if}/></td> | |
| 62 | + {/foreach} | |
| 63 | + </tr> | |
| 64 | +{/foreach} | |
| 65 | +</tbody> | |
| 66 | +</table> | |
| 67 | + | |
| 68 | +<div class="form_actions"> | |
| 69 | + <input type="submit" value="{i18n}Update Action Availability{/i18n}" /> | |
| 70 | +</div> | |
| 71 | +</form> | |
| 72 | +{/if} | |
| 73 | + | ... | ... |
templates/ktcore/workflow/manageStates.smarty
0 โ 100644
| 1 | +{$context->oPage->requireCSSResource('resources/css/workflow-admin.css')} | |
| 2 | +<h2>{i18n}Manage States{/i18n}</h2> | |
| 3 | + | |
| 4 | +<p class="descriptiveText">As documents move through their lifecycle, they | |
| 5 | +are placed in certain <strong>states</strong>. For example, an invoice | |
| 6 | +which has been mailed might be in the "Pending" <strong>state</strong> after | |
| 7 | +the "sent" <strong>transition</strong> has been performed by a user.</p> | |
| 8 | + | |
| 9 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 10 | +<fieldset> | |
| 11 | +<legend>{i18n}Create a new state{/i18n}</legend> | |
| 12 | + | |
| 13 | +<p class="descriptiveText">Please note that additional configuration is | |
| 14 | +possible on states beyond what is specified here (e.g. which users to notify | |
| 15 | +about the document, etc). Please edit the state | |
| 16 | +to access and modify these other properties.</p> | |
| 17 | + | |
| 18 | +<input type="hidden" name="action" value="newState" /> | |
| 19 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 20 | + | |
| 21 | +{* Standard Form *} | |
| 22 | + | |
| 23 | +{foreach item=oWidget from=$add_fields} | |
| 24 | + {$oWidget->render()} | |
| 25 | +{/foreach} | |
| 26 | + | |
| 27 | +<div class="form_actions"> | |
| 28 | +<input type="submit" name="submit" value="{i18n}Create state{/i18n}" /> | |
| 29 | +</div> | |
| 30 | +</fieldset> | |
| 31 | +</form> | |
| 32 | + | |
| 33 | +{if (empty($workflow_info.states))} | |
| 34 | +<div class="ktInfo"><p>This workflow does not define any states.</p></div> | |
| 35 | +{else} | |
| 36 | +<ul id="workflow-states-list"> | |
| 37 | +{foreach item=oState from=$workflow_info.states} | |
| 38 | + <li><span class="workflow_element">State:</span> <a href="{$smarty.server.PHP_SELF}?action=editState&fStateId={$oState->getId()}&fWorkflowId={$oWorkflow->getId()}" class="workflow_label">{$oState->getName()}</a> | |
| 39 | + <ul> | |
| 40 | + <li><a href="{$smarty.server.PHP_SELF}?action=editState&fStateId={$oState->getId()}&fWorkflowId={$oWorkflow->getId()}">{i18n}Notified groups & roles:{/i18n}</a> | |
| 41 | + {$context->getNotificationStringForState($oState)} | |
| 42 | + </li> | |
| 43 | + <li><a href="{$smarty.server.PHP_SELF}?action=editState&fStateId={$oState->getId()}&fWorkflowId={$oWorkflow->getId()}">{i18n}Actions available: {/i18n}</a> | |
| 44 | + {$context->getActionStringForState($oState)} | |
| 45 | + </li> | |
| 46 | + | |
| 47 | + <li><a href="{$smarty.server.PHP_SELF}?action=editTransitions&fWorkflowId={$oWorkflow->getId()}">{i18n}Transitions available: {/i18n}</a> | |
| 48 | + {$context->getTransitionFromStringForState($oState)} | |
| 49 | + </li> | |
| 50 | + | |
| 51 | + <li>{i18n}Transitions to this state: {/i18n} | |
| 52 | + {$context->getTransitionToStringForState($oState)} | |
| 53 | + </li> | |
| 54 | + </ul> | |
| 55 | + </li> | |
| 56 | +{/foreach} | |
| 57 | +</ul> | |
| 58 | +{/if} | |
| 0 | 59 | \ No newline at end of file | ... | ... |
templates/ktcore/workflow/manageTransitions.smarty
0 โ 100644
| 1 | +<h2>{i18n}Manage Transitions{/i18n}</h2> | |
| 2 | + | |
| 3 | +<p class="descriptiveText">{i18n}Transitions are what drive the workflow of documents. | |
| 4 | +Each step that needs to be followed in the document's lifecycle could | |
| 5 | +map to a transition, and can be allowed or denied by a combination | |
| 6 | +of roles, permissions and groups.{/i18n}</p> | |
| 7 | + | |
| 8 | +<p class="descriptiveText">{i18n}Use the form below to create a new Transition, and | |
| 9 | +assign or edit existing transitions using the table below.{/i18n}</p> | |
| 10 | + | |
| 11 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 12 | +<fieldset> | |
| 13 | +<legend>{i18n}Create a new state{/i18n}</legend> | |
| 14 | + | |
| 15 | +<input type="hidden" name="action" value="newTransition" /> | |
| 16 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 17 | + | |
| 18 | +{* Standard Form *} | |
| 19 | + | |
| 20 | +{foreach item=oWidget from=$add_fields} | |
| 21 | + {$oWidget->render()} | |
| 22 | +{/foreach} | |
| 23 | + | |
| 24 | +<div class="form_actions"> | |
| 25 | +<input type="submit" name="submit" value="{i18n}Create transition{/i18n}" /> | |
| 26 | +</div> | |
| 27 | +</fieldset> | |
| 28 | +</form> | |
| 29 | + | |
| 30 | +<h3>{i18n}Transition Availability{/i18n}</h3> | |
| 31 | + | |
| 32 | +<p class="descriptiveText">Click on any transition below to edit it directly, | |
| 33 | +or use the checkboxes to assign which states the transition is available from.</p> | |
| 34 | + | |
| 35 | +<form action="{$smarty.server.PHP_SELF}" method="POST"> | |
| 36 | +<input type="hidden" name="action" value="setTransitionAvailability"> | |
| 37 | +<input type="hidden" name="fWorkflowId" value="{$oWorkflow->getId()}" /> | |
| 38 | + | |
| 39 | +<table class="kt_collection" style="width: auto"> | |
| 40 | +<thead> | |
| 41 | + <tr> | |
| 42 | + <th> | |
| 43 | + | |
| 44 | + </th> | |
| 45 | + {foreach item=oState from=$workflow_info.states} | |
| 46 | + <th> | |
| 47 | + {$oState->getName()} | |
| 48 | + </th> | |
| 49 | + {/foreach} | |
| 50 | + </tr> | |
| 51 | +</thead> | |
| 52 | +<tbody> | |
| 53 | + {foreach item=oTransition from=$workflow_info.transitions} | |
| 54 | + <tr class='{cycle values="odd,even"}'> | |
| 55 | + <td> | |
| 56 | + <a href="{$smarty.server.PHP_SELF}?action=editTransition&fWorkflowId={$oWorkflow->getId()}&fTransitionId={$oTransition->getId()}">{$oTransition->getName()}</a> | |
| 57 | + </td> | |
| 58 | + {foreach item=oState from=$workflow_info.states} | |
| 59 | + <td> | |
| 60 | + {if ($oState->getId() != $oTransition->getTargetStateId())} | |
| 61 | + <input type="checkbox" name="fTransitionAvailability[{$oState->getId()}][{$oTransition->getId()}]" {if ($context->transitionAvailable($oTransition, $oState))}checked="true"{/if}> | |
| 62 | + {else}—{/if} | |
| 63 | + </td> | |
| 64 | + {/foreach} | |
| 65 | + </tr> | |
| 66 | + {/foreach} | |
| 67 | +</tbody> | |
| 68 | +<table> | |
| 69 | + | |
| 70 | +<div class="form_actions"> | |
| 71 | + <input type="submit" value="{i18n}Assign Transition Availability{/i18n}" /> | |
| 72 | +</div> | |
| 73 | + | |
| 74 | +</form> | |
| 0 | 75 | \ No newline at end of file | ... | ... |