Skip to content

Commit fdff690

Browse files
committed
Merge origin/2025.4 into 2026.1
2 parents 803fb0e + 8d14337 commit fdff690

85 files changed

Lines changed: 1589 additions & 549 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/shared-frontend-build.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,6 @@ jobs:
174174
working-directory: ./assets
175175
run: npm run build-rsbuild-plugins
176176

177-
- name: Create package archive
178-
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/1.x' }}
179-
continue-on-error: true
180-
working-directory: ./assets
181-
run: npm pack && mv ./pimcore-studio-ui*.tgz ../public/build/studio-npm-package.tgz
182177
- uses: stefanzweifel/git-auto-commit-action@v5
183178
with:
184179
file_pattern: './public/'

assets/build/api/docs.jsonopenapi.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

assets/build/api/openapi-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ const config: ConfigFile = {
236236
},
237237
'../../js/src/core/modules/gdpr-data-extractor/gdpr-data-extractor-api-slice.gen.ts': {
238238
filterEndpoints: pathMatcher(/\/api\/gdpr\/?/i)
239+
},
240+
'../../js/src/core/modules/cache/cache-api-slice.gen.ts': {
241+
filterEndpoints: pathMatcher(/\/api\/cache\/?/i)
239242
}
240243
},
241244
exportName: 'api',

assets/js/src/core/bootstrap.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,5 @@ import '@Pimcore/modules/quantity-value'
6363
import '@Pimcore/modules/field-definitions'
6464
import '@Pimcore/modules/gdpr-data-extractor'
6565
import '@Pimcore/modules/system-settings'
66+
import '@Pimcore/modules/cache'
6667
import '@Pimcore/modules/classification-store-config'

assets/js/src/core/components/block/block-item.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import { ToolStripBox } from '@Pimcore/components/toolstrip/box/tool-strip-box'
1212
import React, { useMemo } from 'react'
1313
import { BlockToolStrip } from './block-tool-strip'
14+
import { Flex } from '../flex/flex'
1415

1516
export interface BlockItemProps {
1617
field: number
@@ -42,7 +43,12 @@ export const BlockItem = (props: BlockItemProps): React.JSX.Element => {
4243
)
4344
}
4445
>
45-
{children}
46+
<Flex
47+
gap={ 'extra-small' }
48+
vertical
49+
>
50+
{children}
51+
</Flex>
4652
</ToolStripBox>
4753
), [field, noteditable, children, props.disallowAdd, props.disallowDelete, props.disallowReorder, props.itemValue, props.getItemTitle])
4854
}

assets/js/src/core/components/element-tag/element-tag.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import cn from 'classnames'
1818
import { Tooltip } from '../tooltip/tooltip'
1919
import useElementOverflow from '../../utils/use-element-overflow'
2020
import { isEmptyValue } from '@Pimcore/utils/type-utils'
21+
import { SanitizeHtml } from '@Pimcore/components/sanitize-html/sanitize-html'
2122

