From 2b4ad2c50b5726b970fc34d6e9ab58b3fb07751e Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 20 Aug 2013 11:42:46 +0000 Subject: [PATCH] Reviewed the portal (look and feel slightly improved) SVN:trunk[2826] --- application/portalwebpage.class.inc.php | 5 +- .../main.itop-request-mgmt.php | 2 +- .../main.itop-request-mgmt.php | 2 +- portal/index.php | 196 +++++++++++++++--- portal/portal.css | 149 +++++++------ 5 files changed, 256 insertions(+), 98 deletions(-) diff --git a/application/portalwebpage.class.inc.php b/application/portalwebpage.class.inc.php index 8125d787a..641d22c31 100644 --- a/application/portalwebpage.class.inc.php +++ b/application/portalwebpage.class.inc.php @@ -795,7 +795,10 @@ EOF } if ($iButtonFlags & BUTTON_BACK) { - $aButtons[] = "m_sWizardId}');\">"; + if (utils::ReadParam('step_back', 1) != 1) + { + $aButtons[] = "m_sWizardId}');\">"; + } } if ($iButtonFlags & BUTTON_NEXT) { diff --git a/datamodels/1.x/itop-request-mgmt-1.0.0/main.itop-request-mgmt.php b/datamodels/1.x/itop-request-mgmt-1.0.0/main.itop-request-mgmt.php index 32b4ba1cb..635a65cea 100644 --- a/datamodels/1.x/itop-request-mgmt-1.0.0/main.itop-request-mgmt.php +++ b/datamodels/1.x/itop-request-mgmt-1.0.0/main.itop-request-mgmt.php @@ -28,7 +28,7 @@ define('PORTAL_ALL_PARAMS', 'from_service_id,org_id,caller_id,service_id,service define('PORTAL_ATTCODE_LOG', 'ticket_log'); define('PORTAL_ATTCODE_COMMENT', 'user_commment'); -define('PORTAL_REQUEST_FORM_ATTRIBUTES', 'title,description,impact,urgency,workgroup_id'); +define('PORTAL_REQUEST_FORM_ATTRIBUTES', 'title,description,impact,urgency,workgroup_id,ticket_log'); define('PORTAL_ATTCODE_TYPE', ''); // optional if the type has to be set define('PORTAL_SET_TYPE_FROM', ''); // The attribute to get the type from (Subcategory) diff --git a/datamodels/2.x/itop-request-mgmt/main.itop-request-mgmt.php b/datamodels/2.x/itop-request-mgmt/main.itop-request-mgmt.php index 9e601dfdc..fc8b42143 100755 --- a/datamodels/2.x/itop-request-mgmt/main.itop-request-mgmt.php +++ b/datamodels/2.x/itop-request-mgmt/main.itop-request-mgmt.php @@ -28,7 +28,7 @@ define('PORTAL_ALL_PARAMS', 'from_service_id,org_id,caller_id,service_id,service define('PORTAL_ATTCODE_LOG', 'public_log'); define('PORTAL_ATTCODE_COMMENT', 'user_comment'); -define('PORTAL_REQUEST_FORM_ATTRIBUTES', 'title,description,impact,urgency'); +define('PORTAL_REQUEST_FORM_ATTRIBUTES', 'title,description,impact,urgency,public_log'); define('PORTAL_ATTCODE_TYPE', 'request_type'); // optional if the type has to be set define('PORTAL_SET_TYPE_FROM', 'request_type'); // The attribute to get the type from (Subcategory) diff --git a/portal/index.php b/portal/index.php index 8f559c643..87b44eca8 100644 --- a/portal/index.php +++ b/portal/index.php @@ -82,7 +82,7 @@ function ShowClosedTickets(WebPage $oP) */ function SelectServiceCategory($oP, $oUserOrg) { - $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS); + $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS.',template_id'); $oSearch = DBObjectSearch::FromOQL(PORTAL_SERVICECATEGORY_QUERY); $oSearch->AllowAllData(); // In case the user has the rights on his org only @@ -131,11 +131,9 @@ function SelectServiceCategory($oP, $oUserOrg) * @param $iSvcId Id of the selected service in case of pass-through (when there is only one service) * @return void */ - function SelectServiceSubCategory($oP, $oUserOrg, $iSvcId = null) { - $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS); - $iWizardButtons = 0; + $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS.',template_id'); if ($iSvcId == null) { $iSvcId = $aParameters['service_id']; @@ -143,7 +141,6 @@ function SelectServiceSubCategory($oP, $oUserOrg, $iSvcId = null) else { $aParameters['service_id'] = $iSvcId; - $iWizardButtons = BUTTON_NEXT; } $iDefaultSubSvcId = isset($aParameters['servicesubcategory_id']) ? $aParameters['servicesubcategory_id'] : 0; @@ -157,7 +154,7 @@ function SelectServiceSubCategory($oP, $oUserOrg, $iSvcId = null) // Only one sub service, skip this step of the wizard $oSubService = $oSet->Fetch(); $iSubSvdId = $oSubService->GetKey(); - RequestCreationForm($oP, $oUserOrg, $iSvcId, $iSubSvdId); + SelectRequestTemplate($oP, $oUserOrg, $iSvcId, $iSubSvdId); } else { @@ -192,8 +189,7 @@ function SelectServiceSubCategory($oP, $oUserOrg, $iSvcId = null) $oP->add("\n"); $oP->DumpHiddenParams($aParameters, array('servicesubcategory_id')); $oP->add(""); - $iWizardButtons |= BUTTON_NEXT | BUTTON_CANCEL; - $oP->WizardFormButtons($iWizardButtons); + $oP->WizardFormButtons(BUTTON_BACK | BUTTON_NEXT | BUTTON_CANCEL); //Back button automatically discarded if on the first page $oP->WizardFormEnd(); $oP->WizardCheckSelectionOnSubmit(Dict::S('Portal:PleaseSelectAServiceSubCategory')); $oP->add("\n"); @@ -206,22 +202,17 @@ function SelectServiceSubCategory($oP, $oUserOrg, $iSvcId = null) } /** - * Displays the form for the final step of the UserRequest creation - * @param WebPage $oP The current web page for the form output + * Displays the form to select a Template + * @param WebPage $oP Web page for the form output * @param Organization $oUserOrg The organization of the current user - * @param integer $iSvcId The identifier of the service (in cal of fall through, when there is only one service) - * @param integer $iSubSvcId The identifier of the sub-service (in cal of fall through, when there is only one sub-service) + * @param $iSvcId Id of the selected service in case of pass-through (when there is only one service) + * @param integer $iSubSvcId The identifier of the sub-service (fall through when there is only one sub-service) * @return void */ -function RequestCreationForm($oP, $oUserOrg, $iSvcId = null, $iSubSvcId = null) +function SelectRequestTemplate($oP, $oUserOrg, $iSvcId = null, $iSubSvcId = null) { - $oP->add_script( -<<ReadAllParams(PORTAL_ALL_PARAMS); + $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS.',template_id'); + if ($iSvcId != null) { $aParameters['service_id'] = $iSvcId; @@ -230,17 +221,130 @@ EOF { $aParameters['servicesubcategory_id'] = $iSubSvcId; } + + $iDefaultTemplate = isset($aParameters['template_id']) ? $aParameters['template_id'] : 0; + if (MetaModel::IsValidClass('Template')) + { + $oSearch = DBObjectSearch::FromOQL(REQUEST_TEMPLATE_QUERY); + $oSearch->AllowAllData(); + $oSet = new CMDBObjectSet($oSearch, array(), array( + 'service_id' => $aParameters['service_id'], + 'servicesubcategory_id' => $aParameters['servicesubcategory_id'] + )); + if ($oSet->Count() == 0) + { + RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id']); + return; + } + elseif ($oSet->Count() == 1) + { + $oTemplate = $oSet->Fetch(); + $iTemplateId = $oTemplate->GetKey(); + RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id'], $iTemplateId); + return; + } + + $oServiceSubCategory = MetaModel::GetObject('ServiceSubcategory', $aParameters['servicesubcategory_id'], false); + if (is_object($oServiceSubCategory)) + { + $oP->add("
\n"); + $oP->add("

".Dict::Format('Portal:SelectRequestTemplate', $oServiceSubCategory->GetName())."

\n"); + $oP->WizardFormStart('request_wizard', 3); + $oP->add("\n"); + while($oTemplate = $oSet->Fetch()) + { + $id = $oTemplate->GetKey(); + $sChecked = ""; + if ($id == $iDefaultTemplate) + { + $sChecked = "checked"; + } + $oP->add(""); + + $oP->add(""); + + $oP->add(""); + + $oP->add(""); + } + $oP->add("
"); + $oP->p(""); + $oP->add(""); + $oP->p(""); + $oP->p($oTemplate->GetAsHTML('description')); + $oP->add("
\n"); + $oP->DumpHiddenParams($aParameters, array('template_id')); + $oP->add(""); + $oP->WizardFormButtons(BUTTON_BACK | BUTTON_NEXT | BUTTON_CANCEL); //Back button automatically discarded if on the first page + $oP->WizardCheckSelectionOnSubmit(Dict::S('Portal:PleaseSelectATemplate')); + $oP->WizardFormEnd(); + $oP->add("
\n"); + } + else + { + $oP->p("Error: Invalid servicesubcategory_id = ".$aParameters['servicesubcategory_id']); + } + } + else + { + RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id']); + return; + } +} + +/** + * Displays the form for the final step of the UserRequest creation + * @param WebPage $oP The current web page for the form output + * @param Organization $oUserOrg The organization of the current user + * @param integer $iSvcId The identifier of the service (fall through when there is only one service) + * @param integer $iSubSvcId The identifier of the sub-service (fall through when there is only one sub-service) + * @param integer $iTemplateId The identifier of the template (fall through when there is only one template) + * @return void + */ +function RequestCreationForm($oP, $oUserOrg, $iSvcId = null, $iSubSvcId = null, $iTemplateId = null) +{ + $oP->add_script( +<<ReadAllParams(PORTAL_ALL_PARAMS.',template_id'); + if ($iSvcId != null) + { + $aParameters['service_id'] = $iSvcId; + } + if ($iSubSvcId != null) + { + $aParameters['servicesubcategory_id'] = $iSubSvcId; + } + if ($iTemplateId != null) + { + $aParameters['template_id'] = $iTemplateId; + } // Example: $aList = array('title', 'description', 'impact', 'emergency'); $aList = explode(',', PORTAL_REQUEST_FORM_ATTRIBUTES); $sDescription = ''; - if (isset($aParameters['template_id'])) + if (isset($aParameters['template_id']) && ($aParameters['template_id'] != 0)) { + $aTemplateFields = array(); $oTemplate = MetaModel::GetObject('Template', $aParameters['template_id'], false); if (is_object($oTemplate)) { - $sDescription = htmlentities($oTemplate->Get('template'), ENT_QUOTES, 'UTF-8'); + $oFieldSearch = DBObjectSearch::FromOQL('SELECT TemplateField WHERE template_id = :template_id'); + $oFieldSearch->AllowAllData(); + $oFieldSet = new DBObjectSet($oFieldSearch, array('order' => true), array('template_id' => $oTemplate->GetKey())); + while($oField = $oFieldSet->Fetch()) + { + $sAttCode = $oField->Get('code'); + if (isset($aParameters[$sAttCode])) + { + $oField->Set('initial_value', $aParameters[$sAttCode]); + } + $aTemplateFields[$sAttCode] = $oField; + } } } @@ -286,7 +390,27 @@ EOF $sValue = "".$oRequest->GetFormElementForField($oP, get_class($oRequest), $sAttCode, $oAttDef, $value, '', 'attr_'.$sAttCode, '', $iFlags, $aArgs).''; $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sValue); } - $aDetails[] = array('label' => MetaModel::GetLabel('UserRequest', PORTAL_ATTCODE_LOG), 'value' => ''); +// The log must be requested in the constant PORTAL_REQUEST_FORM_ATTRIBUTES +// $aDetails[] = array('label' => MetaModel::GetLabel('UserRequest', PORTAL_ATTCODE_LOG), 'value' => ''); + + if (!empty($aTemplateFields)) + { + foreach ($aTemplateFields as $sAttCode => $oField) + { + if (!in_array($sAttCode, $aList)) + { + $sValue = $oField->GetFormElement($oP, get_class($oRequest)); + if ($oField->Get('input_type') == 'hidden') + { + $aHidden[] = $sValue; + } + else + { + $aDetails[] = array('label' => $oField->GetAsHTML('label'), 'value' => $sValue); + } + } + } + } $oP->add_linked_script("../js/json.js"); $oP->add_linked_script("../js/forms-json-utils.js"); @@ -297,7 +421,7 @@ EOF $oP->add_linked_script("../js/jquery.blockUI.js"); $oP->add("
\n"); $oP->add("

".Dict::S('Portal:DescriptionOfTheRequest')."

\n"); - $oP->WizardFormStart('request_form', 3); + $oP->WizardFormStart('request_form', 4); //$oP->add("\n"); $oP->details($aDetails); @@ -306,7 +430,7 @@ EOF $oP->DumpHiddenParams($aParameters, $aList); $oP->add(""); - $oP->WizardFormButtons(BUTTON_BACK | BUTTON_FINISH | BUTTON_CANCEL); + $oP->WizardFormButtons(BUTTON_BACK | BUTTON_FINISH | BUTTON_CANCEL); //Back button automatically discarded if on the first page $oP->WizardFormEnd(); $oP->add("\n"); $iFieldsCount = count($aFieldsMap); @@ -340,7 +464,7 @@ EOF */ function DoCreateRequest($oP, $oUserOrg) { - $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS); + $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS.',template_id'); $sTransactionId = utils::ReadPostedParam('transaction_id', ''); if (!utils::IsTransactionValid($sTransactionId)) { @@ -399,7 +523,17 @@ function DoCreateRequest($oP, $oUserOrg) list($bRes, $aIssues) = $oRequest->CheckToWrite(); if ($bRes) { - $oRequest->DBInsertNoReload(); + if (isset($aParameters['template_id'])) + { + $oTemplate = MetaModel::GetObject('Template', $aParameters['template_id']); + $oRequest->Set('public_log', $oTemplate->GetPostedValuesAsText($oRequest)."\n"); + $oRequest->DBInsertNoReload(); + $oTemplate->RecordExtraDataFromPostedForm($oRequest); + } + else + { + $oRequest->DBInsertNoReload(); + } $oP->add("

".Dict::Format('UI:Title:Object_Of_Class_Created', $oRequest->GetName(), MetaModel::GetName(get_class($oRequest)))."

\n"); //DisplayObject($oP, $oRequest, $oUserOrg); @@ -430,12 +564,16 @@ function CreateRequest(WebPage $oP, Organization $oUserOrg) case 1: SelectServiceSubCategory($oP, $oUserOrg); break; - + case 2: + SelectRequestTemplate($oP, $oUserOrg); + break; + + case 3: RequestCreationForm($oP, $oUserOrg); break; - case 3: + case 4: DoCreateRequest($oP, $oUserOrg); break; } diff --git a/portal/portal.css b/portal/portal.css index 631aacc7d..5a2231852 100644 --- a/portal/portal.css +++ b/portal/portal.css @@ -2,6 +2,8 @@ html, body { margin: 0; padding:0; overflow-y: auto; + font-family: Arial,Helvetica,Verdana,sans-serif; + font-size: 8pt; } #portal { height: 100%; @@ -10,88 +12,87 @@ html, body { margin: auto; padding-left: 10px; padding-right: 10px; - text-align: center; + no.text-align: center; overflow-y: auto; - no.max-width: 90%; - min-width: 960px; - position: relative; + max-width: 90%; + min-width: 960px; + position: relative; display: block; clear: both; } div#portal #welcome { - display: none; + background: url("./images/dockbar_bg.png") repeat-x scroll 0 0 #97A1AE; + border-bottom: 1px solid #636364; + font-size: 13px; + padding: 1px 5px; + position: relative; + z-index: 300; + text-align:right; + color: #2C2F34; + font-weight: bold; + text-shadow: 1px 1px #FFFFFF; } div#portal #banner { - background-color: #F6F6F1; - display: block; - height: 60px; - vertical-align: middle; - width: 100%; -} -div#portal #admin-banner { - width: 100%; -} -div#portal #logo { - background: url("../images/itop-logo.png") no-repeat scroll 0 0 transparent; - border: 0 none; - display: inline-block; height: 116px; - line-height: 48px; - margin-left: 20px; - margin-right: 20px; - padding-right: 50px; - text-align: center; - vertical-align: middle; - width: 240px; -} - -div#menu { display: block; - left: 200px; - line-height: 48px; - position: absolute; - right: 0; - top: 0; - width: auto; - overflow: hidden; + vertical-align:middle; + background-color: #f6f6f1; + background: none repeat scroll 0 0 transparent; + margin: 0 auto; + max-width: 90%; + min-width: 960px; + position: relative; + margin-bottom: 3em; } +div#portal #logo { + background: url(./images/company_logo.png) 0 0 no-repeat; + margin-left:20px; + margin-right:20px; + height: 70px; + border: 0; + vertical-align: middle; + text-align: center; + display: block; + line-height: 116px; +} +#menu { + background: url("./images/bg.png") repeat-x scroll 0 0 #414445; + clear: both; + min-height: 2.4em; + line-height: 3em; + -moz-border-radius: 4px; + vertical-align: middle; +} #portal_menu { height: 60px; } -#change_pwd { - background: url("../images/password.png") no-repeat scroll 0 0 transparent; - display: block; - float: right; -} - -#logoff { - background: url("../images/logoff.png") no-repeat scroll 0 0 transparent; - display: block; - float: right; -} -#logoff span { -} - div.button { font-size: 1.1em; font-weight: bold; text-decoration: none; } -a.button, a.button:visited { - color: #1C94C4; - display: inline-block; - height: 48px; - line-height: 48px; - text-decoration: none; - vertical-align: middle; +a.button , a.button:visited { + line-height: 1.2em; + color: #FFFFFF; + font-size: 1.1em; + font-weight: bold; + text-decoration: none; + display: inline; + clear:both; +} +a.button:hover span { + background: #000; } - a.button span { - margin-left: 50px; - margin-right: 20px; - vertical-align: middle; + vertical-align:middle; + margin: 0 1px; + padding: 5px; + padding-left: 15px; + padding-right: 15px; + -moz-border-radius: 4px; + border-radius: 4px; } #close_form_table { @@ -111,8 +112,16 @@ a.button span { display: inline-block; } +div.wizContainer +{ + border: 1px solid #C8C9CA; + -moz-border-radius: 4px 4px 4px 4px; + background-color: #fff; + padding: 3px; +} + .wizContainer table { - display: inline-block; + nodisplay: inline-block; text-align: left; } @@ -145,10 +154,18 @@ table.listContainer { width: 100%; } h1 { - font-weight: bold; - font-weight: bold; - padding: 5px; - margin-top: 5px; + background: url("./images/header_bg.png") repeat-x scroll 0 0 #D4D4D4; + border-color: #C8C9CA #9E9E9E #9E9E9E #C8C9CA; + border-style: solid; + border-width: 1px; + font-size: 1.1em; + font-weight: bold; + color: #222222; + font-weight: bold; + text-shadow: 1px 1px #FFFFFF; + padding: 5px; + -moz-border-radius: 4px 4px 4px 4px; + margin-top: 5px; } div.DrawerHandle { @@ -212,4 +229,4 @@ div.edit_item span div table tbody tr td textarea{ } div#ticket_shortcuts form { display: inline-block; -} \ No newline at end of file +}