Skip to content
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
34 changes: 17 additions & 17 deletions apps/sensenet/src/application-paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,28 @@ type RoutesWithContentBrowser = keyof Pick<
type RoutesWithActionParam = keyof Pick<typeof PATHS, 'savedQueries' | 'localization' | 'configuration' | 'webhooks'>

type Options =
| { path: (typeof PATHS)['events']['appPath']; params?: { eventGuid: string;[index: string]: string } }
| { path: (typeof PATHS)['events']['appPath']; params?: { eventGuid: string; [index: string]: string } }
| {
path: (typeof PATHS)[RoutesWithContentBrowser]['appPath']
params: { browseType: (typeof BrowseType)[number]; action?: string;[index: string]: string | undefined }
}
path: (typeof PATHS)[RoutesWithContentBrowser]['appPath']
params: { browseType: (typeof BrowseType)[number]; action?: string; [index: string]: string | undefined }
}
| {
path: (typeof PATHS)['custom']['appPath']
params: {
browseType: (typeof BrowseType)[number]
path: string
action?: string
[index: string]: string | undefined
path: (typeof PATHS)['custom']['appPath']
params: {
browseType: (typeof BrowseType)[number]
path: string
action?: string
[index: string]: string | undefined
}
}
}
| {
path: (typeof PATHS)[RoutesWithActionParam]['appPath']
params?: { action: string;[index: string]: string }
}
path: (typeof PATHS)[RoutesWithActionParam]['appPath']
params?: { action: string; [index: string]: string }
}
| {
path: (typeof PATHS)['settings']['appPath']
params?: { submenu: SettingsItemType;[index: string]: string | SettingsItemType }
}
path: (typeof PATHS)['settings']['appPath']
params?: { submenu: SettingsItemType; [index: string]: string | SettingsItemType }
}