2223
export interface ElementTagProps extends Omit<TagProps, 'id' | 'children'> {
2324
path: string
@@ -27,9 +28,10 @@ export interface ElementTagProps extends Omit<TagProps, 'id' | 'children'> {
2728
disabled?: boolean
2829
onClose?: () => void
2930
inline?: boolean
31+
pathIsHtml?: boolean
3032
}
3133

32-
export const ElementTag: React.FC<ElementTagProps> = ({ path, elementType, id, published, disabled, onClose, inline = false, ...props }) => {
34+
export const ElementTag: React.FC<ElementTagProps> = ({ path, elementType, id, published, disabled, onClose, inline = false, pathIsHtml = false, ...props }) => {
3335
const { openElement } = useElementHelper()
3436
const { styles } = useStyles()
3537
const textRef = useRef<HTMLSpanElement>(null)
@@ -49,7 +51,7 @@ export const ElementTag: React.FC<ElementTagProps> = ({ path, elementType, id, p
4951
}
5052

5153
return (
52-
<Tooltip title={ isOverflow ? path : '' }>
54+
<Tooltip title={ isOverflow && !pathIsHtml ? path : '' }>
5355
<Tag
5456
bordered={ false }
5557
className={ cn(inline ? styles.tagInline : styles.tag, { [styles.tagClickable]: isClickable, [styles.tagDisabled]: disabled }) }
@@ -61,7 +63,14 @@ export const ElementTag: React.FC<ElementTagProps> = ({ path, elementType, id, p
6163
ref={ textRef }
6264
{ ...props }
6365
>
64-
<span className="tag-content">{path}</span>
66+
{pathIsHtml
67+
? (
68+
<span className="tag-content"><SanitizeHtml
69+
html={ path }
70+
tag="span"
71+
/></span>
72+
)
73+
: <span className="tag-content">{path}</span>}
6574
</Tag>
6675
</Tooltip>
6776
)

assets/js/src/core/components/modal/window-modal/window-modal.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
import React, { useState, useRef } from 'react'
12+
import { isInIframe } from '@Pimcore/utils/iframe'
1213
import { ConfigProvider } from 'antd'
1314
import { type IModalProps, Modal } from '@Pimcore/components/modal/modal'
1415
import type { DraggableData, DraggableEvent } from 'react-draggable'
@@ -44,6 +45,14 @@ export const WindowModal = (props: IWindowModalProps): React.JSX.Element => {
4445
})
4546
}
4647

48+
// In an iframe (e.g. document editor) popups must render inside the draggable container to
49+
// inherit the correct stacking context. In the top-level window the modal wrapper has
50+
// pointer-events:none, so popups rendered inside it would be unclickable — use document.body.
51+
const getPopupContainer = (): HTMLElement => {
52+
if (isInIframe()) return draggleRef.current ?? document.body
53+
return document.body
54+
}
55+
4756
return (
4857
<Modal
4958
{ ...restProps }
@@ -84,9 +93,7 @@ export const WindowModal = (props: IWindowModalProps): React.JSX.Element => {
8493
}
8594
wrapClassName={ styles.wrapper }
8695
>
87-
{/* Render popups (Select, DatePicker, etc.) inside the modal's draggable container */}
88-
{/* so they inherit its stacking context and appear above the modal overlay. */}
89-
<ConfigProvider getPopupContainer={ () => draggleRef.current ?? document.body }>
96+
<ConfigProvider getPopupContainer={ getPopupContainer }>
9097
{props.children}
9198
</ConfigProvider>
9299
</Modal>

assets/js/src/core/modules/application-logger/application-logger-container-inner.tsx

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Toolbar } from '@Pimcore/components/toolbar/toolbar'
2121
import { api } from '@Pimcore/modules/application-logger/application-logger-api-slice-enhanced'
2222
import { useAppDispatch } from '@sdk/app'
2323
import { CreatableSelect } from '@sdk/components'
24+
import { type SortingState } from '@tanstack/react-table'
2425
import { isNil } from 'lodash'
2526
import React, { useCallback, useEffect, useState } from 'react'
2627
import { useTranslation } from 'react-i18next'
@@ -35,15 +36,29 @@ export const ApplicationLoggerContainerInner = (): React.JSX.Element => {
3536
const [pageSize, setPageSize] = useState<number>(20)
3637
const [isLoading, setIsLoading] = useState<boolean>(false)
3738
const [refreshInterval, setRefreshInterval] = useState<string | undefined>(undefined)
39+
const [sorting, setSorting] = useState<SortingState>([])
3840
const { columnFilters, setIsLoading: setFilterLoading } = useFilter()
3941

42+
const sortKeyMap: Record<string, string> = {
43+
date: 'date',
44+
message: 'message',
45+
translatedPriority: 'priority',
46+
fileObject: 'fileobject',
47+
component: 'component',
48+
source: 'source'
49+
}
50+
51+
const sortFilter = sorting.length > 0
52+
? { key: sortKeyMap[sorting[0].id] ?? sorting[0].id, direction: sorting[0].desc ? 'DESC' : 'ASC' }
53+
: { key: 'id', direction: 'DESC' }
54+
4055
const { data, isFetching: isRTKFetching } = useBundleApplicationLoggerGetCollectionQuery({
4156
body: {
4257
filters: {
4358
page: currentPage,
4459
pageSize,
4560
columnFilters,
46-
sortFilter: { key: 'id', direction: 'DESC' }
61+
sortFilter
4762
}
4863
}
4964
})
@@ -178,7 +193,12 @@ export const ApplicationLoggerContainerInner = (): React.JSX.Element => {
178193
y: 'none'
179194
} }
180195
>
181-
<ApplicationLogger items={ data?.items ?? [] } />
196+
<ApplicationLogger
197+
isLoading={ isRTKFetching }
198+
items={ data?.items ?? [] }
199+
onSortingChange={ setSorting }
200+
sorting={ sorting }
201+
/>
182202
</Box>
183203
</Content>
184204
</ContentLayout>

assets/js/src/core/modules/application-logger/application-logger.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010

1111
import { ContentLayout, Sidebar } from '@sdk/components'
12+
import { type SortingState } from '@tanstack/react-table'
1213
import { isNil } from 'lodash'
1314
import React from 'react'
1415
import { type BundleApplicationLoggerGetCollectionApiResponse } from './application-logger-api-slice.gen'
@@ -17,9 +18,12 @@ import { Table } from './components/table/table'
1718

1819
interface ApplicationLoggerProps {
1920
items: BundleApplicationLoggerGetCollectionApiResponse['items']
21+
isLoading?: boolean
22+
sorting?: SortingState
23+
onSortingChange?: (sorting: SortingState) => void
2024
}
2125

22-
export const ApplicationLogger = ({ items }: ApplicationLoggerProps): React.JSX.Element => {
26+
export const ApplicationLogger = ({ items, isLoading, sorting, onSortingChange }: ApplicationLoggerProps): React.JSX.Element => {
2327
if (isNil(items)) {
2428
return <></>
2529
}
@@ -32,7 +36,12 @@ export const ApplicationLogger = ({ items }: ApplicationLoggerProps): React.JSX.
3236
/>
3337
}
3438
>
35-
<Table items={ items } />
39+
<Table
40+
isLoading={ isLoading }
41+
items={ items }
42+
onSortingChange={ onSortingChange }
43+
sorting={ sorting }
44+
/>
3645
</ContentLayout>
3746
)
3847
}

assets/js/src/core/modules/application-logger/components/table/table.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { useElementHelper } from '@Pimcore/modules/element/hooks/use-element-hel
1515
import { type ElementType } from '@Pimcore/types/enums/element/element-type'
1616
import { formatDateTime } from '@Pimcore/utils/date-time'
1717
import { Button } from '@sdk/components'
18-
import { createColumnHelper } from '@tanstack/react-table'
18+
import { createColumnHelper, type SortingState } from '@tanstack/react-table'
1919
import { isNil } from 'lodash'
2020
import React, { useState } from 'react'
2121
import { useTranslation } from 'react-i18next'
@@ -25,14 +25,17 @@ import { useStyles } from './table.styles'
2525

2626
interface TableProps {
2727
items: BundleApplicationLoggerGetCollectionApiResponse['items']
28+
isLoading?: boolean
29+
sorting?: SortingState
30+
onSortingChange?: (sorting: SortingState) => void
2831
}
2932

3033
export interface BundleApplicationLoggerLogEntryWithActions extends BundleApplicationLoggerLogEntry {
3134
translatedPriority: string
3235
actions: React.ReactNode
3336
}
3437

35-
export const Table = ({ items }: TableProps): React.JSX.Element => {
38+
export const Table = ({ items, isLoading, sorting, onSortingChange }: TableProps): React.JSX.Element => {
3639
const { t } = useTranslation()
3740
const { openElement } = useElementHelper()
3841
const { styles } = useStyles()
@@ -56,14 +59,16 @@ export const Table = ({ items }: TableProps): React.JSX.Element => {
5659
const columns = [
5760
columnHelper.accessor('date', {
5861
header: t('application-logger.columns.timestamp'),
59-
size: 80
62+
size: 80,
63+
enableSorting: true
6064
}),
6165
columnHelper.accessor('pid', {
6266
header: t('application-logger.columns.pid'),
6367
size: 60
6468
}),
6569
columnHelper.accessor('message', {
6670
header: t('application-logger.columns.message'),
71+
enableSorting: true,
6772
cell: ({ getValue }) => (
6873
<span className={ styles.cellTruncate }>
6974
{getValue()}
@@ -72,10 +77,12 @@ export const Table = ({ items }: TableProps): React.JSX.Element => {
7277
}),
7378
columnHelper.accessor('translatedPriority', {
7479
header: t('application-logger.columns.type'),
75-
size: 60
80+
size: 60,
81+
enableSorting: true
7682
}),
7783
columnHelper.accessor('fileObject', {
7884
header: t('application-logger.columns.file-object'),
85+
enableSorting: true,
7986
cell: ({ row }): React.JSX.Element => {
8087
const column = row.original
8188
const fileObjectBasePath = '/admin/bundle/applicationlogger/log/show-file-object?filePath='
@@ -125,13 +132,16 @@ export const Table = ({ items }: TableProps): React.JSX.Element => {
125132
}),
126133
columnHelper.accessor('component', {
127134
header: t('application-logger.columns.component'),
128-
size: 100
135+
size: 100,
136+
enableSorting: true
129137
}),
130138
columnHelper.accessor('source', {
131-
header: t('application-logger.columns.source')
139+
header: t('application-logger.columns.source'),
140+
enableSorting: true
132141
}),
133142
columnHelper.accessor('actions', {
134143
header: t('application-logger.columns.details'),
144+
enableSorting: false,
135145
cell: ({ row }): React.JSX.Element => {
136146
const column = row.original
137147

@@ -160,9 +170,13 @@ export const Table = ({ items }: TableProps): React.JSX.Element => {
160170
autoWidth
161171
columns={ columns }
162172
data={ tableItems }
163-
// isLoading={notesAndEventsFetching}
173+
enableSorting
174+
isLoading={ isLoading }
175+
manualSorting
164176
modifiedCells={ [] }
177+
onSortingChange={ onSortingChange }
165178
resizable
179+
sorting={ sorting }
166180
/>
167181

168182
<DetailModal

0 commit comments

Comments
 (0)