Skip to content

Add non-editable mode allowing fields to display as read-only#26147

Merged
AlexGaillard merged 162 commits intomainfrom
robl/cms-1245-implement-non-editable-mode-for-form-fields
Nov 15, 2025
Merged

Add non-editable mode allowing fields to display as read-only#26147
AlexGaillard merged 162 commits intomainfrom
robl/cms-1245-implement-non-editable-mode-for-form-fields

Conversation

@robluton
Copy link
Contributor

@robluton robluton commented Nov 7, 2025

Scope

What's changed:

  • Added non-editable mode, much like disabled without the subdued styling, to all interfaces and fields.
  • To apply the nonEditable prop, set it on the v-form component.
  • Applied the non-editable prop to the share item form

Potential Risks / Drawbacks

  • Props and styles have been added/modified in several form interfaces and components.

Tested Scenarios

  • All interfaces in the item view, the comparison modal and the share item form

Review Notes / Questions

  • Review the interfaces in the app

Checklist

  • Added or updated tests
  • Documentation PR created here or not required

Fixes #CMS-1245

@robluton robluton requested review from Copilot and formfcw November 7, 2025 21:17
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a non-editable mode for form fields, allowing forms to be displayed in a read-only state while maintaining visual distinction from truly disabled fields. The key change replaces the disabled attribute with non-editable in the comparison modal and propagates this new mode throughout the form system.

Key Changes:

  • Added nonEditable prop to form components, interfaces, and base UI components
  • Introduced CSS custom properties to style non-editable fields differently from disabled fields
  • Updated comparison modal to use non-editable mode instead of disabled for base and incoming data views

Reviewed Changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
app/src/views/private/components/comparison/comparison-modal.vue Replaced disabled with non-editable for comparison forms
app/src/styles/lib/_codemirror.scss Added CSS variable support for disabled state styling
app/src/components/v-form/v-form.vue Added nonEditable prop and CSS variables for non-editable styling
app/src/components/v-form/form-field.vue Added nonEditable prop propagation to form fields
app/src/components/v-form/form-field-interface.vue Added nonEditable prop to interface wrapper
app/src/components/v-input.vue Added nonEditable prop with visual and behavioral changes
app/src/components/v-textarea.vue Updated CSS for disabled state styling
app/src/components/v-checkbox.vue Added nonEditable prop and styling
app/src/components/v-radio.vue Added nonEditable prop with enhanced styling for non-editable state
app/src/components/v-list-item.vue Added nonEditable prop to allow interaction when non-editable
app/src/components/v-menu.vue Added nonEditable prop definition
app/src/components/v-slider.vue Updated CSS for disabled state styling
app/src/components/v-select/*.vue Added nonEditable prop and logic to v-select and child components
app/src/interfaces/*/ Added nonEditable prop to various interface components (input, select, list, file, datetime, boolean, group)
.changeset/upset-cobras-care.md Added changeset documenting the minor version change

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@AlexGaillard
Copy link
Member

We got some failing tests here ya'll

@AlexGaillard AlexGaillard marked this pull request as draft November 14, 2025 16:17
@AlexGaillard
Copy link
Member

In draft until #26187 is merged into this one

* update changeset

* make share item form to non-editable

* remove unnecessary nonEditable prop declaration

* modify disabled state

* remove unnecessary nonEditable check from condition

* ensure the disabled prop is only applied to compatible elements

* ensure the disabled prop applies to elements where necessary

* use disabled class for styling when element does not support :disabled

* ensure hover only works when not disabled

* revert CSS var declaration

* simplify prop usage

* remove unnecessary non-editable class and styles

* add non-editable class, apply to styles and revert CSS vars

* ensure cursor is not pointer when disabled

* ensure save button in drawer is disabled

* change visibility of elements when nonEditable

* drill down nonEditable prop

