-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom asset fields #17462
base: main
Are you sure you want to change the base?
Custom asset fields #17462
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will not review the UI/UX.
In a next PR, we should implements reordering/removal of all fields of an asset definition, including basic fields. I started a few weeks ago a pr (#16975) for that. I don't have the time right now to finish it but in a very quick summary:
- all fields manipulation should be in a single "Fields" tab
- we can reorder any existing field (basic and custom)
- we can remove any fields (same)
- we can add basic fields (if they have been removed) and new custom fields. The UX here will be not that easy to make
Just one thing, btw, the first displayed input is the system name, it's complicated to understant as the field, although set as read-only is not identifiable as non editable (a global issue in GLPI main we should address) but also is deducted from label input.
I suggest to display the label field first, and make system name just for information (in a HtmlField rather Input in read only)
I'm overriding the form_fields block rather than using more_fields block, so I control where the field goes. Would it be desired to give users the ability to set this field themselves? Right now it is just auto-generated for convenience. There shouldn't be any issue with users changing the field name except that it would break compatibility of API integrations. Everything added by this PR refers to the fields by ID in the DB. |
Not sure it adds something useful, let's keep the information visible (displayed in second), just avoid the field input display |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Things I noted while testing on a fresh instance:
- "Custom Field" tab should be placed 3rd (after "Capacities") and later renamed "Fields"
- "Uncaught Exception Error: Call to undefined function Glpi\Asset_() in /var/www/glpi/src/Glpi/Asset/CustomField.php at line 252" when going to the "Custom fields" tab for the first time
- name field should be labelled "System name"
- The full width toggle is cool, but I think it's more related to what he discussed about (all) fields reordering/removing/adding
- the following could be done later in another PR, but UX for the fields properties could be maybe shared, at least partially, with form questions (ping @AdrienClairembault) . Especially the options setup for dropdowns is better in the current form implementation. We may also have icons for field types (also done in forms questions), date fields also have a current time toggle.
Done
I can't recreate the issue and the referenced line number doesn't line up to anything that makes sense.
Done
That was the plan. I used it to make the richtext field usable while testing the creation/functionality of each field type though.
I'm not so sure about using anything directly from that.
Its just how select2 natively supports custom options.
For "current time" toggle, it would require changing how default values are handled and requiring a mass update of every existing asset of the type to set the value if it isn't already. Right now, the default value is used as a fallback until the asset form is saved again or the value is specifically set in the API. Again, it wasn't really in the spec and also doesn't seem to have existed in the plugin. |
Unrelated to custom fields but on the topic of the Forms feature, the UI isn't working properly in any dark themes. I guess some elements are using hard-coded colors instead of variables from the framework. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO, we should not try to implement custom dropdown in this PR. Indeed, we have to discuss about the best solution first. For instance, people will probably want to translate each dropdown value label. Storing it in a JSON field and adding the UI to handle translations may require some work and would be less flexible than for instance, implementing generic dropdowns support.
a4ffe22
to
947786f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not reviewed everything yet. I will do it later in the week.
122f3b4
to
e5c1f96
Compare
b51c50d
to
db8eb77
Compare
I suashed commits, rebased, and fix some issues. I removed the I will continue the review this afternoon. @cconard96 Could you check the failing E2E test? It is related to flatpicker inputs that does not seems to be targetable by their label. |
Probably. See note in #17323. "Input labels broken when using altInput option". |
Some changes were made, others will be done in a separated PR.
cy.findByLabelText("Active").select('1', { force: true }); | ||
cy.findByRole('button', {name: "Add"}).click(); | ||
|
||
cy.get('div.toast-container .toast-body a').click(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can probably use findByRole('alert')
and/or findByRole('link')
here to not be dependent on the classes.
cy.findByRole('button', {name: 'Add a new field'}).parents('.tab-pane').should('have.class', 'active').first().within(() => { | ||
cy.findByRole('button', {name: 'Add a new field'}).click(); | ||
cy.findByLabelText('Label').type('Test Text'); | ||
cy.findByLabelText('Type').select('Text', { force: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use getSelectByLabel
+ setDropdownValue
to avoid using force: true
(same for other instances).
}); | ||
|
||
cy.findByRole('tab', {name: 'Profiles'}).click(); | ||
cy.get('input[type="checkbox"][id^="cb_checkall_table"]').check({ force: true }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use findByRole('checkbox') here
cy.getDropdownByLabelText('Test YesNo').selectDropdownValue('Yes'); | ||
|
||
// This is the placeholder field | ||
cy.get('.form-field .field-container:not(:has(*))').should('have.length', 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a query method that could be used here instead of a css selector ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The placeholder corresponds to an almost empty element. No ID, no name, no label, just whitespaces.
But as it is not yet possible to reorder fields, maybe this field type should be removed. Indeed, reordering fields and changing the form layout should be done on all fields, not just custom fields, and we should probably only store it in the layout config itself, see #16975 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is a big issue with the lack of polymorphism regarding fields types.
We have condition on specific types everywhere + many match and switch depending on types.
This will cause a lot a maintainability issue in the future, we really need to apply some kind of strategy pattern with a common interface.
Indeed, I think the fields types should each have an own class to be able to give the ability to the plugins to register new fields types. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are still some bugs.
- The options/default values seems to be loaded correctly on the field definition update form, but they are not loaded anyomre on the field definition creation form.
It result in errors like:
Undefined array key "multiple" in /var/www/glpi/src/Glpi/Asset/CustomFieldOption/AbstractOption.php at line 65
Undefined array key "min" in /var/www/glpi/src/Glpi/Asset/CustomFieldOption/AbstractOption.php at line 65
Undefined array key "max" in /var/www/glpi/src/Glpi/Asset/CustomFieldOption/AbstractOption.php at line 65
Undefined array key "step" in /var/www/glpi/src/Glpi/Asset/CustomFieldOption/AbstractOption.php at line 65
-
When a field is defined as mandatory and/or readonly, these options are also applied to the default value field. They should not.
-
The default value field for a
Number
type applies the current min/max/step values. When these are updated, it may produce an unexepected behaviour:
For instance, here I changed the max from 25 to 100 and tried to change the default value to 50:
-
The
itemtype
of aDropdown
field is not configurable (there is no field displayed for that). -
The
Text
field seems to be similar to theString
type, I guess it is an error. In thefields
plugin, there was 3 fields types for a text:Text (single line)
(a basic input),Text (multiple lines)
(a textarea) andRich Text
(a TinyMCE editor). We may implement theRich Text
type later, as it may not be simple as the ther fields, but I think that we should implement the 2 others right now. -
Deleting a field definition does not seems to work. I get a blank page.
-
When I submit the asset form containaing a field of each type, I get the following SQL error:
*** MySQL query warnings:
SQL: SELECT `glpi_computers`.*, '' AS `transname`, '' AS `transcomment` FROM `glpi_computers` WHERE `glpi_computers`.`id` = '{\"2\": \"0\", \"3\": \"abcdef\", \"4\": \"2024-09-18\", \"5\": \"0\", \"6\": \"blabla2\", \"7\": 0, \"8\": \"25\", \"9\": \"2024-09-23 08:00:10\", \"10\": \"http://babla7/**/\"}'
Warnings:
1292: Truncated incorrect DOUBLE value: '{"2": "0", "3": "abcdef", "4": "2024-09-18", "5": "0", "6": "blabla2", "7": 0, "8": "25", "9": "2024-09-23 08:00:10", "10": "htt'
Backtrace :
src/DBmysqlIterator.php:120
src/DBmysql.php:1090 DBmysqlIterator->execute()
src/Dropdown.php:574 DBmysql->request()
src/Log.php:187 Dropdown::getDropdownName()
src/CommonDBTM.php:683 Log::constructHistory()
src/CommonDBTM.php:1675 CommonDBTM->updateInDB()
front/asset/asset.form.php:81 CommonDBTM->update()
...Glpi/Controller/LegacyFileLoadController.php:58 require()
vendor/symfony/http-kernel/HttpKernel.php:101 Glpi\Controller\LegacyFileLoadController->Glpi\Controller\{closure}()
...ymfony/http-foundation/StreamedResponse.php:106 Symfony\Component\HttpKernel\HttpKernel::Symfony\Component\HttpKernel\{closure}()
vendor/symfony/http-foundation/Response.php:423 Symfony\Component\HttpFoundation\StreamedResponse->sendContent()
public/index.php:58 Symfony\Component\HttpFoundation\Response->send()
This is related to the Dropdown
field:
- Other fields types are not logging anything in the
Historical
tab when they are updated.
Also, this is not a bug, but there is currently no way to disable the min/max/step on a Number
field. I do not know if it is a problem, but I guess some people will complain about that. These options were not available, and therefore not mandatory in the fields
plugin. People could probably use max=999999999 min=-999999999999 step=0.0001 as a workaround.
Should be fixed.
I added a param to options to define if they apply to the default value field (true by default) and removed the special handling done previously just for the "full_width" option.
This has been fixed.
Fixed. Check was using the old "dropdown" key instead of the class name.
String - Plain-text only and limited to 255 characters
Fixed
I don't get this SQL error
Not yet addressed. Also not sure why it says a dropdown was updated when the values haven't changed.
Workaround added by supporting a default value for options. |
Do you have the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test again on latest commit with a new asset definition/field definition to ensure the right ID is used in the AJAX request and the field definition is using the new "type" values. |
Yes |
c055747
to
a32441d
Compare
A quick functional review:
I didn't encounter anything blocking regarding usage, no bugs, and no errors in logs. Apart from the above-mentioned UX issues, everything seems robust |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests are failing.
fba2628
to
0e02679
Compare
Yeah, this is more a global issue with the inline forms/sublist combo tabs. If the add/edit is inline when the form isn't too complex, it is good UX as opposed to using a modal. With the UI work I did on Rules, the Add button is always visible. I've removed the code in the new template I started in this PR to standardize "viewsubitem" form display that had hidden the "Add" button after clicking it.
Done
Yeah, I've noticed and there are a ton of 'hacks' in templates that have full width fields to fix label/input sizes. Probably good to do in a separate PR. |
The mandatory "red dot" is only added for dropdown when previewing fields. |
I think it would be very important to add tests to confirm and fix each issues reported by testers here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add tests (with Cypress or PHPUnit) to verify scenarios where bugs were found during code reviews.
2 other minor issues found:
|
A statement about the last comments regarding tests. |
893b04b
to
d02f518
Compare
Still very early WIP, but has at least basic functionality as a proof of concept and allows starting to test performance.
Supported field types (mainly based on Fields plugin types):
Fields will be allowed to be defined as being required or readonly.
UI/UX Notes:
date_
is prefixed to the internal name to match how fields are named in GLPI itself.Technical features:
custom_fields_json
column for existing items of that asset type. The default value will be transparently used in those cases until the asset item is saved again.