From d07d748b668e834722cfc963c70e8ba2a773a4fd Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Fri, 6 Oct 2023 13:45:35 +0200 Subject: [PATCH 1/5] Added object browser icon view. --- .../manage/Sidebar/ObjectBrowserBody.jsx | 180 ++++++++++------ .../manage/Sidebar/ObjectBrowserNav.jsx | 198 +++++++++++------- .../extras/objectbrowser-widget.less | 82 ++++++++ 3 files changed, 323 insertions(+), 137 deletions(-) diff --git a/src/components/manage/Sidebar/ObjectBrowserBody.jsx b/src/components/manage/Sidebar/ObjectBrowserBody.jsx index 2a88c9f981..5d7d2201dc 100644 --- a/src/components/manage/Sidebar/ObjectBrowserBody.jsx +++ b/src/components/manage/Sidebar/ObjectBrowserBody.jsx @@ -21,6 +21,8 @@ import clearSVG from '@plone/volto/icons/clear.svg'; import searchSVG from '@plone/volto/icons/zoom.svg'; import linkSVG from '@plone/volto/icons/link.svg'; import homeSVG from '@plone/volto/icons/home.svg'; +import iconsSVG from '@plone/volto/icons/apps.svg'; +import listSVG from '@plone/volto/icons/list-bullet.svg'; import ObjectBrowserNav from '@plone/volto/components/manage/Sidebar/ObjectBrowserNav'; @@ -132,6 +134,7 @@ class ObjectBrowserBody extends Component { this.props.mode === 'image' ? this.props.searchableTypes || config.settings.imageObjects : this.props.searchableTypes, + view: this.props.mode === 'image' ? 'icons' : 'list', }; this.searchInputRef = React.createRef(); } @@ -201,10 +204,28 @@ class ObjectBrowserBody extends Component { showSearchInput: !prevState.showSearchInput, }), () => { - if (this.searchInputRef?.current) this.searchInputRef.current.focus(); + if (this.searchInputRef?.current) { + this.searchInputRef.current.focus(); + } else { + this.props.searchContent( + this.state.currentFolder, + { + 'path.depth': 1, + sort_on: 'getObjPositionInParent', + metadata_fields: '_all', + b_size: 1000, + }, + `${this.props.block}-${this.props.mode}`, + ); + } }, ); + toggleView = () => + this.setState((prevState) => ({ + view: prevState.view === 'icons' ? 'list' : 'icons', + })); + onSearch = (e) => { const text = flattenToAppURL(e.target.value); if (text.startsWith('/')) { @@ -365,25 +386,9 @@ class ObjectBrowserBody extends Component { */ render() { return ( - +
- {this.state.currentFolder === '/' ? ( - <> - {this.props.mode === 'image' ? ( - - ) : ( - - )} - - ) : ( - - )} {this.state.showSearchInput ? ( - ) : this.props.mode === 'image' ? ( -

- -

) : ( -

- -

+ <> + {this.state.currentFolder === '/' ? ( + <> + {this.props.mode === 'image' ? ( + + ) : ( + + )} + + ) : ( + + )} + {this.props.mode === 'image' ? ( +

+ +

+ ) : ( +

+ +

+ )} + )}
- - {this.state.currentFolder !== '/' ? ( - this.state.currentFolder.split('/').map((item, index, items) => { - return ( - - {index === 0 ? ( - this.navigateTo('/')}> - - - ) : ( - <> - - - this.navigateTo(items.slice(0, index + 1).join('/')) - } - > - {item} - - - )} - - ); - }) - ) : ( - this.navigateTo('/')}> - - - )} - + {this.props.mode === 'image' && ( + + )} + {!this.state.showSearchInput ? ( + + {this.state.currentFolder !== '/' ? ( + this.state.currentFolder + .split('/') + .map((item, index, items) => { + return ( + + {index === 0 ? ( + this.navigateTo('/')} + > + + + ) : ( + <> + + + this.navigateTo( + items.slice(0, index + 1).join('/'), + ) + } + > + {item} + + + )} + + ); + }) + ) : ( + this.navigateTo('/')}> + + + )} + + ) : ( +
+ +
+ )}
{this.props.mode === 'multiple' && ( @@ -489,6 +537,7 @@ class ObjectBrowserBody extends Component { handleClickOnItem={this.handleClickOnItem} handleDoubleClickOnItem={this.handleDoubleClickOnItem} mode={this.props.mode} + view={this.state.view} navigateTo={this.navigateTo} isSelectable={this.isSelectable} /> @@ -502,6 +551,7 @@ export default compose( connect( (state) => ({ searchSubrequests: state.search.subrequests, + lang: state.intl.locale, }), { searchContent }, ), diff --git a/src/components/manage/Sidebar/ObjectBrowserNav.jsx b/src/components/manage/Sidebar/ObjectBrowserNav.jsx index 14e7d605c1..2ef7d94c13 100644 --- a/src/components/manage/Sidebar/ObjectBrowserNav.jsx +++ b/src/components/manage/Sidebar/ObjectBrowserNav.jsx @@ -26,6 +26,7 @@ const ObjectBrowserNav = ({ handleClickOnItem, handleDoubleClickOnItem, mode, + view, navigateTo, isSelectable, }) => { @@ -45,85 +46,138 @@ const ObjectBrowserNav = ({ }; return ( - + {currentSearchResults && - currentSearchResults.items.map((item) => ( -
  • handleClickOnItem(item)} - onDoubleClick={() => handleDoubleClickOnItem(item)} - > - - - {' '} - {flattenToAppURL(item['@id'])} ( {item['@type']}) - - } - trigger={ - - - - } - /> - - {item.title} - - {item.is_folderish && mode === 'image' && ( - - )} - {item.is_folderish && (mode === 'link' || mode === 'multiple') && ( + currentSearchResults.items.map((item) => + view === 'icons' ? ( +
    { - e.stopPropagation(); - navigateTo(item['@id']); - }} + onClick={(e) => handleClickOnItem(item)} + onDoubleClick={() => handleDoubleClickOnItem(item)} + className="image-preview" + aria-label={`${intl.formatMessage(messages.select)} ${ + item.title + }`} > - - - +
    + )} +
    +
    +
    handleClickOnItem(item)} + aria-hidden="true" + > +
    + {item.title} +
    +
    - )} -
  • - ))} + + ) : ( +
  • handleClickOnItem(item)} + onDoubleClick={() => handleDoubleClickOnItem(item)} + > + + + {' '} + {flattenToAppURL(item['@id'])} ( {item['@type']}) + + } + trigger={ + + + + } + /> + + {item.title} + + {item.is_folderish && mode === 'image' && ( + + )} + {item.is_folderish && + (mode === 'link' || mode === 'multiple') && ( +
    { + e.stopPropagation(); + navigateTo(item['@id']); + }} + > + + + +
    + )} +
  • + ), + )}
    ); }; diff --git a/theme/themes/pastanaga/extras/objectbrowser-widget.less b/theme/themes/pastanaga/extras/objectbrowser-widget.less index f1217fc517..100ad3cd25 100644 --- a/theme/themes/pastanaga/extras/objectbrowser-widget.less +++ b/theme/themes/pastanaga/extras/objectbrowser-widget.less @@ -41,3 +41,85 @@ border: none !important; } } + +.object-browser { + .mode-switch { + margin-right: 8px; + cursor: pointer; + float: right; + } + + header h2 { + margin: 2px 0 !important; + } + + .searchResults { + margin-left: 20px; + font-size: 14px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + line-height: 1.5; + text-rendering: optimizeLegibility; + text-size-adjust: 100%; + } + + div.object-listing { + padding: 0; + } + + .image-wrapper { + margin: 16px; + float: left; + + img, + .icon-wrapper { + background-color: #edf1f2; + cursor: pointer; + outline: 0; + } + + .selected { + outline: solid 3px #517776 !important; + } + + img:hover, + .icon-wrapper:hover { + outline: solid 3px rgb(187, 198, 200); + } + + .image-preview, + .image-preview:hover { + display: flex; + border: 0; + border-radius: 0; + box-shadow: none; + + img { + width: 200px; + height: 200px; + object-fit: contain; + } + } + + .image-preview, + .image-title { + cursor: pointer; + text-align: center; + } + + .image-title { + margin-top: 5px; + } + + .image-title-content { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .icon-wrapper { + display: flex; + padding: 46px; + } + } +} From cbc0b884e2410e1d893a06c6fdf4ae496eb272c8 Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Fri, 6 Oct 2023 13:47:21 +0200 Subject: [PATCH 2/5] Add changelog. --- news/5279.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/5279.feature diff --git a/news/5279.feature b/news/5279.feature new file mode 100644 index 0000000000..329f8431c5 --- /dev/null +++ b/news/5279.feature @@ -0,0 +1 @@ +Add object browser icon view @robgietema \ No newline at end of file From 8656c9c02204054e9558301f602e00608dad9c27 Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Fri, 6 Oct 2023 13:51:52 +0200 Subject: [PATCH 3/5] Fix i18n. --- locales/ca/LC_MESSAGES/volto.po | 1 + locales/de/LC_MESSAGES/volto.po | 1 + locales/en/LC_MESSAGES/volto.po | 1 + locales/es/LC_MESSAGES/volto.po | 1 + locales/eu/LC_MESSAGES/volto.po | 1 + locales/fi/LC_MESSAGES/volto.po | 1 + locales/fr/LC_MESSAGES/volto.po | 1 + locales/it/LC_MESSAGES/volto.po | 1 + locales/ja/LC_MESSAGES/volto.po | 1 + locales/nl/LC_MESSAGES/volto.po | 1 + locales/pt/LC_MESSAGES/volto.po | 1 + locales/pt_BR/LC_MESSAGES/volto.po | 1 + locales/ro/LC_MESSAGES/volto.po | 1 + locales/volto.pot | 3 ++- locales/zh_CN/LC_MESSAGES/volto.po | 1 + 15 files changed, 16 insertions(+), 1 deletion(-) diff --git a/locales/ca/LC_MESSAGES/volto.po b/locales/ca/LC_MESSAGES/volto.po index 7e3dcf33e0..aba8116050 100644 --- a/locales/ca/LC_MESSAGES/volto.po +++ b/locales/ca/LC_MESSAGES/volto.po @@ -3049,6 +3049,7 @@ msgid "Search input label" msgstr "Cerca l'etiqueta d'entrada" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index 501400c73c..57d8927e3f 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -3046,6 +3046,7 @@ msgid "Search input label" msgstr "Label Suchfeld" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index 50dce32990..2789eff9ea 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -3040,6 +3040,7 @@ msgid "Search input label" msgstr "" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 595636eec5..bce56b63b9 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -3051,6 +3051,7 @@ msgid "Search input label" msgstr "Etiqueta del campo de búsqueda" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index f7e40a10b4..c16eb6378a 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -3047,6 +3047,7 @@ msgid "Search input label" msgstr "Bilaketa kutxaren etiketa" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/fi/LC_MESSAGES/volto.po b/locales/fi/LC_MESSAGES/volto.po index 71412b10c2..69f427112a 100644 --- a/locales/fi/LC_MESSAGES/volto.po +++ b/locales/fi/LC_MESSAGES/volto.po @@ -3051,6 +3051,7 @@ msgid "Search input label" msgstr "Hakukentän nimike" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index 49959616bd..bc7be42732 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -3057,6 +3057,7 @@ msgid "Search input label" msgstr "Label du champ de recherche" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index e62c2bad73..749d5a0254 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -3040,6 +3040,7 @@ msgid "Search input label" msgstr "Etichetta del campo di ricerca" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 287a210940..3ce2786a68 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -3048,6 +3048,7 @@ msgid "Search input label" msgstr "" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index c35ced2486..26d235664f 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -3059,6 +3059,7 @@ msgid "Search input label" msgstr "" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index 53828a292f..f3acf576b6 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -3048,6 +3048,7 @@ msgid "Search input label" msgstr "" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index 1f84d64b30..83b3a05f73 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -3050,6 +3050,7 @@ msgid "Search input label" msgstr "Rótulo da caixa de busca" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index ae607d5d64..cc762dbc4b 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -3040,6 +3040,7 @@ msgid "Search input label" msgstr "Căutați eticheta de intrare" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/volto.pot b/locales/volto.pot index b243ad1a4c..285a7e1476 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2023-10-02T11:59:20.013Z\n" +"POT-Creation-Date: 2023-10-06T11:50:27.347Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -3042,6 +3042,7 @@ msgid "Search input label" msgstr "" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" diff --git a/locales/zh_CN/LC_MESSAGES/volto.po b/locales/zh_CN/LC_MESSAGES/volto.po index 50a87152f1..1f7fbe811a 100644 --- a/locales/zh_CN/LC_MESSAGES/volto.po +++ b/locales/zh_CN/LC_MESSAGES/volto.po @@ -3046,6 +3046,7 @@ msgid "Search input label" msgstr "搜索输入标签" #: components/manage/Blocks/Search/components/SearchDetails +#: components/manage/Sidebar/ObjectBrowserBody #: components/theme/Search/Search # defaultMessage: Search results msgid "Search results" From fa266f7bf02c4f0e168c19404ea8f03dbe803e26 Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Fri, 6 Oct 2023 14:08:25 +0200 Subject: [PATCH 4/5] Fix acceptance test. --- cypress/tests/core/basic/objectBrowser.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cypress/tests/core/basic/objectBrowser.js b/cypress/tests/core/basic/objectBrowser.js index 293e5303d4..d439725474 100644 --- a/cypress/tests/core/basic/objectBrowser.js +++ b/cypress/tests/core/basic/objectBrowser.js @@ -97,7 +97,10 @@ describe('Object Browser Tests', () => { // The document is not in the list cy.findByLabelText('Browse My Searchable Page').should('not.exist'); // And the list has only 1 item - cy.get('.ui.segment.object-listing li').should('have.length', 1); + cy.get('.ui.segment.object-listing .image-wrapper').should( + 'have.length', + 1, + ); // The image can be selected as usual cy.findByLabelText('Select My Searchable Image').dblclick(); From 85af5ba28cc1b39ccc179df57293788878fab81a Mon Sep 17 00:00:00 2001 From: Rob Gietema Date: Tue, 28 May 2024 13:06:37 +0200 Subject: [PATCH 5/5] PR review fixes. --- news/5279.feature | 2 +- src/components/manage/Sidebar/ObjectBrowserNav.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/news/5279.feature b/news/5279.feature index 329f8431c5..a93c6febfb 100644 --- a/news/5279.feature +++ b/news/5279.feature @@ -1 +1 @@ -Add object browser icon view @robgietema \ No newline at end of file +Added object browser icon view @robgietema \ No newline at end of file diff --git a/src/components/manage/Sidebar/ObjectBrowserNav.jsx b/src/components/manage/Sidebar/ObjectBrowserNav.jsx index 2ef7d94c13..f2f09a3397 100644 --- a/src/components/manage/Sidebar/ObjectBrowserNav.jsx +++ b/src/components/manage/Sidebar/ObjectBrowserNav.jsx @@ -46,7 +46,7 @@ const ObjectBrowserNav = ({ }; return ( - + {currentSearchResults && currentSearchResults.items.map((item) => view === 'icons' ? (