* apply nonEditable to collection-item-multiple-dropdown interface
@robluton robluton marked this pull request as ready for review November 14, 2025 17:55
@robluton robluton marked this pull request as draft November 14, 2025 17:58
@formfcw formfcw changed the title Implement non editable mode for form fields Add a non-editable mode in form fields, allowing fields to be displayed as read-only when editing is not permitted Nov 14, 2025
@formfcw formfcw changed the title Add a non-editable mode in form fields, allowing fields to be displayed as read-only when editing is not permitted Add non-editable mode allowing fields to display as read-only Nov 14, 2025
@formfcw formfcw marked this pull request as ready for review November 14, 2025 19:11
Copy link
Contributor

@formfcw formfcw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🎉

@AlexGaillard @robluton is currently updating the docs around this PR and will update the link in the PR description once he’s finished.

@AlexGaillard
Copy link
Member

Screenshot 2025-11-15 at 09 03 41

So, I noticed that you can still focus on the MD field, and the WYSIWYG field is greyed out when everything else is not?

@formfcw
Copy link
Contributor

formfcw commented Nov 15, 2025

So, I noticed that you can still focus on the MD field, and the WYSIWYG field is greyed out when everything else is not?

Thank you @AlexGaillard, good catch! It seems like we forgot to check the WYSIWYG in dark mode. So, I checked every interface in dark mode as well. The markdown issue is not related to this PR, but will be fixed with either the upcoming fix-disabled-state PR or the codemirror-update PR.

@AlexGaillard AlexGaillard merged commit b988a60 into main Nov 15, 2025
69 checks passed
@AlexGaillard AlexGaillard deleted the robl/cms-1245-implement-non-editable-mode-for-form-fields branch November 15, 2025 17:45
@github-actions github-actions bot added this to the Next Release milestone Nov 15, 2025
AlexGaillard pushed a commit that referenced this pull request Nov 19, 2025
* basic layout

* styling

* add metadata to version heading

* rename version-promote-drawer to comparison-modal

* styling and fields edited count

* Select all checkbox

* remove css no longer being used

* add border below the version headers

* rework css and class naming

* extract header component

* add checkbox to interfaces

* only show checkboxes next to fields in the version

* create a diff between version and main, as a version can include fields with values that match those on main

* simplify diff

* green and red color indicators

* refactor to pass down object instead of several props

* responsive styling

* changeset

* lint changes

* remove redundant types and unneeded defaults

* move computed vars and methods into composable

* incorporate revisions into content comparison modal

* get checkboxes to work with revisions

* refactor

* separate normalizer into its own util

* refactor to use new normalizer

* delta selector

* consolidate and cleanup

* simplify tests

* add versions to selectableDeltas for consistency

* more refactoring - normalize more data to allow the modal to get it from the same places

* the latest tag should only show up if the base is showing the latest state of the current version

* tests and small refactor

* remove dead code from earlier refactor

* fix bug with latest tag for version

* use consistent terminology for comparison sides

* cleanup

* add translations

* put toggleComparison inside comparison context object

* remove data attrs

* cleanup

* copmarison-specific breakpoints

* Update .changeset/free-trains-clap.md

Co-authored-by: Florian C. Wachmann <[email protected]>

* checkbox styles

* loading state

* change terminology for left and right sides

* change revision revert to promote

* remove legacy revisions code

* use subdued foreground color for unchecked checkbox

* Update app/src/modules/content/components/comparison-modal.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-header.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-header.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-header.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-header.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-header.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* updates

* updates

* keep full width fields until 1330px

* updates

* more feedback updates

* feedback updates

* remove latest tag feature

* change sides to base and incoming to avoid confusion with version comparison api response

* adjust tests

* style tweaks

* change title of left side back to Main

* use the term Latest in place of the date on left side of comparison

* calculate updated fields for revisions list

* label first revision in drawer as Latest

