Shout: Continue creating dialplan UI
authorBen Klang <ben@alkaloid.net>
Thu, 4 Mar 2010 01:41:07 +0000 (20:41 -0500)
committerBen Klang <ben@alkaloid.net>
Thu, 4 Mar 2010 01:41:33 +0000 (20:41 -0500)
shout/lib/Ajax/Application.php
shout/lib/Shout.php
shout/templates/dialplan/edit.inc
shout/themes/screen.css

index 55075ff..b466f7e 100644 (file)
@@ -13,6 +13,7 @@
  */
 class Shout_Ajax_Application extends Horde_Ajax_Application_Base
 {
+    protected $_responseType = 'json';
     /**
      * Returns a notification handler object to use to output any
      * notification messages triggered by the action.
@@ -89,19 +90,19 @@ class Shout_Ajax_Application extends Horde_Ajax_Application_Base
      */
     public function getMenuInfo()
     {
-        $vars = $this->_vars;
-        $shout = Horde_Registry::appInit('shout');
-        $context = $_SESSION['shout']['context'];
-        $menus = $shout->storage->getMenus($context);
-        $menu = $vars->menu;
-        if (!isset($menus[$menu])) {
-            Horde::logMessage("User requested a menu that does not exist.", __FILE__, __LINE__, PEAR_LOG_ERR);
-            $notification->push(_("That menu does not exist."), 'horde.error');
-            $action = 'list';
-            // FIXME notifications
-            return false;
-        }
         try {
+            $vars = $this->_vars;
+            $shout = Horde_Registry::appInit('shout');
+            $context = $_SESSION['shout']['context'];
+            $menus = $shout->storage->getMenus($context);
+            $menu = $vars->menu;
+            if (!isset($menus[$menu])) {
+                Horde::logMessage("User requested a menu that does not exist.", __FILE__, __LINE__, PEAR_LOG_ERR);
+                $notification->push(_("That menu does not exist."), 'horde.error');
+                $action = 'list';
+                // FIXME notifications
+                return false;
+            }
             $data['meta'] = $menus[$menu];
             $data['actions'] = $shout->dialplan->getMenuActions($context, $menu);
             return $data;
@@ -111,4 +112,61 @@ class Shout_Ajax_Application extends Horde_Ajax_Application_Base
             return false;
         }
     }
+    /**
+     * TODO
+     */
+    public function getMenuActions()
+    {
+        try {
+            $vars = $this->_vars;
+            $GLOBALS['shout'] = Horde_Registry::appInit('shout');
+            $context = $_SESSION['shout']['context'];
+            $actions = Shout::getMenuActions();
+            return $actions;
+        } catch (Exception $e) {
+            //FIXME: Create a way to notify the user of the failure.
+            Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
+            return false;
+        }
+    }
+
+    public function getActionForm()
+    {
+        try {
+            $vars = $this->_vars;
+            if (!($action = $vars->get('action'))) {
+                throw new Shout_Exception("Invalid action requested.");
+            }
+            $GLOBALS['shout'] = Horde_Registry::appInit('shout');
+            $context = $_SESSION['shout']['context'];
+            $actions = Shout::getMenuActions();
+            $action = $actions[$action];
+            $form = new Horde_Form($vars, $action['description']);
+            foreach($action['args'] as $name => $info) {
+                $defaults = array(
+                    'required' => true,
+                    'readonly' => false,
+                    'description' => null,
+                    'params' => array()
+                );
+                //$info = array_merge($info, $defaults);
+                $form->addVariable($info['name'], $name, $info['type'],
+                                   $info['required'], $info['readonly'],
+                                   $info['description'], $info['params']);
+            }
+            $this->_responseType = 'html';
+            $form->renderActive();
+            $output = ob_get_clean();
+            return $output;
+        } catch (Exception $e) {
+            //FIXME: Create a way to notify the user of the failure.
+            Horde::logMessage($e->getMessage(), __FILE__, __LINE__, PEAR_LOG_ERR);
+            return false;
+        }
+    }
+
+    public function responseType()
+    {
+        return $this->_responseType;
+    }
 }
index d35a142..2b0c02f 100644 (file)
@@ -136,4 +136,84 @@ class Shout
 
         return array($devid, $password);
     }
