Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions assets/js/src/examples/api-data/components/api-data-widget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Content, Header } from '@pimcore/studio-ui-bundle/components'
import { useAssetGetTreeQuery } from '@pimcore/studio-ui-bundle/api/asset'
import React, { useEffect } from 'react'
import { ApiError, trackError } from '@pimcore/studio-ui-bundle/modules/app'

export const ApiDataWidget = (): React.JSX.Element => {
const { isLoading, data, isError, error } = useAssetGetTreeQuery({
page: 1,
pageSize: 10
})

useEffect(() => {
if (isError) {
trackError(new ApiError(error))
}
}, [isError])

return (
<Content
loading={ isLoading }
padded
>
<Header title="API data" />

{data?.items.map((item) => (
<div key={ item.id }>
{item.filename}
</div>
))}
</Content>
)
}
10 changes: 10 additions & 0 deletions assets/js/src/examples/api-data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type IAbstractPlugin } from '@pimcore/studio-ui-bundle'
import { ApiDataExtension } from './modules/api-data-extension'

export const ApiDataPlugin: IAbstractPlugin = {
name: 'ApiDataPlugin',

onStartup ({ moduleSystem }) {
moduleSystem.registerModule(ApiDataExtension)
}
}
32 changes: 32 additions & 0 deletions assets/js/src/examples/api-data/modules/api-data-extension.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { type AbstractModule, container } from '@pimcore/studio-ui-bundle'
import { serviceIds } from '@pimcore/studio-ui-bundle/app'
import { type MainNavRegistry } from '@pimcore/studio-ui-bundle/modules/app'
import { type WidgetRegistry } from '@pimcore/studio-ui-bundle/modules/widget-manager'
import { ApiDataWidget } from '../components/api-data-widget'