* Show hidden fields in comparison view (#25878)

Co-authored-by: Florian C. Wachmann <[email protected]>

* Apply suggestions from code review

Co-authored-by: Florian C. Wachmann <[email protected]>

* Update app/src/modules/content/components/comparison-modal.vue

Co-authored-by: Florian C. Wachmann <[email protected]>

* use new translations

* Refine comparison component styles and structure (#25897)

* apply margin only to comparison checkbox

* update comparison padding values according to the design

* remove unnecessary wrapper from the title

* simplify meta-content structure and remove dropdown class

* ensure meta selection text always aligns left/start

* add hover style for dropdown

* adjust focus ring offset of dropdown button

* adjust dropdown option styling

* reuse delta option time and user extraction logic

* simplify vertical divider

* Use "Latest" instead of "Created"

* fix issue causing field count differences

* filter out read-only fields after api call

* add debug button to help investigate any issues with the diff

* do not allow fields that do not exist in the collection itself

* fix tests

* remove more legacy code

* rename revisions-drawer-detail to revisions-sidebar-detail

* Prevent empty fields when trying to promote a version that has not diverged from main

* Refine comparison style (#25904)

* simplify grid adjustments for comparison forms

* improve field label responsiveness

* add intermediate breakpoint for the column width

* update header height according to design

* fix responsiveness of comparison header

* adjust padding for meta text in comparison header according to design

* improve responsiveness and text-overflow for comparison header

* remove extra flex-wrap property

---------

Co-authored-by: Rob Luton <[email protected]>

* add new prop and styling for non-editable mode

* make non-editable work when nested in groups

* change terminology from "udpated" to "differences"

* do not allow click event on latest revision

* do not include latest revision in comparison dropdown

* Revision Updates (#25954)

Co-authored-by: formfcw <[email protected]>

* Apply suggestions from code review

Co-authored-by: Florian C. Wachmann <[email protected]>

* Revision diff bug fixes (#25969)

* Apply suggestions from code review

Co-authored-by: Florian C. Wachmann <[email protected]>

* more updates from code review

* deal with revisionId and versionId type mismatch

* add translations

* Apply suggestions from code review

Co-authored-by: Florian C. Wachmann <[email protected]>

* skip auto date fields

* for revisions, use related values from main so the form is consistent

* use correct endpoints for system collections

* use new translation

* fix type issue

* ignore primary key fields and user-created and user-updated fields for comparisons

* fix count issue between revision list and modal

* skip primary key fields for version promotion

* Comparison < Updates (#25991)

* simplify props usage in revisions-date-group component

* simplify field retrieval

* make array merge customizer reusable

* use existing isSystemCollection function and sort imports

* streamline comparison logic and enhance readability

* simplify currentVersion handling in comparison data normalization *

* simplify revisions handling in comparison data normalization *

* simplify versions handling in comparison data normalization *

* simplify system collection check

* replace getSystemCollectionEndpoint with existing getEndpoint function

* simplify item endpoint retrieval in useRevisions and remove isSystemCollection check

* remove unnecessary export keywords

* remove unused ComparisonSide type and related constants

* rename copyRelationalFieldsFromBaseToIncoming to copySpecialFieldsFromBaseToIncoming for clarity

* remove comment

* update css var for clarity

* use formatTitle for version key for human-readable titles

* improve footer responsiveness

* simplify item fetching logic in useComparison (#25993)

* Comparison < Updated Fields Indication (#26011)

* add updated fields indication

* update badge class for v-chip and adjust import order

* update translation for revision messages for clarity

* improve responsiveness of field label (#26015)

* Comparison < fix merge bug (#26017)

* fix merge bug

* add tests

* refactor: move getFieldsWithDifferences test into utils test file

* refactor: rename mergeMissingMainItemKeysIntoRevision to mergeMainItemKeysIntoRevision

* refactor buildRevisionComparison logic

* Comparison < sidebar updates (#26042)

* squash commit robl/sidebar-updates

* (re-)use existing i18n key

* remove unused isFirstGroup prop

* remove unused computeDifferentFields function and lodash mergeWith import

* refactor: move getItemEndpoint function into useComparison and restore import

* refactor: remove unused mergeMainItemKeysIntoRevision function

* refactor: remove unnecessary differentFields from revision data structure

* improve field comparison logic and enhance revision handling

* Comparison < Updates 27/1 (#26054)

* drill down comparisonActive prop instead of recalculating

* remove debug mode

* Ensure NormalizedItem gets correct user for the base side

* Refactor to use type PrimaryKey instead of `string | number`

* refactor to require collection parameter

* rename normalizeComparisonData to getNormalizedComparisonData for clarity

* add mainVersionMeta to ComparisonData to get activity information of latest main

* refactor user fetching logic for clarity

* Comparison ← refactor, clean up and small fixes (#26063)

* use a different tooltip for the updated badge when the field auto-populates

* refactor: move data fetching logic to the modal component

* refactor: remove comparison-utils and reorganize utility functions

- Deleted the comparison-utils and moved relevant functions to new utility files and the use-comparison composable
- Refactored use-comparison composable to utilize the utility functions
- Added new field-utils for field-related checks (e.g., isPrimaryKey, isRelational)
- Added new get-revision-fields utility to handle revision field filtering logic
- Added new get-version-display-name utility for version display name formatting

* refactor: move files comparison-header.vue, comparison-modal.vue, use-comparison.ts and use-comparison.test.ts to @/views/private/components/comparison

* refactor: move type definitions to types.ts and update imports in use-comparison.ts

* refactor: rename main to base and current to incoming

* fix types by preventing renaming when newVersionKey is null

* update changeset

* update changeset

* Comparison ← add tests (#26076)

* add unit tests for field utility functions

* add unit tests for getRevisionFields function

* add unit tests for getVersionDisplayName function

* fix boolean checks

* add unit tests for useComparison

* Comparison ← small fix, add more tests (#26078)

* clean-up

* refactor: update test descriptions for clarity on user and date fields

* fix user display and simplify logic

* simplify mock API implementation in tests and add user updated field checks

* fix visibility logic for hidden fields in form components

* ensure field labels are visible when in comparison mode

* add revisionFields to comparison data on base side

* first pass - wysiwyg, raw-editor, field-interface, file, select, repeater

* use existing disabled prop to prevent field interaction

* override disabled subdued colors

* remove redundant isNonEditable checks

* add nonEditable to comparison v-forms

* cleanup and fixes

* datetime field

* add non-editable to list-o2m

* remove create and update buttons from o2m when non-editable

* remove create and update buttons from m2m and m2a when non-editable

* markdown editor

* select-radio interface

* add non-editable class to slider interface

* add non-editable prop and class to bool interface

* add non-editable prop and class to input-multiline interface

* remove non-editable from child components

* restore v-input and v-select from main

* implement css vars for non-editable

* implement css vars for non-editable - continued

* file - allow download, preview, edit buttons in non-editable mode

* block-editor

* implement css vars for non-editable - more updates

* changeset

* remove non-editable styles from datetime and pass nonEditable prop to its children

* remove action buttons from tree view

* fix css var syntax

* hide deselect all from multi select when non-editable

* Non-editable ← Updates (#26187)

* update changeset

* make share item form to non-editable

* remove unnecessary nonEditable prop declaration

* modify disabled state

* remove unnecessary nonEditable check from condition

* ensure the disabled prop is only applied to compatible elements

* ensure the disabled prop applies to elements where necessary

* use disabled class for styling when element does not support :disabled

* ensure hover only works when not disabled

* revert CSS var declaration

* simplify prop usage

* remove unnecessary non-editable class and styles

* add non-editable class, apply to styles and revert CSS vars

* ensure cursor is not pointer when disabled

* ensure save button in drawer is disabled

* change visibility of elements when nonEditable

* drill down nonEditable prop

* apply nonEditable to collection-item-multiple-dropdown interface

* update snapshots

* update snapshot

* update changeset

* ensure nonEditable variant of wysiwyg renders correctly in dark mode

---------

Co-authored-by: Florian C. Wachmann <[email protected]>
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 15, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants