Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create pagination #188

Merged
merged 24 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f606339
Task: create pagination story
robertSt7 Mar 26, 2024
fde8b45
Task: create pagination
robertSt7 Apr 2, 2024
4cc5101
Task: create pagination
robertSt7 Apr 4, 2024
0a8f926
Merge remote 1.x into create-pagination
robertSt7 Apr 4, 2024
d14d2a2
Task: create pagination - add page jumper
robertSt7 Apr 8, 2024
39e96fd
Merge remote-tracking branch 'origin/1.x' into create-pagination
robertSt7 Apr 8, 2024
be34a9f
Task: merge 1.x and rebuild
robertSt7 Apr 8, 2024
2a6d2e4
Automatic frontend build
robertSt7 Apr 8, 2024
c6bfb26
Task: refactoring
robertSt7 Apr 9, 2024
f9d58cb
Task: create pagination
robertSt7 Apr 11, 2024
5bbd675
Merge remote-tracking branch 'origin/1.x' into create-pagination
robertSt7 Apr 11, 2024
5cb2109
Task: rebuild
robertSt7 Apr 11, 2024
8df555c
Task: create pagination
robertSt7 Apr 17, 2024
1ba9614
Task: clean up
robertSt7 Apr 22, 2024
b7ec3ee
Merge remote-tracking branch 'origin/1.x' into create-pagination
robertSt7 Apr 22, 2024
c86b0d0
Task: add a11y
robertSt7 Apr 22, 2024
004cb59
Apply eslint-fixer changes
robertSt7 Apr 22, 2024
36992ab
Task: small improvements
robertSt7 Apr 30, 2024
1e82cad
Merge remote tracking branch 'origin/1.x' into create-pagination
robertSt7 Apr 30, 2024
f0aa2e8
Improve: empty input on Blur
robertSt7 May 6, 2024
ecd543f
Merge branch '1.x' of https://github.com/pimcore/studio-ui-bundle int…
vin0401 May 13, 2024
49e98d9
Merge branch 'create-pagination' of https://github.com/pimcore/studio…
vin0401 May 13, 2024
4e966bf
Migrante pagination to new folder structure
vin0401 May 13, 2024
2b52dc7
Apply eslint-fixer changes
vin0401 May 13, 2024
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
2 changes: 1 addition & 1 deletion assets/dist/core-dll/core-manifest.json

Large diffs are not rendered by default.

