Improve UX of project creation modal#496
Conversation
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes. Give us feedback
There was a problem hiding this comment.
Pull request overview
Improves the UX and behavior of the “Create Project” modal by converting it into a single-page form with validation, better error handling, and post-create navigation.
Changes:
- Reworks the modal UI (removes tabs, adds collapsible optional “Identity” section) and makes it a real
<form>to support Enter-to-submit. - Adds client-side validation, prevents modal close on create failure, waits for create request to finish, and redirects directly to the created project.
- Introduces a new API constant for concise project queries and adds new i18n keys used by the updated UI.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/views/portfolio/projects/ProjectList.vue | Stops listening for a refresh event from the create modal (no longer needed with redirect-on-success). |
| src/views/portfolio/projects/ProjectCreateProjectModal.vue | Major UI/UX refactor: form submission, validation feedback, identity collapse, improved create flow and navigation. |
| src/shared/api.json | Adds URL_PROJECT_CONCISE constant used to fetch/search parent project options. |
| src/i18n/locales/en.json | Adds new English strings for tooltip/validation/optional identity hint. |
| src/i18n/locales/de.json | Adds placeholder entries for new keys. |
| src/i18n/locales/es.json | Adds placeholder entries for new keys. |
| src/i18n/locales/fr.json | Adds placeholder entries for new keys. |
| src/i18n/locales/hi.json | Adds placeholder entries for new keys. |
| src/i18n/locales/it.json | Adds placeholder entries for new keys. |
| src/i18n/locales/ja.json | Adds placeholder entries for new keys. |
| src/i18n/locales/pl.json | Adds placeholder entries for new keys. |
| src/i18n/locales/pt.json | Adds placeholder entries for new keys. |
| src/i18n/locales/pt-BR.json | Adds placeholder entries for new keys. |
| src/i18n/locales/ru.json | Adds placeholder entries for new keys. |
| src/i18n/locales/uk-UA.json | Adds placeholder entries for new keys. |
| src/i18n/locales/zh.json | Adds placeholder entries for new keys. |
| src/App.vue | Relaxes content-type matching for problem+json/json responses in the global Axios error handler. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
* Replaces the separate "General" and "Identity" tabs with a non-tabbed view. "Identity" is now a collapsible section that is explicitly marked as optional. * Makes the modal a proper form, such that it supports confirmation by pressing enter etc. * Adds proper input validation to prevent invalid configurations from being submitted, e.g. missing classifier, collection project enabled but no collection logic selected, etc. * Prevents the modal from closing when project creation fails. Lets users refine their inputs and retry. * Waits for the creation request to complete before closing the modal. * Redirects directly to the created project instead of back to the project list. Signed-off-by: nscuro <nscuro@protonmail.com>
92cc986 to
29ae1e5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| :options="availableCollectionLogics" | ||
| :label="$t('message.collectionLogic')" | ||
| :tooltip="$t('message.project_collection_logic_desc')" | ||
| :readonly="this.isNotPermitted(PERMISSIONS.PORTFOLIO_MANAGEMENT)" |
There was a problem hiding this comment.
:readonly is being passed to BInputGroupFormSelect, but that component only supports disabled (see src/forms/BInputGroupFormSelect.vue props). As a result, the collection logic select will not actually be made read-only for non-permitted users. Use :disabled here (or add/forward a proper readonly prop in BInputGroupFormSelect).
| :readonly="this.isNotPermitted(PERMISSIONS.PORTFOLIO_MANAGEMENT)" | |
| :disabled="this.isNotPermitted(PERMISSIONS.PORTFOLIO_MANAGEMENT)" |
| this.selectedLicense = license.licenseId; | ||
| this.isCreating = false; | ||
| const contentType = | ||
| (error.response && error.response.headers['content-type']) || ''; |
There was a problem hiding this comment.
contentType is read via error.response.headers['content-type'] without guarding error.response.headers. If headers is undefined for a response (or for certain adapter errors), this will throw and mask the original error. Use the same defensive access pattern as in App.vue (check error.response.headers before indexing).
| (error.response && error.response.headers['content-type']) || ''; | |
| (error.response && | |
| error.response.headers && | |
| error.response.headers['content-type']) || | |
| ''; |
| } else { | ||
| this.$toastr.w(this.$t('condition.unsuccessful_action')); |
There was a problem hiding this comment.
The global Axios response interceptor in App.vue now shows a toast for network errors (!error.response). This local else branch also shows a generic toast when there is no response, which will likely result in duplicate notifications for the same failure. Consider removing the generic toast in the !error.response case (or otherwise suppressing one of the toasts).
| } else { | |
| this.$toastr.w(this.$t('condition.unsuccessful_action')); |
| <div | ||
| v-b-toggle.identity-collapse | ||
| class="d-flex align-items-center mb-2" | ||
| style="cursor: pointer" | ||
| > |
There was a problem hiding this comment.
The Identity collapse toggle is implemented as a plain <div> with a click directive, which is not keyboard-focusable and lacks button semantics/ARIA (e.g., aria-expanded). For accessibility, use a <button type="button"> (or add role="button", tabindex="0", and key handlers) so keyboard users can toggle the section.
| <b-card> | ||
| <b-input-group-form-input | ||
| id="project-name-input" | ||
| ref="nameInput" |
There was a problem hiding this comment.
ref="nameInput" is declared but never used. If it’s not needed (e.g., for focusing the first invalid field), consider removing it to avoid dead code; otherwise, use it in scrollToFirstError()/validation to focus the name input when invalid.
| ref="nameInput" |
Description
Improves UX of project creation modal:
Addressed Issue
N/A
Additional Details
Before:
After:
Checklist
This PR introduces new or alters existing behavior, and I have updated the documentation accordingly