+
+    static public function getMenuActions()
+    {
+        global $shout;
+        $context = $_SESSION['shout']['context'];
+
+        return array(
+            'menu' => array(
+                'description' => _("Jump to menu."),
+                'args' => array (
+                    'menu' => array(
+                        'name' => _("Menu"),
+                        'type' => 'enum',
+                        'required' => true,
+                        'params' => array(self::getNames($shout->dialplan->getMenus($context)))
+                    )
+                )
+            ),
+            'ringexten' => array(
+                'description' => _("Ring an extension."),
+                'args' => array(
+                    'exten' => array(
+                        'name' => _("Extension"),
+                        'type' => 'enum',
+                        'required' => true,
+                        'params' => array(self::getNames($shout->extensions->getExtensions($context)))
+                    )
+                )
+            ),
+            'voicemail' => array(
+                'description' => _("Leave a message."),
+                'args' => array(
+                    'mailbox' => array(
+                        'name' => _("Mailbox"),
+                        'type' => 'enum',
+                        'required' => true,
+                        'params' => array(self::getNames($shout->extensions->getExtensions($context)))
+                        )
+                )
+            ),
+            'conference' => array(
+                'description' => _("Enter conference room"),
+                'args' => array(
+                    'roomno' => array(
+                        'name' => _("Room Number"),
+                        'type' => 'number',
+                        'required' => false
+                    )
+                )
+            ),
+            'directory' => array(
+                'description' => _("Enter company directory."),
+                'args' => array()
+            ),
+            'dial' => array(
+                'description' => _("Place an outgoing call."),
+                'args' => array(
+                    'number' => array(
+                        'name' => _("Phone Number"),
+                        'type' => 'phone',
+                        'required' => true
+                    )
+                )
+            ),
+            'rewind' => array(
+                'description' => _("Restart the current menu."),
+                'args' => array()
+            ),
+        );
+    }
+
+    static public function getNames($array)
+    {
+        $res = array();
+        foreach ($array as $id => $info) {
+            $res[$id] = $info['name'];
+        }
+        return $res;
+    }
+
 }
index c859b1d..5686754 100644 (file)
@@ -2,24 +2,26 @@
 </table>
 
 <div id="digitpad">
-  <div id="digitAction">
+  <div id="editAction">
       <div onClick="saveAction('x');">SAVE</div>
   </div>
-  <div class="digit" onClick="editAction('1');"><span class="digitLabel">1</span></div>
-  <div class="digit" onClick="editAction('2');"><span class="digitLabel">2</span></div>
-  <div class="digit" onClick="editAction('3');"><span class="digitLabel">3</span></div>
+  <div class="digit" id="digit_1" onClick="editAction('1');"><span class="digitLabel">1</span></div>
+  <div class="digit" id="digit_2" onClick="editAction('2');"><span class="digitLabel">2</span></div>
+  <div class="digit" id="digit_3" onClick="editAction('3');"><span class="digitLabel">3</span></div>
   <br style="clear:both;">
-  <div class="digit" onClick="editAction('4');"><span class="digitLabel">4</span></div>
-  <div class="digit" onClick="editAction('5');"><span class="digitLabel">5</span></div>
-  <div class="digit" onClick="editAction('6');"><span class="digitLabel">6</span></div>
+  <div class="digit" id="digit_4" onClick="editAction('4');"><span class="digitLabel">4</span></div>
+  <div class="digit" id="digit_5" onClick="editAction('5');"><span class="digitLabel">5</span></div>
+  <div class="digit" id="digit_6" onClick="editAction('6');"><span class="digitLabel">6</span></div>
   <br style="clear:both;">
-  <div class="digit" onClick="editAction('7');"><span class="digitLabel">7</span></div>
-  <div class="digit" onClick="editAction('8');"><span class="digitLabel">8</span></div>
-  <div class="digit" onClick="editAction('9');"><span class="digitLabel">9</span></div>
+  <div class="digit" id="digit_7" onClick="editAction('7');"><span class="digitLabel">7</span></div>
+  <div class="digit" id="digit_8" onClick="editAction('8');"><span class="digitLabel">8</span></div>
+  <div class="digit" id="digit_9" onClick="editAction('9');"><span class="digitLabel">9</span></div>
   <br style="clear:both;">