export const ApiDataExtension: AbstractModule = {
onInit () {
const mainNavRegistryService = container.get<MainNavRegistry>(serviceIds.mainNavRegistry)

mainNavRegistryService.registerMainNavItem({
path: 'Example Plugin/Api Data',
widgetConfig: {
name: 'Api Data',
id: 'api-data',
component: 'api-data-widget',
config: {
icon: {
type: 'name',
value: 'pimcore'
}
}
}
})

const widgetRegistryService = container.get<WidgetRegistry>(serviceIds.widgetManager)
widgetRegistryService.registerWidget({
name: 'api-data-widget',
component: ApiDataWidget
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const ExampleWidget = (): React.JSX.Element => {
const widgetManager = useWidgetManager()
const [selectedOption, setSelectedOption] = React.useState<SelectProps['value']>(undefined)
const [selectedWidget, setSelectedWidget] = React.useState<Record<string, any> | undefined>(undefined)
const areButtonsDisabled = selectedWidget === undefined

const widgets = [
{
Expand Down Expand Up @@ -73,19 +74,31 @@ export const ExampleWidget = (): React.JSX.Element => {
direction='vertical'
size='small'
>
<Button onClick={ () => { widgetManager.openMainWidget(selectedWidget) } }>
<Button
disabled={ areButtonsDisabled }
onClick={ () => { widgetManager.openMainWidget(selectedWidget) } }
>
Open main widget
</Button>

<Button onClick={ () => { widgetManager.openLeftWidget(selectedWidget) } }>
<Button
disabled={ areButtonsDisabled }
onClick={ () => { widgetManager.openLeftWidget(selectedWidget) } }
>
Open left widget
</Button>

<Button onClick={ () => { widgetManager.openRightWidget(selectedWidget) } }>
<Button
disabled={ areButtonsDisabled }
onClick={ () => { widgetManager.openRightWidget(selectedWidget) } }
>
Open right widget
</Button>

<Button onClick={ () => { widgetManager.openBottomWidget(selectedWidget) } }>
<Button
disabled={ areButtonsDisabled }
onClick={ () => { widgetManager.openBottomWidget(selectedWidget) } }
>
Open bottom widget
</Button>
</Space>
Expand Down
76 changes: 76 additions & 0 deletions assets/js/src/examples/dynamic-types/components/data-grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Grid } from '@pimcore/studio-ui-bundle/components'
import React from 'react'

type GridProps = Parameters<typeof Grid>
const columns: GridProps[0]['columns'] = [
{
id: 'number-cell',
accessorFn: (row) => row['number-cell'],
accessorKey: 'number-cell',
header: 'Number',
meta: {
type: 'number'
}
},

{
id: 'text-cell',
accessorFn: (row) => row['text-cell'],
accessorKey: 'text-cell',
header: 'Text',
meta: {
type: 'text'
}
},

{
id: 'boolean-cell',
accessorFn: (row) => row['boolean-cell'],
accessorKey: 'boolean-cell',
header: 'Boolean',
meta: {
type: 'boolean',
editable: false
}
},

{
id: 'live-updating',
accessorFn: (row) => row['live-updating'],
accessorKey: 'live-updating',
header: 'Live Updating',
meta: {
type: 'live-updating'
}
}
]

const data: GridProps[0]['data'] = [
{
'number-cell': 1,
'text-cell': 'Hello',
'live-updating': '2234',
'boolean-cell': true
},
{
'number-cell': 2,
'text-cell': 'World',
'live-updating': '543',
'boolean-cell': false
},
{
'number-cell': 3,
'text-cell': '!',
'live-updating': '234',
'boolean-cell': true
}
]

export const DataGrid = (): React.JSX.Element => {
return (
<Grid
columns={ columns }
data={ data }
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Content, Header } from '@pimcore/studio-ui-bundle/components'
import React from 'react'
import { DataGrid } from './data-grid'

export const DynamicTypesWidget = (): React.JSX.Element => {
return (
<Content padded>
<Header title="Dynamic types" />

<DataGrid />
</Content>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { type AbstractGridCellDefinition } from '@pimcore/studio-ui-bundle/modules/element'
import React, { useEffect, useState } from 'react'

export interface LiveUpdatingCellComponentProps extends AbstractGridCellDefinition {}

export const LiveUpdatingCellComponent = ({ getValue }: LiveUpdatingCellComponentProps): React.JSX.Element => {
const [currentValue, setCurrentValue] = useState(0)

useEffect(() => {
// Simulate a live updating value
// In a real-world scenario, this could be a Server Side Event or an API call
// The cell value could be used as a configuration for the API call
// or the SSE connection
const timer = setInterval(() => {
const newValue = Math.floor(Math.random() * 1000)
setCurrentValue(newValue)
}, 2000)

return () => {
clearInterval(timer)
}
}, [])

return (
<div className='default-cell__content'>
{currentValue}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { type AbstractGridCellDefinition, DynamicTypeGridCellAbstract } from '@pimcore/studio-ui-bundle/modules/element'
import React, { type ReactElement } from 'react'
import { LiveUpdatingCellComponent } from '../components/live-updating-cell-component'
import { injectable } from 'inversify'

@injectable()
export class LiveUpdatingCell extends DynamicTypeGridCellAbstract {
id: string = 'live-updating'

getGridCellComponent (props: AbstractGridCellDefinition): ReactElement<AbstractGridCellDefinition> {
return <LiveUpdatingCellComponent { ...props } />
}
}
15 changes: 15 additions & 0 deletions assets/js/src/examples/dynamic-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { type IAbstractPlugin } from '@pimcore/studio-ui-bundle'
import { DynamicTypeExtension } from './modules/dynamic-types-extension'
import { LiveUpdatingCell } from './dynamic-types/definitions/live-updating-cell'

export const DynamicTypePlugin: IAbstractPlugin = {
name: 'DynamicTypePlugin',

onInit ({ container }) {
container.bind('DynamicTypes/GridCell/LiveUpdatingCell').to(LiveUpdatingCell)
},

onStartup ({ moduleSystem }) {
moduleSystem.registerModule(DynamicTypeExtension)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { type AbstractModule, container } from '@pimcore/studio-ui-bundle'
import { serviceIds } from '@pimcore/studio-ui-bundle/app'
import { type MainNavRegistry } from '@pimcore/studio-ui-bundle/modules/app'
import { type WidgetRegistry } from '@pimcore/studio-ui-bundle/modules/widget-manager'
import { DynamicTypesWidget } from '../components/dynamic-types-widget'
import { type DynamicTypeGridCellRegistry } from '@pimcore/studio-ui-bundle/modules/element'

export const DynamicTypeExtension: AbstractModule = {
onInit: (): void => {
const mainNavRegistryService = container.get<MainNavRegistry>(serviceIds.mainNavRegistry)

mainNavRegistryService.registerMainNavItem({
path: 'Example Plugin/Dynamic Types',
widgetConfig: {
name: 'Dynamic Types',
id: 'dynamic-types',
component: 'dynamic-types',
config: {
icon: {
type: 'name',
value: 'pimcore'
}
}
}
})

const widgetRegistryService = container.get<WidgetRegistry>(serviceIds.widgetManager)
widgetRegistryService.registerWidget({
name: 'dynamic-types',
component: DynamicTypesWidget
})

const gridCellRegistry = container.get<DynamicTypeGridCellRegistry>(serviceIds['DynamicTypes/GridCellRegistry'])

gridCellRegistry.registerDynamicType(container.get('DynamicTypes/GridCell/LiveUpdatingCell'))
}
}
4 changes: 4 additions & 0 deletions assets/js/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { AssetEditorToolbarButtonPlugin } from './examples/asset-editor-toolbar-
import { TabManagerPlugin } from './examples/tab-manager'
import { CustomIconPlugin } from './examples/custom-icons'
import { CustomWidgetsPlugin } from './examples/custom-widgets'
import { DynamicTypePlugin } from './examples/dynamic-types'
import { ApiDataPlugin } from './examples/api-data'

if (module.hot !== undefined) {
module.hot.accept()
Expand All @@ -20,3 +22,5 @@ pluginSystem.registerPlugin(AssetEditorToolbarButtonPlugin)
pluginSystem.registerPlugin(TabManagerPlugin)
pluginSystem.registerPlugin(CustomIconPlugin)
pluginSystem.registerPlugin(CustomWidgetsPlugin)
pluginSystem.registerPlugin(DynamicTypePlugin)
pluginSystem.registerPlugin(ApiDataPlugin)
9 changes: 9 additions & 0 deletions assets/public/build/entrypoints.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"entrypoints": {
"main": {
"js": [
"http://localhost:3030/build/main.js"
]
}
}
}
3 changes: 3 additions & 0 deletions assets/public/build/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"build/main.js": "http://localhost:3030/build/main.js"
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"entrypoints": {
"main": {
"js": [
"/bundles/pimcorestudioexample/build/6b1710b2-8725-4a5d-8724-6b0a9d1a9b2e/main.8cea60c6.js"
]
}
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"bundles/pimcorestudioexample/build/6b1710b2-8725-4a5d-8724-6b0a9d1a9b2e/main.js": "/bundles/pimcorestudioexample/build/6b1710b2-8725-4a5d-8724-6b0a9d1a9b2e/main.8cea60c6.js"
}