Skip to content

[WC-3471]: fix(image-web): migrate image source properties to allowUpload - #2354

Open
yordan-st wants to merge 7 commits into
mainfrom
feat/WC-3471_image-allowupload
Open

[WC-3471]: fix(image-web): migrate image source properties to allowUpload#2354
yordan-st wants to merge 7 commits into
mainfrom
feat/WC-3471_image-allowupload

Conversation

@yordan-st

Copy link
Copy Markdown
Contributor

Pull request type

Bug fix (non-breaking change which fixes an issue)


Description

imageObject and defaultImageDynamic in the Image widget were declared as type="image" without allowUpload, which Mendix has deprecated — DynamicValue<WebImage> is removed in Mendix 12, and Studio Pro 11.8+ already shows a design-time deprecation warning for this pattern.

This adds allowUpload="true" to both properties and regenerates typings accordingly (EditableImageValue<WebImage>). The widget's read logic in Image.tsx is unchanged — EditableImageValue exposes the same status/value.uri shape the widget already consumes, so this is a display-only migration with no new upload UI.

marketplace.minimumMXVersion is bumped to 11.12.0 since the widget XML now requires allowUpload support, which older Studio Pro versions cannot parse (verified: Studio Pro <11.8 fails to load the widget package with "The 'allowUpload' attribute is not declared").

Manually verified in Studio Pro 11.12 that both Static and Dynamic image-source configuration remain available in the property editor after this change — existing apps using a static image are not broken.

Widget version is not bumped in this PR (bumped at release time per repo convention); this change will require a major bump (2.0.0) on release due to the minimumMXVersion increase.

What should be covered while testing?

  • Existing Image widget configurations (static image, dynamic/attribute-bound image, icon, image URL datasources) continue to render identically.
  • No upload/file-picker UI appears anywhere on the widget.
  • Widget can be added to a page in Studio Pro 11.12+; "Image source" and "Default image" properties still offer both Static and Dynamic configuration.

@yordan-st
yordan-st requested a review from a team as a code owner July 23, 2026 13:50
@github-actions

This comment has been minimized.

Comment thread packages/pluggableWidgets/image-web/src/__tests__/Image.spec.tsx Outdated
r0b1n
r0b1n previously approved these changes Jul 27, 2026
@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from 4437e17 to 86b2aa7 Compare July 28, 2026 07:51
@github-actions

This comment has been minimized.

@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from 86b2aa7 to ef2f88c Compare July 28, 2026 08:06
@github-actions

This comment has been minimized.

@leonardomendix
leonardomendix force-pushed the feat/WC-3471_image-allowupload branch from 15827f1 to 4294cd4 Compare July 28, 2026 12:48
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from 0e525b7 to d7e64de Compare July 29, 2026 08:36
@github-actions

This comment has been minimized.

@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from d7e64de to e062707 Compare July 30, 2026 07:43
@github-actions

This comment has been minimized.

@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from e062707 to 629ac25 Compare July 30, 2026 09:22
@github-actions

This comment has been minimized.

ImageContainerProps now types imageObject/defaultImageDynamic as
EditableImageValue<WebImage>, but the spec still built inputs with
dynamic.available/loading/unavailable (DynamicValue<WebImage>),
causing tsc failures (TS2322) and a failing test suite in CI.

Migrate the datasource: "image" cases to the editableImage builder,
matching the pattern already used in image-cropper tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@yordan-st
yordan-st force-pushed the feat/WC-3471_image-allowupload branch from 629ac25 to 8ab1f86 Compare July 30, 2026 09:56
@github-actions

Copy link
Copy Markdown
Contributor

AI Code Review

⚠️ Approved with suggestions — low-severity items only, safe to merge


What was reviewed

