Content
View differences
Updated by Aleix Suau about 5 years ago
For work packages, fields can be configured as multiple selections for all projects or for individual projects. The same function is desired for user-defined fields of the type Project.
**Acceptance requirements**
* The administration of custom fields for projects gets a checkbox "Allow multi-select", just like the lists for work packages
* The project form is extended such that list custom fields can be multi-selected
* The project advanced settings is extended such that list custom fields can be multi-selected
* The project overview list/table is extended to show multi-select custom fields
* The project details widget on the project overview / dashboard displays custom lists with multiple selections.
* When copying projects, multi-selection custom fields are also copied
<figure class="image op-uc-figure"><div class="op-uc-figure--content"><img class="op-uc-image" src="/api/v3/attachments/20761/content"></div></figure>
### Development Notes
* Test route: http://localhost:4200/projects/demo-project/settings/generic/
* Admin > Custom fields > Wps > multiselect checkbox
* Project > Overview > Project details should allow multi-select custom fields
* Form Config:
* [https://docs.openproject.org/api/endpoints/projects/](https://docs.openproject.org/api/endpoints/projects/)
* [https://docs.openproject.org/api/endpoints/projects/#projects-projects-schema](https://docs.openproject.org/api/endpoints/projects/#projects-projects-schema)
* [https://docs.openproject.org/api/endpoints/projects/#projects-project-create-form](https://docs.openproject.org/api/endpoints/projects/#projects-project-create-form)
* 3 steps:
* Replace view with formly
* Enable the backend capable of multiselect fields project
* Enable multiselect fields project in the frontend
### Dev requirements
* Change Sources:
* Layout:
* Schema loading (FormConfig):
When the user changes the type.
* First load
* Schema change
* Model:
* Schema loading (Payload (Model + Default values)) :
When the user changes the type.
* First load
* Schema change
* User interaction
* Form component:
* 2 ways of getting its config:
* New >>> POST to _api/v3/projects/\[projectId\]/work\_packages/form_ with payload _{\_links: {type: {href: "/api/v3/types/1"}}}_
* Existing >>> POST _api/v3/work\_packages/\[wp\_id\]/form_ with payload _{lockVersion: 2, \_links: {}}_
### TODO
* [ ] Sort fields in the front
* [ ] Tests
* [ ] Documentation
* [ ] Replace project setting's Information tab:
* [ ] exclude required disk storage
* [x] Review TODOs
* [x] Hide non-writable fields
* [x] Hide identifier
* [x] Multiselect custom fields
* [x] Top left buttons (subproject, copy project...)
* [x] Next steps:
* [x] Clean useless code and do a draft PR (wp specific case)
* [x] Op-form-field
* [x] Differentiate between update/create form (/id or href)
* [x] Create routes:
* [x] Take the formId from the params?
* [x] Custom fields (starting with \[\])
* [x] Print form
* [x] Fill model
* [x] Default values
* [x] Group fields
* [x] Layout
* [x] Validation
* [x] Sync
* [x] Async
* [x] Custom component
* [x] Send to endpoint
* [x] Postprocess the model
* [x] Set default values if the user has deleted the default value
* [ ] New Inputs:
* [x] TextEditFieldComponent
* [x] IntegerEditFieldComponent
* [x] SelectEditFieldComponent
* [x] MultiSelectEditFieldComponent
* [x] DateEditFieldComponent
* [x] two datepickers are displayed
* [x] not close on blur
* [x] displayed when invalid (also the rest of the project)
* [x] not disabled properly when formControl.disable
* [x] FormattableEditFieldComponent
* [x] _onTouch not working this_.editor.ckEditorInstance.ui.focusTracker.on( 'change:isFocused'
* [x] FloatEditFieldComponent
* [x] BooleanEditFieldComponent
* [ ] Others
* [x] Translations
* [x] Manage focus
* [x] ng-select
* [x] Between fields with tabs (inline edit)
* [x] Routes
* [x] Existing form route
* [x] New form route
* [x] Redirect when new form is created
* [x] Resolve data before entering the route?
* [x] Check touched, disabled, change, onsubmit... on every new input (datepicker)
* [x] User feedback on submit success/error
* [x] Import only necessary fields from OpenprojectFieldsModule into DynamicFormsModule (EditFieldControlsComponent)
* [ ] Accesibility
* [ ] Review API responses Typings
* [ ] Where do we place the submit button?
* [ ] Remove '\_links' from the model in the front, just add them in the formatToSubmit process.
* [ ] Improve performance:
* [ ] CkEditor
* [ ] Dynamic form reloaded when new resource is created (because we redirect to the new url, the resourceId changes...)
* [ ] A <formly-field> tag is wrapping all the <formly-field> tags (could be related with the way the groups are defined (\_links...))
## **Dynamic V2**
* [ ] Content projection:
* [ ] Allow the developer to project the content (layout, op-form-field, formly-fields...) so it is more flexible
* [ ] Save
* [ ] Save the entire form when it is new
* [ ] Save on every field edit when it has model
* [ ] Remove values that don't belong to the schema (e.g. if the user has filled some custom fields and then changed the type )
* [ ] Manage:
* [ ] LockVersion
* [ ] Id (on new wps)
* [ ] Replace selects with the the op-autocompleter?
* [ ] Handle remaining field types (from _initializeCoreEditFields_): New Inputs:
* [ ] ProjectStatusEditFieldComponent
* [ ] WorkPackageCommentFieldComponent
* [ ] CombinedDateEditFieldComponent
* [ ] PlainFormattableEditFieldComponent
* [ ] TimeEntryWorkPackageEditFieldComponent
* [ ] DurationEditFieldComponent
* [ ] WorkPackageEditFieldComponent
* [ ] SelectEditFieldComponent:
* [ ] 3 flavours:
* [ ] CreateAutocompleterComponent
* [ ] VersionAutocompleterComponent (+ @Output create + createNewVersion + ngselect.addTag)
* [ ] WorkPackageAutocompleterComponent
* [ ] Why/how do we sort option this.halSorting.sort(availableValues)?
* [ ] What is addEmptyOption()?
* [ ] Open directly this.\_autocompleterComponent.openDirectly = true;?
* [ ] Optimization:
* [ ] Manage results with pagination
* [ ] Skip extra calls when all results are returned (no pagination)
* [ ] FormattableEditFieldComponent
* [ ] editorType
* [ ] HalResource >> constrained
* [ ] ProjectResource >> 'statusExplanation' || 'description' >> full, other constrained)
* [ ] _WorkPackageBaseResource: fieldName_ === 'description' ? 'full' : 'constrained';
* [ ] CustomTextEditFieldService >> full
* [ ] What is previewContext for?
* [ ] Implement _edit-field-controls_
* [ ] Combo inputs (country > province)
* [ ] Click and edit
* [ ] _\[disabled\]_\="inFlight"?
* [ ] EditFieldHandler.handleUserKeydown:
"Handle users pressing enter inside an edit mode. Outside an edit mode, the regular save event is captured by handleUserSubmit (submit event). In an edit mode, we can't derive from a submit event wheteher the user pressed enter (and on what field he did that).
* [ ] Seems that it is only implemented in the ckEditor
* [ ] Unify options (select/multiselect) format: Different data format for options: sometimes they are resources, sometimes they don't, sometimes they have \_links.self.title other don't.
* [ ] Tests:
* [ ] field wrappers
* [ ] Form inputs outside of the form (how do we deal with it?)
* [ ] Wp type
* [ ] Hide op-form-field wrapper when the formly-field is hidden dynamically
* [ ] I like the idea that the pathhelperService is the responsible of building the form path.I’d also like to provide a simple API so you can load a form without knowing anything about HAL resources or PathHelper. Both ideas are not incompatible, the component could have: @Input formHref, Input resource: ‘project’ | ‘user’ | …, Input resourceId, So it can be used easy in all the scenarios (loading from resource, loading form params, loading from template…)
* [ ] Handle dynamic resourceId @Input (currently if the resourceId is async (@resourceId="resourceId$ | async")) the call to the backend is done twice and we rely on race conditions (the call without id could return earlier and ew end up with a void form).
* [ ] Customizations:
* [ ] Hide/Exclude some fields
* [ ] Add some fields
* [ ] Keep state between form reloads (when clicking on expand form in splitting views). There is a closed PRs with this changes
* [ ] Valid result (In this order) = Form config + Form Payload + User Changes (that applies to the active Type)
* [ ] Whenever the Type is changes, we have to reapply the entire previous sequence.
* [ ] Whenever the form is submitted, the User Changes have to be reset
* [ ] _DynamicFormsHub Use cases:_
* [ ] _Keeps a reference of every active form_
* [ ] _Registers a form when it is created_
* [ ] _Removes a form when it is destroyed_
* [ ] _Keeps the unsaved changes_
* [ ] On route changes, o\_nly when they are not discarded (maximize side panel).\_
* [ ] _How do we know that the change has not been discarded (alert)_
**Acceptance requirements**
* The administration of custom fields for projects gets a checkbox "Allow multi-select", just like the lists for work packages
* The project form is extended such that list custom fields can be multi-selected
* The project advanced settings is extended such that list custom fields can be multi-selected
* The project overview list/table is extended to show multi-select custom fields
* The project details widget on the project overview / dashboard displays custom lists with multiple selections.
* When copying projects, multi-selection custom fields are also copied
<figure class="image op-uc-figure"><div class="op-uc-figure--content"><img class="op-uc-image" src="/api/v3/attachments/20761/content"></div></figure>
### Development Notes
* Test route: http://localhost:4200/projects/demo-project/settings/generic/
* Admin > Custom fields > Wps > multiselect checkbox
* Project > Overview > Project details should allow multi-select custom fields
* Form Config:
* [https://docs.openproject.org/api/endpoints/projects/](https://docs.openproject.org/api/endpoints/projects/)
* [https://docs.openproject.org/api/endpoints/projects/#projects-projects-schema](https://docs.openproject.org/api/endpoints/projects/#projects-projects-schema)
* [https://docs.openproject.org/api/endpoints/projects/#projects-project-create-form](https://docs.openproject.org/api/endpoints/projects/#projects-project-create-form)
* 3 steps:
* Replace view with formly
* Enable the backend capable of multiselect fields project
* Enable multiselect fields project in the frontend
### Dev requirements
* Change Sources:
* Layout:
* Schema loading (FormConfig):
When the user changes the type.
* First load
* Schema change
* Model:
* Schema loading (Payload (Model + Default values)) :
When the user changes the type.
* First load
* Schema change
* User interaction
* Form component:
* 2 ways of getting its config:
* New >>> POST to _api/v3/projects/\[projectId\]/work\_packages/form_ with payload _{\_links: {type: {href: "/api/v3/types/1"}}}_
* Existing >>> POST _api/v3/work\_packages/\[wp\_id\]/form_ with payload _{lockVersion: 2, \_links: {}}_
### TODO
* [ ] Sort fields in the front
* [ ] Tests
* [ ] Documentation
* [ ] Replace project setting's Information tab:
* [ ] exclude required disk storage
* [x] Review TODOs
* [x] Hide non-writable fields
* [x] Hide identifier
* [x] Multiselect custom fields
* [x] Top left buttons (subproject, copy project...)
* [x] Next steps:
* [x] Clean useless code and do a draft PR (wp specific case)
* [x] Op-form-field
* [x] Differentiate between update/create form (/id or href)
* [x] Create routes:
* [x] Take the formId from the params?
* [x] Custom fields (starting with \[\])
* [x] Print form
* [x] Fill model
* [x] Default values
* [x] Group fields
* [x] Layout
* [x] Validation
* [x] Sync
* [x] Async
* [x] Custom component
* [x] Send to endpoint
* [x] Postprocess the model
* [x] Set default values if the user has deleted the default value
* [ ] New Inputs:
* [x] TextEditFieldComponent
* [x] IntegerEditFieldComponent
* [x] SelectEditFieldComponent
* [x] MultiSelectEditFieldComponent
* [x] DateEditFieldComponent
* [x] two datepickers are displayed
* [x] not close on blur
* [x] displayed when invalid (also the rest of the project)
* [x] not disabled properly when formControl.disable
* [x] FormattableEditFieldComponent
* [x] _onTouch not working this_.editor.ckEditorInstance.ui.focusTracker.on( 'change:isFocused'
* [x] FloatEditFieldComponent
* [x] BooleanEditFieldComponent
* [ ] Others
* [x] Translations
* [x] Manage focus
* [x] ng-select
* [x] Between fields with tabs (inline edit)
* [x] Routes
* [x] Existing form route
* [x] New form route
* [x] Redirect when new form is created
* [x] Resolve data before entering the route?
* [x] Check touched, disabled, change, onsubmit... on every new input (datepicker)
* [x] User feedback on submit success/error
* [x] Import only necessary fields from OpenprojectFieldsModule into DynamicFormsModule (EditFieldControlsComponent)
* [ ] Accesibility
* [ ] Review API responses Typings
* [ ] Where do we place the submit button?
* [ ] Remove '\_links' from the model in the front, just add them in the formatToSubmit process.
* [ ] Improve performance:
* [ ] CkEditor
* [ ] Dynamic form reloaded when new resource is created (because we redirect to the new url, the resourceId changes...)
* [ ] A <formly-field> tag is wrapping all the <formly-field> tags (could be related with the way the groups are defined (\_links...))
## **Dynamic V2**
* [ ] Content projection:
* [ ] Allow the developer to project the content (layout, op-form-field, formly-fields...) so it is more flexible
* [ ] Save
* [ ] Save the entire form when it is new
* [ ] Save on every field edit when it has model
* [ ] Remove values that don't belong to the schema (e.g. if the user has filled some custom fields and then changed the type )
* [ ] Manage:
* [ ] LockVersion
* [ ] Id (on new wps)
* [ ] Replace selects with the the op-autocompleter?
* [ ] Handle remaining field types (from _initializeCoreEditFields_):
* [ ] ProjectStatusEditFieldComponent
* [ ] WorkPackageCommentFieldComponent
* [ ] CombinedDateEditFieldComponent
* [ ] PlainFormattableEditFieldComponent
* [ ] TimeEntryWorkPackageEditFieldComponent
* [ ] DurationEditFieldComponent
* [ ] WorkPackageEditFieldComponent
* [ ] SelectEditFieldComponent:
* [ ] 3 flavours:
* [ ] CreateAutocompleterComponent
* [ ] VersionAutocompleterComponent (+ @Output create + createNewVersion + ngselect.addTag)
* [ ] WorkPackageAutocompleterComponent
* [ ] Why/how do we sort option this.halSorting.sort(availableValues)?
* [ ] What is addEmptyOption()?
* [ ] Open directly this.\_autocompleterComponent.openDirectly = true;?
* [ ] Optimization:
* [ ] Manage results with pagination
* [ ] Skip extra calls when all results are returned (no pagination)
* [ ] FormattableEditFieldComponent
* [ ] editorType
* [ ] HalResource >> constrained
* [ ] ProjectResource >> 'statusExplanation' || 'description' >> full, other constrained)
* [ ] _WorkPackageBaseResource: fieldName_ === 'description' ? 'full' : 'constrained';
* [ ] CustomTextEditFieldService >> full
* [ ] What is previewContext for?
* [ ] Implement _edit-field-controls_
* [ ] Combo inputs (country > province)
* [ ] Click and edit
* [ ] _\[disabled\]_\="inFlight"?
* [ ] EditFieldHandler.handleUserKeydown:
"Handle users pressing enter inside an edit mode. Outside an edit mode, the regular save event is captured by handleUserSubmit (submit event). In an edit mode, we can't derive from a submit event wheteher the user pressed enter (and on what field he did that).
* [ ] Seems that it is only implemented in the ckEditor
* [ ] Unify options (select/multiselect) format: Different data format for options: sometimes they are resources, sometimes they don't, sometimes they have \_links.self.title other don't.
* [ ] Tests:
* [ ] field wrappers
* [ ] Form inputs outside of the form (how do we deal with it?)
* [ ] Wp type
* [ ] Hide op-form-field wrapper when the formly-field is hidden dynamically
* [ ] I like the idea that the pathhelperService is the responsible of building the form path.I’d also like to provide a simple API so you can load a form without knowing anything about HAL resources or PathHelper. Both ideas are not incompatible, the component could have: @Input formHref, Input resource: ‘project’ | ‘user’ | …, Input resourceId, So it can be used easy in all the scenarios (loading from resource, loading form params, loading from template…)
* [ ] Handle dynamic resourceId @Input (currently if the resourceId is async (@resourceId="resourceId$ | async")) the call to the backend is done twice and we rely on race conditions (the call without id could return earlier and ew end up with a void form).
* [ ] Customizations:
* [ ] Hide/Exclude some fields
* [ ] Add some fields
* [ ] Keep state between form reloads (when clicking on expand form in splitting views). There is a closed PRs with this changes
* [ ] Valid result (In this order) = Form config + Form Payload + User Changes (that applies to the active Type)
* [ ] Whenever the Type is changes, we have to reapply the entire previous sequence.
* [ ] Whenever the form is submitted, the User Changes have to be reset
* [ ] _DynamicFormsHub Use cases:_
* [ ] _Keeps a reference of every active form_
* [ ] _Registers a form when it is created_
* [ ] _Removes a form when it is destroyed_
* [ ] _Keeps the unsaved changes_
* [ ] On route changes, o\_nly when they are not discarded (maximize side panel).\_
* [ ] _How do we know that the change has not been discarded (alert)_