diff --git a/include/ajax.admin.php b/include/ajax.admin.php new file mode 100644 index 0000000000000000000000000000000000000000..2e6ac9561f79053d9bb1e767ca1e47528d0ac995 --- /dev/null +++ b/include/ajax.admin.php @@ -0,0 +1,50 @@ +<?php + +require_once(INCLUDE_DIR . 'class.dept.php'); + +class AdminAjaxAPI extends AjaxController { + + /** + * Ajax: GET /admin/add/department + * + * Uses a dialog to add a new department + * + * Returns: + * 200 - HTML form for addition + * 201 - {id: <id>, name: <name>} + * + * Throws: + * 403 - Not logged in + */ + function addDepartment() { + global $ost, $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Agent login required'); + + $form = new DepartmentQuickAddForm($_POST); + + if ($_POST && $form->isValid()) { + $dept = Dept::create(); + $errors = array(); + $vars = $form->getClean(); + $vars += array( + 'group_membership' => Dept::ALERTS_DEPT_AND_GROUPS, + ); + if ($dept->update($vars, $errors)) + Http::response(201, $this->encode(array( + 'id' => $dept->id, + 'name' => $dept->name, + ), 'application/json')); + + foreach ($errors as $name=>$desc) + if ($F = $form->getField($name)) + $F->addError($desc); + } + + $title = __("Add New Department"); + $path = $ost->get_path_info(); + + include STAFFINC_DIR . 'templates/quick-add-department.tmpl.php'; + } +} diff --git a/include/class.dept.php b/include/class.dept.php index 2950f82793fdf699acff6a40649165769c7ac875..bd2de00cd3c1592518327db1640133e2b48954d2 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -623,4 +623,61 @@ class GroupDeptAccess extends VerySimpleModel { ), ); } -?> + +class DepartmentQuickAddForm +extends Form { + function getFields() { + if ($this->fields) + return $this->fields; + + return $this->fields = array( + 'pid' => new ChoiceField(array( + 'label' => '', + 'default' => 0, + 'choices' => array_merge( + array(0 => __('Top-Level Department')), + Dept::getDepartments() + ) + )), + 'name' => new TextboxField(array( + 'required' => true, + 'configuration' => array( + 'placeholder' => __('Name'), + 'classes' => 'span12', + 'autofocus' => true, + 'length' => 128, + ), + )), + 'email_id' => new ChoiceField(array( + 'label' => __('Email Mailbox'), + 'default' => 0, + 'choices' => array_merge( + array(0 => '— '.__('System Default').' —'), + Email::getAddresses() + ), + 'configuration' => array( + 'classes' => 'span12', + ), + )), + 'private' => new BooleanField(array( + 'configuration' => array( + 'classes' => 'form footer', + 'desc' => __('This department is for internal use'), + ), + )), + ); + } + + function getClean() { + $clean = parent::getClean(); + + $clean['ispublic'] = !$clean['private']; + unset($clean['private']); + + return $clean; + } + + function render($staff=true) { + return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php')); + } +} diff --git a/include/class.forms.php b/include/class.forms.php index 3c8c2bab55219e1d4db2a313a883fbbac2dfe665..bacfe3b36c83d783170a295a757410a1d54d67de 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -163,10 +163,11 @@ class Form { if (isset($options['instructions'])) $this->instructions = $options['instructions']; $form = $this; + $template = $options['template'] ?: 'dynamic-form.tmpl.php'; if ($staff) - include(STAFFINC_DIR . 'templates/dynamic-form.tmpl.php'); + include(STAFFINC_DIR . 'templates/' . $template); else - include(CLIENTINC_DIR . 'templates/dynamic-form.tmpl.php'); + include(CLIENTINC_DIR . 'templates/' . $template); echo $this->getMedia(); } @@ -2913,8 +2914,11 @@ class ChoicesWidget extends Widget { if (!is_array($values)) $values = $have_def ? array($def_key => $choices[$def_key]) : array(); + if (isset($config['classes'])) + $classes = 'class="'.$config['classes'].'"'; ?> <select name="<?php echo $this->name; ?>[]" + <?php echo implode(' ', array_filter(array($classes))); ?> id="<?php echo $this->id; ?>" data-placeholder="<?php echo $prompt; ?>" <?php if ($config['multiselect']) @@ -3017,7 +3021,10 @@ class CheckboxWidget extends Widget { $config = $this->field->getConfiguration(); if (!isset($this->value)) $this->value = $this->field->get('default'); + if (isset($config['classes'])) + $classes = 'class="'.$config['classes'].'"'; ?> + <div <?php echo implode(' ', array_filter(array($classes))); ?>> <input id="<?php echo $this->id; ?>" style="vertical-align:top;" type="checkbox" name="<?php echo $this->name; ?>[]" <?php if ($this->value) echo 'checked="checked"'; ?> value="<?php @@ -3025,7 +3032,9 @@ class CheckboxWidget extends Widget { <?php if ($config['desc']) { echo Format::viewableImages($config['desc']); - } + } ?> + </div> +<?php } function getValue() { diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php index f6dbcfe7bb813d619ccbf60043e9ab2a940457fb..93e98cc08c3e046cd8b4f767e42c35f987a7c662 100644 --- a/include/staff/helptopic.inc.php +++ b/include/staff/helptopic.inc.php @@ -122,14 +122,14 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php echo __('Department'); ?>: </td> <td> - <select name="dept_id"> + <select name="dept_id" data-quick-add="department"> <option value="0">— <?php echo __('System Default'); ?> —</option> <?php foreach (Dept::getDepartments() as $id=>$name) { $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':''; echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name); - } - ?> + } ?> + <option value="0" data-quick-add>— <?php echo __('Add New');?> —</option> </select> <span class="error"> <?php echo $errors['dept_id']; ?></span> <i class="help-tip icon-question-sign" href="#department"></i> diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php index 3e09d725c19bd2715eb0265b4d59759905fb63dc..cc268739cff48bf5433e7964c68799c536e572e0 100644 --- a/include/staff/settings-system.inc.php +++ b/include/staff/settings-system.inc.php @@ -47,16 +47,17 @@ $gmtime = Misc::gmtime(); <tr> <td width="220" class="required"><?php echo __('Default Department');?>:</td> <td> - <select name="default_dept_id"> + <select name="default_dept_id" data-quick-add="department"> <option value="">— <?php echo __('Select Default Department');?> —</option> <?php if (($depts=Dept::getPublicDepartments())) { foreach ($depts as $id => $name) { $selected = ($config['default_dept_id']==$id)?'selected="selected"':''; ?> - <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?> <?php echo __('Dept');?></option> + <option value="<?php echo $id; ?>"<?php echo $selected; ?>><?php echo $name; ?></option> <?php } } ?> + <option value="0" data-quick-add>— <?php echo __('Add New');?> —</option> </select> <font class="error">* <?php echo $errors['default_dept_id']; ?></font> <i class="help-tip icon-question-sign" href="#default_department"></i> </td> diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php index b18b7cd772b11206c46962cd0a2937f204163789..babf07db01da01030d2625fa3592a2807a9f1b19 100644 --- a/include/staff/staff.inc.php +++ b/include/staff/staff.inc.php @@ -230,7 +230,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php echo __('Primary Department');?>: </td> <td> - <select name="dept_id" id="dept_id"> + <select name="dept_id" id="dept_id" data-quick-add="department"> <option value="0">— <?php echo __('Select Department');?> —</option> <?php foreach (Dept::getDepartments() as $id=>$name) { @@ -238,6 +238,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); echo sprintf('<option value="%d" %s>%s</option>',$id,$sel,$name); } ?> + <option value="0" data-quick-add>— <?php echo __('Add New');?> —</option> </select> <span class="error">*</span> <i class="help-tip icon-question-sign" href="#primary_department"></i> diff --git a/include/staff/templates/dynamic-form-simple.tmpl.php b/include/staff/templates/dynamic-form-simple.tmpl.php index 8ec0cb2726a6c9b0b33c4d90c5a069938549e920..ca7a91b4982f8646f35e322229face5e9e46b4b1 100644 --- a/include/staff/templates/dynamic-form-simple.tmpl.php +++ b/include/staff/templates/dynamic-form-simple.tmpl.php @@ -4,15 +4,17 @@ foreach ($form->getFields() as $name=>$f) { ?> <div class="flush-left custom-field" id="field<?php echo $f->getWidget()->id; ?>" <?php if (!$f->isVisible()) echo 'style="display:none;"'; ?>> + <div> + <?php if ($f->get('label')) { ?> <div class="field-label <?php if ($f->get('required')) echo 'required'; ?>"> <label for="<?php echo $f->getWidget()->name; ?>"> - <?php if ($f->get('label')) { ?> <?php echo Format::htmlchars($f->get('label')); ?>: - <?php } ?> <?php if ($f->get('required')) { ?> <span class="error">*</span> <?php } ?> </label> + </div> + <?php } ?> <?php if ($f->get('hint')) { ?> <em style="color:gray;display:block"><?php diff --git a/include/staff/templates/quick-add-department.tmpl.php b/include/staff/templates/quick-add-department.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..4d0e71e79aca2a8bb535797c02ca9002bf33abef --- /dev/null +++ b/include/staff/templates/quick-add-department.tmpl.php @@ -0,0 +1,22 @@ +<h3 class="drag-handle"><?php echo $title ?></h3> +<b><a class="close" href="#"><i class="icon-remove-circle"></i></a></b> +<div class="clear"></div> +<hr/> +<form method="post" action="#<?php echo $path; ?>"> + <div class="inset"> + <?php $form->render(); ?> + </div> + <hr> + <p class="full-width"> + <span class="buttons pull-left"> + <input type="reset" value="<?php echo __('Reset'); ?>" /> + <input type="button" name="cancel" class="close" + value="<?php echo __('Cancel'); ?>" /> + </span> + <span class="buttons pull-right"> + <input type="submit" value="<?php + echo $verb ?: __('Submit'); ?>" /> + </span> + </p> + <div class="clear"></div> +</form> diff --git a/scp/ajax.php b/scp/ajax.php index 054ef105068f6b36eb92797b4cac48467f78c066..3634a6cdb5e3065d744cc04dc7f4061bf8a389a3 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -224,6 +224,11 @@ $dispatcher = patterns('', url_get('^translate/(?P<tag>\w+)$', 'getTranslations'), url_post('^translate/(?P<tag>\w+)$', 'updateTranslations'), url_get('^(?P<lang>[\w_]+)/(?P<tag>\w+)$', 'getLanguageFile') + )), + url('^/admin', patterns('', + url('^/quick-add', patterns('ajax.admin.php:AdminAjaxAPI', + url('^/department$', 'addDepartment') + )) )) ); diff --git a/scp/css/scp.css b/scp/css/scp.css index 88df4b16599867216d074dd03a8b32a431efa073..a3e0b4b8e95176da707eaea789cef84c0a68b2b1 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -1620,11 +1620,10 @@ time.faq { } .custom-field .field-label { - margin-left: 3px; - margin-right: 3px; + margin: 0 3px 4px; } .custom-field + .custom-field { - margin-top: 5px; + margin-top: 8px; } .dialog label.fixed-size { width:100px; @@ -2446,3 +2445,25 @@ td.indented { margin-bottom: 0.3em; font-size: 1.1em; } + +/* Form simple grid sizing */ +.iblock { + display: inline-block; +} +form.inset { + padding: 10px; +} +.span12 { + width: 100%; +} +.span6 { + width: 48%; + width: calc(50% - 10px); +} +.span6 + .span6 { + margin-left: 1%; + margin-left: calc(0 + 10px); +} +.form.footer { + margin-top: 50px; +} diff --git a/scp/js/scp.js b/scp/js/scp.js index dfa6ed4e08beb7a497e2ab57710186153d3b449e..b8e86184326c7cedde04d16e0aa922c0fcb79527 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -956,6 +956,25 @@ if ($.support.pjax) { }) } +// Quick-Add dialogs +$(document).on('change', 'select[data-quick-add]', function() { + var $select = $(this), + selected = $select.find('option:selected'); + if (selected.data('quick-add') === undefined) + return; + $.dialog('ajax.php/admin/quick-add/' + $select.data('quick-add'), 201, + function(xhr, data) { + data = JSON.parse(data); + if (data && data.id && data.name) { + $('<option>') + .attr('value', data.id) + .text(data.name) + .insertBefore($select.find('option[data-quick-add]')); + $select.val(data.id); + } + }); +}); + // Quick note interface $(document).on('click.note', '.quicknote .action.edit-note', function() { var note = $(this).closest('.quicknote'),