Skip to content

Commit

Permalink
[Asset] Finish asset grid config save process (#891)
Browse files Browse the repository at this point in the history
* hide the save filters logic

* changed the value of date from static to dynamic

* changed the value of username from static to dynamic

* added the role api and get lists of data

* refactored the typing

* styled the switcher and fixed the icon name around the project

* styled the renderUserView

* created the UsersRolesDropdown component

* updated the UsersRolesDropdown

* updated the UsersRolesDropDown component

* added the logic into the dropdown component

* updated logic for showing selected values

* updated styles

* refactored code

* updated the UsersRolesDropdown component

* updated logic

* added the comment to  resolve it after the backend improvement has been done

* added translations

* added translations

* updated translations

* fixed style

* updated logic in the EditView component

* filtered the option list by user ID

* fixed the test code

* updated the API

* fixed the isLoading state

* fixed select

* deleted the test code

* deleted test code

* Automatic frontend build

---------

Co-authored-by: ValeriaMaltseva <[email protected]>
  • Loading branch information
ValeriaMaltseva and ValeriaMaltseva authored Jan 28, 2025
1 parent d25473c commit 658eacc
Show file tree
Hide file tree
Showing 39 changed files with 2,548 additions and 123 deletions.
3 changes: 3 additions & 0 deletions assets/build/api/openapi-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const config: ConfigFile = {
'../../js/src/core/modules/user/user-api-slice.gen.ts': {
filterEndpoints: pathMatcher(/user/i)
},
'../../js/src/core/modules/user/role/role-api-slice.gen.ts': {
filterEndpoints: pathMatcher(/role/i)
},
'../../js/src/core/modules/element/editor/shared-tab-manager/tabs/versions/version-api-slice.gen.ts': {
filterEndpoints: pathMatcher(/version/i)
},
Expand Down
9 changes: 6 additions & 3 deletions assets/js/src/core/app/api/pimcore/tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export const tagNames = {
DEPENDENCIES: 'DEPENDENCIES',
NOTES_AND_EVENTS: 'NOTES_AND_EVENTS',
AVAILABLE_TAGS: 'AVAILABLE_TAGS',
ELEMENT_TAGS: 'ELEMENT_TAGS'
ELEMENT_TAGS: 'ELEMENT_TAGS',
ROLE: 'ROLE'
}

export const providingTags = {
Expand Down Expand Up @@ -74,7 +75,8 @@ export const providingTags = {
ELEMENT_NOTES_AND_EVENTS: (elementType: ElementType, id: number) => [getElementDetailTag(elementType, id), tagNames.NOTES_AND_EVENTS],
NOTES_AND_EVENTS_ID: (id: number) => [tagNames.NOTES_AND_EVENTS, { type: tagNames.NOTES_AND_EVENTS, id }],
ELEMENT_TAGS: (elementType: ElementType, id: number) => [getElementDetailTag(elementType, id), { type: tagNames.ELEMENT_TAGS, id }],
AVAILABLE_TAGS: () => [tagNames.AVAILABLE_TAGS]
AVAILABLE_TAGS: () => [tagNames.AVAILABLE_TAGS],
ROLE: () => [tagNames.ROLE]
}

export const invalidatingTags = {
Expand All @@ -101,7 +103,8 @@ export const invalidatingTags = {
VERSIONS_DETAIL: (id: number) => [{ type: tagNames.VERSIONS, id }],
ELEMENT_NOTES_AND_EVENTS: (elementType: ElementType, id: number) => [tagNames.NOTES_AND_EVENTS],
ELEMENT_TAGS: (elementType: ElementType, id: number) => [{ type: tagNames.ELEMENT_TAGS, id }],
AVAILABLE_TAGS: () => [tagNames.AVAILABLE_TAGS]
AVAILABLE_TAGS: () => [tagNames.AVAILABLE_TAGS],
ROLE: () => [tagNames.ROLE]
}

const getElementDetailTag = (elementType: ElementType, id: number): Tag | undefined => {
Expand Down
6 changes: 3 additions & 3 deletions assets/js/src/core/components/menu/menu.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const MOCK_DEFAULT_DATA: IMenuProps = {
{
key: 'sub1',
label: 'Navigation One',
icon: <Icon value='user-01' />,
icon: <Icon value='user' />,
children: [
{
key: 'g1',
Expand All @@ -48,7 +48,7 @@ const MOCK_DEFAULT_DATA: IMenuProps = {
{
key: 'sub2',
label: 'Navigation Two',
icon: <Icon value='user-01' />,
icon: <Icon value='user' />,
children: [
{ key: '5', label: 'Option 5' },
{ key: '6', label: 'Option 6' },
Expand All @@ -68,7 +68,7 @@ const MOCK_DEFAULT_DATA: IMenuProps = {
{
key: 'sub4',
label: 'Navigation Three',
icon: <Icon value='user-01' />,
icon: <Icon value='user' />,
children: [
{ key: '9', label: 'Option 9' },
{ key: '10', label: 'Option 10' },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* 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 useStyles = createStyles(({ token, css }) => {
return {
dropdown: css`
position: absolute;
top: 35px;
width: 360px;
background-color: ${token.colorBgContainer};
box-shadow: ${token.boxShadowSecondary};
z-index: 1;
`,

tabs: css`
.ant-tabs-nav-list {
justify-content: space-around;
width: 100%;
}
.ant-tabs-ink-bar {
width: 50% !important;
}
.ant-tabs-content-holder {
padding: ${token.paddingXS}px;
}
`,

btnGroupWrapper: css`
display: flex;
justify-content: flex-end;
padding: 7px ${token.paddingXS}px;
`
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
/**
* 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, { useState, type ReactNode } from 'react'
import { useTranslation } from 'react-i18next'
import { isEmpty } from 'lodash'
import { useListGridConfig } from '@Pimcore/modules/asset/editor/types/folder/tab-manager/tabs/list/hooks/use-list'
import { type ITabsProps, Tabs } from '@Pimcore/components/tabs/tabs'
import { Select } from '@Pimcore/components/select/select'
import { Text } from '@Pimcore/components/text/text'
import { Flex } from '@Pimcore/components/flex/flex'
import { Icon } from '@Pimcore/components/icon/icon'
import { ButtonGroup } from '@Pimcore/components/button-group/button-group'
import { Button } from '@Pimcore/components/button/button'
import { useUser } from '@Pimcore/modules/auth/hooks/use-user'
import type { RoleGetCollectionApiResponse } from '@Pimcore/modules/user/role/role-api-slice.gen'
import type { UserGetCollectionApiResponse } from '@Pimcore/modules/auth/user/user-api-slice.gen'
import { useStyles } from './users-roles-dropdown.styles'

interface IUsersRolesDropdownProps {
roleList?: RoleGetCollectionApiResponse
userList?: UserGetCollectionApiResponse
handleClose: () => void
}

interface IRenderSelectProps {
options?: Array<{ value: string, label: ReactNode }>
placeholder: string
handleOnChange: any
selectedOptions: number[]
}

export const UsersRolesDropdown = ({ userList, roleList, handleClose }: IUsersRolesDropdownProps): React.JSX.Element => {
const { gridConfig, setGridConfig } = useListGridConfig()
const userData = useUser()

const initialSharedUsers = gridConfig?.sharedUsers as number[]
const initialSharedRoles = gridConfig?.sharedRoles as number[]

const [sharedUsersList, setSharedUsersList] = useState<number[]>(initialSharedUsers ?? [])
const [sharedRolesList, setSharedRolesList] = useState<number[]>(initialSharedRoles ?? [])

const { t } = useTranslation()
const { styles } = useStyles()

const handleChangeSharedUsers = (usersIdList: number[]): void => {
setSharedUsersList(usersIdList)
}

const handleChangeSharedRoles = (rolesIdList: number[]): void => {
setSharedRolesList(rolesIdList)
}

const handleApplyChanges = (): void => {
if (!isEmpty(gridConfig)) {
setGridConfig({
...gridConfig,
shareGlobal: false,
sharedUsers: sharedUsersList,
sharedRoles: sharedRolesList
})

handleClose()
}
}

const renderLabel = ({ labelName, iconName }: { labelName?: string, iconName: string }): React.JSX.Element => (
<Flex
align="center"
gap="mini"
>
<Icon value={ iconName } />
<Text>{labelName}</Text>
</Flex>
)

const renderSelect = ({ options, selectedOptions, placeholder, handleOnChange }: IRenderSelectProps): React.JSX.Element => (
<Select
mode="multiple"
onChange={ handleOnChange }
optionFilterProp="value"
options={ options }
placeholder={ t(placeholder) }
showSearch
value={ selectedOptions }
/>
)

const renderUsers = (): React.JSX.Element => {
const options = userList?.items
?.filter(item => userData?.id !== item.id)
?.map((item, index) => ({
value: `${index}-${item?.username}`,
label: renderLabel({ labelName: item?.username, iconName: 'user' })
}))

return renderSelect({
options,
selectedOptions: sharedUsersList,
placeholder: 'user-management.user.search',
handleOnChange: handleChangeSharedUsers
})
}

const renderRoles = (): React.JSX.Element => {
const options = roleList?.items?.map((item, index) => ({
value: `${index}-${item?.name}`,
label: renderLabel({ labelName: item?.name, iconName: 'shield' })
}))

return renderSelect({
options,
selectedOptions: sharedRolesList,
placeholder: 'user-management.role.search',
handleOnChange: handleChangeSharedRoles
})
}

const tabItems: ITabsProps['items'] = [
{
key: 'users',
label: t('user-management.key-bindings.users'),
children: renderUsers()
},
{
key: 'roles',
label: t('user-management.key-bindings.roles'),
children: renderRoles()
}
]

return (
<div className={ styles.dropdown }>
<Tabs
centered
className={ styles.tabs }
items={ tabItems }
/>
<div className={ styles.btnGroupWrapper }>
<ButtonGroup
items={ [
<Button
key="cancel"
onClick={ handleClose }
>
{t('button.cancel-edits')}
</Button>,
<Button
key="apply"
onClick={ handleApplyChanges }
type="primary"
>
{t('button.apply')}
</Button>
] }
/>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ const defaultTheme = {
Colors: {
Neutral: {
Fill: {
colorFill: 'rgba(215, 199, 236, 0.60)'
colorFill: 'rgba(215, 199, 236, 0.60)',
colorFillTertiary: '#f5f5f5'
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* 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 useStyles = createStyles(({ css, token }) => {
return {
label: css`
color: ${token.colorTextLabel};
`,

icon: css`
color: ${token.colorTextLabel};
`,

updateButton: css`
color: ${token.Button.defaultColor};
.pimcore-icon {
color: ${token.Button.defaultColor};
}
&:hover {
cursor: pointer;
}
`,

updateButtonText: css`
color: ${token.Button.defaultColor};
`,

tag: css`
.ant-tag {
background-color: ${token.Colors.Neutral.Fill.colorFillTertiary};
}
`
}
})
Loading

0 comments on commit 658eacc

Please sign in to comment.