-  <div class="digit" onClick="editAction('*');"><span class="digitLabel">*</span></div>
-  <div class="digit" onClick="editAction('0');"><span class="digitLabel">0</span></div>
-  <div class="digit" onClick="editAction('#');"><span class="digitLabel">#</span></div>
+  <div class="digit" id="digit_*" onClick="editAction('*');"><span class="digitLabel">*</span></div>
+  <div class="digit" id="digit_0" onClick="editAction('0');"><span class="digitLabel">0</span></div>
+  <div class="digit" id="digit_#" onClick="editAction('#');"><span class="digitLabel">#</span></div>
+  <br style="clear:both;">
+  <div id="defaultAction" onclick="editAction('defaultAction');"><span class="digitLabel">Default Action</span></div>
 </div>
 
 <script type="text/javascript">
 var ajax_url = '<?php echo Horde::getServiceLink('ajax', 'shout') ?>';
 var menu = '<?php echo $menu['name']; ?>';
 var menuInfo = $H();
+var menuActions = $H();
 
 function editAction(digit)
 {
-    $('digitAction').show();
+    if ($('selectActionForm') == null) {
+        // Draw the selectActionForm
+        $('editAction').show();
+        while ((e = $('editAction').childNodes[0]) != null) {
+            $('editAction').removeChild(e);
+        }
+        var form = document.createElement('form');
+        form.id = 'selectActionForm';
+        form.setAttribute('onChange', 'editAction('+digit+')');
+        var select = document.createElement('select');
+        select.name = 'action';
+        menuActions.each(function (item) {
+            var option = document.createElement('option');
+            option.value = item.key;
+            var text = document.createTextNode(item.value.description);
+            option.appendChild(text);
+            select.appendChild(option);
+        });
+        form.appendChild(select);
+        $('editAction').appendChild(form);
+    } else {
+        var action = null;
+        // Draw the options for this action
+        $('selectActionForm').getElements().each(function (e){
+            if (e.name == 'action') {
+                action = e.value;
+            }
+        });
+        var params = $H({'action': action});
+        var actionForm;
+        var div = document.createElement('div');
+        div.id = 'editActionForm';
+        $('editAction').appendChild(div);
+        new Ajax.Updater('editActionForm', ajax_url + 'getActionForm',
+        {
+            method: 'post',
+            parameters: params
+        });
+    }
 }
 
 function saveAction(digit)
 {
-    $('digitAction').hide();
+    $('editAction').hide();
 }
 
 function changeSoundfile()
@@ -114,7 +155,7 @@ function getMetaRow(name, value)
     return row;
 }
 
-$('digitAction').hide();
+$('editAction').hide();
 new Ajax.Request(ajax_url + 'getMenuInfo',
 {
     method: 'post',
@@ -126,5 +167,13 @@ new Ajax.Request(ajax_url + 'getMenuInfo',
         refreshMenu();
     }
 });
+new Ajax.Request(ajax_url + 'getMenuActions',
+{
+    method: 'post',
+    onSuccess: function(r) {
+        menuActions = $H(r.responseJSON.response);
+        refreshMenu();
+    }
+});
 // -->
 </script>
\ No newline at end of file
index f555193..9ceef34 100644 (file)
@@ -104,6 +104,22 @@ ul {
     -webkit-border-radius: 10px;
 }
 
+#defaultAction {
+    width: 288px;
+    height: 38px;
+    border-top: 4px solid #aaa;
+    border-left: 4px solid #aaa;
+    border-right: 4px solid #444;
+    border-bottom: 4px solid #444;
+    padding: 3px;
+    margin: 1px;
+    background-image: url('graphics/digit-bg.png');
+    background-repeat: no-repeat;
+    background-color: #999;
+    -moz-border-radius: 10px;
+    -webkit-border-radius: 10px;
+}
+
 .digitLabel {
     font-style: italic;
     font-family: Sans-serif;
@@ -112,9 +128,9 @@ ul {
     color: #666;
 }
 
-#digitAction {
+#editAction {
     width: 290px;
-    height: 390px;
+    height: 440px;
     margin: 5px;
     position: absolute;
     top: 0px;