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

Added options to context-menu #733

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 18 additions & 11 deletions assets/js/src/core/components/preview-card/preview-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* @license https://github.com/pimcore/studio-ui-bundle/blob/1.x/LICENSE.md POCL and PCL
*/

import { Button, Card, Checkbox } from 'antd'
import React, { useState } from 'react'
import { Button, Card, Checkbox, type MenuRef } from 'antd'
import React, { useRef, useState } from 'react'
import { useStyle } from './preview-card.styles'
import Meta from 'antd/es/card/Meta'
import { Icon } from '../icon/icon'
Expand All @@ -32,12 +32,11 @@ interface PreviewCardProps {
onClick?: (e) => void
}

export const PreviewCard = ({
name, dropdownItems, imgSrc, size = SizeTypes.SMALL, onClick
}: PreviewCardProps
): React.JSX.Element => {
export const PreviewCard = (props: PreviewCardProps): React.JSX.Element => {
const { size = SizeTypes.SMALL } = props
const { styles } = useStyle()
const [selected, setSelected] = useState(false)
const dropdownMenuRef = useRef<MenuRef>(null)

let classCard: string = ''
let classImg: string = 'img'
Expand All @@ -62,13 +61,20 @@ export const PreviewCard = ({
cover={
<div className={ classImgDiv }>
<PimcoreImage
alt={ name }
alt={ props.name }
className={ classImg }
src={ imgSrc }
src={ props.imgSrc }
/>
</div>
}
onClick={ onClick }
onClick={ (event) => {
if (
dropdownMenuRef.current === null ||
dropdownMenuRef.current.menu?.list.contains(event.target as Node) === false
) {
props.onClick?.(event)
}
} }
>
<Checkbox
checked={ selected }
Expand All @@ -78,8 +84,9 @@ export const PreviewCard = ({
/>
<Dropdown
menu={ {
items: dropdownItems
items: props.dropdownItems
} }
menuRef={ dropdownMenuRef }
placement='bottomLeft'
>
<Button
Expand All @@ -93,7 +100,7 @@ export const PreviewCard = ({
/>
</Dropdown>
<Meta
title={ name }
title={ props.name }
/>
</Card>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { useAssetHelper } from '@Pimcore/modules/asset/hooks/use-asset-helper'
import { type AssetGetTreeApiResponse } from '@Pimcore/modules/asset/asset-api-slice-enhanced'
import { type DropdownProps } from '@Pimcore/components/dropdown/dropdown'
import { Icon } from '@Pimcore/components/icon/icon'
import { useRename } from '@Pimcore/modules/element/actions/rename/use-rename'
import { useDelete } from '@Pimcore/modules/element/actions/delete/use-delete'

interface FlexContainerProps {
assets: AssetGetTreeApiResponse
Expand All @@ -30,34 +32,8 @@ const FlexContainer = (props: FlexContainerProps): React.JSX.Element => {
const { assets } = props
const { t } = useTranslation()
const { openAsset } = useAssetHelper()

const dropdownItems: DropdownProps['menu']['items'] = [
{
key: 'locate-in-tree',
icon: <Icon value="target" />,
label: t('preview-card.locate-in-tree')
},
{
key: 'info',
icon: <Icon value="info-circle-outlined" />,
label: t('info')
},
{
key: 'rename',
icon: <Icon value="rich-edit" />,
label: t('preview-card.rename')
},
{
key: 'download-zip',
icon: <Icon value="download-02" />,
label: t('preview-card.download-zip')
},
{
key: 'delete',
icon: <Icon value="trash" />,
label: t('preview-card.delete')
}
]
const { renameContextMenuItem } = useRename('asset')
const { deleteContextMenuItem } = useDelete('asset')

const cards: ReactNode[] = []
assets.items.forEach((asset) => {
Expand All @@ -69,6 +45,23 @@ const FlexContainer = (props: FlexContainerProps): React.JSX.Element => {
})
}

const dropdownItems: DropdownProps['menu']['items'] = [
{
key: 'locate-in-tree',
icon: <Icon value="target" />,
label: t('preview-card.locate-in-tree'),
hidden: true
},
{
key: 'info',
icon: <Icon value="info-circle-outlined" />,
label: t('info'),
hidden: true
},
renameContextMenuItem(asset),
deleteContextMenuItem(asset)
]

if ('imageThumbnailPath' in asset && asset.imageThumbnailPath !== undefined && asset.imageThumbnailPath !== null) {
cards.push(
<PreviewCard
Expand Down
30 changes: 15 additions & 15 deletions assets/js/src/core/modules/asset/tree/context-menu/context-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export const AssetTreeContextMenu = (props: TreeContextMenuProps): React.JSX.Ele

const uploadContext = React.useContext(UploadContext)!
const { createZipDownloadContextMeuItem } = useZipDownload({ type: 'folder' })
const { addFolderContextMenuItem } = useAddFolder('asset')
const { renameContextMenuItem } = useRename('asset')
const { deleteContextMenuItem } = useDelete('asset')
const { addFolderTreeContextMenuItem } = useAddFolder('asset')
const { renameTreeContextMenuItem } = useRename('asset')
const { deleteTreeContextMenuItem } = useDelete('asset')
const { refreshTreeContextMenuItem } = useRefreshTree('asset')
const { copyContextMenuItem, cutContextMenuItem, pasteContextMenuItem, pasteCutContextMenuItem } = useCopyPaste('asset')
const { lockContextMenuItem, lockAndPropagateContextMenuItem, unlockContextMenuItem, unlockAndPropagateContextMenuItem } = useLock('asset')
const { copyTreeContextMenuItem, cutTreeContextMenuItem, pasteTreeContextMenuItem, pasteCutContextMenuItem } = useCopyPaste('asset')
const { lockTreeContextMenuItem, lockAndPropagateTreeContextMenuItem, unlockTreeContextMenuItem, unlockAndPropagateTreeContextMenuItem } = useLock('asset')
const node = props.node

useEffect(() => {
Expand Down Expand Up @@ -81,13 +81,13 @@ export const AssetTreeContextMenu = (props: TreeContextMenuProps): React.JSX.Ele
}
]
},
addFolderContextMenuItem(props.node),
renameContextMenuItem(props.node),
copyContextMenuItem(props.node),
pasteContextMenuItem(props.node),
cutContextMenuItem(props.node),
addFolderTreeContextMenuItem(props.node),
renameTreeContextMenuItem(props.node),
copyTreeContextMenuItem(props.node),
pasteTreeContextMenuItem(props.node),
cutTreeContextMenuItem(props.node),
pasteCutContextMenuItem(parseInt(props.node.id)),
deleteContextMenuItem(props.node),
deleteTreeContextMenuItem(props.node),
createZipDownloadContextMeuItem(props.node),
{
label: t('element.tree.context-menu.advanced'),
Expand All @@ -100,10 +100,10 @@ export const AssetTreeContextMenu = (props: TreeContextMenuProps): React.JSX.Ele
icon: <Icon value={ 'lock-01' } />,
hidden: !checkElementPermission(props.node.permissions, 'publish') || props.node.isLocked,
children: [
lockContextMenuItem(props.node),
lockAndPropagateContextMenuItem(props.node),
unlockContextMenuItem(props.node),
unlockAndPropagateContextMenuItem(props.node)
lockTreeContextMenuItem(props.node),
lockAndPropagateTreeContextMenuItem(props.node),
unlockTreeContextMenuItem(props.node),
unlockAndPropagateTreeContextMenuItem(props.node)
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ export const DataObjectTreeContextMenu = (props: DataObjectTreeContextMenuProps)
const { t } = useTranslation()

const { createZipDownloadContextMeuItem } = useZipDownload({ type: 'folder' })
const { addFolderContextMenuItem } = useAddFolder('data-object')
const { renameContextMenuItem } = useRename('data-object')
const { deleteContextMenuItem } = useDelete('data-object')
const { addFolderTreeContextMenuItem } = useAddFolder('data-object')
const { renameTreeContextMenuItem } = useRename('data-object')
const { deleteTreeContextMenuItem } = useDelete('data-object')
const { refreshTreeContextMenuItem } = useRefreshTree('data-object')
const { copyContextMenuItem, cutContextMenuItem, pasteContextMenuItem, pasteCutContextMenuItem } = useCopyPaste('data-object')
const { lockContextMenuItem, lockAndPropagateContextMenuItem, unlockContextMenuItem, unlockAndPropagateContextMenuItem } = useLock('data-object')
const { copyTreeContextMenuItem, cutTreeContextMenuItem, pasteTreeContextMenuItem, pasteCutContextMenuItem } = useCopyPaste('data-object')
const { lockTreeContextMenuItem, lockAndPropagateTreeContextMenuItem, unlockTreeContextMenuItem, unlockAndPropagateTreeContextMenuItem } = useLock('data-object')

const items: DropdownMenuProps['items'] = [
addFolderContextMenuItem(props.node),
renameContextMenuItem(props.node),
copyContextMenuItem(props.node),
pasteContextMenuItem(props.node),
cutContextMenuItem(props.node),
addFolderTreeContextMenuItem(props.node),
renameTreeContextMenuItem(props.node),
copyTreeContextMenuItem(props.node),
pasteTreeContextMenuItem(props.node),
cutTreeContextMenuItem(props.node),
pasteCutContextMenuItem(parseInt(props.node.id)),
deleteContextMenuItem(props.node),
deleteTreeContextMenuItem(props.node),
createZipDownloadContextMeuItem(props.node),

{
Expand All @@ -60,10 +60,10 @@ export const DataObjectTreeContextMenu = (props: DataObjectTreeContextMenuProps)
key: 'advanced-lock',
icon: <Icon value={ 'lock-01' } />,
children: [
lockContextMenuItem(props.node),
lockAndPropagateContextMenuItem(props.node),
unlockContextMenuItem(props.node),
unlockAndPropagateContextMenuItem(props.node)
lockTreeContextMenuItem(props.node),
lockAndPropagateTreeContextMenuItem(props.node),
unlockTreeContextMenuItem(props.node),
unlockAndPropagateTreeContextMenuItem(props.node)
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ import React from 'react'
import type { TreeNodeProps } from '@Pimcore/components/element-tree/node/tree-node'
import { useRefreshTree } from '@Pimcore/modules/element/actions/refresh-tree/use-refresh-tree'
import { checkElementPermission } from '@Pimcore/modules/element/permissions/permission-helper'
import { type Element } from '@Pimcore/modules/element/element-helper'

export interface UseAddFolderHookReturn {
addFolder: (parentId: number) => void
addFolderContextMenuItem: (node: TreeNodeProps) => ItemType
addFolderTreeContextMenuItem: (node: TreeNodeProps) => ItemType
addFolderContextMenuItem: (node: Element, onFinish?: () => void) => ItemType
addFolderMutation: (parentId: number, value: string) => Promise<void>
}

Expand All @@ -34,19 +36,19 @@ export const useAddFolder = (elementType: ElementType): UseAddFolderHookReturn =
const { refreshTree } = useRefreshTree(elementType)
const [elementFolderCreateMutation] = useElementFolderCreateMutation()

const addFolder = (parentId: number): void => {
const addFolder = (parentId: number, onFinish?: () => void): void => {
modal.input({
title: t('element.add-folder'),
label: t('element.add-folder.label'),
rule: {
required: true,
message: t('element.add-folder.validation')
},
onOk: async (value: string) => { await addFolderMutation(parentId, value) }
onOk: async (value: string) => { await addFolderMutation(parentId, value, onFinish) }
})
}

const addFolderContextMenuItem = (node: TreeNodeProps): ItemType => {
const addFolderTreeContextMenuItem = (node: TreeNodeProps): ItemType => {
return {
label: t('element.add-folder'),
key: 'add-folder',
Expand All @@ -59,7 +61,20 @@ export const useAddFolder = (elementType: ElementType): UseAddFolderHookReturn =
}
}

const addFolderMutation = async (parentId: number, value: string): Promise<void> => {
const addFolderContextMenuItem = (node: Element, onFinish?: () => void): ItemType => {
return {
label: t('element.add-folder'),
key: 'add-folder',
icon: <Icon value={ 'folder' } />,
hidden: node.type !== 'folder' || !checkElementPermission(node.permissions!, 'create'),
onClick: () => {
addFolder(node.id)
onFinish?.()
}
}
}

const addFolderMutation = async (parentId: number, value: string, onFinish?: () => void): Promise<void> => {
const elementFolderCreateMutationTask = elementFolderCreateMutation({
parentId,
elementType,
Expand All @@ -72,13 +87,16 @@ export const useAddFolder = (elementType: ElementType): UseAddFolderHookReturn =
await elementFolderCreateMutationTask

refreshTree(parentId)

onFinish?.()
} catch (error) {
console.error('Error creating folder', error)
}
}

return {
addFolder,
addFolderTreeContextMenuItem,
addFolderContextMenuItem,
addFolderMutation
}
Expand Down
Loading