From 7db248ea2ef860a9b5fe91d59c615ebd4842f6e6 Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Mon, 27 Apr 2015 16:20:40 -0500
Subject: [PATCH] Fixup a few small style issues on the client portal

This includes adding support to the Redactor editor to force the width of th
editable content to match the width of the displayed content on the client
portal. Also, the landing page displayed on the client portal is themed
(css-class wise) to match that of the Redactor content similar to the FAQ
and thread-entry designer boxes as well.
---
 assets/default/css/theme.css |  51 ++++++++++----
 css/redactor.css             |  12 ++--
 css/thread.css               |   6 +-
 include/class.forms.php      |   8 +++
 include/client/view.inc.php  | 126 +++++++++++++++++++----------------
 include/staff/page.inc.php   |  18 +++--
 index.php                    |   2 +
 js/redactor-osticket.js      |   2 +
 js/redactor-plugins.js       |   2 +-
 scp/css/scp.css              |   9 +--
 tickets.php                  |   4 +-
 11 files changed, 149 insertions(+), 91 deletions(-)

diff --git a/assets/default/css/theme.css b/assets/default/css/theme.css
index f3b1290f8..8adafc32e 100644
--- a/assets/default/css/theme.css
+++ b/assets/default/css/theme.css
@@ -6,7 +6,7 @@ html {
 }
 body {
   margin: 0;
-  font-size: 13px;
+  font-size: 14px;
   line-height: 1.231;
   padding: 0;
 }
@@ -14,7 +14,7 @@ body,
 input,
 select,
 textarea {
-  font-family: sans-serif;
+  font-family: "Helvetica Neue", sans-serif;
   color: #000;
 }
 b,
@@ -201,7 +201,7 @@ h2, .subject {
   border: 1px solid #0a0;
   background: url('../images/icons/ok.png') 10px 50% no-repeat #e0ffe0;
 }
-#msg_warning {
+#msg_warning, .warning-banner {
   margin: 0;
   padding: 5px 10px 5px 36px;
   height: 16px;
@@ -528,10 +528,10 @@ body {
     overflow: hidden;
 }
 .article-title {
-    font-weight: 400;
+    font-weight: 500;
 }
 .faq-content .article-title {
-    font-size: 16pt;
+    font-size: 17pt;
     margin-top: 15px;
 }
 #kb-search {
@@ -727,12 +727,14 @@ label.required, span.required {
 }
 #reply {
   margin-top: 20px;
-  padding: 10px 5px;
+  padding: 10px;
   background: #f9f9f9;
   border: 1px solid #ccc;
 }
 #reply h2 {
   margin-bottom: 10px;
+  padding-bottom: 5px;
+  border-bottom: 2px dotted rgba(0,0,0,0.1);
 }
 #reply > table {
   width: auto;
@@ -851,6 +853,7 @@ a.refresh {
 }
 .infoTable th {
   text-align: left;
+  padding: 3px 8px;
 }
 #ticketThread table.response,
 #ticketThread table.message {
