volto-searchblocks 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changelog.draft +3 -0
- package/.release-it.json +34 -0
- package/CHANGELOG.md +23 -0
- package/README.md +201 -0
- package/babel.config.js +17 -0
- package/locales/de/LC_MESSAGES/volto.po +83 -0
- package/locales/en/LC_MESSAGES/volto.po +83 -0
- package/locales/es/LC_MESSAGES/volto.po +90 -0
- package/locales/it/LC_MESSAGES/volto.po +84 -0
- package/locales/pt_BR/LC_MESSAGES/volto.po +88 -0
- package/locales/volto.pot +85 -0
- package/news/.gitkeep +0 -0
- package/package.json +43 -0
- package/public/.gitkeep +0 -0
- package/src/actions/searchBlocks.js +27 -0
- package/src/components/.gitkeep +0 -0
- package/src/components/SearchBlocks/SearchBlocks.jsx +288 -0
- package/src/config/settings.ts +26 -0
- package/src/constants/ActionTypes.js +3 -0
- package/src/index.ts +28 -0
- package/src/reducers/searchBlocks.js +51 -0
- package/towncrier.toml +33 -0
- package/tsconfig.json +30 -0
package/.changelog.draft
ADDED
package/.release-it.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"plugins": {
|
|
3
|
+
"../../core/packages/scripts/prepublish.js": {}
|
|
4
|
+
},
|
|
5
|
+
"hooks": {
|
|
6
|
+
"after:bump": [
|
|
7
|
+
"pipx run towncrier build --draft --yes --version ${version} > .changelog.draft",
|
|
8
|
+
"pipx run towncrier build --yes --version ${version}",
|
|
9
|
+
"cp ../../README.md ./ && cp CHANGELOG.md ../../CHANGELOG.md",
|
|
10
|
+
"python3 -c 'import json; data = json.load(open(\"../../package.json\")); data[\"version\"] = \"${version}\"; json.dump(data, open(\"../../package.json\", \"w\"), indent=2)'",
|
|
11
|
+
"git add ../../CHANGELOG.md ../../package.json"
|
|
12
|
+
],
|
|
13
|
+
"after:release": "rm .changelog.draft README.md"
|
|
14
|
+
},
|
|
15
|
+
"npm": {
|
|
16
|
+
"publish": true
|
|
17
|
+
},
|
|
18
|
+
"plonePrePublish": {
|
|
19
|
+
"publish": false
|
|
20
|
+
},
|
|
21
|
+
"git": {
|
|
22
|
+
"changelog": "pipx run towncrier build --draft --yes --version 0.0.0",
|
|
23
|
+
"requireUpstream": false,
|
|
24
|
+
"requireCleanWorkingDir": false,
|
|
25
|
+
"commitMessage": "Release ${version}",
|
|
26
|
+
"tagName": "${version}",
|
|
27
|
+
"tagAnnotation": "Release ${version}"
|
|
28
|
+
},
|
|
29
|
+
"github": {
|
|
30
|
+
"release": false,
|
|
31
|
+
"releaseName": "${version}",
|
|
32
|
+
"releaseNotes": "cat .changelog.draft"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
<!-- You should *NOT* be adding new change log entries to this file.
|
|
4
|
+
You should create a file in the news directory instead.
|
|
5
|
+
For helpful instructions, please see:
|
|
6
|
+
https://6.docs.plone.org/contributing/index.html#contributing-change-log-label
|
|
7
|
+
-->
|
|
8
|
+
|
|
9
|
+
<!-- towncrier release notes start -->
|
|
10
|
+
|
|
11
|
+
## 0.1.8 (2026-02-05)
|
|
12
|
+
|
|
13
|
+
## 0.1.5 (2026-02-03)
|
|
14
|
+
|
|
15
|
+
## 0.1.4 (2026-02-03)
|
|
16
|
+
|
|
17
|
+
## 0.1.3 (2026-02-03)
|
|
18
|
+
|
|
19
|
+
## 0.1.2 (2026-02-03)
|
|
20
|
+
|
|
21
|
+
## 0.1.1 (2026-02-03)
|
|
22
|
+
|
|
23
|
+
## 0.1.0 (2026-02-03)
|
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Search blocks (volto-searchblocks)
|
|
2
|
+
|
|
3
|
+
A Volto add-on that provides a control panel for searching and managing content that uses specific blocks.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/volto-searchblocks)
|
|
6
|
+
[](https://collective.github.io/volto-searchblocks/)
|
|
7
|
+
[](https://github.com/collective/collective-searchblocks/actions/workflows/main.yml)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## Features ✨
|
|
11
|
+
|
|
12
|
+
- **Search Blocks Control Panel**: Dedicated control panel view for searching content by block types
|
|
13
|
+
- **Table Display**: Results displayed in a sortable table with key metadata
|
|
14
|
+
- **Pagination**: Navigate through results with configurable page sizes (default, 50, or all)
|
|
15
|
+
- **Block Type Selection**: Dropdown selector for choosing which block type to search for
|
|
16
|
+
- **Multilingual Support**: Full i18n support with Italian translation included
|
|
17
|
+
- **Error Handling**: Comprehensive error displays for API failures
|
|
18
|
+
- **Semantic UI Integration**: Uses Volto's standard Semantic UI components for consistent styling
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
To install your project, you must choose the method appropriate to your version of Volto.
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Volto 18 and later
|
|
26
|
+
|
|
27
|
+
Add `volto-searchblocks` to your `package.json`.
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"volto-searchblocks": "*"
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Add `volto-searchblocks` to your `volto.config.js`.
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
const addons = ['volto-searchblocks'];
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If this package provides a Volto theme, and you want to activate it, then add the following to your `volto.config.js`.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const theme = 'volto-searchblocks';
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Volto 17 and earlier
|
|
48
|
+
|
|
49
|
+
Create a new Volto project.
|
|
50
|
+
You can skip this step if you already have one.
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
npm install -g yo @plone/generator-volto
|
|
54
|
+
yo @plone/volto my-volto-project --addon volto-searchblocks
|
|
55
|
+
cd my-volto-project
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Add `volto-searchblocks` to your `package.json`.
|
|
59
|
+
|
|
60
|
+
```JSON
|
|
61
|
+
"addons": [
|
|
62
|
+
"volto-searchblocks"
|
|
63
|
+
],
|
|
64
|
+
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"volto-searchblocks": "*"
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Download and install the new add-on.
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
yarn install
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Start Volto.
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
yarn start
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Test installation
|
|
83
|
+
|
|
84
|
+
Visit http://localhost:3000/ in a browser, login, and check the awesome new features.
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
The development of this add-on is done in isolation using pnpm workspaces, the latest `mrs-developer`, and other Volto core improvements.
|
|
90
|
+
For these reasons, it only works with pnpm and Volto 18.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
### Prerequisites ✅
|
|
94
|
+
|
|
95
|
+
- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned.
|
|
96
|
+
- [nvm](https://6.docs.plone.org/install/create-project-cookieplone.html#nvm)
|
|
97
|
+
- [Node.js and pnpm](https://6.docs.plone.org/install/create-project.html#node-js) 22
|
|
98
|
+
- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make)
|
|
99
|
+
- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git)
|
|
100
|
+
- [Docker](https://docs.docker.com/get-started/get-docker/) (optional)
|
|
101
|
+
|
|
102
|
+
### Installation 🔧
|
|
103
|
+
|
|
104
|
+
1. Clone this repository, then change your working directory.
|
|
105
|
+
|
|
106
|
+
```shell
|
|
107
|
+
git clone git@github.com:collective/collective-searchblocks.git
|
|
108
|
+
cd collective-searchblocks/frontend
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
2. Install this code base.
|
|
112
|
+
|
|
113
|
+
```shell
|
|
114
|
+
make install
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
### Make convenience commands
|
|
119
|
+
|
|
120
|
+
Run `make help` to list the available Make commands.
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
### Set up development environment
|
|
124
|
+
|
|
125
|
+
Install package requirements.
|
|
126
|
+
|
|
127
|
+
```shell
|
|
128
|
+
make install
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Start developing
|
|
132
|
+
|
|
133
|
+
Start the backend.
|
|
134
|
+
|
|
135
|
+
```shell
|
|
136
|
+
make backend-docker-start
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
In a separate terminal session, start the frontend.
|
|
140
|
+
|
|
141
|
+
```shell
|
|
142
|
+
make start
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Lint code
|
|
146
|
+
|
|
147
|
+
Run ESlint, Prettier, and Stylelint in analyze mode.
|
|
148
|
+
|
|
149
|
+
```shell
|
|
150
|
+
make lint
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Format code
|
|
154
|
+
|
|
155
|
+
Run ESlint, Prettier, and Stylelint in fix mode.
|
|
156
|
+
|
|
157
|
+
```shell
|
|
158
|
+
make format
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### i18n
|
|
162
|
+
|
|
163
|
+
Extract the i18n messages to locales.
|
|
164
|
+
|
|
165
|
+
```shell
|
|
166
|
+
make i18n
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Unit tests
|
|
170
|
+
|
|
171
|
+
Run unit tests.
|
|
172
|
+
|
|
173
|
+
```shell
|
|
174
|
+
make test
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Run Cypress tests
|
|
178
|
+
|
|
179
|
+
Run each of these steps in separate terminal sessions.
|
|
180
|
+
|
|
181
|
+
In the first session, start the frontend in development mode.
|
|
182
|
+
|
|
183
|
+
```shell
|
|
184
|
+
make acceptance-frontend-dev-start
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
In the second session, start the backend acceptance server.
|
|
188
|
+
|
|
189
|
+
```shell
|
|
190
|
+
make acceptance-backend-start
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
In the third session, start the Cypress interactive test runner.
|
|
194
|
+
|
|
195
|
+
```shell
|
|
196
|
+
make acceptance-test
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
The project is licensed under the MIT license.
|
package/babel.config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = function (api) {
|
|
2
|
+
api.cache(true);
|
|
3
|
+
const presets = ['razzle'];
|
|
4
|
+
const plugins = [
|
|
5
|
+
[
|
|
6
|
+
'react-intl', // React Intl extractor, required for the whole i18n infrastructure to work
|
|
7
|
+
{
|
|
8
|
+
messagesDir: './build/messages/',
|
|
9
|
+
},
|
|
10
|
+
],
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
return {
|
|
14
|
+
plugins,
|
|
15
|
+
presets,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: \n"
|
|
4
|
+
"Report-Msgid-Bugs-To: \n"
|
|
5
|
+
"POT-Creation-Date: \n"
|
|
6
|
+
"PO-Revision-Date: \n"
|
|
7
|
+
"Last-Translator: \n"
|
|
8
|
+
"Language: de\n"
|
|
9
|
+
"Language-Team: \n"
|
|
10
|
+
"Content-Type: \n"
|
|
11
|
+
"Content-Transfer-Encoding: \n"
|
|
12
|
+
"Plural-Forms: \n"
|
|
13
|
+
|
|
14
|
+
#. Default: "Back to Control Panel"
|
|
15
|
+
#: components/SearchBlocks/SearchBlocks
|
|
16
|
+
msgid "Back to Control Panel"
|
|
17
|
+
msgstr ""
|
|
18
|
+
|
|
19
|
+
#. Default: "Block Type"
|
|
20
|
+
#: components/SearchBlocks/SearchBlocks
|
|
21
|
+
msgid "Block Type"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "Choose a block type"
|
|
25
|
+
#: components/SearchBlocks/SearchBlocks
|
|
26
|
+
msgid "Choose a block type"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#. Default: "Created"
|
|
30
|
+
#: components/SearchBlocks/SearchBlocks
|
|
31
|
+
msgid "Created"
|
|
32
|
+
msgstr ""
|
|
33
|
+
|
|
34
|
+
#. Default: "Loading..."
|
|
35
|
+
#: components/SearchBlocks/SearchBlocks
|
|
36
|
+
msgid "Loading"
|
|
37
|
+
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Modified"
|
|
40
|
+
#: components/SearchBlocks/SearchBlocks
|
|
41
|
+
msgid "Modified"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "No results found for"
|
|
45
|
+
#: components/SearchBlocks/SearchBlocks
|
|
46
|
+
msgid "No results found for"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
50
|
+
#: components/SearchBlocks/SearchBlocks
|
|
51
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "Results"
|
|
55
|
+
#: components/SearchBlocks/SearchBlocks
|
|
56
|
+
msgid "Results"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Review State"
|
|
60
|
+
#: components/SearchBlocks/SearchBlocks
|
|
61
|
+
msgid "Review State"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Search blocks"
|
|
65
|
+
#: components/SearchBlocks/SearchBlocks
|
|
66
|
+
#: config/settings
|
|
67
|
+
msgid "Search blocks"
|
|
68
|
+
msgstr ""
|
|
69
|
+
|
|
70
|
+
#. Default: "Select Block Type:"
|
|
71
|
+
#: components/SearchBlocks/SearchBlocks
|
|
72
|
+
msgid "Select Block Type"
|
|
73
|
+
msgstr ""
|
|
74
|
+
|
|
75
|
+
#. Default: "Title"
|
|
76
|
+
#: components/SearchBlocks/SearchBlocks
|
|
77
|
+
msgid "Title"
|
|
78
|
+
msgstr ""
|
|
79
|
+
|
|
80
|
+
#. Default: "Type"
|
|
81
|
+
#: components/SearchBlocks/SearchBlocks
|
|
82
|
+
msgid "Type"
|
|
83
|
+
msgstr ""
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: \n"
|
|
4
|
+
"Report-Msgid-Bugs-To: \n"
|
|
5
|
+
"POT-Creation-Date: \n"
|
|
6
|
+
"PO-Revision-Date: \n"
|
|
7
|
+
"Last-Translator: \n"
|
|
8
|
+
"Language: en\n"
|
|
9
|
+
"Language-Team: \n"
|
|
10
|
+
"Content-Type: \n"
|
|
11
|
+
"Content-Transfer-Encoding: \n"
|
|
12
|
+
"Plural-Forms: \n"
|
|
13
|
+
|
|
14
|
+
#. Default: "Back to Control Panel"
|
|
15
|
+
#: components/SearchBlocks/SearchBlocks
|
|
16
|
+
msgid "Back to Control Panel"
|
|
17
|
+
msgstr ""
|
|
18
|
+
|
|
19
|
+
#. Default: "Block Type"
|
|
20
|
+
#: components/SearchBlocks/SearchBlocks
|
|
21
|
+
msgid "Block Type"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "Choose a block type"
|
|
25
|
+
#: components/SearchBlocks/SearchBlocks
|
|
26
|
+
msgid "Choose a block type"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#. Default: "Created"
|
|
30
|
+
#: components/SearchBlocks/SearchBlocks
|
|
31
|
+
msgid "Created"
|
|
32
|
+
msgstr ""
|
|
33
|
+
|
|
34
|
+
#. Default: "Loading..."
|
|
35
|
+
#: components/SearchBlocks/SearchBlocks
|
|
36
|
+
msgid "Loading"
|
|
37
|
+
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Modified"
|
|
40
|
+
#: components/SearchBlocks/SearchBlocks
|
|
41
|
+
msgid "Modified"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "No results found for"
|
|
45
|
+
#: components/SearchBlocks/SearchBlocks
|
|
46
|
+
msgid "No results found for"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
50
|
+
#: components/SearchBlocks/SearchBlocks
|
|
51
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "Results"
|
|
55
|
+
#: components/SearchBlocks/SearchBlocks
|
|
56
|
+
msgid "Results"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Review State"
|
|
60
|
+
#: components/SearchBlocks/SearchBlocks
|
|
61
|
+
msgid "Review State"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Search blocks"
|
|
65
|
+
#: components/SearchBlocks/SearchBlocks
|
|
66
|
+
#: config/settings
|
|
67
|
+
msgid "Search blocks"
|
|
68
|
+
msgstr ""
|
|
69
|
+
|
|
70
|
+
#. Default: "Select Block Type:"
|
|
71
|
+
#: components/SearchBlocks/SearchBlocks
|
|
72
|
+
msgid "Select Block Type"
|
|
73
|
+
msgstr ""
|
|
74
|
+
|
|
75
|
+
#. Default: "Title"
|
|
76
|
+
#: components/SearchBlocks/SearchBlocks
|
|
77
|
+
msgid "Title"
|
|
78
|
+
msgstr ""
|
|
79
|
+
|
|
80
|
+
#. Default: "Type"
|
|
81
|
+
#: components/SearchBlocks/SearchBlocks
|
|
82
|
+
msgid "Type"
|
|
83
|
+
msgstr ""
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: Plone\n"
|
|
4
|
+
"Report-Msgid-Bugs-To: \n"
|
|
5
|
+
"POT-Creation-Date: 2023-05-09 11:45-0400\n"
|
|
6
|
+
"PO-Revision-Date: 2023-05-10 11:34-0400\n"
|
|
7
|
+
"Last-Translator: Leonardo J. Caballero G. <leonardocaballero@gmail.com>\n"
|
|
8
|
+
"Language: es\n"
|
|
9
|
+
"Language-Team: ES <LL@li.org>\n"
|
|
10
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
11
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
12
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
13
|
+
"Preferred-Encodings: utf-8\n"
|
|
14
|
+
"MIME-Version: 1.0\n"
|
|
15
|
+
"Language-Code: es\n"
|
|
16
|
+
"Language-Name: Español\n"
|
|
17
|
+
"Domain: volto\n"
|
|
18
|
+
"X-Is-Fallback-For: es-ar es-bo es-cl es-co es-cr es-do es-ec es-es es-sv es-gt es-hn es-mx es-ni es-pa es-py es-pe es-pr es-us es-uy es-ve\n"
|
|
19
|
+
"X-Generator: Poedit 2.2.1\n"
|
|
20
|
+
|
|
21
|
+
#. Default: "Back to Control Panel"
|
|
22
|
+
#: components/SearchBlocks/SearchBlocks
|
|
23
|
+
msgid "Back to Control Panel"
|
|
24
|
+
msgstr ""
|
|
25
|
+
|
|
26
|
+
#. Default: "Block Type"
|
|
27
|
+
#: components/SearchBlocks/SearchBlocks
|
|
28
|
+
msgid "Block Type"
|
|
29
|
+
msgstr ""
|
|
30
|
+
|
|
31
|
+
#. Default: "Choose a block type"
|
|
32
|
+
#: components/SearchBlocks/SearchBlocks
|
|
33
|
+
msgid "Choose a block type"
|
|
34
|
+
msgstr ""
|
|
35
|
+
|
|
36
|
+
#. Default: "Created"
|
|
37
|
+
#: components/SearchBlocks/SearchBlocks
|
|
38
|
+
msgid "Created"
|
|
39
|
+
msgstr ""
|
|
40
|
+
|
|
41
|
+
#. Default: "Loading..."
|
|
42
|
+
#: components/SearchBlocks/SearchBlocks
|
|
43
|
+
msgid "Loading"
|
|
44
|
+
msgstr ""
|
|
45
|
+
|
|
46
|
+
#. Default: "Modified"
|
|
47
|
+
#: components/SearchBlocks/SearchBlocks
|
|
48
|
+
msgid "Modified"
|
|
49
|
+
msgstr ""
|
|
50
|
+
|
|
51
|
+
#. Default: "No results found for"
|
|
52
|
+
#: components/SearchBlocks/SearchBlocks
|
|
53
|
+
msgid "No results found for"
|
|
54
|
+
msgstr ""
|
|
55
|
+
|
|
56
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
57
|
+
#: components/SearchBlocks/SearchBlocks
|
|
58
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#. Default: "Results"
|
|
62
|
+
#: components/SearchBlocks/SearchBlocks
|
|
63
|
+
msgid "Results"
|
|
64
|
+
msgstr ""
|
|
65
|
+
|
|
66
|
+
#. Default: "Review State"
|
|
67
|
+
#: components/SearchBlocks/SearchBlocks
|
|
68
|
+
msgid "Review State"
|
|
69
|
+
msgstr ""
|
|
70
|
+
|
|
71
|
+
#. Default: "Search blocks"
|
|
72
|
+
#: components/SearchBlocks/SearchBlocks
|
|
73
|
+
#: config/settings
|
|
74
|
+
msgid "Search blocks"
|
|
75
|
+
msgstr ""
|
|
76
|
+
|
|
77
|
+
#. Default: "Select Block Type:"
|
|
78
|
+
#: components/SearchBlocks/SearchBlocks
|
|
79
|
+
msgid "Select Block Type"
|
|
80
|
+
msgstr ""
|
|
81
|
+
|
|
82
|
+
#. Default: "Title"
|
|
83
|
+
#: components/SearchBlocks/SearchBlocks
|
|
84
|
+
msgid "Title"
|
|
85
|
+
msgstr ""
|
|
86
|
+
|
|
87
|
+
#. Default: "Type"
|
|
88
|
+
#: components/SearchBlocks/SearchBlocks
|
|
89
|
+
msgid "Type"
|
|
90
|
+
msgstr ""
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: Plone\n"
|
|
4
|
+
"Report-Msgid-Bugs-To: \n"
|
|
5
|
+
"POT-Creation-Date: 2025-01-16T00:00:00.000Z\n"
|
|
6
|
+
"PO-Revision-Date: 2025-01-16\n"
|
|
7
|
+
"Last-Translator: \n"
|
|
8
|
+
"Language: it\n"
|
|
9
|
+
"Language-Team: Italian\n"
|
|
10
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
11
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
12
|
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
13
|
+
"MIME-Version: 1.0\n"
|
|
14
|
+
|
|
15
|
+
#. Default: "Back to Control Panel"
|
|
16
|
+
#: components/SearchBlocks/SearchBlocks
|
|
17
|
+
msgid "Back to Control Panel"
|
|
18
|
+
msgstr "Torna al Pannello di Controllo"
|
|
19
|
+
|
|
20
|
+
#. Default: "Block Type"
|
|
21
|
+
#: components/SearchBlocks/SearchBlocks
|
|
22
|
+
msgid "Block Type"
|
|
23
|
+
msgstr "Tipo di Blocco"
|
|
24
|
+
|
|
25
|
+
#. Default: "Choose a block type"
|
|
26
|
+
#: components/SearchBlocks/SearchBlocks
|
|
27
|
+
msgid "Choose a block type"
|
|
28
|
+
msgstr "Scegli un tipo di blocco"
|
|
29
|
+
|
|
30
|
+
#. Default: "Created"
|
|
31
|
+
#: components/SearchBlocks/SearchBlocks
|
|
32
|
+
msgid "Created"
|
|
33
|
+
msgstr "Creato"
|
|
34
|
+
|
|
35
|
+
#. Default: "Loading..."
|
|
36
|
+
#: components/SearchBlocks/SearchBlocks
|
|
37
|
+
msgid "Loading"
|
|
38
|
+
msgstr "Caricamento in corso..."
|
|
39
|
+
|
|
40
|
+
#. Default: "Modified"
|
|
41
|
+
#: components/SearchBlocks/SearchBlocks
|
|
42
|
+
msgid "Modified"
|
|
43
|
+
msgstr "Modificato"
|
|
44
|
+
|
|
45
|
+
#. Default: "No results found for"
|
|
46
|
+
#: components/SearchBlocks/SearchBlocks
|
|
47
|
+
msgid "No results found for"
|
|
48
|
+
msgstr "Nessun risultato trovato per"
|
|
49
|
+
|
|
50
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
51
|
+
#: components/SearchBlocks/SearchBlocks
|
|
52
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
53
|
+
msgstr "In questa pagina puoi vedere quali contenuti del sito utilizzano un determinato blocco"
|
|
54
|
+
|
|
55
|
+
#. Default: "Results"
|
|
56
|
+
#: components/SearchBlocks/SearchBlocks
|
|
57
|
+
msgid "Results"
|
|
58
|
+
msgstr "Risultati"
|
|
59
|
+
|
|
60
|
+
#. Default: "Review State"
|
|
61
|
+
#: components/SearchBlocks/SearchBlocks
|
|
62
|
+
msgid "Review State"
|
|
63
|
+
msgstr "Stato di Revisione"
|
|
64
|
+
|
|
65
|
+
#. Default: "Search blocks"
|
|
66
|
+
#: components/SearchBlocks/SearchBlocks
|
|
67
|
+
#: config/settings
|
|
68
|
+
msgid "Search blocks"
|
|
69
|
+
msgstr "Ricerca blocchi"
|
|
70
|
+
|
|
71
|
+
#. Default: "Select Block Type:"
|
|
72
|
+
#: components/SearchBlocks/SearchBlocks
|
|
73
|
+
msgid "Select Block Type"
|
|
74
|
+
msgstr "Seleziona Tipo di Blocco"
|
|
75
|
+
|
|
76
|
+
#. Default: "Title"
|
|
77
|
+
#: components/SearchBlocks/SearchBlocks
|
|
78
|
+
msgid "Title"
|
|
79
|
+
msgstr "Titolo"
|
|
80
|
+
|
|
81
|
+
#. Default: "Type"
|
|
82
|
+
#: components/SearchBlocks/SearchBlocks
|
|
83
|
+
msgid "Type"
|
|
84
|
+
msgstr "Tipo"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: Plone\n"
|
|
4
|
+
"Report-Msgid-Bugs-To: \n"
|
|
5
|
+
"POT-Creation-Date: 2023-04-06T16:01:32.969Z\n"
|
|
6
|
+
"PO-Revision-Date: \n"
|
|
7
|
+
"Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
8
|
+
"Language: \n"
|
|
9
|
+
"Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
10
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
11
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
12
|
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
13
|
+
"MIME-Version: 1.0\n"
|
|
14
|
+
"Language-Code: pt_BR\n"
|
|
15
|
+
"Language-Name: Português do Brasil\n"
|
|
16
|
+
"Preferred-Encodings: utf-8\n"
|
|
17
|
+
"Domain: volto\n"
|
|
18
|
+
|
|
19
|
+
#. Default: "Back to Control Panel"
|
|
20
|
+
#: components/SearchBlocks/SearchBlocks
|
|
21
|
+
msgid "Back to Control Panel"
|
|
22
|
+
msgstr ""
|
|
23
|
+
|
|
24
|
+
#. Default: "Block Type"
|
|
25
|
+
#: components/SearchBlocks/SearchBlocks
|
|
26
|
+
msgid "Block Type"
|
|
27
|
+
msgstr ""
|
|
28
|
+
|
|
29
|
+
#. Default: "Choose a block type"
|
|
30
|
+
#: components/SearchBlocks/SearchBlocks
|
|
31
|
+
msgid "Choose a block type"
|
|
32
|
+
msgstr ""
|
|
33
|
+
|
|
34
|
+
#. Default: "Created"
|
|
35
|
+
#: components/SearchBlocks/SearchBlocks
|
|
36
|
+
msgid "Created"
|
|
37
|
+
msgstr ""
|
|
38
|
+
|
|
39
|
+
#. Default: "Loading..."
|
|
40
|
+
#: components/SearchBlocks/SearchBlocks
|
|
41
|
+
msgid "Loading"
|
|
42
|
+
msgstr ""
|
|
43
|
+
|
|
44
|
+
#. Default: "Modified"
|
|
45
|
+
#: components/SearchBlocks/SearchBlocks
|
|
46
|
+
msgid "Modified"
|
|
47
|
+
msgstr ""
|
|
48
|
+
|
|
49
|
+
#. Default: "No results found for"
|
|
50
|
+
#: components/SearchBlocks/SearchBlocks
|
|
51
|
+
msgid "No results found for"
|
|
52
|
+
msgstr ""
|
|
53
|
+
|
|
54
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
55
|
+
#: components/SearchBlocks/SearchBlocks
|
|
56
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
57
|
+
msgstr ""
|
|
58
|
+
|
|
59
|
+
#. Default: "Results"
|
|
60
|
+
#: components/SearchBlocks/SearchBlocks
|
|
61
|
+
msgid "Results"
|
|
62
|
+
msgstr ""
|
|
63
|
+
|
|
64
|
+
#. Default: "Review State"
|
|
65
|
+
#: components/SearchBlocks/SearchBlocks
|
|
66
|
+
msgid "Review State"
|
|
67
|
+
msgstr ""
|
|
68
|
+
|
|
69
|
+
#. Default: "Search blocks"
|
|
70
|
+
#: components/SearchBlocks/SearchBlocks
|
|
71
|
+
#: config/settings
|
|
72
|
+
msgid "Search blocks"
|
|
73
|
+
msgstr ""
|
|
74
|
+
|
|
75
|
+
#. Default: "Select Block Type:"
|
|
76
|
+
#: components/SearchBlocks/SearchBlocks
|
|
77
|
+
msgid "Select Block Type"
|
|
78
|
+
msgstr ""
|
|
79
|
+
|
|
80
|
+
#. Default: "Title"
|
|
81
|
+
#: components/SearchBlocks/SearchBlocks
|
|
82
|
+
msgid "Title"
|
|
83
|
+
msgstr ""
|
|
84
|
+
|
|
85
|
+
#. Default: "Type"
|
|
86
|
+
#: components/SearchBlocks/SearchBlocks
|
|
87
|
+
msgid "Type"
|
|
88
|
+
msgstr ""
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
msgid ""
|
|
2
|
+
msgstr ""
|
|
3
|
+
"Project-Id-Version: Plone\n"
|
|
4
|
+
"POT-Creation-Date: 2026-01-27T12:21:38.702Z\n"
|
|
5
|
+
"Last-Translator: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
6
|
+
"Language-Team: Plone i18n <plone-i18n@lists.sourceforge.net>\n"
|
|
7
|
+
"Content-Type: text/plain; charset=utf-8\n"
|
|
8
|
+
"Content-Transfer-Encoding: 8bit\n"
|
|
9
|
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
|
10
|
+
"MIME-Version: 1.0\n"
|
|
11
|
+
"Language-Code: en\n"
|
|
12
|
+
"Language-Name: English\n"
|
|
13
|
+
"Preferred-Encodings: utf-8\n"
|
|
14
|
+
"Domain: volto\n"
|
|
15
|
+
|
|
16
|
+
#. Default: "Back to Control Panel"
|
|
17
|
+
#: components/SearchBlocks/SearchBlocks
|
|
18
|
+
msgid "Back to Control Panel"
|
|
19
|
+
msgstr ""
|
|
20
|
+
|
|
21
|
+
#. Default: "Block Type"
|
|
22
|
+
#: components/SearchBlocks/SearchBlocks
|
|
23
|
+
msgid "Block Type"
|
|
24
|
+
msgstr ""
|
|
25
|
+
|
|
26
|
+
#. Default: "Choose a block type"
|
|
27
|
+
#: components/SearchBlocks/SearchBlocks
|
|
28
|
+
msgid "Choose a block type"
|
|
29
|
+
msgstr ""
|
|
30
|
+
|
|
31
|
+
#. Default: "Created"
|
|
32
|
+
#: components/SearchBlocks/SearchBlocks
|
|
33
|
+
msgid "Created"
|
|
34
|
+
msgstr ""
|
|
35
|
+
|
|
36
|
+
#. Default: "Loading..."
|
|
37
|
+
#: components/SearchBlocks/SearchBlocks
|
|
38
|
+
msgid "Loading"
|
|
39
|
+
msgstr ""
|
|
40
|
+
|
|
41
|
+
#. Default: "Modified"
|
|
42
|
+
#: components/SearchBlocks/SearchBlocks
|
|
43
|
+
msgid "Modified"
|
|
44
|
+
msgstr ""
|
|
45
|
+
|
|
46
|
+
#. Default: "No results found for"
|
|
47
|
+
#: components/SearchBlocks/SearchBlocks
|
|
48
|
+
msgid "No results found for"
|
|
49
|
+
msgstr ""
|
|
50
|
+
|
|
51
|
+
#. Default: "On this page you can see which contents on the site use a specific block"
|
|
52
|
+
#: components/SearchBlocks/SearchBlocks
|
|
53
|
+
msgid "On this page you can see which contents on the site use a specific block"
|
|
54
|
+
msgstr ""
|
|
55
|
+
|
|
56
|
+
#. Default: "Results"
|
|
57
|
+
#: components/SearchBlocks/SearchBlocks
|
|
58
|
+
msgid "Results"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
61
|
+
#. Default: "Review State"
|
|
62
|
+
#: components/SearchBlocks/SearchBlocks
|
|
63
|
+
msgid "Review State"
|
|
64
|
+
msgstr ""
|
|
65
|
+
|
|
66
|
+
#. Default: "Search blocks"
|
|
67
|
+
#: components/SearchBlocks/SearchBlocks
|
|
68
|
+
#: config/settings
|
|
69
|
+
msgid "Search blocks"
|
|
70
|
+
msgstr ""
|
|
71
|
+
|
|
72
|
+
#. Default: "Select Block Type:"
|
|
73
|
+
#: components/SearchBlocks/SearchBlocks
|
|
74
|
+
msgid "Select Block Type"
|
|
75
|
+
msgstr ""
|
|
76
|
+
|
|
77
|
+
#. Default: "Title"
|
|
78
|
+
#: components/SearchBlocks/SearchBlocks
|
|
79
|
+
msgid "Title"
|
|
80
|
+
msgstr ""
|
|
81
|
+
|
|
82
|
+
#. Default: "Type"
|
|
83
|
+
#: components/SearchBlocks/SearchBlocks
|
|
84
|
+
msgid "Type"
|
|
85
|
+
msgstr ""
|
package/news/.gitkeep
ADDED
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "volto-searchblocks",
|
|
3
|
+
"version": "0.1.8",
|
|
4
|
+
"description": "Additional control-panel that allow users to search which contents using a specific block",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"volto-addon",
|
|
9
|
+
"volto",
|
|
10
|
+
"plone",
|
|
11
|
+
"react"
|
|
12
|
+
],
|
|
13
|
+
"author": "RedTurtle Technology",
|
|
14
|
+
"homepage": "https://github.com/collective/collective-searchblocks#readme",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git@github.com:collective/collective-searchblocks"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public",
|
|
21
|
+
"registry": "https://registry.npmjs.org/"
|
|
22
|
+
},
|
|
23
|
+
"addons": [],
|
|
24
|
+
"theme": "",
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^18.2.0",
|
|
27
|
+
"react-dom": "^18.2.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/react": "^18.3.1",
|
|
31
|
+
"@types/react-dom": "^18.3.1",
|
|
32
|
+
"release-it": "^19.0.5",
|
|
33
|
+
"typescript": "^5.7.3",
|
|
34
|
+
"@plone/scripts": "^3.10.3"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"i18n": "rm -rf build/messages && NODE_ENV=production i18n --addon",
|
|
38
|
+
"dry-release": "release-it --dry-run",
|
|
39
|
+
"release": "release-it",
|
|
40
|
+
"release-major-alpha": "release-it major --preRelease=alpha",
|
|
41
|
+
"release-alpha": "release-it --preRelease=alpha"
|
|
42
|
+
}
|
|
43
|
+
}
|
package/public/.gitkeep
ADDED
|
File without changes
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SEARCH_BLOCKS } from '../constants/ActionTypes';
|
|
2
|
+
|
|
3
|
+
export function searchBlocks(options = {}) {
|
|
4
|
+
const params = {
|
|
5
|
+
sort_on: 'sortable_title',
|
|
6
|
+
metadata_fields: ['modified', 'created'],
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
if (options.block_types) {
|
|
10
|
+
params.block_types = options.block_types;
|
|
11
|
+
}
|
|
12
|
+
if (options.b_size) {
|
|
13
|
+
params.b_size = options.b_size;
|
|
14
|
+
}
|
|
15
|
+
if (options.b_start) {
|
|
16
|
+
params.b_start = options.b_start;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
type: SEARCH_BLOCKS,
|
|
21
|
+
request: {
|
|
22
|
+
op: 'get',
|
|
23
|
+
path: '/@search-blocks',
|
|
24
|
+
params,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { useDispatch, useSelector } from 'react-redux';
|
|
3
|
+
import { createPortal } from 'react-dom';
|
|
4
|
+
import { Link } from 'react-router-dom';
|
|
5
|
+
import { Container, Segment, Header, Table } from 'semantic-ui-react';
|
|
6
|
+
import { Helmet } from '@plone/volto/helpers';
|
|
7
|
+
import { SelectWidget } from '@plone/volto/components';
|
|
8
|
+
import Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar';
|
|
9
|
+
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
10
|
+
import Pagination from '@plone/volto/components/theme/Pagination/Pagination';
|
|
11
|
+
import Error from '@plone/volto/components/theme/Error/Error';
|
|
12
|
+
import backSVG from '@plone/volto/icons/back.svg';
|
|
13
|
+
import { useClient } from '@plone/volto/hooks';
|
|
14
|
+
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
|
15
|
+
import config from '@plone/volto/registry';
|
|
16
|
+
import { searchBlocks } from '../../actions/searchBlocks';
|
|
17
|
+
|
|
18
|
+
const messages = defineMessages({
|
|
19
|
+
pageTitle: {
|
|
20
|
+
id: 'Search blocks',
|
|
21
|
+
defaultMessage: 'Search blocks',
|
|
22
|
+
},
|
|
23
|
+
pageDescription: {
|
|
24
|
+
id: 'On this page you can see which contents on the site use a specific block',
|
|
25
|
+
defaultMessage:
|
|
26
|
+
'On this page you can see which contents on the site use a specific block',
|
|
27
|
+
},
|
|
28
|
+
selectBlockType: {
|
|
29
|
+
id: 'Select Block Type',
|
|
30
|
+
defaultMessage: 'Select Block Type:',
|
|
31
|
+
},
|
|
32
|
+
blockTypeLabel: {
|
|
33
|
+
id: 'Block Type',
|
|
34
|
+
defaultMessage: 'Block Type',
|
|
35
|
+
},
|
|
36
|
+
chooseBlockType: {
|
|
37
|
+
id: 'Choose a block type',
|
|
38
|
+
defaultMessage: 'Choose a block type',
|
|
39
|
+
},
|
|
40
|
+
title: {
|
|
41
|
+
id: 'Title',
|
|
42
|
+
defaultMessage: 'Title',
|
|
43
|
+
},
|
|
44
|
+
type: {
|
|
45
|
+
id: 'Type',
|
|
46
|
+
defaultMessage: 'Type',
|
|
47
|
+
},
|
|
48
|
+
reviewState: {
|
|
49
|
+
id: 'Review State',
|
|
50
|
+
defaultMessage: 'Review State',
|
|
51
|
+
},
|
|
52
|
+
created: {
|
|
53
|
+
id: 'Created',
|
|
54
|
+
defaultMessage: 'Created',
|
|
55
|
+
},
|
|
56
|
+
modified: {
|
|
57
|
+
id: 'Modified',
|
|
58
|
+
defaultMessage: 'Modified',
|
|
59
|
+
},
|
|
60
|
+
results: {
|
|
61
|
+
id: 'Results',
|
|
62
|
+
defaultMessage: 'Results',
|
|
63
|
+
},
|
|
64
|
+
loading: {
|
|
65
|
+
id: 'Loading',
|
|
66
|
+
defaultMessage: 'Loading...',
|
|
67
|
+
},
|
|
68
|
+
noResults: {
|
|
69
|
+
id: 'No results found for',
|
|
70
|
+
defaultMessage: 'No results found for',
|
|
71
|
+
},
|
|
72
|
+
backToControlPanel: {
|
|
73
|
+
id: 'Back to Control Panel',
|
|
74
|
+
defaultMessage: 'Back to Control Panel',
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const SearchBlocks = (props) => {
|
|
79
|
+
const dispatch = useDispatch();
|
|
80
|
+
const isClient = useClient();
|
|
81
|
+
const intl = useIntl();
|
|
82
|
+
const pathname = props.location?.pathname || '/controlpanel/blocks-search';
|
|
83
|
+
const [selectedBlockType, setSelectedBlockType] = useState(null);
|
|
84
|
+
const [currentPage, setCurrentPage] = useState(0);
|
|
85
|
+
const [currentPageSize, setCurrentPageSize] = useState(
|
|
86
|
+
config.settings.defaultPageSize,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const searchResults = useSelector((state) => state.searchBlocks);
|
|
90
|
+
const { block_types, items, total, loading, batching, b_start, error } =
|
|
91
|
+
searchResults;
|
|
92
|
+
|
|
93
|
+
useEffect(() => {
|
|
94
|
+
// Initial fetch to get block types
|
|
95
|
+
dispatch(
|
|
96
|
+
searchBlocks({
|
|
97
|
+
b_start: b_start * currentPageSize,
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
101
|
+
}, [dispatch]);
|
|
102
|
+
|
|
103
|
+
if (error) {
|
|
104
|
+
return <Error error={error} />;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const handleSelect = (key) => {
|
|
108
|
+
setSelectedBlockType(key);
|
|
109
|
+
setCurrentPage(0);
|
|
110
|
+
dispatch(searchBlocks({ block_types: key }));
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const handlePageChange = (e, { value }) => {
|
|
114
|
+
setCurrentPage(value);
|
|
115
|
+
dispatch(
|
|
116
|
+
searchBlocks({
|
|
117
|
+
block_types: selectedBlockType,
|
|
118
|
+
b_size: currentPageSize,
|
|
119
|
+
b_start: value * currentPageSize,
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const handlePageSizeChange = (e, { value }) => {
|
|
125
|
+
setCurrentPageSize(
|
|
126
|
+
value === intl.formatMessage({ id: 'All', defaultMessage: 'All' })
|
|
127
|
+
? total
|
|
128
|
+
: value,
|
|
129
|
+
);
|
|
130
|
+
setCurrentPage(0);
|
|
131
|
+
dispatch(
|
|
132
|
+
searchBlocks({
|
|
133
|
+
block_types: selectedBlockType,
|
|
134
|
+
b_size:
|
|
135
|
+
value === intl.formatMessage({ id: 'All', defaultMessage: 'All' })
|
|
136
|
+
? total
|
|
137
|
+
: value,
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<Container className="view-wrapper controlpanel-blocks-search cms-ui">
|
|
144
|
+
<Helmet title={intl.formatMessage(messages.pageTitle)} />
|
|
145
|
+
<Segment.Group raised>
|
|
146
|
+
<Segment className="primary">
|
|
147
|
+
<Header as="h1">
|
|
148
|
+
<FormattedMessage {...messages.pageTitle} />
|
|
149
|
+
</Header>
|
|
150
|
+
<p>
|
|
151
|
+
<FormattedMessage {...messages.pageDescription} />
|
|
152
|
+
</p>
|
|
153
|
+
</Segment>
|
|
154
|
+
|
|
155
|
+
<Segment>
|
|
156
|
+
<div className="blocks-search-controls ui form">
|
|
157
|
+
<label style={{ display: 'block', marginBottom: '0.5rem' }}>
|
|
158
|
+
<FormattedMessage {...messages.selectBlockType} />
|
|
159
|
+
</label>
|
|
160
|
+
<SelectWidget
|
|
161
|
+
id="block_type"
|
|
162
|
+
title={intl.formatMessage(messages.blockTypeLabel)}
|
|
163
|
+
required={false}
|
|
164
|
+
value={selectedBlockType || ''}
|
|
165
|
+
onChange={(id, value) => handleSelect(value)}
|
|
166
|
+
choices={block_types?.map((type) => [type, type]) || []}
|
|
167
|
+
wrapped={false}
|
|
168
|
+
isClearable={false}
|
|
169
|
+
/>
|
|
170
|
+
</div>
|
|
171
|
+
</Segment>
|
|
172
|
+
|
|
173
|
+
<Segment>
|
|
174
|
+
<div className="blocks-search-results">
|
|
175
|
+
{loading && (
|
|
176
|
+
<div className="loader">
|
|
177
|
+
<FormattedMessage {...messages.loading} />
|
|
178
|
+
</div>
|
|
179
|
+
)}
|
|
180
|
+
|
|
181
|
+
{!loading && items && items.length > 0 && (
|
|
182
|
+
<>
|
|
183
|
+
<Header as="h2">
|
|
184
|
+
<FormattedMessage
|
|
185
|
+
{...messages.results}
|
|
186
|
+
values={{ count: total }}
|
|
187
|
+
/>{' '}
|
|
188
|
+
({total})
|
|
189
|
+
</Header>
|
|
190
|
+
<Table celled striped>
|
|
191
|
+
<Table.Header>
|
|
192
|
+
<Table.Row>
|
|
193
|
+
<Table.HeaderCell>
|
|
194
|
+
<FormattedMessage {...messages.title} />
|
|
195
|
+
</Table.HeaderCell>
|
|
196
|
+
<Table.HeaderCell>
|
|
197
|
+
<FormattedMessage {...messages.type} />
|
|
198
|
+
</Table.HeaderCell>
|
|
199
|
+
<Table.HeaderCell>
|
|
200
|
+
<FormattedMessage {...messages.reviewState} />
|
|
201
|
+
</Table.HeaderCell>
|
|
202
|
+
<Table.HeaderCell>
|
|
203
|
+
<FormattedMessage {...messages.created} />
|
|
204
|
+
</Table.HeaderCell>
|
|
205
|
+
<Table.HeaderCell>
|
|
206
|
+
<FormattedMessage {...messages.modified} />
|
|
207
|
+
</Table.HeaderCell>
|
|
208
|
+
</Table.Row>
|
|
209
|
+
</Table.Header>
|
|
210
|
+
<Table.Body>
|
|
211
|
+
{items.map((item) => (
|
|
212
|
+
<Table.Row key={item['@id']}>
|
|
213
|
+
<Table.Cell>
|
|
214
|
+
<a href={item['@id']}>{item.title}</a>
|
|
215
|
+
</Table.Cell>
|
|
216
|
+
<Table.Cell>{item['@type']}</Table.Cell>
|
|
217
|
+
<Table.Cell>{item.review_state}</Table.Cell>
|
|
218
|
+
<Table.Cell>
|
|
219
|
+
{item.created
|
|
220
|
+
? new Date(item.created).toLocaleDateString()
|
|
221
|
+
: '-'}
|
|
222
|
+
</Table.Cell>
|
|
223
|
+
<Table.Cell>
|
|
224
|
+
{item.modified
|
|
225
|
+
? new Date(item.modified).toLocaleDateString()
|
|
226
|
+
: '-'}
|
|
227
|
+
</Table.Cell>
|
|
228
|
+
</Table.Row>
|
|
229
|
+
))}
|
|
230
|
+
</Table.Body>
|
|
231
|
+
</Table>
|
|
232
|
+
|
|
233
|
+
{/* Pagination using Volto component */}
|
|
234
|
+
{batching && (
|
|
235
|
+
<Pagination
|
|
236
|
+
current={currentPage}
|
|
237
|
+
total={Math.ceil(total / currentPageSize)}
|
|
238
|
+
pageSize={currentPageSize}
|
|
239
|
+
pageSizes={[
|
|
240
|
+
config.settings.defaultPageSize,
|
|
241
|
+
50,
|
|
242
|
+
intl.formatMessage({ id: 'All', defaultMessage: 'All' }),
|
|
243
|
+
]}
|
|
244
|
+
onChangePage={handlePageChange}
|
|
245
|
+
onChangePageSize={handlePageSizeChange}
|
|
246
|
+
/>
|
|
247
|
+
)}
|
|
248
|
+
</>
|
|
249
|
+
)}
|
|
250
|
+
|
|
251
|
+
{!loading && selectedBlockType && items.length === 0 && (
|
|
252
|
+
<p>
|
|
253
|
+
<FormattedMessage
|
|
254
|
+
{...messages.noResults}
|
|
255
|
+
values={{ blockType: selectedBlockType }}
|
|
256
|
+
/>{' '}
|
|
257
|
+
{selectedBlockType}.
|
|
258
|
+
</p>
|
|
259
|
+
)}
|
|
260
|
+
</div>
|
|
261
|
+
</Segment>
|
|
262
|
+
</Segment.Group>
|
|
263
|
+
|
|
264
|
+
{isClient &&
|
|
265
|
+
createPortal(
|
|
266
|
+
<Toolbar
|
|
267
|
+
pathname={pathname}
|
|
268
|
+
hideDefaultViewButtons
|
|
269
|
+
inner={
|
|
270
|
+
<>
|
|
271
|
+
<Link to="/controlpanel" className="item">
|
|
272
|
+
<Icon
|
|
273
|
+
name={backSVG}
|
|
274
|
+
className="contents circled"
|
|
275
|
+
size="30px"
|
|
276
|
+
title={intl.formatMessage(messages.backToControlPanel)}
|
|
277
|
+
/>
|
|
278
|
+
</Link>
|
|
279
|
+
</>
|
|
280
|
+
}
|
|
281
|
+
/>,
|
|
282
|
+
document.getElementById('toolbar'),
|
|
283
|
+
)}
|
|
284
|
+
</Container>
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export default SearchBlocks;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ConfigType } from '@plone/registry';
|
|
2
|
+
import { defineMessages } from 'react-intl';
|
|
3
|
+
import cardsSVG from '@plone/volto/icons/cards.svg';
|
|
4
|
+
|
|
5
|
+
const messages = defineMessages({
|
|
6
|
+
controlPanelTitle: {
|
|
7
|
+
id: 'Search blocks',
|
|
8
|
+
defaultMessage: 'Search blocks',
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default function install(config: ConfigType) {
|
|
13
|
+
config.settings.controlpanels = [
|
|
14
|
+
...config.settings.controlpanels,
|
|
15
|
+
{
|
|
16
|
+
'@id': '/search-blocks',
|
|
17
|
+
group: 'General',
|
|
18
|
+
title: messages.controlPanelTitle.defaultMessage,
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
config.settings.controlPanelsIcons = {
|
|
22
|
+
...config.settings.controlPanelsIcons,
|
|
23
|
+
'blocks-search': cardsSVG,
|
|
24
|
+
};
|
|
25
|
+
return config;
|
|
26
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ConfigType } from '@plone/registry';
|
|
2
|
+
import installSettings from './config/settings';
|
|
3
|
+
|
|
4
|
+
import { searchBlocks } from './actions/searchBlocks';
|
|
5
|
+
import searchBlocksReducer from './reducers/searchBlocks';
|
|
6
|
+
import SearchBlocks from './components/SearchBlocks/SearchBlocks';
|
|
7
|
+
|
|
8
|
+
function applyConfig(config: ConfigType) {
|
|
9
|
+
installSettings(config);
|
|
10
|
+
|
|
11
|
+
config.addonReducers = {
|
|
12
|
+
...config.addonReducers,
|
|
13
|
+
searchBlocks: searchBlocksReducer,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
config.addonRoutes = [
|
|
17
|
+
...(config.addonRoutes || []),
|
|
18
|
+
{
|
|
19
|
+
path: '/controlpanel/search-blocks',
|
|
20
|
+
component: SearchBlocks,
|
|
21
|
+
},
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
return config;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default applyConfig;
|
|
28
|
+
export { searchBlocks };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SEARCH_BLOCKS,
|
|
3
|
+
SEARCH_BLOCKS_SUCCESS,
|
|
4
|
+
SEARCH_BLOCKS_FAIL,
|
|
5
|
+
} from '../constants/ActionTypes';
|
|
6
|
+
|
|
7
|
+
const initialState = {
|
|
8
|
+
error: null,
|
|
9
|
+
items: [],
|
|
10
|
+
total: 0,
|
|
11
|
+
block_types: [],
|
|
12
|
+
batching: null,
|
|
13
|
+
b_start: 0,
|
|
14
|
+
loaded: false,
|
|
15
|
+
loading: false,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default function searchBlocks(state = initialState, action = {}) {
|
|
19
|
+
switch (action.type) {
|
|
20
|
+
case SEARCH_BLOCKS:
|
|
21
|
+
return {
|
|
22
|
+
...state,
|
|
23
|
+
error: null,
|
|
24
|
+
loading: true,
|
|
25
|
+
loaded: false,
|
|
26
|
+
};
|
|
27
|
+
case SEARCH_BLOCKS_SUCCESS:
|
|
28
|
+
return {
|
|
29
|
+
...state,
|
|
30
|
+
error: null,
|
|
31
|
+
items: action.result.items || [],
|
|
32
|
+
total: action.result.items_total || 0,
|
|
33
|
+
block_types: action.result.block_types || [],
|
|
34
|
+
batching: action.result.batching || null,
|
|
35
|
+
b_start: action.result.b_start || 0,
|
|
36
|
+
loaded: true,
|
|
37
|
+
loading: false,
|
|
38
|
+
};
|
|
39
|
+
case SEARCH_BLOCKS_FAIL:
|
|
40
|
+
return {
|
|
41
|
+
...state,
|
|
42
|
+
error: action.error,
|
|
43
|
+
items: [],
|
|
44
|
+
total: 0,
|
|
45
|
+
loaded: false,
|
|
46
|
+
loading: false,
|
|
47
|
+
};
|
|
48
|
+
default:
|
|
49
|
+
return state;
|
|
50
|
+
}
|
|
51
|
+
}
|
package/towncrier.toml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[tool.towncrier]
|
|
2
|
+
filename = "CHANGELOG.md"
|
|
3
|
+
directory = "news/"
|
|
4
|
+
title_format = "## {version} ({project_date})"
|
|
5
|
+
underlines = ["", "", ""]
|
|
6
|
+
template = "./node_modules/@plone/scripts/templates/towncrier_template.jinja"
|
|
7
|
+
start_string = "<!-- towncrier release notes start -->\n"
|
|
8
|
+
issue_format = "[#{issue}](https://github.com/collective/collective-searchblocks/issue/{issue})"
|
|
9
|
+
|
|
10
|
+
[[tool.towncrier.type]]
|
|
11
|
+
directory = "breaking"
|
|
12
|
+
name = "Breaking"
|
|
13
|
+
showcontent = true
|
|
14
|
+
|
|
15
|
+
[[tool.towncrier.type]]
|
|
16
|
+
directory = "feature"
|
|
17
|
+
name = "Feature"
|
|
18
|
+
showcontent = true
|
|
19
|
+
|
|
20
|
+
[[tool.towncrier.type]]
|
|
21
|
+
directory = "bugfix"
|
|
22
|
+
name = "Bugfix"
|
|
23
|
+
showcontent = true
|
|
24
|
+
|
|
25
|
+
[[tool.towncrier.type]]
|
|
26
|
+
directory = "internal"
|
|
27
|
+
name = "Internal"
|
|
28
|
+
showcontent = true
|
|
29
|
+
|
|
30
|
+
[[tool.towncrier.type]]
|
|
31
|
+
directory = "documentation"
|
|
32
|
+
name = "Documentation"
|
|
33
|
+
showcontent = true
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"esModuleInterop": true,
|
|
4
|
+
"skipLibCheck": true,
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"moduleDetection": "force",
|
|
9
|
+
"isolatedModules": true,
|
|
10
|
+
"verbatimModuleSyntax": true,
|
|
11
|
+
"module": "preserve",
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"lib": ["es2022", "dom", "dom.iterable"],
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"paths": {
|
|
16
|
+
"@plone/volto/*": ["../../core/packages/volto/src/*"],
|
|
17
|
+
"volto-searchblocks/*": ["./src/*"]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
|
|
21
|
+
"exclude": [
|
|
22
|
+
"node_modules",
|
|
23
|
+
"build",
|
|
24
|
+
"public",
|
|
25
|
+
"coverage",
|
|
26
|
+
"**/*.test.{js,jsx,ts,tsx}",
|
|
27
|
+
"**/*.spec.{js,jsx,ts,tsx}",
|
|
28
|
+
"**/*.stories.{js,jsx,ts,tsx}"
|
|
29
|
+
]
|
|
30
|
+
}
|