From 2b0d8561293dc260581d0c8e0b2747d90d11b08c Mon Sep 17 00:00:00 2001 From: vin0401 Date: Wed, 19 Nov 2025 14:30:23 +0100 Subject: [PATCH 1/4] Add example for custum data object listings --- .../listings/components/custom-listing.tsx | 26 +++ .../decorator/header/header-decorator.tsx | 11 ++ .../decorator/header/with-header.tsx | 19 +++ .../pql-filter/pql-filter-decorator.tsx | 15 ++ .../provider/pql-filter-provider.tsx | 32 ++++ .../pql-filter/sidebar/pql-sidebar.tsx | 30 ++++ .../pql-filter/with-pql-filter-provider.tsx | 15 ++ .../pql-filter/with-pql-filter-query.tsx | 39 +++++ .../pql-filter/with-pql-filter-sidebar.tsx | 28 +++ .../toolbar/extra-button/extra-button.tsx | 6 + .../custom-listing/toolbar/toolbar.tsx | 17 ++ assets/js/src/examples/listings/index.tsx | 10 ++ .../modules/custom-data-object-listing.tsx | 118 +++++++++++++ .../listings/widgets/custom-listing.tsx | 6 + assets/js/src/plugins.ts | 4 +- assets/package-lock.json | 35 +++- .../entrypoints.json | 25 +++ .../exposeRemote.js | 7 + .../manifest.json | 50 ++++++ .../build/entrypoints.json | 9 - .../build/manifest.json | 3 - .../entrypoints.json | 24 --- .../exposeRemote.js | 7 - .../main.html | 1 - .../manifest.json | 36 ---- .../mf-manifest.json | 118 ------------- .../mf-stats.json | 159 ------------------ .../static/js/328.82a03387.js | 6 - .../static/js/328.82a03387.js.LICENSE.txt | 9 - ...deration_expose_default_export.13b9ff4f.js | 2 - ...ose_default_export.13b9ff4f.js.LICENSE.txt | 9 - .../static/js/main.b24a02e1.js | 1 - .../static/js/remoteEntry.js | 6 - .../static/js/remoteEntry.js.LICENSE.txt | 9 - 34 files changed, 489 insertions(+), 403 deletions(-) create mode 100644 assets/js/src/examples/listings/components/custom-listing.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/header/header-decorator.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/header/with-header.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/pql-filter-decorator.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/provider/pql-filter-provider.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/sidebar/pql-sidebar.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/with-pql-filter-provider.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/with-pql-filter-query.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/with-pql-filter-sidebar.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/toolbar/extra-button/extra-button.tsx create mode 100644 assets/js/src/examples/listings/components/custom-listing/toolbar/toolbar.tsx create mode 100644 assets/js/src/examples/listings/index.tsx create mode 100644 assets/js/src/examples/listings/modules/custom-data-object-listing.tsx create mode 100644 assets/js/src/examples/listings/widgets/custom-listing.tsx create mode 100644 public/build/06c446b2-5759-4c1c-98e8-62c7c32fabae/entrypoints.json create mode 100644 public/build/06c446b2-5759-4c1c-98e8-62c7c32fabae/exposeRemote.js create mode 100644 public/build/06c446b2-5759-4c1c-98e8-62c7c32fabae/manifest.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/build/entrypoints.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/build/manifest.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/entrypoints.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/exposeRemote.js delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/main.html delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/manifest.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/mf-manifest.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/mf-stats.json delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/328.82a03387.js delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/328.82a03387.js.LICENSE.txt delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/async/__federation_expose_default_export.13b9ff4f.js delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/async/__federation_expose_default_export.13b9ff4f.js.LICENSE.txt delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/main.b24a02e1.js delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/remoteEntry.js delete mode 100644 public/build/476d8760-a20c-4891-8dbe-c175b8229ad7/static/js/remoteEntry.js.LICENSE.txt diff --git a/assets/js/src/examples/listings/components/custom-listing.tsx b/assets/js/src/examples/listings/components/custom-listing.tsx new file mode 100644 index 0000000..004b8c9 --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing.tsx @@ -0,0 +1,26 @@ +import { container } from "@pimcore/studio-ui-bundle"; +import { BaseListing, DataObjectProvider, listingDefaultProps, ObjectListingBuilder } from "@pimcore/studio-ui-bundle/modules/data-object"; +import React from "react"; + +export const CustomListing = (): React.JSX.Element => { + const listingBuilder = container.get("Cars/Listing/Builder"); + + return ( + + + + ) +} diff --git a/assets/js/src/examples/listings/components/custom-listing/decorator/header/header-decorator.tsx b/assets/js/src/examples/listings/components/custom-listing/decorator/header/header-decorator.tsx new file mode 100644 index 0000000..8eb663c --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing/decorator/header/header-decorator.tsx @@ -0,0 +1,11 @@ +import { AbstractDecorator } from "@pimcore/studio-ui-bundle/modules/element"; +import { withHeader } from "./with-header"; + +export const HeaderDecorator: AbstractDecorator = (props) => { + const { ViewComponent } = props; + + return { + ...props, + ViewComponent: withHeader(ViewComponent) + } +} diff --git a/assets/js/src/examples/listings/components/custom-listing/decorator/header/with-header.tsx b/assets/js/src/examples/listings/components/custom-listing/decorator/header/with-header.tsx new file mode 100644 index 0000000..5eff4de --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing/decorator/header/with-header.tsx @@ -0,0 +1,19 @@ +import { ContentLayout, Header, Toolbar } from "@pimcore/studio-ui-bundle/components"; +import { AbstractDecoratorProps } from "@pimcore/studio-ui-bundle/modules/element"; +import React from "react"; + +export const withHeader = (BaseComponent: AbstractDecoratorProps['ViewComponent']): AbstractDecoratorProps['ViewComponent'] => { + const HeaderComponent: AbstractDecoratorProps['ViewComponent'] = (props) => { + return ( + +
+ + }> + + + ); + } + + return HeaderComponent; +} diff --git a/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/pql-filter-decorator.tsx b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/pql-filter-decorator.tsx new file mode 100644 index 0000000..48590b4 --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/pql-filter-decorator.tsx @@ -0,0 +1,15 @@ +import { AbstractDecorator } from "@pimcore/studio-ui-bundle/modules/element"; +import { withPqlFilterProvider } from "./with-pql-filter-provider"; +import { withPqlFilterSidebar } from "./with-pql-filter-sidebar"; +import { withPqlFilterQuery } from "./with-pql-filter-query"; + +export const PqlFilterDecorator: AbstractDecorator = (props) => { + const { useSidebarOptions, ContextComponent, useDataQueryHelper } = props; + + return { + ...props, + ContextComponent: withPqlFilterProvider(ContextComponent), + useSidebarOptions: withPqlFilterSidebar(useSidebarOptions), + useDataQueryHelper: withPqlFilterQuery(useDataQueryHelper), + } +} diff --git a/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/provider/pql-filter-provider.tsx b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/provider/pql-filter-provider.tsx new file mode 100644 index 0000000..3af53c4 --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/provider/pql-filter-provider.tsx @@ -0,0 +1,32 @@ +import React, { createContext, useContext, useState } from "react"; + +export interface IPqlFilterContext { + pqlFilter: string | null; + setPqlFilter: (filter: string | null) => void; +} + +export const PqlFilterContext = createContext(undefined); + +export interface IPqlFilterProviderProps { + children: React.ReactNode; +} + +export const PqlFilterProvider = ({ children }: IPqlFilterProviderProps): React.JSX.Element => { + const [pqlFilter, setPqlFilter] = useState(null); + + return ( + + {children} + + ); +} + +export const usePqlFilterContext = (): IPqlFilterContext => { + const context = useContext(PqlFilterContext); + + if (!context) { + throw new Error("usePqlFilterContext must be used within a PqlFilterProvider"); + } + + return context; +} diff --git a/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/sidebar/pql-sidebar.tsx b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/sidebar/pql-sidebar.tsx new file mode 100644 index 0000000..1b206d6 --- /dev/null +++ b/assets/js/src/examples/listings/components/custom-listing/decorator/pql-filter/sidebar/pql-sidebar.tsx @@ -0,0 +1,30 @@ +import React from "react" +import { Content, ContentLayout, Header, Select } from "@pimcore/studio-ui-bundle/components" +import { usePqlFilterContext } from "../provider/pql-filter-provider"; + +export interface predefinedPqlFilter { + label: string; + pql: string; +} + +export const PqlSidebar = (): React.JSX.Element => { + const { pqlFilter, setPqlFilter } = usePqlFilterContext(); + const predefinedPqls: predefinedPqlFilter[] = [ + { label: "All E-Type models which are green or produced before 1965.", pql: 'series = "E-Type" AND (color = "green" OR productionYear < 1965)' }, + { label: "All Alfa cars produced after 1965", pql: 'manufacturer:Manufacturer.name = "Alfa" AND productionYear > 1965' }, + { label: "All red or blue cars using standard PQL syntax.", pql: 'color = "red" OR color = "blue"' }, + ] + + const options = predefinedPqls.map((filter) => ({ + label: filter.label, + value: filter.pql, + })) + + return + +
+ + - - +