22 changes: 20 additions & 2 deletions assets/dist/sdk/manifest.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/dist/vendor/vendor-manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"name":"studio_vendor","content":{"./node_modules/antd-style/es/index.js":{"id":233,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["StyleProvider","ThemeProvider","createGlobalStyle","createInstance","createStyles","createStylish","css","cx","extractStaticStyle","injectGlobal","keyframes","setupStyled","styleManager","useAntdStylish","useAntdTheme","useAntdToken","useResponsive","useTheme","useThemeMode"]},"./node_modules/react-dom/index.js":{"id":3935,"buildMeta":{"exportsType":"dynamic","defaultObject":"redirect"},"exports":["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","createPortal","createRoot","findDOMNode","flushSync","hydrate","hydrateRoot","render","unmountComponentAtNode","unstable_batchedUpdates","unstable_renderSubtreeIntoContainer","version"]},"./node_modules/inversify/es/inversify.js":{"id":6594,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["AsyncContainerModule","BindingScopeEnum","BindingTypeEnum","Container","ContainerModule","LazyServiceIdentifer","LazyServiceIdentifier","METADATA_KEY","MetadataReader","TargetTypeEnum","createTaggedDecorator","decorate","getServiceIdentifierAsString","id","inject","injectable","interfaces","multiBindToService","multiInject","named","namedConstraint","optional","postConstruct","preDestroy","tagged","taggedConstraint","targetName","traverseAncerstors","typeConstraint","unmanaged"]},"./node_modules/react/index.js":{"id":7294,"buildMeta":{"exportsType":"dynamic","defaultObject":"redirect"},"exports":["Children","Component","Fragment","Profiler","PureComponent","StrictMode","Suspense","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","act","cloneElement","createContext","createElement","createFactory","createRef","forwardRef","isValidElement","lazy","memo","startTransition","unstable_act","useCallback","useContext","useDebugValue","useDeferredValue","useEffect","useId","useImperativeHandle","useInsertionEffect","useLayoutEffect","useMemo","useReducer","useRef","useState","useSyncExternalStore","useTransition","version"]},"./node_modules/reflect-metadata/Reflect.js":{"id":8520,"buildMeta":{}},"./node_modules/antd/es/index.js":{"id":9078,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["Affix","Alert","Anchor","App","AutoComplete","Avatar","BackTop","Badge","Breadcrumb","Button","Calendar","Card","Carousel","Cascader","Checkbox","Col","Collapse","ColorPicker","ConfigProvider","DatePicker","Descriptions","Divider","Drawer","Dropdown","Empty","Flex","FloatButton","Form","Grid","Image","Input","InputNumber","Layout","List","Mentions","Menu","Modal","Pagination","Popconfirm","Popover","Progress","QRCode","Radio","Rate","Result","Row","Segmented","Select","Skeleton","Slider","Space","Spin","Statistic","Steps","Switch","Table","Tabs","Tag","TimePicker","Timeline","Tooltip","Tour","Transfer","Tree","TreeSelect","Typography","Upload","Watermark","message","notification","theme","version"]}}}
{"name":"studio_vendor","content":{"./node_modules/antd-style/es/index.js":{"id":233,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["StyleProvider","ThemeProvider","createGlobalStyle","createInstance","createStyles","createStylish","css","cx","extractStaticStyle","injectGlobal","keyframes","setupStyled","styleManager","useAntdStylish","useAntdTheme","useAntdToken","useResponsive","useTheme","useThemeMode"]},"./node_modules/antd/es/index.js":{"id":2853,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["Affix","Alert","Anchor","App","AutoComplete","Avatar","BackTop","Badge","Breadcrumb","Button","Calendar","Card","Carousel","Cascader","Checkbox","Col","Collapse","ColorPicker","ConfigProvider","DatePicker","Descriptions","Divider","Drawer","Dropdown","Empty","Flex","FloatButton","Form","Grid","Image","Input","InputNumber","Layout","List","Mentions","Menu","Modal","Pagination","Popconfirm","Popover","Progress","QRCode","Radio","Rate","Result","Row","Segmented","Select","Skeleton","Slider","Space","Spin","Statistic","Steps","Switch","Table","Tabs","Tag","TimePicker","Timeline","Tooltip","Tour","Transfer","Tree","TreeSelect","Typography","Upload","Watermark","message","notification","theme","version"]},"./node_modules/antd/es/config-provider/context.js":{"id":3124,"buildMeta":{"exportsType":"namespace"},"exports":["ConfigConsumer","ConfigContext","defaultIconPrefixCls"]},"./node_modules/react-dom/index.js":{"id":3935,"buildMeta":{"exportsType":"dynamic","defaultObject":"redirect"},"exports":["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","createPortal","createRoot","findDOMNode","flushSync","hydrate","hydrateRoot","render","unmountComponentAtNode","unstable_batchedUpdates","unstable_renderSubtreeIntoContainer","version"]},"./node_modules/antd/es/pagination/style/index.js":{"id":4781,"buildMeta":{"exportsType":"namespace"},"exports":["default","prepareComponentToken","prepareToken"]},"./node_modules/antd/es/table/style/index.js":{"id":5347,"buildMeta":{"exportsType":"namespace"},"exports":["default","prepareComponentToken"]},"./node_modules/inversify/es/inversify.js":{"id":6594,"buildMeta":{"exportsType":"namespace","sideEffectFree":true},"exports":["AsyncContainerModule","BindingScopeEnum","BindingTypeEnum","Container","ContainerModule","LazyServiceIdentifer","LazyServiceIdentifier","METADATA_KEY","MetadataReader","TargetTypeEnum","createTaggedDecorator","decorate","getServiceIdentifierAsString","id","inject","injectable","interfaces","multiBindToService","multiInject","named","namedConstraint","optional","postConstruct","preDestroy","tagged","taggedConstraint","targetName","traverseAncerstors","typeConstraint","unmanaged"]},"./node_modules/react/index.js":{"id":7294,"buildMeta":{"exportsType":"dynamic","defaultObject":"redirect"},"exports":["Children","Component","Fragment","Profiler","PureComponent","StrictMode","Suspense","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","act","cloneElement","createContext","createElement","createFactory","createRef","forwardRef","isValidElement","lazy","memo","startTransition","unstable_act","useCallback","useContext","useDebugValue","useDeferredValue","useEffect","useId","useImperativeHandle","useInsertionEffect","useLayoutEffect","useMemo","useReducer","useRef","useState","useSyncExternalStore","useTransition","version"]},"./node_modules/reflect-metadata/Reflect.js":{"id":8520,"buildMeta":{}}}}
3 changes: 3 additions & 0 deletions assets/js/src/core/assets/icons/ellipsis-outlined.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/js/src/core/assets/icons/left-outlined.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion assets/js/src/core/assets/icons/right-outlined.inline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { type Meta } from '@storybook/react'
import { InlineTextfield as InlineTextfieldComponent } from './inline-textfield'