export const resolvePathParams = ({ path, params }: Options) => {
let currentPath: string = path
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReactClientFieldSetting, ReferenceGrid as SnReferenceGrid } from '@sensenet/controls-react'
import { clsx } from 'clsx'
import React from 'react'
import { PATHS } from '../../application-paths'
import { useGlobalStyles } from '../../globalStyles'
import { DialogTitle } from '../dialogs/dialog-title'
import { Icon } from '../Icon'
Expand All @@ -14,6 +15,7 @@ export const ReferenceGrid: React.FC<ReactClientFieldSetting> = (props) => {
dialogTitleComponent={DialogTitle}
renderPickerIcon={(item) => <Icon item={item} />}
pickerClasses={{ cancelButton: globalClasses.cancelButton }}
paths={PATHS}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/* eslint-disable require-jsdoc */
import {
Avatar,
createStyles,
Icon,
IconButton,
ListItem,
ListItemAvatar,
ListItemIcon,
ListItemSecondaryAction,
ListItemText,
makeStyles,
} from '@material-ui/core'
import { InsertDriveFile } from '@material-ui/icons'
import { Repository } from '@sensenet/client-core'
Expand All @@ -15,6 +18,42 @@ import { GenericContent, Image, User } from '@sensenet/default-content-types'
import React from 'react'
import { renderIconDefault } from '../icon'

export type PathConfig = {
appPath: string
snPath?: string
}

export type Paths = Record<string, PathConfig>

function getAppPathAndContent(PATHS: Paths, targetPath: string) {
const matches = Object.entries(PATHS)
.filter(([, config]) => config.snPath && targetPath.startsWith(config.snPath))
.sort((a, b) => b[1].snPath!.length - a[1].snPath!.length)

if (!matches[0]) return undefined

const [, config] = matches[0]
const contentePath = targetPath.substring(config.snPath!.length)

return {
appPath: config.appPath,
contentePath,
}
}

function buildCustomPath(path: string, action: string | undefined, contentePath: string) {
const customPath = path
.replace(':browseType', 'explorer')
.replace('/:path', '') // Remove the path parameter
.replace(':action?', action || 'default')

const url = new URL(window.location.origin)
url.pathname = customPath
url.searchParams.set('content', contentePath)

return url.toString()
}

interface DefaultItemTemplateProps {
content: GenericContent
remove?: (id: number) => void
Expand All @@ -24,13 +63,29 @@ interface DefaultItemTemplateProps {
repository?: Repository
multiple: boolean
renderIcon?: (name: string) => JSX.Element
paths: Paths
}

const useStyles = makeStyles(() =>
createStyles({
referenceItemText: {
textAlign: 'left',
paddingRight: 15,
cursor: 'pointer',
'&[data-clickable="true"]:hover': {
textDecoration: 'underline',
},
},
}),
)

/**
* Represents a default renderer for reference grid row
*/
export const DefaultItemTemplate: React.FC<DefaultItemTemplateProps> = (props) => {
const { content, repository } = props
const { content, repository, paths } = props

const classes = useStyles()

const renderIcon = (item: GenericContent | User | Image) => {
if (repository?.schemas.isContentFromType<User>(item, 'User')) {
Expand Down Expand Up @@ -107,7 +162,26 @@ export const DefaultItemTemplate: React.FC<DefaultItemTemplateProps> = (props) =
return (
<ListItem style={props.actionName === 'browse' ? { padding: 0 } : undefined} key={content.Id} button={false}>
{content.Type ? renderIcon(content) : null}
<ListItemText primary={content.DisplayName} style={{ textAlign: 'left', paddingRight: 15 }} />
<ListItemText
onClick={() => {
if (content.Id === -1 || !paths) {
return
}
const referencedItemPaths = getAppPathAndContent(paths, content.Path)

if (!referencedItemPaths) {
return
}

const { appPath, contentePath } = referencedItemPaths

const fullUrl = buildCustomPath(appPath, props.actionName, contentePath)
window.location.href = fullUrl
}}
primary={content.DisplayName}
className={classes.referenceItemText}
data-clickable={content.Id !== -1}
/>
{props.actionName && props.actionName !== 'browse' && !props.readOnly ? (
<ListItemSecondaryAction>
{content.Id > 0 ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { PickerClassKey } from '@sensenet/pickers-react'
import React, { ElementType, useCallback, useEffect, useMemo, useState } from 'react'
import { ReactClientFieldSetting } from '../client-field-setting'
import { defaultLocalization } from '../localization'
import { DefaultItemTemplate } from './default-item-template'
import { DefaultItemTemplate, Paths } from './default-item-template'
import { ReferencePicker } from './reference-picker'

const styles = {
Expand All @@ -38,6 +38,7 @@ interface ReferenceGridProps extends ReactClientFieldSetting<ReferenceFieldSetti
dialogTitleComponent?: ElementType
renderPickerIcon?: (item: any) => JSX.Element
pickerClasses?: PickerClassKey
paths: Paths
}

export const ReferenceGrid: React.FC<ReferenceGridProps> = (props) => {
Expand Down Expand Up @@ -185,7 +186,11 @@ export const ReferenceGrid: React.FC<ReferenceGridProps> = (props) => {
case 'new':
case 'edit':
return (
<FormControl style={styles.root as any} component={'fieldset' as 'div'} required={props.settings.Compulsory}>
<FormControl
data-test="edit-refence"
style={styles.root as any}
component={'fieldset' as 'div'}
required={props.settings.Compulsory}>
<TextField
name={props.content?.Name}
autoComplete="off"
Expand All @@ -211,6 +216,7 @@ export const ReferenceGrid: React.FC<ReferenceGridProps> = (props) => {
repository={props.repository}
multiple={props.settings.AllowMultiple ? props.settings.AllowMultiple : false}
renderIcon={props.renderIcon}
paths={props.paths}
/>
))}
{!props.settings.ReadOnly ? (
Expand All @@ -221,6 +227,7 @@ export const ReferenceGrid: React.FC<ReferenceGridProps> = (props) => {
repository={props.repository}
multiple={props.settings.AllowMultiple ? props.settings.AllowMultiple : false}
renderIcon={props.renderIcon}
paths={props.paths}
/>
) : null}
</List>
Expand Down Expand Up @@ -271,6 +278,7 @@ export const ReferenceGrid: React.FC<ReferenceGridProps> = (props) => {
repository={props.repository}
multiple={props.settings.AllowMultiple ? props.settings.AllowMultiple : false}
renderIcon={props.renderIcon}
paths={props.paths}
/>
))
) : (
Expand Down