Skip to content

Commit da83c75

Browse files
committed
Merge branch '2025.4' into 2026.1
2 parents bab5b30 + 71099df commit da83c75

2,279 files changed

Lines changed: 92258 additions & 113 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.

assets/js/src/core/components/form/localisation/localized-fields/form-item/types/form-control-with-element-context.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export const FormControlWithElementContext = ({ children, ...props }: KeyedFormI
6262
<Component
6363
{ ...Child.props }
6464
{ ...props }
65-
disabled={ props.disabled !== true ? isDisabled : false }
65+
disabled={ Child.props.disabled === true || (props.disabled !== true ? isDisabled : false) }
6666
/>
6767
), [Child, props])
6868
}

assets/js/src/core/components/select/select.styles.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @license Pimcore Open Core License (POCL)
99
*/
1010

11+
/* eslint-disable max-lines */
1112
import { createStyles } from 'antd-style'
1213
import { isEmptyValue } from '@Pimcore/utils/type-utils'
1314
import { type SelectTheme } from './select'
@@ -167,7 +168,21 @@ export const useStyles = createStyles(({ css, token }, props: StylesProps) => {
167168
padding: 2px ${token.controlPaddingHorizontal}px 2px ${token.paddingXXS}px !important;
168169
}
169170
}
170-
171+
172+
// The !important padding above skews Ant Design's JS mirror width measurement,
173+
// causing the search input to clip typed text. flex: 1 (= flex: 1 1 0%) overrides
174+
// the JS-set width via flex-basis precedence and grows to fill the remaining row
175+
// space without wrapping to a new line (unlike flex-basis: 100%).
176+
.ant-select-selection-overflow-item-suffix {
177+
flex: 1 !important;
178+
}
179+
.ant-select-selection-search {
180+
width: 100% !important;
181+
}
182+
.ant-select-selection-search-input {
183+
width: 100% !important;
184+
}
185+
171186
&:hover {
172187
.ant-select-selection-item {
173188
.ant-select-selection-item-content {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* This source file is available under the terms of the
3+
* Pimcore Open Core License (POCL)
4+
* Full copyright and license information is available in
5+
* LICENSE.md which is distributed with this source code.
6+
*
7+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
8+
* @license Pimcore Open Core License (POCL)
9+
*/
10+
11+
import { createStyles } from 'antd-style'
12+
13+
export const useStyles = createStyles(({ css, token }) => ({
14+
loadingRow: css`
15+
padding: ${token.paddingXXS}px ${token.paddingSM}px;
16+
`,
17+
18+
dropdownFooter: css`
19+
padding: ${token.paddingXXS}px ${token.paddingSM}px;
20+
font-size: ${token.fontSizeSM}px;
21+
color: ${token.colorTextDescription};
22+
border-top: 1px solid ${token.colorBorderSecondary};
23+
text-align: right;
24+
`
25+
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* This source file is available under the terms of the
3+
* Pimcore Open Core License (POCL)
4+
* Full copyright and license information is available in
5+
* LICENSE.md which is distributed with this source code.
6+
*
7+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
8+
* @license Pimcore Open Core License (POCL)
9+
*/
10+
11+
import React from 'react'
12+
import { Skeleton } from 'antd'
13+
import { useTranslation } from 'react-i18next'
14+
import { Flex } from '@Pimcore/components/flex/flex'
15+
import { useStyles } from './combo-field-ui.styles'
16+
17+
const SKELETON_ROW_KEYS = ['skeleton-0', 'skeleton-1', 'skeleton-2']
18+
19+
export const LoadingRows = (): React.JSX.Element => {
20+
const { styles } = useStyles()
21+
return (
22+
<>
23+
{ SKELETON_ROW_KEYS.map(key => (
24+
<Flex
25+
align="center"
26+
className={ styles.loadingRow }
27+
key={ key }
28+
>
29+
<Skeleton.Input
30+
active
31+
block
32+
size="small"
33+
/>
34+
</Flex>
35+
)) }
36+
</>
37+
)
38+
}
39+
40+
interface DropdownFooterProps {
41+
loaded: number
42+
total: number | undefined
43+
allLoaded: boolean
44+
backgroundMode: boolean
45+
}
46+
47+
export const DropdownFooter = ({ loaded, total, allLoaded, backgroundMode }: DropdownFooterProps): React.JSX.Element | null => {
48+
const { t } = useTranslation()
49+
const { styles } = useStyles()
50+
if (loaded === 0 || allLoaded || backgroundMode || total === undefined) return null
51+
return (
52+
<div className={ styles.dropdownFooter }>
53+
{ t('pagination.showing-x-of-y', { loaded, total }) }
54+
</div>
55+
)
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* This source file is available under the terms of the
3+
* Pimcore Open Core License (POCL)
4+
* Full copyright and license information is available in
5+
* LICENSE.md which is distributed with this source code.
6+
*
7+
* @copyright Copyright (c) Pimcore GmbH (https://www.pimcore.com)
8+
* @license Pimcore Open Core License (POCL)
9+
*/
10+
11+
import { isArray, isEmpty, isNil, isPlainObject, isString } from 'lodash'
12+
import { type DataObjectGetSearchApiResponse } from '@Pimcore/modules/search/search-api-slice.gen'
13+
import { type ManyToManyRelationValueItem } from '@Pimcore/components/many-to-many-relation/hooks/use-value'
14+
import { type VisibleFieldDefinition } from '../../many-to-many-object-relation'
15+
16+
export type SearchItem = NonNullable<DataObjectGetSearchApiResponse['items']>[number]
17+
18+
const isBlankColumnValue = (v: unknown): boolean => {
19+
if (isNil(v)) return true
20+
if (isString(v)) return isEmpty(v) || v === 'null'
21+
if (isArray(v) || isPlainObject(v)) return isEmpty(v)
22+
return false
23+
}
24+
25+
export const buildLabel = (item: SearchItem, resolvedVisibleDefs: VisibleFieldDefinition[]): string => {
26+
const fullpath = item.columns?.find(c => c.key === 'fullpath')?.value as string ?? String(item.id)
27+
if (resolvedVisibleDefs.length === 0) return fullpath
28+
29+
return resolvedVisibleDefs
30+
.map(fd => {
31+
const v = item.columns?.find(c => c.key === fd.key)?.value
32+
if (isBlankColumnValue(v)) return '-'
33+
return isArray(v) || isPlainObject(v) ? JSON.stringify(v) : String(v)
34+
})
35+
.join(', ')
36+
}
37+
38+
export const processItems = (
39+
items: SearchItem[],
40+
resolvedVisibleDefs: VisibleFieldDefinition[],
41+
itemMap: Map<number, ManyToManyRelationValueItem>
42+
): Map<number, string> => {
43+
const newLabels = new Map<number, string>()
44+
items.forEach(item => {
45+
if (item.id === undefined) return
46+
const fullpath = item.columns?.find(c => c.key === 'fullpath')?.value as string ?? String(item.id)
47+
const classname = item.columns?.find(c => c.key === 'classname')?.value as string ?? 'object'
48+
itemMap.set(item.id, {
49+
id: item.id,
50+
type: 'object',
51+
subtype: classname,
52+
fullPath: fullpath,
53+
isPublished: null
54+
})
55+
newLabels.set(item.id, buildLabel(item, resolvedVisibleDefs))
56+
})
57+
return newLabels
58+
}

0 commit comments

Comments
 (0)