Skip to content

Commit

Permalink
Forms: basic fields
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienClairembault authored Sep 18, 2023
1 parent 1f6bd43 commit c0fc3a1
Show file tree
Hide file tree
Showing 14 changed files with 530 additions and 73 deletions.
3 changes: 2 additions & 1 deletion css/includes/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ $tabs-active-fg: $dark !default;
$tabs-active-border: $tabs-border !default;
$badge-bg: $secondary !default;
$badge-fg: $light !default;
$itil-secondary-bg: #f5f5f5 !default; // secondary color for right side and footer (primary color is card background)
$itil-secondary-bg: #f3f5f9 !default; // secondary color for ITIL footer toolbar (primary color is card background), tabler use cold grays thus we must also use a grey with a similar temperature here
$footer-toolbar-bg: $itil-secondary-bg; // More generic alias, should be used if possible
$timeline-itilc-bg: #e2f2e3 !default;
$timeline-itilc-fg: #155210 !default;
$timeline-itilc-border: #87aa8a !default;
Expand Down
2 changes: 2 additions & 0 deletions css/includes/_includes.scss
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ $is-dark: false !default;
@import "components/asset-form";
@import "components/buttons-group";
@import "components/callout";
@import "components/content-editable-inputs";
@import "components/documentation";
@import "components/debug-toolbar";
@import "components/fileupload";
@import "components/flatpickr";
@import "components/floating-buttons";
@import "components/form/form-editor";
@import "components/fuzzy";
@import "components/global-menu";
@import "components/kanban";
Expand Down
109 changes: 109 additions & 0 deletions css/includes/components/_content-editable-inputs.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*!
* ---------------------------------------------------------------------
*
* GLPI - Gestionnaire Libre de Parc Informatique
*
* http://glpi-project.org
*
* @copyright 2015-2023 Teclib' and contributors.
* @copyright 2003-2014 by the INDEPNET Development Team.
* @licence https://www.gnu.org/licenses/gpl-3.0.html
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
*/

/**
* Styles for inputs that are disguised as "content editable" DOM elements
* This inputs may be more convenient than real "content-editable" elements for
* some use cases (richtext editor, ...)
*/

// Padding for content-editable inputs
// Must not be too high as content-editable is usually done without padding
$inline-input-padding: 2px 4px;

.content-editable-h2 {
// Copy h2 styles
font-size: 1.2rem !important;
line-height: 1.5rem;
font-weight: var(--tblr-font-weight-medium);
border: 0;
padding: $inline-input-padding;
margin-bottom: 1rem;
background-color: transparent;

&:hover {
box-shadow: 0 0 0 0.25rem rgba($primary, 0.20);
}
}


.content-editable-tinymce {
// Remove default border and padding, add similar hover style used on our inputs
.tox-tinymce {
border-color: transparent !important;
padding: $inline-input-padding;

&:hover {
box-shadow: 0 0 0 0.25rem rgba($primary, 0.20);
}
}

// Status bar is empty here, do not display to gain some vertical space
.tox-statusbar {
display: none !important;
}

// Small left padding to match our content-editable inputs padding
.tox-toolbar__primary {
.tox-toolbar__group:first-child {
padding-left: 2px !important;
}
}

// Hide richtext actions toolbor
.tox-editor-header {
// Can't use "display: none" as tinymce doens't like it and it break
// the rendering of the header (probably caused by some calculations done
// on width)
opacity: 0;
height: 0;
}
}

// Simulate focus like a bootstrap input, needed for tinymce with some javascript
// help to trigger and remove the class as needed
.simulate-focus {
box-shadow: 0 0 0 0.25rem rgba($primary, 0.20);

// Show richtext toolbar only when focused
.tox-editor-header {
opacity: unset;
height: unset;
}
}

// Class inside tinymce's iframe, remove internal padding
.content-editable-tinymce-editor {
margin: 0 !important;
padding: 0 !important;
}
63 changes: 63 additions & 0 deletions css/includes/components/form/_form-editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*!
* ---------------------------------------------------------------------
*
* GLPI - Gestionnaire Libre de Parc Informatique
*
* http://glpi-project.org
*
* @copyright 2015-2023 Teclib' and contributors.
* @copyright 2003-2014 by the INDEPNET Development Team.
* @licence https://www.gnu.org/licenses/gpl-3.0.html
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
*/

.form-editor {
// Use all available parent space
flex-grow: 1;

// Subtle gradient to avoid white on white cards while still keeping a white/white connection to the active tab (experimental)
// TODO: keep / remove / tweak when the UX is more complete (questions, sections, ...)
background: linear-gradient(
169deg,
rgb(255,255,255) 0%,
rgb(254,254,254) 14%,
rgb(253,253,253) 22%,
rgb(252,252,252) 33%,
rgb(251,251,252) 41%,
rgb(248,250,252) 48%
);

.designer {
.form-details {
.card-title {
// Emphasis form title with an above average font size
font-size: 1.2rem !important;
}
}
}
}

.editor-footer {
border-top: 1px solid $border-color;
background: $footer-toolbar-bg;
}
44 changes: 42 additions & 2 deletions front/form/form.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,45 @@
// Only super admins for now - TODO add specific rights
Session::checkRight("config", UPDATE);

