Skip to content

Commit d84791f

Browse files
authored
Add rule builder SDK (#2929)
1 parent 9e9abd2 commit d84791f

787 files changed

Lines changed: 5086 additions & 1115 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/code-editor/code-editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import ReactCodeMirror, { type ReactCodeMirrorProps } from '@uiw/react-codemirro
1313
import { getPresetExtensions } from '@Pimcore/components/code-editor/helpers'
1414
import { useStyles } from './code-editor.styles'
1515

16-
export type CodeEditorPreset = 'text' | 'yaml'
16+
export type CodeEditorPreset = 'text' | 'yaml' | 'html'
1717

1818
export interface CodeEditorProps extends Omit<ReactCodeMirrorProps, 'extensions' | 'value' | 'onChange'> {
1919
preset?: CodeEditorPreset

assets/js/src/core/components/code-editor/helpers.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import yaml from 'js-yaml'
1414
import { isEmpty } from 'lodash'
1515
import type { Extension } from '@codemirror/state'
1616
import { yaml as codeMirrorYaml } from '@codemirror/lang-yaml'
17+
import { html as codeMirrorHtml } from '@codemirror/lang-html'
1718
import { type CodeEditorPreset } from '@Pimcore/components/code-editor/code-editor'
1819

1920
const yamlLinter = linter((view: EditorView): Diagnostic[] => {
@@ -51,6 +52,8 @@ export const getPresetExtensions = (preset: CodeEditorPreset): Extension[] => {
5152
switch (preset) {
5253
case 'yaml':
5354
return [codeMirrorYaml(), yamlLinter, lintGutter()]
55+
case 'html':
56+
return [codeMirrorHtml()]
5457
case 'text':
5558
default:
5659
return []
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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 { Dropdown } from 'antd'
13+
import { useTranslation } from 'react-i18next'
14+
import { IconTextButton } from '@Pimcore/components/icon-text-button/icon-text-button'
15+
import { useAddConditionMenuItems } from '../../hooks/use-add-condition-menu-items'
16+
17+
interface AddConditionButtonProps {
18+
afterIndex: number
19+
disabled?: boolean
20+
children?: React.ReactNode
21+
}
22+
23+
export const AddConditionButton = ({
24+
afterIndex,
25+
disabled = false,
26+
children
27+
}: AddConditionButtonProps): React.JSX.Element => {
28+
const { t } = useTranslation()
29+
const menuItems = useAddConditionMenuItems(afterIndex)
30+
31+
const defaultButton = (
32+
<IconTextButton
33+
disabled={ disabled }
34+
icon={ { value: 'plus-circle' } }
35+
>
36+
{t('rule-condition.add-condition')}
37+
</IconTextButton>
38+
)
39+
40+
return (
41+
<Dropdown
42+
disabled={ disabled }
43+
menu={ { items: menuItems } }
44+
trigger={ ['click'] }
45+
>
46+
{children ?? defaultButton}
47+
</Dropdown>
48+
)
49+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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(({ token, css }) => ({
14+
bracketButton: css`
15+
min-width: 20px;
16+
height: auto;
17+
padding: 0;
18+
margin: 0 ${token.marginXXS}px;
19+
font-size: 48px;
20+
font-weight: 200 !important;
21+
line-height: 1;
22+
border: none;
23+
background-color: transparent;
24+
color: ${token.colorTextDisabled};
25+
cursor: pointer;
26+
transition: all ${token.motionDurationMid};
27+
align-self: stretch;
28+
display: flex;
29+
align-items: center;
30+
justify-content: center;
31+
32+
&:hover:not(:disabled) {
33+
color: ${token.colorPrimary};
34+
}
35+
36+
&:disabled {
37+
cursor: not-allowed;
38+
opacity: 0.3;
39+
}
40+
`,
41+
42+
bracketButtonActive: css`
43+
color: ${token.colorPrimary};
44+
font-weight: bold;
45+
46+
&:hover:not(:disabled) {
47+
color: ${token.colorPrimaryHover};
48+
}
49+
`,
50+
51+
bracketButtonError: css`
52+
color: ${token.colorError};
53+
font-weight: bold;
54+
55+
&:hover:not(:disabled) {
56+
color: ${token.colorErrorHover};
57+
}
58+
`
59+
}))
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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 { useTranslation } from 'react-i18next'
13+
import { useStyles } from './bracket-button.styles'
14+
15+
interface BracketButtonProps {
16+
side: 'left' | 'right'
17+
active: boolean
18+
onToggle: () => void
19+
disabled?: boolean
20+
hasError?: boolean
21+
}
22+
23+
export const BracketButton = ({
24+
side,
25+
active,
26+
onToggle,
27+
disabled = false,
28+
hasError = false
29+
}: BracketButtonProps): React.JSX.Element => {
30+
const { t } = useTranslation()
31+
const { styles, cx } = useStyles()
32+
33+
const label = t(side === 'left' ? 'rule-condition.bracket.toggle-left' : 'rule-condition.bracket.toggle-right')
34+
const icon = side === 'left' ? '(' : ')'
35+
36+
return (
37+
<button
38+
aria-label={ label }
39+
aria-pressed={ active }
40+
className={ cx(
41+
styles.bracketButton,
42+
{
43+
[styles.bracketButtonActive]: active && !hasError,
44+
[styles.bracketButtonError]: hasError
45+
}
46+
) }
47+
disabled={ disabled }
48+
onClick={ onToggle }
49+
type="button"
50+
>
51+
{icon}
52+
</button>
53+
)
54+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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+
import { CONDITION_ANIMATION_DURATION } from '../../rule-condition.constants'
13+
14+
export const useStyles = createStyles(({ token, css }) => {
15+
const borderPseudoElements = css`
16+
&::before,
17+
&::after {
18+
content: '';
19+
position: absolute;
20+
top: 0;
21+
bottom: 0;
22+
width: 2px;
23+
}
24+
25+
&::before {
26+
left: 0;
27+
}
28+
29+
&::after {
30+
right: 0;
31+
}
32+
`
33+
34+
return {
35+
conditionItemWrapper: css`
36+
position: relative;
37+
padding-left: ${token.paddingXS}px;
38+
padding-right: ${token.paddingXS}px;
39+
${borderPseudoElements}
40+
`,
41+
42+
conditionItemWrapperNew: css`
43+
animation: slideInFade ${CONDITION_ANIMATION_DURATION}ms ease-in-out;
44+
45+
@keyframes slideInFade {
46+
0% {
47+
opacity: 0;
48+
transform: translateY(-12px);
49+
}
50+
100% {
51+
opacity: 1;
52+
transform: translateY(0);
53+
}
54+
}
55+
`,
56+
57+
borderLevel1: css`
58+
${borderPseudoElements}
59+
&::before,
60+
&::after {
61+
background-color: ${token.colorPrimaryBorder};
62+
}
63+
`,
64+
65+
borderLevel2: css`
66+
${borderPseudoElements}
67+
&::before,
68+
&::after {
69+
background-color: ${token.colorAccent};
70+
}
71+
`,
72+
73+
borderLevel3: css`
74+
${borderPseudoElements}
75+
&::before,
76+
&::after {
77+
background-color: ${token.colorAccentSecondary};
78+
}
79+
`,
80+
81+
conditionBoxWrapper: css`
82+
flex: 1;
83+
min-width: 0;
84+
`,
85+
86+
conditionFormContainer: css`
87+
width: 100%;
88+
`
89+
}
90+
})

0 commit comments

Comments
 (0)