const config: Meta = {
title: 'Pimcore studio/UI/InlineTextfield',
component: InlineTextfieldComponent,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
}

export default config

export const _default = {
args: {
value: '2',
showDotsValues: ['1', '2', '3', '9', '10'],
onKeyDown: (e) => {
if (e.key === 'Enter') {
e.target.value = ''
e.target.blur()
}
console.log(e.key)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { createStyles } from 'antd-style'

export const useStyle = createStyles(({ token, css }) => {
return {
'editable-container': css`
position: relative;
height: 30px;

.input-field {
font-family: Lato, sans-serif;
font-size: 12px;
text-align: center;
line-height: ${token.controlHeight}px;

border-radius: ${token.borderRadius}px;
border-color: ${token.colorBorder};
background-color: white;

/* Firefox */
-moz-appearance: textfield;
}

.input-field:focus-visible {
outline: none;
}

/* Chrome, Safari, Edge, Opera */

.input-field::-webkit-outer-spin-button,
.input-field::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}

& button[type="button"], .input-field {
display: block;
position: absolute;
top: 0;
inset-inline-end: 0;
bottom: 0;
inset-inline-start: 0;
padding: unset;
margin: auto;

width: ${token.controlHeight}px;
height: ${token.controlHeight}px;
}

.input-field.remove-decoration {
border: none;
background: none;
}

& button.inline-label.display-none, & button.inline-label-dots.display-none, & input.input-field.display-none {
display: none;
}

button.inline-label-dots {
border: none;
}

button.inline-label-dots, button.inline-label {
font-family: Lato, sans-serif;
line-height: 30px;
text-align: center;
vertical-align: text-bottom;
box-shadow: none;
background-color: transparent;
cursor: text;
}

button.inline-label {
color: ${token.colorPrimary};
border: 1px solid ${token.colorPrimary};
border-radius: ${token.borderRadius}px;
}
`
}
}, { hashPriority: 'low' })
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import React, { useEffect, useState } from 'react'
import { useStyle } from './inline-textfield.styles'
import { isSet } from '@Pimcore/utils/helpers'
import { Button } from 'antd'
import { Icon } from '@Pimcore/components/icon/icon'

interface InlineTextfieldProps {
value: string
onKeyDown: (e) => void
showDotsValues?: string[]
defaultClassNameInput?: string
defaultClassNameLabel?: string
defaultClassNameLabelDots?: string
}

enum VisibleElement {
input = 'input',
label = 'label',
labelDots = 'labelDots'
}

export const InlineTextfield = ({
value = '',
onKeyDown,
showDotsValues,
defaultClassNameInput = 'remove-decoration',
defaultClassNameLabel = 'display-none',
defaultClassNameLabelDots = ''
}: InlineTextfieldProps): React.JSX.Element => {
const { styles } = useStyle()
const [classNameInput, setClassNameInput] = useState(defaultClassNameInput)
const [classNameLabel, setClassNameLabel] = useState(defaultClassNameLabel)
const [classNameLabelDots, setClassNameLabelDots] = useState(defaultClassNameLabelDots)

const setVisibleElement = (element: VisibleElement): void => {
switch (element) {
case VisibleElement.input:
setClassNameInput('')
setClassNameLabel('display-none')
setClassNameLabelDots('display-none')
break
case VisibleElement.label:
setClassNameInput('remove-decoration')
setClassNameLabel('')
setClassNameLabelDots('display-none')
break
case VisibleElement.labelDots:
setClassNameInput('remove-decoration')
setClassNameLabel('display-none')
setClassNameLabelDots('')
break
}
}

const onClickLabel = (e): void => {
setVisibleElement(VisibleElement.input)
e.target.previousElementSibling?.focus()
}

const onBlurInput = (e): void => {
setClassNameBasedOnValue()
e.target.value = ''
}

const onMouseOverDots = (e): void => {
setVisibleElement(VisibleElement.input)
e.target.focus()
}
const onFocusDots = (e): void => {
setVisibleElement(VisibleElement.input)
}

const onFocusInput = (e): void => {
setVisibleElement(VisibleElement.input)
}

const onMouseLeaveInput = (e): void => {
if (document.activeElement !== e.target) {
setVisibleElement(VisibleElement.labelDots)
}
}

const setClassNameBasedOnValue = (): void => {
if (isSet(showDotsValues)) {
if (showDotsValues!.includes(value) && classNameLabelDots === 'display-none') {
setVisibleElement(VisibleElement.labelDots)
} else if (!showDotsValues!.includes(value) && classNameLabel === 'display-none') {
setVisibleElement(VisibleElement.label)
}
}
}

useEffect(() => {
setClassNameBasedOnValue()
}, [value])

return (
<div className={ styles['editable-container'] }>
<input
className={ 'input-field ' + classNameInput }
min='1'
onBlur={ onBlurInput }
onFocus={ onFocusInput }
onKeyDown={ onKeyDown }
onMouseLeave={ onMouseLeaveInput }
type='number'
/>
<Button
className={ 'inline-label ' + classNameLabel }
onClick={ onClickLabel }
>{value}</Button>
<Button
className={ 'inline-label-dots ' + classNameLabelDots }
icon={ <Icon
name={ 'ellipsis-outlined' }
options={ { width: '32px', height: '32px' } }
/> }
onFocus={ onFocusDots }
onMouseOver={ onMouseOverDots }
/>
</div>
)
}
45 changes: 45 additions & 0 deletions assets/js/src/core/components/pagination/pagination.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* Pimcore
*
* This source file is available under two different licenses:
* - Pimcore Open Core License (POCL)
* - Pimcore Commercial License (PCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { type Meta } from '@storybook/react'
import { Pagination as PaginationComponent } from './pagination'

const config: Meta = {
title: 'Pimcore studio/UI/Pagination',
component: PaginationComponent,
argTypes: {
total: {
control: false
}
},
parameters: {
layout: 'centered'
},
tags: ['autodocs']
}

export default config

export const _default = {
args: {
total: 182,
current: 2,
pageSizeOptions: [5, 25, 55, 80],
defaultPageSize: 25,
showSizeChanger: true,
hideOnSinglePage: true,
amountOfVisiblePages: 4,
showTotal: (total: number) => `Total ${total} items`,
onChange: (currentPage: number, pageSize: number) => { console.log(`Current page: ${currentPage}, Page size: ${pageSize}`) }
}
}
Loading
Loading