Skip to content

Comments

Studio UI Development - Compare Objects#73

Open
ValeriaMaltseva wants to merge 48 commits intostudiofrom
63-compare-objects
Open

Studio UI Development - Compare Objects#73
ValeriaMaltseva wants to merge 48 commits intostudiofrom
63-compare-objects

Conversation

@ValeriaMaltseva
Copy link

Task: #63

@ValeriaMaltseva ValeriaMaltseva added this to the 5.2.0 milestone Feb 19, 2026
@sonarqubecloud
Copy link

Copy link

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

Adds an Object Merger / “Compare Objects” screen to the Studio UI bundle, wiring it into navigation + widget registry and providing the client-side compare/apply/reset/save behavior for Pimcore data objects.

Changes:

  • Introduces a new object-merger module (page, toolbar, form, versions view, context + data hook) and supporting helpers/types.
  • Adds Studio translations for the compare/merge UI.
  • Updates Rsbuild module federation remote wiring and bumps @pimcore/studio-ui-bundle canary; replaces the committed studio build output.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Resources/translations/studio.en.yaml Adds translation keys for the compare objects UI.
src/Resources/public/studio/build/7cd2589e-1c49-4de1-9674-b88c2473c540/manifest.json New build manifest for the studio bundle output.
src/Resources/public/studio/build/7cd2589e-1c49-4de1-9674-b88c2473c540/exposeRemote.js New remote exposure script for module federation.
src/Resources/public/studio/build/7cd2589e-1c49-4de1-9674-b88c2473c540/entrypoints.json New entrypoints used by Symfony to load studio assets.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/static/js/remoteEntry.js Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/static/js/main.69be1148.js Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/static/js/async/__federation_expose_default_export.9c01be30.js Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/mf-stats.json Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/mf-manifest.json Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/manifest.json Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/main.html Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/exposeRemote.js Removes previous build artifact.
src/Resources/public/studio/build/774b960f-178a-4c0b-b61a-a1560ed6e8a4/entrypoints.json Removes previous build artifact.
assets/studio/rsbuild.config.ts Switches remote definition to createDynamicRemote and updates imports.
assets/studio/package.json Bumps @pimcore/studio-ui-bundle canary and reorders deps.
assets/studio/package-lock.json Locks updated @pimcore/studio-ui-bundle version.
assets/studio/js/src/plugins.ts Updates module import path for ObjectMerger module entry.
assets/studio/js/src/modules/object-merger/types.ts Adds shared types for merger data structures.
assets/studio/js/src/modules/object-merger/object-merger-page/object-merger-page.tsx Adds main page layout composing form/toolbar/view.
assets/studio/js/src/modules/object-merger/object-merger-page/object-merger-page-wrapper.tsx Wraps the page with the merger context provider.
assets/studio/js/src/modules/object-merger/object-merger-page/components/refetch/refetch.tsx Adds refetch button/spinner component for toolbar.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/types.ts Adds types for selected objects (A/B).
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/object-merger-view.tsx Implements compare screen content and header actions.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/object-merger-view.styles.ts Adds styles for sticky header and compare layout.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/helpers.ts Adds breadcrumb/category building helpers.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/constants.tsx Adds category enum and merge source list.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/components/object-merger-versions/object-merger-versions.tsx Renders side-by-side version fields and merge/reset actions.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-toolbar/object-merger-toolbar.tsx Adds toolbar actions (mirror/apply/reset/save).
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-form/object-merger-form.tsx Adds object selection form and compare trigger.
assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-form/object-merger-form.styles.ts Adds form layout styles.
assets/studio/js/src/modules/object-merger/index.tsx Registers nav item and widget for the new page.
assets/studio/js/src/modules/object-merger/hooks/use-object-merger-data.tsx Adds the data fetching/merge/apply/reset/save logic.
assets/studio/js/src/modules/object-merger/helpers/details-functions.ts Adds layout processing + merger field creation helpers.
assets/studio/js/src/modules/object-merger/context/object-merger-context.tsx Provides context wiring for module state/actions.
Files not reviewed (1)
  • assets/studio/package-lock.json: Language not supported
Comments suppressed due to low confidence (5)

assets/studio/js/src/modules/object-merger/object-merger-page/components/object-merger-view/object-merger-view.styles.ts:29

  • The sticky header uses an extremely large z-index: 999999999 and a hard-coded background-color: #fff. This can cause stacking issues with other overlays/modals and breaks theming (dark mode). Prefer using design tokens for background and a project-standard z-index value/token so the header participates correctly in the global stacking context.
    headerContainer: css`
      position: sticky;
      top: 0;
      width: 100%;
      z-index: 999999999;

      &::before {
        content: '';
        position: absolute;
        top: -15px;
        bottom: 0;
        width: 100%;
        height: 20px;
        background-color: #fff;
        z-index: -1;

assets/studio/js/src/modules/object-merger/object-merger-page/components/refetch/refetch.tsx:32

  • onClick is declared async but doesn't await anything (and refetch is sync). This creates an unnecessary promise and can confuse error handling. Use onClick={refetch} or onClick={() => refetch()} instead.
    <IconButton
      icon={ { value: 'refresh' } }
      onClick={ async () => { refetch() } }
    />

assets/studio/js/src/modules/object-merger/helpers/details-functions.ts:189

  • fieldCollectionModifiedList is computed from itemA/itemB regardless of the current roles. After using “Mirror view”, mainValue/targetValue swap, but this diff logic still compares the original A/B inputs, so highlighting can become incorrect. Compute the differences from mainValue vs targetValue (or from mainItem vs targetItem) so it stays consistent with the current roles.
    if (field.Field.fieldtype === 'fieldcollections') {
      const mainLength = mainValue?.length ?? 0
      const targetLength = targetValue?.length ?? 0

      const mainList = targetLength > mainLength ? itemB : itemA
      const targetList = mainLength < targetLength ? itemA : itemB

      const differences = differenceWith(
        mainList?.fieldValue as IFieldCollectionValue[] ?? [],
        targetList?.fieldValue as IFieldCollectionValue[] ?? [],
        (item1, item2) => {
          return item1?.type === item2?.type && isEqual(item1?.data, item2?.data)
        }
      )

      field.fieldCollectionModifiedList = differences.map(item => item.type)
    }

assets/studio/js/src/modules/object-merger/hooks/use-object-merger-data.tsx:181

  • applyAll does Array.find(...) on both formattedDataMain and formattedDataTarget inside a loop over formattedFullData, which is quadratic. For objects with many fields this can become noticeably slow. Consider pre-indexing formattedDataMain/Target by fieldPath (e.g. Map<string, IFormattedFieldData>) before the loop.
    formattedFullData.forEach((fieldItem) => {
      const mainItem = formattedDataMain.find(item => item.fieldPath === fieldItem.fieldPath)
      const targetItem = formattedDataTarget.find(item => item.fieldPath === fieldItem.fieldPath)

assets/studio/rsbuild.config.ts:8

  • This file mixes semicolon-terminated imports with non-semicolon imports. To keep formatting consistent (and avoid lint/prettier churn), align the new imports with the existing style used in this repo/file (either all semicolons or none).
import { defineConfig } from '@rsbuild/core'
import { pluginReact } from '@rsbuild/plugin-react'
import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
import { pluginGenerateEntrypoints } from '@pimcore/studio-ui-bundle/rsbuild/plugins'
import { createDynamicRemote } from '@pimcore/studio-ui-bundle/rsbuild/utils';
import path from 'node:path'
import fs from 'node:fs';
import { v4 } from 'uuid';

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

Copy link

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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant