@@ -5,13 +5,12 @@ import { getParentUrl, flattenToAppURL } from '@plone/volto/helpers/Url/Url';
55import debounce from 'lodash/debounce' ;
66import { useClient } from '@plone/volto/hooks' ;
77import config from '@plone/volto/registry' ;
8- import { useState , useEffect } from 'react' ;
8+ import { useEffect } from 'react' ;
99import { createPortal } from 'react-dom' ;
1010import { FormattedMessage , defineMessages , useIntl } from 'react-intl' ;
1111import { useDispatch , useSelector } from 'react-redux' ;
1212import { Link , useParams } from 'react-router-dom' ;
13- import Unauthorized from '@plone/volto/components/theme/Unauthorized/Unauthorized' ;
14- import { listRoles } from '@plone/volto/actions/roles/roles' ;
13+ import Error from '@plone/volto/components/theme/Error/Error' ;
1514
1615import backSVG from '@plone/volto/icons/back.svg' ;
1716import searchSVG from '@plone/volto/icons/zoom.svg' ;
@@ -35,11 +34,9 @@ type RouteProps = {
3534
3635const BlockTypeControlpanel = ( props : RouteProps ) => {
3736 const { location } = props ;
38- const [ isUserManager , setIsUserManager ] = useState ( false ) ;
3937 const params = useParams < { id : string } > ( ) ;
4038 const id = params . id ;
4139 const intl = useIntl ( ) ;
42- const roles = useSelector ( ( state ) => state . roles . roles ) ;
4340 const blockTypes = useSelector ( ( state ) => state . blockTypes ) ;
4441 const isClient = useClient ( ) ;
4542 const dispatch = useDispatch ( ) ;
@@ -48,95 +45,102 @@ const BlockTypeControlpanel = (props: RouteProps) => {
4845 config . blocks . blocksConfig [ id as keyof typeof config . blocks . blocksConfig ] ;
4946
5047 useEffect ( ( ) => {
51- dispatch ( listRoles ( ) ) ;
52- } , [ ] ) ;
53-
54- useEffect ( ( ) => {
55- if ( roles . length > 0 && roles . map ( ( role ) => role . id === 'Manager' ) ) {
56- setIsUserManager ( true ) ;
57- dispatch ( getBlockTypes ( id ) ) ;
58- }
59- } , [ roles , id ] ) ;
48+ dispatch ( getBlockTypes ( id ) ) ;
49+ } , [ dispatch , id ] ) ;
6050
6151 const onChangeSearch = ( value : string ) => {
6252 dispatch ( getBlockTypes ( id , value ) ) ;
6353 } ;
6454
6555 const debouncedSearch = debounce ( onChangeSearch , 600 ) ;
6656
67- return isUserManager ? (
68- < div id = "page-block_type" className = "ui container controlpanel-block_type" >
69- < h1 >
70- < FormattedMessage
71- id = "block-type"
72- defaultMessage = "{title}"
73- values = { { title : block . title } }
74- />
75- </ h1 >
76- < form className = "search" onSubmit = { ( e ) => e . preventDefault ( ) } >
77- < input
78- type = "text"
79- placeholder = "Search"
80- onChange = { ( e ) => debouncedSearch ( e . target . value ) }
81- />
82- < Icon
83- name = { searchSVG }
84- size = "16px"
85- title = { intl . formatMessage ( messages . search ) }
86- />
87- </ form >
88- { blockTypes . items ?. length > 0 ? (
89- < table className = "table" >
90- < thead className = "table-header" >
91- < tr className = "table-row" >
92- < th className = "table-heading" >
93- < FormattedMessage id = "Title" defaultMessage = "Title" />
94- </ th >
95- < th className = "table-heading" >
96- < FormattedMessage id = "Occurrence" defaultMessage = "Occurrence" />
97- </ th >
98- </ tr >
99- </ thead >
100- < tbody className = "table-body" >
101- { blockTypes . items . map ( ( item ) => (
102- < tr key = { item [ '@id' ] } className = "table-row" >
103- < td className = "table-cell" >
104- < a href = { item [ '@id' ] } > { item . title } </ a >
105- < span > { flattenToAppURL ( item [ '@id' ] ) || '/' } </ span >
106- </ td >
107- < td className = "table-cell" > { item . count } </ td >
57+ if ( blockTypes . loading ) {
58+ return < div > Loading...</ div > ;
59+ }
60+
61+ if ( blockTypes ?. error ?. status ) {
62+ return < Error error = { blockTypes . error } /> ;
63+ }
64+
65+ return (
66+ blockTypes . loaded && (
67+ < div
68+ id = "page-block_type"
69+ className = "ui container controlpanel-block_type"
70+ >
71+ < h1 >
72+ < FormattedMessage
73+ id = "block-type"
74+ defaultMessage = "{title}"
75+ values = { { title : block . title } }
76+ />
77+ </ h1 >
78+ < form className = "search" onSubmit = { ( e ) => e . preventDefault ( ) } >
79+ < input
80+ type = "text"
81+ placeholder = "Search"
82+ onChange = { ( e ) => debouncedSearch ( e . target . value ) }
83+ />
84+ < Icon
85+ name = { searchSVG }
86+ size = "16px"
87+ title = { intl . formatMessage ( messages . search ) }
88+ />
89+ </ form >
90+ { blockTypes . items ?. length > 0 ? (
91+ < table className = "table" >
92+ < thead className = "table-header" >
93+ < tr className = "table-row" >
94+ < th className = "table-heading" >
95+ < FormattedMessage id = "Title" defaultMessage = "Title" />
96+ </ th >
97+ < th className = "table-heading" >
98+ < FormattedMessage
99+ id = "Occurrence"
100+ defaultMessage = "Occurrence"
101+ />
102+ </ th >
108103 </ tr >
109- ) ) }
110- </ tbody >
111- </ table >
112- ) : (
113- < FormattedMessage
114- id = "no-blocks-found"
115- defaultMessage = "No items found for type: {type}."
116- values = { { type : id } }
117- />
118- ) }
119- { isClient &&
120- createPortal (
121- < Toolbar
122- pathname = { pathname }
123- hideDefaultViewButtons
124- inner = {
125- < Link to = { getParentUrl ( pathname ) } className = "item" >
126- < Icon
127- name = { backSVG }
128- className = "contents circled"
129- size = "30px"
130- title = { intl . formatMessage ( messages . back ) }
131- />
132- </ Link >
133- }
134- /> ,
135- document . getElementById ( 'toolbar' ) as HTMLElement ,
104+ </ thead >
105+ < tbody className = "table-body" >
106+ { blockTypes . items . map ( ( item ) => (
107+ < tr key = { item [ '@id' ] } className = "table-row" >
108+ < td className = "table-cell" >
109+ < a href = { item [ '@id' ] } > { item . title } </ a >
110+ < span > { flattenToAppURL ( item [ '@id' ] ) || '/' } </ span >
111+ </ td >
112+ < td className = "table-cell" > { item . count } </ td >
113+ </ tr >
114+ ) ) }
115+ </ tbody >
116+ </ table >
117+ ) : (
118+ < FormattedMessage
119+ id = "no-blocks-found"
120+ defaultMessage = "No items found for type: {type}."
121+ values = { { type : id } }
122+ />
136123 ) }
137- </ div >
138- ) : (
139- < Unauthorized pathname = { pathname } staticContext = { props . staticContext } />
124+ { isClient &&
125+ createPortal (
126+ < Toolbar
127+ pathname = { pathname }
128+ hideDefaultViewButtons
129+ inner = {
130+ < Link to = { getParentUrl ( pathname ) } className = "item" >
131+ < Icon
132+ name = { backSVG }
133+ className = "contents circled"
134+ size = "30px"
135+ title = { intl . formatMessage ( messages . back ) }
136+ />
137+ </ Link >
138+ }
139+ /> ,
140+ document . getElementById ( 'toolbar' ) as HTMLElement ,
141+ ) }
142+ </ div >
143+ )
140144 ) ;
141145} ;
142146
0 commit comments