@@ -982,9 +985,7 @@ img.sign-in-image {
 .sidebar {
     margin-bottom: 20px;
     margin-left: 20px;
-}
-.sidebar {
-    width: 220px;
+    width: 215px;
 }
 .rtl .sidebar {
     margin-left: 0;
@@ -999,12 +1000,13 @@ img.sign-in-image {
 
 .sidebar section .header {
     font-weight: bold;
+    margin-bottom: 0.3em;
 }
 .sidebar section + section {
     margin-top: 15px;
 }
 .search-form {
-    padding: 12px 0px 20px 0;
+    padding-top: 12px;
 }
 .searchbar .search,
 .search-form .search {
@@ -1029,13 +1031,13 @@ img.sign-in-image {
 }
 .span4 {
     display: inline-block;
-    width: 30.5%;
+    width: 29.5%;
     margin: 0 1%;
     vertical-align: top;
 }
 .span8 {
     display: inline-block;
-    width: 64.5%;
+    width: 66.5%;
     margin: 0 1%;
     vertical-align: top;
 }
@@ -1052,3 +1054,28 @@ img.sign-in-image {
     color: initial !important;
     text-decoration: none;
 }
+table.custom-data {
+    margin-top: 10px;
+}
+table.custom-data th {
+    width: 25%;
+}
+table.custom-data th {
+    background-color: #F4FAFF;
+    padding: 3px 8px;
+}
+table .headline,
+table.custom-data .headline {
+    border-bottom: 2px solid #ddd;
+    border-bottom: 2px solid rgba(0,0,0,0.15);
+    font-weight: bold;
+    background-color: white;
+}
+#ticketInfo h1 {
+    padding-bottom: 10px;
+    margin-bottom: 5px;
+    border-bottom: 2px dotted rgba(0, 0, 0, 0.15);
+}
+#ticketInfo h1 small {
+    font-weight: normal;
+}
diff --git a/css/redactor.css b/css/redactor.css
index 54222c9a1..a3dc97844 100644
--- a/css/redactor.css
+++ b/css/redactor.css
@@ -17,7 +17,8 @@
 .redactor-box {
   position: relative;
   overflow: visible;
-  background: #fff;
+  overflow-x: hidden;
+  background: #ddd;
 }
 .redactor-box textarea {
   display: block;
@@ -41,8 +42,7 @@
 /*
 	Z-index setup
 */
-.redactor-editor,
-.redactor-box {
+.redactor-editor {
   background: #fff;
 }
 .redactor-editor,
@@ -109,6 +109,7 @@ body .redactor-box-fullscreen {
   font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
   font-size: 14px;
   line-height: 1.6em;
+  box-shadow: 5px 0 10px -8px rgba(0,0,0,0.5);
 }
 .redactor-editor:focus {
   outline: none;
@@ -148,8 +149,9 @@ body .redactor-box-fullscreen {
   font-size: 14px !important;
   line-height: 1 !important;
   background: #fff;
-  border: none;
-  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
+  border: 1px solid rgba(0,0,0,0.05);
+  border-bottom: 0;
+  box-shadow: 0 1px 4px -2px rgba(0, 0, 0, 0.4);
 }
 .redactor-toolbar:after {
   content: "";
diff --git a/css/thread.css b/css/thread.css
index 6fe012353..233f28315 100644
--- a/css/thread.css
+++ b/css/thread.css
@@ -208,15 +208,15 @@
 }
 .thread-body h1,
 .thread-body .h1 {
-  font-size: 36px;
+  font-size: 30px;
 }
 .thread-body h2,
 .thread-body .h2 {
-  font-size: 30px;
+  font-size: 25px;
 }
 .thread-body h3,
 .thread-body .h3 {
-  font-size: 24px;
+  font-size: 21px;
 }
 .thread-body h4,
 .thread-body .h4 {
diff --git a/include/class.forms.php b/include/class.forms.php
index 44d3bee3c..a7b384231 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1622,6 +1622,14 @@ class ThreadEntryField extends FormField {
         return false;
     }
 
+    function getMedia() {
+        $config = $this->getConfiguration();
+        $media = parent::getMedia() ?: array();
+        if ($config['attachments'])
+            $media = array_merge_recursive($media, FileUploadWidget::$media);
+        return $media;
+    }
+
     function getConfigurationOptions() {
         global $cfg;
 
diff --git a/include/client/view.inc.php b/include/client/view.inc.php
index 3b55a0fb6..4f96855d7 100644
--- a/include/client/view.inc.php
+++ b/include/client/view.inc.php
@@ -31,7 +31,8 @@ if ($thisclient && $thisclient->isGuest()
     <tr>
         <td colspan="2" width="100%">
             <h1>
-                <?php echo sprintf(__('Ticket #%s'), $ticket->getNumber()); ?> &nbsp;
+                <b><?php echo $ticket->getSubject(); ?></b>
+                <small>#<?php echo $ticket->getNumber(); ?></small>
                 <a href="tickets.php?id=<?php echo $ticket->getId(); ?>" title="<?php echo __('Reload'); ?>"><span class="Icon refresh">&nbsp;</span></a>
 <div class="pull-right">
     <a class="action-button" href="tickets.php?a=print&id=<?php
@@ -39,7 +40,7 @@ if ($thisclient && $thisclient->isGuest()
 <?php if ($ticket->hasClientEditableFields()
         // Only ticket owners can edit the ticket details (and other forms)
         && $thisclient->getId() == $ticket->getUserId()) { ?>
-                <a class="action-button pull-right" href="tickets.php?a=edit&id=<?php
+                <a class="action-button" href="tickets.php?a=edit&id=<?php
                      echo $ticket->getId(); ?>"><i class="icon-edit"></i> <?php echo __('Edit'); ?></a>
 <?php } ?>
 </div>
@@ -49,6 +50,11 @@ if ($thisclient && $thisclient->isGuest()
     <tr>
         <td width="50%">
             <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
+                <thead>
+                    <tr><td class="headline" colspan="2">
+                        <?php echo __('Basic Ticket Information'); ?>
+                    </td></tr>
+                </thead>
                 <tr>
                     <th width="100"><?php echo __('Ticket Status');?>:</th>
                     <td><?php echo ($S = $ticket->getStatus()) ? $S->getLocalName() : ''; ?></td>
@@ -65,6 +71,11 @@ if ($thisclient && $thisclient->isGuest()
        </td>
        <td width="50%">
            <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
+                <thead>
+                    <tr><td class="headline" colspan="2">
+                        <?php echo __('User Information'); ?>
+                    </td></tr>
+                </thead>
                <tr>
                    <th width="100"><?php echo __('Name');?>:</th>
                    <td><?php echo mb_convert_case(Format::htmlchars($ticket->getName()), MB_CASE_TITLE); ?></td>
@@ -81,32 +92,40 @@ if ($thisclient && $thisclient->isGuest()
        </td>
     </tr>
     <tr>
+        <td colspan="2">
+<!-- Custom Data -->
 <?php
-foreach (DynamicFormEntry::forTicket($ticket->getId()) as $idx=>$form) {
-    $answers = $form->getAnswers();
-    if ($idx > 0 and $idx % 2 == 0) { ?>
-        </tr><tr>
-    <?php } ?>
-    <td width="50%">
-        <table class="infoTable" cellspacing="1" cellpadding="3" width="100%" border="0">
-    <?php foreach ($answers as $answer) {
-        if (in_array($answer->getField()->get('name'), array('name', 'email', 'subject')))
-            continue;
-        elseif (!$answer->getField()->isVisibleToUsers())
-            continue;
-        ?>
-        <tr>
-        <th width="100"><?php echo $answer->getField()->get('label');
-            ?>:</th>
-        <td><?php echo $answer->display(); ?></td>
-        </tr>
-    <?php } ?>
-    </table></td>
-<?php } ?>
+foreach (DynamicFormEntry::forTicket($ticket->getId()) as $form) {
+    // Skip core fields shown earlier in the ticket view
+    $answers = $form->getAnswers()->exclude(Q::any(array(
+        'field__flags__hasbit' => DynamicFormField::FLAG_EXT_STORED,
+        'field__name__in' => array('subject', 'priority'),
+        Q::not(array('field__flags__hasbit' => DynamicFormField::FLAG_CLIENT_VIEW)),
+    )));
+    if (count($answers) == 0)
+        continue;
+    ?>
+        <table class="custom-data" cellspacing="0" cellpadding="4" width="100%" border="0">
+        <tr><td colspan="2" class="headline flush-left"><?php echo $form->getTitle(); ?></th></tr>
+        <?php foreach($answers as $a) {
+            if (!($v = $a->display())) continue; ?>
+            <tr>
+                <th><?php
+    echo $a->getField()->get('label');
+                ?>:</th>
+                <td><?php
+    echo $v;
+                ?></td>
+            </tr>
+            <?php } ?>
+        </table>
+    <?php
+    $idx++;
+} ?>
+    </td>
 </tr>
 </table>
 <br>
-<div class="subject"><?php echo __('Subject'); ?>: <strong><?php echo Format::htmlchars($ticket->getSubject()); ?></strong></div>
 <div id="ticketThread">
 <?php
 if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) {
@@ -163,46 +182,37 @@ if($ticket->getThreadCount() && ($thread=$ticket->getClientThread())) {
     <div id="msg_notice"><?php echo $msg; ?></div>
 <?php }elseif($warn) { ?>
     <div id="msg_warning"><?php echo $warn; ?></div>
-<?php } ?>
-
-<?php
+<?php }
 
 if (!$ticket->isClosed() || $ticket->isReopenable()) { ?>
-<form id="reply" action="tickets.php?id=<?php echo $ticket->getId(); ?>#reply" name="reply" method="post" enctype="multipart/form-data">
+<form id="reply" action="tickets.php?id=<?php echo $ticket->getId();
+?>#reply" name="reply" method="post" enctype="multipart/form-data">
     <?php csrf_token(); ?>
     <h2><?php echo __('Post a Reply');?></h2>
     <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>">
     <input type="hidden" name="a" value="reply">
-    <table border="0" cellspacing="0" cellpadding="3" style="width:100%">
-        <tr>
-            <td colspan="2">
-                <?php
-                if($ticket->isClosed()) {
-                    $msg='<b>'.__('Ticket will be reopened on message post').'</b>';
-                } else {
-                    $msg=__('To best assist you, we request that you be specific and detailed');
-                }
-                ?>
-                <span id="msg"><em><?php echo $msg; ?> </em></span><font class="error">*&nbsp;<?php echo $errors['message']; ?></font>
-                <br/>
-                <textarea name="message" id="message" cols="50" rows="9" wrap="soft"
-                    class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
-                        ?> draft" <?php
-    list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.client', $ticket->getId(), $info['message']);
-    echo $attrs; ?>><?php echo $draft ?: $info['message'];
-                ?></textarea>
-        <?php
-        if ($messageField->isAttachmentsEnabled()) { ?>
-<?php
-            print $attachments->render(array('client'=>true));
-            print $attachments->getForm()->getMedia();
-?>
-        <?php
-        } ?>
-            </td>
-        </tr>
-    </table>
-    <p style="padding-left:165px;">
+    <div>
+        <p><em><?php
+         echo __('To best assist you, we request that you be specific and detailed'); ?></em>
+        <font class="error">*&nbsp;<?php echo $errors['message']; ?></font>
+        </p>
+        <textarea name="message" id="message" cols="50" rows="9" wrap="soft"
+            class="<?php if ($cfg->isHtmlThreadEnabled()) echo 'richtext';
+                ?> draft" <?php
+list($draft, $attrs) = Draft::getDraftAndDataAttrs('ticket.client', $ticket->getId(), $info['message']);
+echo $attrs; ?>><?php echo $draft ?: $info['message'];
+            ?></textarea>
+    <?php
+    if ($messageField->isAttachmentsEnabled()) {
+        print $attachments->render(array('client'=>true));
+    } ?>
+    </div>
+<?php if ($ticket->isClosed()) { ?>
+    <div class="warning-banner">
+        <?php echo __('Ticket will be reopened on message post'); ?>
+    </div>
+<?php } ?>
+    <p style="text-align:center">
         <input type="submit" value="<?php echo __('Post Reply');?>">
         <input type="reset" value="<?php echo __('Reset');?>">
         <input type="button" value="<?php echo __('Cancel');?>" onClick="history.go(-1)">
diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php
index ae445a656..1a959a4c8 100644
--- a/include/staff/page.inc.php
+++ b/include/staff/page.inc.php
@@ -131,7 +131,14 @@ if ($page && count($langs) > 1) { ?>
 <?php } ?>
     </ul>
 <?php
-} ?>
+}
+
+// For landing page, constrain to the diplayed width of 565px;
+if ($info['type'] == 'landing')
+    $width = '565px';
+else
+    $width = '100%';
+?>
 </td>
 <td id="translations_container" style="padding-left: 10px">
     <div id="msg_info">
@@ -143,7 +150,8 @@ if ($page && count($langs) > 1) { ?>
 
         <div id="translation-<?php echo $cfg->getPrimaryLanguage(); ?>" class="tab_content"
             lang="<?php echo $cfg->getPrimaryLanguage(); ?>">
-        <textarea name="body" cols="21" rows="12" style="width:100%" class="richtext draft"
+        <textarea name="body" cols="21" rows="12" class="richtext draft"
+            data-width="<?php echo $width; ?>"
 <?php
     if (!$info['type'] || $info['type'] == 'thank-you') echo 'data-root-context="thank-you"';
     list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'], $info['body']);
@@ -154,11 +162,11 @@ if ($page && count($langs) > 1) { ?>
     foreach ($langs as $tag=>$nfo) {
         if ($tag == $cfg->getPrimaryLanguage())
             continue; ?>
-        <div id="translation-<?php echo $tag; ?>" class="tab_content"
-            style="display:none;" lang="<?php echo $tag; ?>">
+        <div id="translation-<?php echo $tag; ?>" class="tab_content hidden"
+            lang="<?php echo $tag; ?>">
         <textarea name="trans[<?php echo $tag; ?>][body]" cols="21" rows="12"
 <?php if ($info['type'] == 'thank-you') echo 'data-root-context="thank-you"'; ?>
-            style="width:100%" class="richtext draft"
+            style="width:100%" class="richtext draft" data-width="<?php echo $width; ?>"
 <?php
     list($draft, $attrs) = Draft::getDraftAndDataAttrs('page', $info['id'].'.'.$tag, $info['trans'][$tag]);
     echo $attrs; ?>><?php echo $draft ?: $info['trans'][$tag]; ?></textarea>
diff --git a/index.php b/index.php
index 7f341f6e4..6c9558fa9 100644
--- a/index.php
+++ b/index.php
@@ -32,6 +32,7 @@ if ($cfg && $cfg->isKnowledgebaseEnabled()) { ?>
     <button type="submit" class="green button">Search</button>
     </form>
 </div>
+    <div class="thread-body">
 <?php
 }
     if($cfg && ($page = $cfg->getLandingPage()))
@@ -39,6 +40,7 @@ if ($cfg && $cfg->isKnowledgebaseEnabled()) { ?>
     else
         echo  '<h1>'.__('Welcome to the Support Center').'</h1>';
     ?>
+    </div>
 </div>
 <div class="clear"></div>
 
diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js
index 19ff52a6a..07c17fb9b 100644
--- a/js/redactor-osticket.js
+++ b/js/redactor-osticket.js
@@ -269,6 +269,8 @@ $(function() {
                 'toolbarFixedBox': true,
                 'focusCallback': function() { this.$box.addClass('no-pjax'); },
                 'initCallback': function() {
+                    if (this.$element.data('width'))
+                        this.$editor.width(this.$element.data('width'));
                     this.$editor.attr('spellcheck', 'true');
                     var lang = this.$editor.closest('[lang]').attr('lang');
                     if (lang)
diff --git a/js/redactor-plugins.js b/js/redactor-plugins.js
index 772573bab..6aaeea3bd 100644
--- a/js/redactor-plugins.js
+++ b/js/redactor-plugins.js
@@ -93,7 +93,7 @@ RedactorPlugins.fontcolor = function()
 			{
 				var color = colors[z];
 
-				var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 22px; height: 22px;"></a>');
+				var $swatch = $('<a rel="' + color + '" data-rule="' + rule +'" href="#" style="float: left; font-size: 0; border: 2px solid #fff; padding: 0; margin: 0; width: 22px; height: 22px; box-sizing: border-box;"></a>');
 				$swatch.css('background-color', color);
 				$swatch.on('click', func);
 
diff --git a/scp/css/scp.css b/scp/css/scp.css
index 2b6701e9c..59312e8b8 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -28,10 +28,6 @@ div#header a {
     color:#E65524;
 }
 
-.form_table a:hover {
-    text-decoration: underline;
-}
-
 .centered {
     text-align:center;
 }
@@ -989,6 +985,9 @@ ul.tabs li a {
     outline: none;
     padding: 5px 10px;
 }
+ul.tabs li a:hover {
+    text-decoration: none;
+}
 
 ul.tabs li.active a {
     font-weight: bold;
@@ -1791,6 +1790,8 @@ div.selected-signature {
     overflow-y: hidden;
     font-size: 15px;
     line-height: 1.25rem;
+    background-color: white;
+    background-color: rgba(255, 255, 255, 0.9);
 }
 div.selected-signature .inner {
     opacity: 0.5;
diff --git a/tickets.php b/tickets.php
index 10f70676a..6260e08aa 100644
--- a/tickets.php
+++ b/tickets.php
@@ -35,7 +35,7 @@ if($_REQUEST['id']) {
 if (!$ticket && $thisclient->isGuest())
     Http::redirect('view.php');
 
-$tform = TicketForm::objects()->one();
+$tform = TicketForm::getInstance()->getForm();
 $messageField = $tform->getField('message');
 $attachments = $messageField->getWidget()->getAttachments();
 
@@ -130,8 +130,6 @@ if($ticket && $ticket->checkUserAccess($thisclient)) {
 }
 include(CLIENTINC_DIR.'header.inc.php');
 include(CLIENTINC_DIR.$inc);
-if ($tform instanceof DynamicFormEntry)
-    $tform = $tform->getForm();
 print $tform->getMedia();
 include(CLIENTINC_DIR.'footer.inc.php');
 ?>
-- 
GitLab