// Show requested form
Form::displayFullPageForItem($_GET['id'] ?? 0, ['admin', Form::getType()], []);
// Read parameters
$id = $_REQUEST['id'] ?? null;

if (isset($_POST["add"])) {
// Create form
$form = new Form();
$form->check($id, CREATE);

if ($form->add($_POST)) {
if ($_SESSION['glpibackcreated']) {
Html::redirect($form->getLinkURL());
}
}
Html::back();
} elseif (isset($_POST["update"])) {
// Update form
$form = new Form();
$form->check($id, UPDATE);
$form->update($_POST);
Html::back();
} elseif (isset($_POST["delete"])) {
// Delete form
$form = new Form();
$form->check($id, DELETE);
$form->delete($_POST);
$form->redirectToList();
} elseif (isset($_POST["restore"])) {
// Restore form
$form = new Form();
$form->check($id, DELETE);
$form->restore($_POST);
$form->redirectToList();
} elseif (isset($_POST["purge"])) {
// Purge form
$form = new Form();
$form->check($id, PURGE);
$form->delete($_POST, true);
$form->redirectToList();
} else {
// Show requested form
Form::displayFullPageForItem($id, ['admin', Form::getType()], []);
}
2 changes: 1 addition & 1 deletion inc/define.php
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@
],
'config' => ['clipboard']
],
'admin' => ['clipboard', 'sortable'],
'admin' => ['clipboard', 'sortable', 'tinymce'],
'preference' => ['clipboard'],
'self-service' => array_merge(['tinymce'], $reservations_libs),
'tickets' => [
Expand Down
1 change: 1 addition & 0 deletions install/empty_data.php
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,7 @@ public function getEmptyData(): array
],
];

$ADDTODISPLAYPREF['Glpi\Form\Form'] = [1, 80, 86, 3, 4];
$ADDTODISPLAYPREF['Cluster'] = [31, 19];
$ADDTODISPLAYPREF['Domain'] = [3, 4, 2, 6, 7];
$ADDTODISPLAYPREF['DomainRecord'] = [2, 3];
Expand Down
13 changes: 13 additions & 0 deletions js/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,19 @@ $(() => {
blockFormSubmit(form, e);
}
});

// Clear focus on content-editable-tinymce items when clicking outside of their content
$(document).on('click focus', 'body', function(e) {
if (
// Event must be outside of our simulate-focus item
$(e.target).closest('.simulate-focus').length == 0
// Special case when target is part of tinymce toolbar/aux, must NOT drop focus in this case
&& $(e.target).closest('.tox-toolbar__overflow').length == 0
&& $(e.target).closest('.tox-tinymce-aux').length == 0
) {
$('.content-editable-tinymce').removeClass('simulate-focus');
}
});
});

/**
Expand Down
58 changes: 34 additions & 24 deletions src/Form/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,15 @@ public function defineTabs($options = [])
return $tabs;
}

public function getEmpty()
{
parent::getEmpty();
$this->fields['name'] = __("Untitled form");
$this->fields['header'] = __("My form description...");

return true;
}

public function showForm($id, array $options = [])
{
if (!empty($id)) {
Expand All @@ -99,8 +108,9 @@ public function showForm($id, array $options = [])
}
$this->initForm($id, $options);

// Render twig template
$twig = TemplateRenderer::getInstance();
$twig->display('pages/admin/form_editor.html.twig', [
$twig->display('pages/admin/form/form_editor.html.twig', [
'item' => $this,
'params' => $options,
]);
Expand All @@ -112,12 +122,12 @@ public function rawSearchOptions()
$search_options = parent::rawSearchOptions();

$search_options[] = [
'id' => '2',
'table' => self::getTable(),
'field' => 'id',
'name' => __('ID'),
'massiveaction' => false,
'datatype' => 'number'
'id' => '2',
'table' => self::getTable(),
'field' => 'id',
'name' => __('ID'),
'massiveaction' => false,
'datatype' => 'number'
];
$search_options[] = [
'id' => '80',
Expand All @@ -128,27 +138,27 @@ public function rawSearchOptions()
'massiveaction' => false,
];
$search_options[] = [
'id' => '3',
'table' => $this->getTable(),
'field' => 'is_active',
'name' => __('Active'),
'datatype' => 'bool'
'id' => '3',
'table' => $this->getTable(),
'field' => 'is_active',
'name' => __('Active'),
'datatype' => 'bool'
];
$search_options[] = [
'id' => '4',
'table' => $this->getTable(),
'field' => 'date_mod',
'name' => __('Last update'),
'datatype' => 'datetime',
'massiveaction' => false
'id' => '4',
'table' => $this->getTable(),
'field' => 'date_mod',
'name' => __('Last update'),
'datatype' => 'datetime',
'massiveaction' => false
];
$search_options[] = [
'id' => '5',
'table' => $this->getTable(),
'field' => 'date_creation',
'name' => __('Creation date'),
'datatype' => 'datetime',
'massiveaction' => false
'id' => '5',
'table' => $this->getTable(),
'field' => 'date_creation',
'name' => __('Creation date'),
'datatype' => 'datetime',
'massiveaction' => false
];

return $search_options;
Expand Down
Loading

0 comments on commit c0fc3a1

Please sign in to comment.