File Change
automation/run-e2e/docker/mxbuild.Dockerfile Adds libgdiplus, libfontconfig1, and ENV LD_PRELOAD for font rendering
package.json Adds mendix: 11.10.0 to pnpm overrides
packages/pluggableWidgets/image-web/src/Image.xml Adds allowUpload="true" to imageObject and defaultImageDynamic
packages/pluggableWidgets/image-web/typings/ImageProps.d.ts DynamicValue<WebImage>EditableImageValue<WebImage> for both props
packages/pluggableWidgets/image-web/package.json Bumps minimumMXVersion to 11.12.0, pins MENDIX_VERSION for E2E
packages/pluggableWidgets/image-web/CHANGELOG.md Adds [Unreleased] entry for the deprecation fix
packages/pluggableWidgets/image-web/src/__tests__/Image.spec.tsx New container-level unit tests for imageObject states
packages/pluggableWidgets/image-web/src/utils/__tests__/getImageProps.spec.ts Migrates from dynamic.* builders to editableImage builder
packages/pluggableWidgets/image-web/openspec/changes/fix-image-allow-upload-deprecation/ New openspec artifacts (proposal, tests)
packages/pluggableWidgets/image-cropper-web/src/__tests__/*.spec.tsx Migrates manual EditableImageValue mock objects to editableImage builder
packages/pluggableWidgets/image-cropper-web/src/stores/__tests__/ImageCropperStore.spec.ts Same builder migration
packages/shared/widget-plugin-test-utils/src/builders/EditableImageValueBuilder.ts New builder class for EditableImageValue
packages/shared/widget-plugin-test-utils/src/primitives/editableImage.ts New editableImage() factory primitive with .with() shorthand
packages/shared/widget-plugin-test-utils/src/main.ts Exports new builder and primitive
packages/shared/filter-commons/package.json mendix dep changed to * (resolves via root override)
packages/shared/widget-plugin-dropdown-filter/package.json Same
packages/shared/widget-plugin-filtering/package.json Same
packages/shared/widget-plugin-test-utils/package.json Same

Skipped (out of scope): pnpm-lock.yaml

CI check results not available (command required interactive approval) — verify passing before merge.


Findings

⚠️ Low — mendix npm override (11.10.0) lags behind minimumMXVersion (11.12.0)

File: package.json line 76
Note: The root pnpm override pins mendix to 11.10.0, but the widget's minimumMXVersion is 11.12.0. These version axes are different things (npm types vs Studio Pro runtime), and the PR description explains the intentional gap (types exist in 11.10, native runtime support landed in 11.11, 11.12 is the chosen LTS floor). However, if EditableImageValue changes shape between mendix@11.10.0 and mendix@11.12.x, tests would compile against the older type while targeting the newer runtime. A brief comment in package.json would help future maintainers understand why these don't match, and bumping the override to a version that corresponds to Studio Pro 11.12 would eliminate the gap entirely.


⚠️ Low — imprecise assertion in third Image container test

File: packages/pluggableWidgets/image-web/src/__tests__/Image.spec.tsx line 61
Note: expect(image?.getAttribute("src")).toBeFalsy() passes for three distinct outcomes: no <img> element at all (image is null), an img with no src attribute (returns null), and an img with src="". Since the test intends to verify "no meaningful src", these cases have different semantics. Consider being explicit:

// If widget renders no img element when unavailable:
expect(container.querySelector("img")).toBeNull();

// OR if it renders an img with empty src:
const image = getByRole("img") as HTMLImageElement;
expect(image.src).toBe("");

Not blocking — the current assertion is functionally safe, just ambiguous about expected DOM structure.


Positives

  • The new EditableImageValueBuilder mirrors EditableValueBuilder's exact API surface — isLoading(), isUnavailable(), isReadOnly(), withValidation(), build() — making it immediately familiar to contributors.
  • The editableImage.with() shorthand mirrors the existing editable.with() and dynamic.available() pattern, keeping the test-utils API consistent.
  • Replacing seven-field manual mock objects across five spec files with a single builder call removes a whole class of brittle as unknown as SomeType casts.
  • XML ↔ TypeScript alignment is exact: allowUpload="true" in XML → EditableImageValue<WebImage> in typings — no drift.
  • CHANGELOG entry is user-facing and clearly calls out the minimumMXVersion impact — important for users upgrading.
  • E2E MENDIX_VERSION=11.12.0 is correctly pinned to match the new minimum, ensuring E2E runs against a compatible mxbuild.
  • The mendix: * + root override pattern cleanly centralises the version for all shared packages without requiring per-package updates on each mendix bump.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants