Skip to content

Commit

Permalink
Add pagination for folder listing (#113)
Browse files Browse the repository at this point in the history
* Add grid pagination

* Add default layouts for asset editor
  • Loading branch information
vin0401 committed Mar 5, 2024
1 parent 586072b commit 891b281
Show file tree
Hide file tree
Showing 23 changed files with 349 additions and 72 deletions.
28 changes: 25 additions & 3 deletions assets/js/src/components/editor-tabs/editor-tabs.styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,26 @@ export const useStyle = createStyles(({ token, css }) => {
return {
editorTabs: css`
height: 100%;
width: 100%;
overflow: hidden;

.ant-tabs-content {
display: flex;
height: 100%;
}

&.ant-tabs .ant-tabs-tab {
padding: 0;
transition: color .2s;
}

.ant-tabs-tabpane {
position: relative;
display: flex;
height: 100%;
width: 100%;
}

.ant-tabs-content-holder {
overflow: auto;
}
Expand All @@ -20,13 +38,18 @@ export const useStyle = createStyles(({ token, css }) => {
&.ant-tabs-top >.ant-tabs-nav {
margin-bottom: 0;
}

&.ant-tabs .ant-tabs-tab-btn .ant-tabs-tab-icon:not(:last-child) {
margin-inline-end: 0;
}

.ant-tabs-tab {
padding: 0;

&:first-of-type {
margin-left: ${token.paddingSM}px;
margin-right: ${token.paddingSM}px;
}
padding: 0;

.ant-tabs-tab-btn {
display: flex;
Expand Down Expand Up @@ -89,8 +112,7 @@ export const useStyle = createStyles(({ token, css }) => {

.ant-tabs-tab.ant-tabs-tab-active {
border-bottom: 2px solid ${token.colorPrimaryActive};
animation: fadeIn .2s;
}
`
}
})
}, { hashPriority: 'low' })
5 changes: 5 additions & 0 deletions assets/js/src/components/grid/grid.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export const useStyles = createStyles(({ token, css }) => {
user-select: none;
}
th, td {
line-height: 1.83;
padding: ${token.Table.cellPaddingBlockSM}px ${token.Table.cellPaddingInlineSM}px;
}
&.ant-table-wrapper .ant-table-container table>thead>tr:first-child >*:first-child {
border-start-start-radius: 0;
}
Expand Down
8 changes: 6 additions & 2 deletions assets/js/src/components/grid/grid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCssComponentHash } from '@Pimcore/modules/ant-design/hooks/use-css-component-hash'
import { type ColumnDef, flexRender, getCoreRowModel, useReactTable, type ColumnResizeMode, type TableOptions } from '@tanstack/react-table'
import React, { useState } from 'react'
import React, { useEffect, useState } from 'react'
import { useStyles } from './grid.styles'
import { Resizer } from './resizer/resizer'

Expand All @@ -12,11 +12,15 @@ export interface GridProps {

export const Grid = (props: GridProps): React.JSX.Element => {
const [columns] = useState(props.columns)
const [data] = useState(props.data)
const [data, setData] = useState(props.data)
const hashId = useCssComponentHash('table')
const { styles } = useStyles()
const [columnResizeMode] = useState<ColumnResizeMode>('onEnd')

useEffect(() => {
setData(props.data)
}, [props.data])

const tableProps: TableOptions<any> = {
data,
columns,
Expand Down
10 changes: 8 additions & 2 deletions assets/js/src/modules/asset/editor-tabs/tabs/view-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Image } from 'antd'
import { AssetContext } from '@Pimcore/modules/asset/asset-container'
import { useAssetDraft } from '@Pimcore/modules/asset/hooks/use-asset-draft'

export const ViewTabContainer = (): React.JSX.Element => {
const ViewTabContainer = (): React.JSX.Element => {
const assetContext = useContext(AssetContext)
const { isError, isLoading, asset } = useAssetDraft(assetContext.id!)

Expand All @@ -23,5 +23,11 @@ export const ViewTabContainer = (): React.JSX.Element => {
)
}

return <div>view</div>
return (
<>
<div>view</div>
</>
)
}

export { ViewTabContainer }
1 change: 1 addition & 0 deletions assets/js/src/modules/asset/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { registerWidget } from '@Pimcore/modules/widget-manager/utils/widget-registry'
import '@Pimcore/modules/asset/editor-tabs/index'
import '@Pimcore/modules/asset/types/folder'
import { AssetContainer } from './asset-container'

registerWidget({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import React from 'react'
import { folderEditorTabManager } from '..'
import { EditorTabs as EditorTabsView } from '@Pimcore/components/editor-tabs/editor-tabs'

const EditorTabsContainer = (): React.JSX.Element => {
const tabs = folderEditorTabManager.getTabs()
const tabs = folderEditorTabManager.getTabs()

return <EditorTabsView key={1} items={tabs} />
const EditorTabsContainer = (): React.JSX.Element => {
return <EditorTabsView defaultActiveKey='list' items={tabs} showLabelIfActive />
}

export { EditorTabsContainer }
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import { FormattedDate } from '@Pimcore/components/formatted-date/formatted-date'
import { Grid } from '@Pimcore/components/grid/grid'
import { useApiAssetsGetCollectionQuery } from '@Pimcore/modules/asset/asset-api-slice.gen'
import { AssetContext } from '@Pimcore/modules/asset/asset-container'
import { createColumnHelper } from '@tanstack/react-table'
import { Tag } from 'antd'
import React, { useContext } from 'react'
import { useTranslation } from 'react-i18next'
import { PreviewContainer } from './list/grid-columns/preview-container'
import React, { useContext, useState } from 'react'
import { GridContainer } from './list/grid-container'
import { GridToolbarContainer } from './list/grid-toolbar-container'
import { ContentToolbarSidebarView } from '@Pimcore/modules/element-editor/tab-layouts/content-toolbar-sidebar-view'

const ListContainer = (): React.JSX.Element => {
const assetContext = useContext(AssetContext)
const { t } = useTranslation()
const [currentPage, setCurrentPage] = useState(1)
const [pageSize, setPageSize] = useState(20)
const assetId = assetContext.id
const { isLoading, isError, data } = useApiAssetsGetCollectionQuery({ parentId: assetId })
const { isLoading, isError, data } = useApiAssetsGetCollectionQuery({ parentId: assetId, page: currentPage, itemsPerPage: pageSize })

if (isLoading || data === undefined) {
return <div>Loading...</div>
Expand All @@ -22,51 +20,28 @@ const ListContainer = (): React.JSX.Element => {
return <div>Error</div>
}

const assets = data['hydra:member']
const columnHelper = createColumnHelper<typeof assets[0]>()
const total = data['hydra:totalItems']!

const columns = [
columnHelper.accessor('fullPath', {
header: t('asset.asset-editor-tabs.list.columns.preview'),
cell: info => {
if (info.row.original.type !== 'image') {
return <></>
}

return <PreviewContainer cellInfo={info} />
},
id: 'preview',
size: 110
}),

columnHelper.accessor('id', {
header: t('asset.asset-editor-tabs.list.columns.id')
}),

columnHelper.accessor('type', {
header: t('asset.asset-editor-tabs.list.columns.type')
}),

columnHelper.accessor('fullPath', {
header: t('asset.asset-editor-tabs.list.columns.fullPath'),
cell: info => <Tag bordered={false} color='processing'>{info.getValue()!}</Tag>,
id: 'fullPath',
size: 300
}),

columnHelper.accessor('creationDate', {
header: t('asset.asset-editor-tabs.list.columns.creationDate'),
cell: info => <FormattedDate timestamp={info.getValue() as number * 1000} />
}),

columnHelper.accessor('modificationDate', {
header: t('asset.asset-editor-tabs.list.columns.modificationDate'),
cell: info => <FormattedDate timestamp={info.getValue() as number * 1000} />
})
]
function onPagerChange (page: number, pageSize: number): void {
setCurrentPage(page)
setPageSize(pageSize)
}

return (
<Grid data={assets} columns={columns} resizeable />
<ContentToolbarSidebarView
renderToolbar={
<GridToolbarContainer
pager={{
current: currentPage,
total,
pageSize,
onChange: onPagerChange
}}
/>
}
>
<GridContainer assets={data['hydra:member']} />
</ContentToolbarSidebarView>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react'
import { FormattedDate } from '@Pimcore/components/formatted-date/formatted-date'
import { Grid } from '@Pimcore/components/grid/grid'
import { createColumnHelper } from '@tanstack/react-table'
import { Tag } from 'antd'
import { PreviewContainer } from './grid-columns/preview-container'
import { type ApiAssetsGetCollection, type ApiAssetsGetCollectionItem } from '@Pimcore/modules/asset/asset-api'
import { useTranslation } from 'react-i18next'

interface GridContainerProps {
assets: ApiAssetsGetCollection
}

const GridContainer = (props: GridContainerProps): React.JSX.Element => {
const { assets } = props
const { t } = useTranslation()
const columnHelper = createColumnHelper<ApiAssetsGetCollectionItem>()

const columns = [
columnHelper.accessor('fullPath', {
header: t('asset.asset-editor-tabs.list.columns.preview'),
cell: info => {
if (info.row.original.type !== 'image') {
return <></>
}

return <PreviewContainer cellInfo={info} />
},
id: 'preview',
size: 110
}),

columnHelper.accessor('id', {
header: t('asset.asset-editor-tabs.list.columns.id')
}),

columnHelper.accessor('type', {
header: t('asset.asset-editor-tabs.list.columns.type')
}),

columnHelper.accessor('fullPath', {
header: t('asset.asset-editor-tabs.list.columns.fullPath'),
cell: info => <Tag bordered={false} color='processing'>{info.getValue()!}</Tag>,
id: 'fullPath',
size: 300
}),

columnHelper.accessor('creationDate', {
header: t('asset.asset-editor-tabs.list.columns.creationDate'),
cell: info => <FormattedDate timestamp={info.getValue() as number * 1000} />
}),

columnHelper.accessor('modificationDate', {
header: t('asset.asset-editor-tabs.list.columns.modificationDate'),
cell: info => <FormattedDate timestamp={info.getValue() as number * 1000} />
})
]

return (
<Grid data={assets} columns={columns} resizeable />
)
}

export { GridContainer }
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react'
import { GridToolbarView } from './grid-toolbar-view'
import { Pagination } from 'antd'

interface GridToolbarContainerProps {
pager: {
total: number
pageSize: number
current: number
onChange: (page: number, pageSize: number) => void
}
}

const GridToolbarContainer = (props: GridToolbarContainerProps): React.JSX.Element => {
const { pager } = props

return (
<GridToolbarView
renderPagination={
<Pagination
total={pager.total}
showTotal={(total) => `Total ${total} items`} // @todo translation
defaultPageSize={pager.pageSize}
current={pager.current}
onChange={pager.onChange}
pageSizeOptions={['10', '20', '50', '100']}
/>
}
/>
)
}

export { GridToolbarContainer }
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createStyles } from 'antd-style'

export const useStyles = createStyles(({ css, token }) => {
return {
GridToolbar: css`
display: flex;
justify-content: space-between;
background-color: ${token.colorBgToolbar};
border-top: 1px solid ${token.colorBorderTertiary};
padding-right: ${token.paddingSM}px;
padding-left: ${token.paddingXS}px;
height: ${token.sizeXXL}px;
align-items: center;
justify-content: space-between;
`
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { type ReactNode } from 'react'
import { useStyles } from './grid-toolbar-view.styles'

export interface GridToolbarViewProps {
renderPagination: ReactNode
}

const GridToolbarView = (props: GridToolbarViewProps): React.JSX.Element => {
const { styles } = useStyles()

return (
<div className={styles.GridToolbar}>
<div /> {/* @todo tools */}

{props.renderPagination}
</div>
)
}

export { GridToolbarView }
13 changes: 10 additions & 3 deletions assets/js/src/modules/asset/types/folder/folder-container.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import React from 'react'
import { EditorTabsContainer } from './editor-tabs/editor-tabs-container'
import { TabsToolbarView } from '@Pimcore/modules/element-editor/layouts/tabs-toolbar-view'

const FolderContainer = (): React.JSX.Element => {
return (
<>
<EditorTabsContainer />
</>
<TabsToolbarView
renderTabbar={
<EditorTabsContainer />
}

renderToolbar={
<div>Toolbar</div>
}
/>
)
}

Expand Down
Loading

0 comments on commit 891b281

Please sign in to comment.