From 3c2e7bd90f3f92816f45d669ddffed7d27d8422d Mon Sep 17 00:00:00 2001
From: Tim Steiner <tsteiner2@unl.edu>
Date: Wed, 25 Jun 2008 17:50:10 +0000
Subject: [PATCH] Added Approval Chain Manager (can only edit links at this
 time)

---
 .../ApprovalChainManagerController.php        | 124 +++++++++++++
 .../approval-chain-manager/index.phtml        | 127 ++++++++++++++
 .../css/requests/approval-chain-manager.css   |   4 +
 .../requests/approval-chain-manager.js        | 163 ++++++++++++++++++
 4 files changed, 418 insertions(+)
 create mode 100644 application/modules/requests/controllers/ApprovalChainManagerController.php
 create mode 100644 application/modules/requests/views/scripts/approval-chain-manager/index.phtml
 create mode 100644 document_root/css/requests/approval-chain-manager.css
 create mode 100644 document_root/javascript/requests/approval-chain-manager.js

diff --git a/application/modules/requests/controllers/ApprovalChainManagerController.php b/application/modules/requests/controllers/ApprovalChainManagerController.php
new file mode 100644
index 00000000..d664c7a7
--- /dev/null
+++ b/application/modules/requests/controllers/ApprovalChainManagerController.php
@@ -0,0 +1,124 @@
+<?php
+
+class Requests_ApprovalChainManagerController extends App_Controller_Action
+{
+    public function indexAction()
+    {
+        $in = $this->getRequest()->getParams();
+        $approvalChains = Requests_ApprovalChainModel::findAll();
+
+        $approvalChain = null;
+        if ($id = $in['id']) {
+            $approvalChain = Requests_ApprovalChainModel::find($id);
+            $user = Auth_UserModel::findCurrentUser();
+            $userGroups = Auth_GroupModel::findByUser($user);
+            $approvalBodies = Requests_ApprovalBodyModel::findWithAdminGroups($userGroups);
+            $bodies = new Unl_Model_Collection('Requests_ApprovalBodyModel');
+            foreach ($approvalBodies as $approvalBody) {
+                $bodies->merge($approvalBody);
+            }
+
+            $approvalLinks = Requests_ApprovalLinkModel::findForApprovalChains($approvalChain);
+            $approvalActions = Requests_ApprovalActionModel::findForApprovalChains($approvalChain);
+        }
+
+        $this->view->approvalChains = $approvalChains;
+        $this->view->approvalChain = $approvalChain;
+        $this->view->approvalBodies = $bodies;
+        $this->view->approvalLinks = $approvalLinks;
+        $this->view->approvalActions = $approvalActions;
+    }
+
+    public function getActionDetailXmlAction()
+    {
+        $in = $this->getRequest()->getParams();
+        $id = $in['id'];
+
+        $action = Requests_ApprovalActionModel::find($id);
+        if (!$action) {
+            exit;
+        }
+
+        $dom = new DOMDocument();
+        $actionNode = $dom->createElement('action');
+        $dom->appendChild($actionNode);
+        $actionNode->setAttribute('id', $action->getId());
+        $actionNode->setAttribute('name', $action->getName());
+        foreach ($action->getResultStatusStrings() as $key => $value) {
+            $result = $dom->createElement('result');
+            $result->setAttribute('value', $key);
+            $result->setAttribute('name', $value);
+            $actionNode->appendChild($result);
+        }
+
+        header('Content-type: text/xml');
+        echo $dom->saveXML();
+
+        exit;
+    }
+
+    public function editChainPostAction()
+    {
+        $in = $this->getRequest()->getParams();
+
+        $chain = Requests_ApprovalChainModel::find($in['id']);
+        if ($chain) {
+            $chain->setName($in['name']);
+            $chain->setOwnerBodyId($in['owner']);
+            Requests_ApprovalChainModel::save($chain);
+        }
+
+        $this->_redirect('/requests/approval-chain-manager/index/id/' . $in['id']);
+    }
+
+    public function addLinkPostAction()
+    {
+        $in = $this->getRequest()->getParams();
+
+        $link = Requests_ApprovalLinkModel::fetchNew();
+        $link->setChainId($in['approvalChain']);
+        if ($in['currentAction'] != '_null') {
+            $link->setCurrentActionId($in['currentAction']);
+        }
+        if ($in['currentState'] != '_null') {
+            $link->setCurrentState($in['currentState']);
+        }
+        if ($in['nextAction'] != '_null') {
+            $link->setNextActionId($in['nextAction']);
+        }
+
+        Requests_ApprovalLinkModel::save($link);
+        $this->_redirect('/requests/approval-chain-manager/index/id/' . $in['approvalChain']);
+    }
+
+    public function editLinksPostAction()
+    {
+        $in = $this->getRequest()->getParams();
+
+        $linkIds = array_keys($in['currentAction']);
+        $links = Requests_ApprovalLinkModel::find($linkIds);
+        $linksToDelete = new Unl_Model_Collection('Requests_ApprovalLinkModel');
+        $linksToSave = new Unl_Model_Collection('Requests_ApprovalLinkModel');
+        foreach ($links as $link) {
+            if ($in['currentAction'][$link->getId()] != '_null') {
+                $link->setCurrentActionId($in['currentAction'][$link->getId()]);
+            }
+            if ($in['currentState'][$link->getId()] != '_null') {
+                $link->setCurrentState($in['currentState'][$link->getId()]);
+            }
+            if ($in['nextAction'][$link->getId()] != '_null') {
+                $link->setNextActionId($in['nextAction'][$link->getId()]);
+            }
+            if ($in['delete'][$link->getId()]) {
+                $linksToDelete[] = $link;
+            } else {
+                $linksToSave[] = $link;
+            }
+        }
+        Requests_ApprovalLinkModel::save($linksToSave);
+        Requests_ApprovalLinkModel::delete($linksToDelete);
+
+        $this->_redirect('/requests/approval-chain-manager/index/id/' . $in['approvalChain']);
+    }
+
+}
\ No newline at end of file
diff --git a/application/modules/requests/views/scripts/approval-chain-manager/index.phtml b/application/modules/requests/views/scripts/approval-chain-manager/index.phtml
new file mode 100644
index 00000000..5f57c0ed
--- /dev/null
+++ b/application/modules/requests/views/scripts/approval-chain-manager/index.phtml
@@ -0,0 +1,127 @@
+<?php $this->headLink()->appendStylesheet($this->baseUrl() . '/css/requests/approval-chain-manager.css'); ?>
+<?php $this->headScript()->appendFile($this->baseUrl() . '/javascript/requests/approval-chain-manager.js'); ?>
+<?php $this->layout()->tagline = 'Approval Chain Manager'; ?>
+<?php $this->layout()->hideMenu = true; ?>
+
+<ul class="editMenu">
+<?php $this->approvalChains->orderBy('getName'); ?>
+<?php foreach ($this->approvalChains as $key => $approvalChain) { ?>
+    <li <?php if ($approvalChain == $this->approvalChain) {?>class="selected"<?php } ?>>
+        <a href="<?php echo $this->baseUrl(); ?>/requests/approval-chain-manager/index/id/<?php echo $approvalChain->getId(); ?>">
+        <?php echo Zend_Filter_HtmlEntities::filter($approvalChain->getName()); ?>
+        </a>
+    </li>
+<?php } ?>
+</ul>
+
+<?php if (!$this->approvalChain) { return; } ?>
+<?php $this->approvalBodies->orderBy('getName'); ?>
+
+<div class="editMain">
+    <form method="post" action="<?php echo $this->baseUrl(); ?>/requests/approval-chain-manager/edit-chain.post">
+        <?php echo $this->formHidden('id', $this->approvalChain->getId()); ?>
+        Chain Name: <?php echo $this->formText('name', $this->approvalChain->getName()); ?> <br />
+        Owner: <?php echo $this->formSelect('owner', $this->approvalChain->getOwnerBody(), null, $this->approvalBodies->arrayFromMethod('getName')); ?> <br />
+        <?php echo $this->formSubmit('submit', 'Update'); ?>
+    </form>
+
+    <div>
+        <a href="#">Links</a> |
+        <a href="#">Actions</a>
+    </div>
+
+    <div>
+        <h3>Add Link to Chain</h3>
+        <form method="post" action="<?php echo $this->baseUrl(); ?>/requests/approval-chain-manager/add-link.post">
+            <?php echo $this->formHidden('approvalChain', $this->approvalChain->getId()); ?>
+            <table>
+                <tr>
+                    <th>Previous Action</th>
+                    <th>Resulted In</th>
+                    <th>Next Action</th>
+                </tr>
+                <tr>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'currentAction',
+                            null,
+                            array('class' => 'actionSelectElement'),
+                            array('_null' => '--Just Entered Chain--')
+                            + $this->approvalActions->arrayFromMethod('getName')
+                        ); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'currentState',
+                            null,
+                            null,
+                            array('_null' => '--N/A--')
+                        ); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'nextAction',
+                            null,
+                            null,
+                            $this->approvalActions->arrayFromMethod('getName')
+                        ); ?>
+                    </td>
+                </tr>
+            </table>
+            <?php echo $this->formSubmit('submitAddLink', 'Add Link'); ?>
+        </form>
+    </div>
+
+
+    <div>
+        <h3>Edit/Remove Links in Chain</h3>
+        <form method="post" action="<?php echo $this->baseUrl(); ?>/requests/approval-chain-manager/edit-links.post">
+            <?php echo $this->formHidden('approvalChain', $this->approvalChain->getId()); ?>
+            <table>
+                <tr>
+                    <th>Previous Action</th>
+                    <th>Resulted In</th>
+                    <th>Next Action</th>
+                    <th>Delete</th>
+                </tr>
+                <?php foreach ($this->approvalLinks as $approvalLink) { ?>
+                <tr>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'currentAction[' . $approvalLink->getId() . ']',
+                            $approvalLink->getCurrentAction(),
+                            array('class' => 'actionSelectElement'),
+                            array('_null' => '--Just Entered Chain--')
+                            + $this->approvalActions->arrayFromMethod('getName')
+                        ); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'currentState[' . $approvalLink->getId() . ']',
+                            $approvalLink->getCurrentState(),
+                            null,
+                            array('_null' => '--N/A--')
+                            + ($approvalLink->getCurrentAction()
+                                ? $this->approvalActions[$approvalLink->getCurrentAction()]->getResultStatusStrings()
+                                : array())
+                        ); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formSelect(
+                            'nextAction[' . $approvalLink->getId() . ']',
+                            $approvalLink->getNextAction(),
+                            null,
+                            $this->approvalActions->arrayFromMethod('getName')
+                        ); ?>
+                    </td>
+                    <td>
+                        <?php echo $this->formCheckbox('delete[' . $approvalLink->getId() . ']'); ?>
+                    </td>
+                </tr>
+                <?php } ?>
+            </table>
+            <?php echo $this->formSubmit('submitEditLinks', 'Update Links'); ?>
+        </form>
+    </div>
+
+</div>
diff --git a/document_root/css/requests/approval-chain-manager.css b/document_root/css/requests/approval-chain-manager.css
new file mode 100644
index 00000000..e7cc3fde
--- /dev/null
+++ b/document_root/css/requests/approval-chain-manager.css
@@ -0,0 +1,4 @@
+ul.editMenu {float: left;}
+li.selected {font-weight: bold; font-size: 110%;}
+
+div.editMain {float: left; overflow: hidden; padding: 0px 1em;}
\ No newline at end of file
diff --git a/document_root/javascript/requests/approval-chain-manager.js b/document_root/javascript/requests/approval-chain-manager.js
new file mode 100644
index 00000000..e4cec201
--- /dev/null
+++ b/document_root/javascript/requests/approval-chain-manager.js
@@ -0,0 +1,163 @@
+var actionTypeSelectAjaxResponder = AjaxClient.extend(
+{
+    selectElement: null,
+
+    processResponse: function() {
+        var resultNodes = this.requestObject.responseXML.childNodes[0].childNodes;
+        var resultStrings = new Array();
+        for (var i = 0; i < resultNodes.length; i++) {
+            var resultNode = resultNodes[i];
+            resultStrings.push(resultNode.getAttribute("name"));
+        }
+
+        this.selectElement.options.length = 0;
+        this.selectElement.add(new Option('--N/A--', '_null', false, false), null);
+        for (var i = 0; i < resultStrings.length; i++) {
+            var resultString = resultStrings[i]
+            this.selectElement.add(new Option(resultString, resultString, false, false), null);
+        }
+    }
+});
+
+function loadApprovalChainManager()
+{
+    var actionSelectElements = getElementsByClass('actionSelectElement');
+    for(var i = 0; i < actionSelectElements.length; i++) {
+        var actionSelectElement = actionSelectElements[i];
+        actionSelectElement.onchange = updateActionResults;
+    }
+/*
+    document.getElementById('select_manage_links').onclick = selectLinksOrActions;
+    document.getElementById('select_manage_actions').onclick = selectLinksOrActions;
+
+    var actionTypeSelects = getElementsByClass('action_type_select');
+    for (var i = 0; i < actionTypeSelects.length; i++) {
+        actionTypeSelects[i].onchange = updateEditActionDetails;
+    }
+
+
+    var addButtons = getElementsByClass('add_record_button');
+    for(var i = 0; i < addButtons.length; i++) {
+        addButtons[i].onclick = handleAddRecord;
+    }
+
+    var removeButtons = getElementsByClass('remove_record_button');
+    for(var i = 0; i < removeButtons.length; i++) {
+        removeButtons[i].onclick = handleRemoveRecord;
+    }
+    */
+}
+
+addLoadEvent(loadApprovalChainManager);
+
+
+
+function selectLinksOrActions()
+{
+    if(this.id == 'select_manage_links') {
+        document.getElementById('manage_links').style.display = '';
+        document.getElementById('manage_actions').style.display = 'none';
+    } else {
+        document.getElementById('manage_links').style.display = 'none';
+        document.getElementById('manage_actions').style.display = '';
+    }
+}
+
+
+
+
+var _serverActionList = new Array();
+
+function saveActionList(response)
+{
+    if (req.readyState != 4) {
+        return;
+    }
+    if (req.status != 200) {
+        return;
+    }
+
+    _serverActionList = new Array();
+
+    actionXML = req.responseXML;
+    for (var i = 0; i < actionXML.childNodes.length; i++) {
+        var currentActionNode = actionXML.childNodes[i];
+        var currentAction = new Object();
+        currentAction.name = currentActionNode.getAttribute('name');
+        currentAction.className = currentActionNode.getAttribute('className');
+        currentAction.results = new Array();
+        for (var j = 0; j < currentActionNode.childNodes.length; j++) {
+            currentAction.results[j] = currentActionNode.childNodes[j].getAttribute('name');
+        }
+        _serverActionList[i] = currentAction;
+    }
+}
+
+
+function updateActionResults()
+{
+    var actionResultElement = this.parentNode;
+    for(actionResultElement = actionResultElement.nextSibling;
+        actionResultElement.nodeName.toLowerCase() != 'td';
+        actionResultElement = actionResultElement.nextSibling);
+
+    actionResultElement = actionResultElement.getElementsByTagName('select').item(0);
+
+    if (this.value == '_null') {
+        actionResultElement.options.length = 0;
+        actionResultElement.add(new Option('--N/A--', '_null', false, false), null);
+    } else {
+        var responder = new actionTypeSelectAjaxResponder();
+        responder.selectElement = actionResultElement;
+        responder.sendRequest(baseUrl + '/requests/approval-chain-manager/get-action-detail-xml/id/' + this.value);
+    }
+}
+
+function updateEditActionDetails()
+{
+    var chainId = document.getElementById('chainId').value;
+    var url = '/ApprovalChainManager/GetActionEditXhtml/' + this.value + '/' + chainId;
+    var responder = new updateEditActionDetailsAjaxResponder();
+    responder.actionElement = this;
+    responder.sendRequest(url);
+}
+
+function handleAddRecord()
+{
+    var currentTR = this.parentNode.parentNode;
+    var currentTable = currentTR.parentNode;
+    var hiddenTR = currentTR.previousSibling.previousSibling;
+    var currentIndex = currentTable.getElementsByTagName('tr').length - 2;
+
+    var newNode = hiddenTR.cloneNode(true);
+    for(var i = 1; i < newNode.childNodes.length; i+=2) {
+        var inputElement = newNode.childNodes[i].childNodes[1];
+        inputElement.disabled = false;
+        var keyIndex = inputElement.name.indexOf('__key__');
+        if(keyIndex > 0) {
+            inputElement.name = inputElement.name.substr(0, keyIndex) + '-' + currentIndex + inputElement.name.substr(keyIndex + 7);
+            inputElement.id = inputElement.name;
+        }
+    }
+    newNode.childNodes[newNode.childNodes.length - 2].childNodes[1].onclick = handleRemoveRecord;
+    currentTable.insertBefore(newNode, hiddenTR);
+    newNode.className = '';
+
+    return false;
+}
+
+function handleRemoveRecord()
+{
+    var currentTR = this.parentNode.parentNode;
+    var currentTable = currentTR.parentNode;
+
+    if(this.id.substr(0, 20) == 'remove_tie_in_button') {
+        var addButtonId = 'add' + this.id.substr(6);
+        document.getElementById(addButtonId).style.display = 'inline';
+    }
+
+    currentTable.removeChild(currentTR);
+
+    return false;
+}
+
-- 
GitLab