diff --git a/docs/customize/look-and-feel/img/communities-dashboard.png b/docs/customize/look-and-feel/img/communities-dashboard.png
new file mode 100644
index 00000000..7e04b1c7
Binary files /dev/null and b/docs/customize/look-and-feel/img/communities-dashboard.png differ
diff --git a/docs/customize/look-and-feel/img/settings-menu.png b/docs/customize/look-and-feel/img/settings-menu.png
new file mode 100644
index 00000000..76a4950c
Binary files /dev/null and b/docs/customize/look-and-feel/img/settings-menu.png differ
diff --git a/docs/customize/look-and-feel/img/user-dashboard.png b/docs/customize/look-and-feel/img/user-dashboard.png
new file mode 100644
index 00000000..68a2902a
Binary files /dev/null and b/docs/customize/look-and-feel/img/user-dashboard.png differ
diff --git a/docs/customize/look-and-feel/menus.md b/docs/customize/look-and-feel/menus.md
new file mode 100644
index 00000000..75bf7569
--- /dev/null
+++ b/docs/customize/look-and-feel/menus.md
@@ -0,0 +1,150 @@
+# Change Menus/Tabs
+
+For navigation, InvenioRDM often uses menus or tabs. For example, one such menu is the user-dropdown menu:
+
+
+
+And one such set of tabs is at the top of the user-dashboard:
+
+
+
+In the codebase, menus and sets of tabs like those are referred as *menus*, so we do so here for the remainder of this how-to as well.
+Their options (e.g., "Uploads", "Profile") are referred as *submenus*.
+
+These *menus* can be configured in the following ways:
+
+- which submenus to show
+- what title-text to show in those submenus
+- which endpoint to request when clicking them
+- how to dynamically show/hide them (e.g. depending on currently logged-in user)
+
+## Configurable Properties
+
+Properties of existing submenus can be overridden,
+properties of newly added submenus can be freely chosen.
+All submenus share the following properties:
+
+| Name | Example values | Notes |
+|----------------|--------------------------------------|-----------------------------------------------------|
+| `endpoint` | `"invenio_app_rdm_users.uploads"` | flask-endpoint requested when clicking this submenu |
+| `order` | `1`, `2`, `10`, `-1`, `1.5` | lower ordered submenus are shown further left |
+| `text` | `_("Uploads")`, `_("Communities")` | title-text shown on submenus |
+| `visible_when` | `flask_menu.menu.CONDITION_TRUE` | when to show this submenu
- must be of type `callable[[], bool]`
- `CONDITION_TRUE` is just a named `lambda: True`
- use `CONDITION_FALSE` to hide a submenu |
+| ... | ... | in addtion to the above properties, all arguments for `flask_menu.menu:MenuNode.register` are configurable |
+
+For example, consider the user-dashboard pictured above.
+Its *Uploads* submenu has the following default configuration:
+```python
+{
+ "endpoint": "invenio_app_rdm_users.uploads",
+ "order": 1, # small number as to show this submenu left-most
+ "text": _("Uploads"),
+ "visible_when": flask_menu.menu.CONDITION_TRUE, # always show this submenu
+ ..., # advanced configuration properties omitted for brevity
+}
+```
+
+## Add new submenus to existing menu
+
+Existing menus can be extended by custom-configured submenus.
+To add a new submenu to an existing menu:
+
+1. Get the name of the to-be-added-to menu from the [list of menus](#list-of-menus)
+ For example, the user-dashboard is named `"dashboard"` (most names of menus/submenus are straightforward).
+2. Write a function that registers the new submenu
+ ```python
+ # ext.py # ext.py is commonly used, you may use another file though
+
+ from flask_menu import current_menu
+ from invenio_i18n import lazy_gettext as _ # for translations
+
+ def finalize_app():
+ # get the user-dashboard menu via its name "dashboard":
+ user_dashboard_menu = current_menu.submenu("dashboard")
+
+ # register a new submenu to the user-dashboard:
+ user_dashboard_menu.register(
+ "name-of-submenu",
+ endpoint="my_blueprint.my_endpoint",
+ order=4, # the three already existing submenus have `order` 1 through 3
+ text=_("Title of new Submenu"), # could also use an untranslated bare string
+ # note: could add other properties here, otherwise their default is used
+ # note: `visible_when` defaults to always visible
+ )
+
+ ... # could .register more submenus here (or do so in another package)
+ ```
+3. Register your function with the `invenio_base.finalize_app` entrypoint.
+ This will make your function be called at the app-finalization build-step.
+ For example, when using setuptools' `setup.cfg` with your python package, add:
+ ```ini
+ # setup.cfg
+
+ [options.entry_points]
+ invenio_base.finalize_app =
+ my_package_name = my_package_name.ext:finalize_app
+ ```
+
+!!! info "For entrypoints to take effect"
+ For entrypoint changes to be picked up, you will need to reinstall the python package.
+ *This is necessary even if the package is installed editably!*
+
+ After entrypoint changes are picked up,
+ you will further need to restart the server for changes to take effect:
+ ```shell
+
+ invenio-cli run
+ ```
+
+## Modify existing submenus
+
+The defaults of submenus' properties are selectively overridable via config-variables.
+To modify an existing submenu's properties:
+
+1. Find the name of the corresponding override-variable in the [list of menus](#list-of-menus)
+ For example, the override-variable for the user-dashboard is named `USER_DASHBOARD_MENU_OVERRIDES`.
+2. Find the name of the to-be-overridden submenu in that same [list of menus](#list-of-menus)
+ For example, the user-dashboard has a submenu for communities.
+ This submenu is named (obviously enough) `"communities"`.
+3. Add to your `invenio.cfg`:
+ ```python
+ # invenio.cfg
+
+ from flask_menu.menu import CONDITION_FALSE
+
+ USER_DASHBOARD_MENU_OVERRIDES = {
+ "communities": {
+ "visible_when": CONDITION_FALSE,
+ # other properties will be left unchanged
+ }
+ # other submenus will be left unchanged
+ }
+ ```
+
+The above example hides the *Communities* submenu from the user-dashboard menu
+by overriding its `visible_when` property.
+For other overridable properties see [configurable properties](#configurable-properties).
+
+!!! info "Have you tried to turn it off and on again?"
+ You will need to restart the server for changes to take effect:
+ ```shell
+
+ invenio-cli run
+ ```
+
+!!! warning "On overriding user-added submenus: DON'T"
+ Currently, (sub)menu-overrides are adopted at app-finalization.
+ Users adding their own submenus (as described above) is also done at app-finalization.
+ Hence attempting to override submenus added by (other) users depends on
+ loading order of app-finalization entrypoints and might break anytime.
+
+## List of menus
+
+The following list of menus is non-exhaustive.
+Not all menus are overridable, but all menus can be extended by additional submenus.
+
+| Image | Description | Name of menu and its submenus | Name of override-variable |
+|-------|-------------|-------------------------------|---------------------------|
+|  | Dashboard on user's personal page | `"dashboard"`
├─`"uploads"`
├─`"communities"`
└─`"requests"` | `USER_DASHBOARD_MENU_OVERRIDES` |
+|  | Dashboard on communities page | `"communities"`
├─`"home"`
├─`"search"`
├─`"requests"`
├─`"submit"`
├─`"members"`
├─`"settings"`
├─`"curation_policy"`
└─`"about"` | No associated override-variable |
+|  | User settings menu | `"settings"`
├─`"profile"`
├─`"change_password"`
├─`"security"`
├─`"notifications"`
├─`"oauthclient"`
└─`"applications"` | No associated override-variable |
diff --git a/docs/customize/metadata/custom_fields/records.md b/docs/customize/metadata/custom_fields/records.md
index a912750d..921ce9c2 100644
--- a/docs/customize/metadata/custom_fields/records.md
+++ b/docs/customize/metadata/custom_fields/records.md
@@ -283,7 +283,7 @@ You should add the `my_template.html` file in the `my-site/templates` folder in
- `field_value`: the value of the field, as it is stored in the record after the UI serialization i.e. what is returned from the `ui_field` method when you [define your custom field](../../../develop/howtos/custom_fields.md).
- `field_cfg`: the UI configuration for that specific field as it is defined in the `RDM_CUSTOM_FIELDS_UI` config.
-See the example in the [How-to](../../../develop/howtos/custom_fields.md#define-the-template-for-the-record-landing-page).
+See the example in the [How-to](../../../develop/howtos/custom_fields.md).
### Search
diff --git a/docs/customize/vocabularies/names.md b/docs/customize/vocabularies/names.md
index 79e72fa2..2dd4647a 100644
--- a/docs/customize/vocabularies/names.md
+++ b/docs/customize/vocabularies/names.md
@@ -17,7 +17,7 @@ A _Name_ record contains:
are present they will overwrite `name`.
- A list of `identifiers`, composed by their identifier value and scheme.
The scheme can potentially be autocompleted if it is known by the _idutils_
- library (e.g. ORCiD).
+ library (e.g. ORCID).
- A list of `affiliations`, which can be represented by its `name` or, if it
belongs to the _Affiliations_ vocabulary, by its `id`.
@@ -96,7 +96,7 @@ invenio vocabularies update \
### Creating a `names.yaml` file
The Names vocabulary has been implemented with the
-[ORCiD public dataset](https://orcid.figshare.com/articles/dataset/ORCID_Public_Data_File_2021/16750535?file=31020067)
+[ORCID public dataset](https://support.orcid.org/hc/en-us/articles/360006897394-How-do-I-get-the-public-data-file)
as a possible source to import entries from. This means that the functionality
to **read** entries from this format is already available. For example, you
can use the `vocabularies convert` command to convert this dataset into a YAML
@@ -112,7 +112,7 @@ invenio vocabularies convert \
Alternatively, you can simply import it directly:
!!! warning "Long and blocking operation"
- Note that the import process is done synchronously and the ORCiD dataset is
+ Note that the import process is done synchronously and the ORCID dataset is
very large. Therefore, this operation can take a long time.
```bash
diff --git a/docs/develop/howtos/custom_code.md b/docs/develop/howtos/custom_code.md
index 5c333eff..9cdd99ba 100644
--- a/docs/develop/howtos/custom_code.md
+++ b/docs/develop/howtos/custom_code.md
@@ -24,7 +24,7 @@ To generate the site folder, you will need to select option `1 - yes` (this is a
```python hl_lines="3"
[packages]
...
-my-site = {editable="True", path="./site"}
+my-site = {editable=true, path="./site"}
```
This means that the site folder will be installed as a package with the name `my-site`, and it is editable. This package now works as any other package installed in your instance (`invenio-app-rdm`, `invenio-communities`, etc.), allowing you to customize your instance and create new views and features without adding a separate package manually.
diff --git a/docs/develop/howtos/restrict_access.md b/docs/develop/howtos/restrict_access.md
new file mode 100644
index 00000000..05d91412
--- /dev/null
+++ b/docs/develop/howtos/restrict_access.md
@@ -0,0 +1,52 @@
+# How to restrict access to pages
+
+Sometimes it can be desirable to live by the motto "better safe than sorry", especially regarding potentially sensitive features like the administration panel (enabled in InvenioRDM v12).
+
+This guide briefly describes how to narrow down access to subsets of the system.
+
+
+## Restricting access for IP ranges via `nginx`
+
+While most features in InvenioRDM are guarded by configurable permission policies, this isn't necessarily always the case.
+For these exceptions, as well as extra precautions generally, it can be beneficial to restrict access on an `nginx` level.
+
+!!! info "Current exceptions"
+ At the time of writing, one of these exceptions is the administration panel which has a hard-coded check for the `administration-access` action.
+
+An access restriction based on the client's IP address can be put into place via the `nginx` configuration, e.g. by adding nested `location` directives in the existing configuration:
+
+```nginx
+location / {
+ uwsgi_pass ui_server;
+ include uwsgi_params;
+ # ... your configuration for the UI paths ...
+
+ # restrict access to the administration panel UI to your network only
+ location /administration/ {
+ # action directives like `uwsgi_pass` aren't inherited like other configs
+ uwsgi_pass ui_server;
+
+ # allow your networks (replace with your IP ranges)
+ allow 128.130.0.0/15;
+ allow 192.35.240.0/22;
+ allow 2001:629::/32;
+ # etc.
+
+ # also allow localhost and private networks (e.g. for local access through Docker)
+ allow 127.0.0.1/8;
+ allow ::1/128;
+ allow 10.0.0.0/8;
+ allow 172.16.0.0/12;
+ allow 192.168.0.0/16;
+ allow fd00::/8;
+
+ # disallow anybody else
+ deny all;
+ }
+}
+```
+
+!!! info "The `uwsgi_pass` directive doesn't get inherited"
+ Note that the `uwsgi_pass` directive is part of a [class of directives that do not get inherited in nested locations](https://forum.nginx.org/read.php?2,243488,243488) and thus has to be specified explicitly again.
+
+Restricting access to API endpoints follows a similar schema, but in the `location /api` block and with `uwsgi_pass api_server` instead.
diff --git a/docs/develop/index.md b/docs/develop/index.md
index 62eca14c..29e4149b 100644
--- a/docs/develop/index.md
+++ b/docs/develop/index.md
@@ -53,6 +53,7 @@ Step-by-step guides on how to perform certain tasks:
- [Fix a vulnerability](howtos/security-fix.md)
- [Test emails locally](howtos/dev_email.md)
- [Migrate legacy routes](howtos/route_migration.md)
+- [Restrict access to pages](howtos/restrict_access.md)
## Architecture
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index 253016d8..d6dd4526 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -480,3 +480,7 @@ invenio rdm rebuild-all-indices -o users,communities,records,requests,request_ev
if you don't specify services, The following services will be reindexed:
`users, groups, domains, communities, members, records, record-media-files, affiliations, awards, funders, names, subjects, vocabularies, requests, request_events, oaipmh-server`
+
+Note that the users, groups, and members use bulk indexing and rely on celery running. They will not be reindexed if celery is not running.
+
+This command does not impact usage statistics indexes. You need to manually restore statistics indexes [from a backup](../develop/howtos/backup_search_indices.md).
diff --git a/docs/reference/metadata.md b/docs/reference/metadata.md
index b4383be3..d07554f4 100644
--- a/docs/reference/metadata.md
+++ b/docs/reference/metadata.md
@@ -117,7 +117,7 @@ External PIDs are persistent identifiers managed via [Invenio-PIDStore](https://
with external registration services.
Persistent identifiers are globally unique in the system, thus you cannot have two records
-with the same system-managed persistent identifier (see also [Metadata > Identifiers](#identifiers-0-n)).
+with the same system-managed persistent identifier (see also [Metadata > Identifiers](#alternate-identifiers-0-n)).
You can add a DOI that is not managed by InvenioRDM by using the provider `external`. You are not able to add `external` DOIs that have a prefix that is configured as part of a different PID provider.
@@ -1091,7 +1091,7 @@ Example:
IIIF links are only returned for files who are compatible with IIIF.
Those formats are defined by the `IIIF_FORMATS` configuration variable.
By default _gif_, _jp2_, _jpeg_, _jpg_, _png_, _tif_, and _tiff_.
-
+
### Default preview (0-1)
The default preview field names the filename of the file which should by default
diff --git a/docs/reference/rest_api_communities.md b/docs/reference/rest_api_communities.md
index 1228c33b..11f64390 100644
--- a/docs/reference/rest_api_communities.md
+++ b/docs/reference/rest_api_communities.md
@@ -779,7 +779,7 @@ Content-Type: application/json
|----------------|--------|----------|-----------------------------------------------------------------------------------------------|
| `accept` | string | header | - `application/json` (default)
- `application/vnd.inveniordm.v1+json` |
| `community_id` | string | path | ID of the community. |
-| `start_date` | string | body | Required, datetime in iso format. Community will be featured from this point in time onwards. |
+| `start_date` | string | body | Required, ISO 8601 DateTime format in UTC (YYYY-MM-DDTHH:MM:SS.ssssssZ). Community will be featured from this point in time onwards. |
**Request**
diff --git a/docs/reference/rest_api_drafts_records.md b/docs/reference/rest_api_drafts_records.md
index 4e737079..86c924dc 100644
--- a/docs/reference/rest_api_drafts_records.md
+++ b/docs/reference/rest_api_drafts_records.md
@@ -29,6 +29,8 @@ Used for interacting with unpublished or edited draft records.
| `default_preview` | string | body | Filename of file to be previewed by default. |
| `order` | array | body | Array of filename strings in display order. |
+A file must be uploaded to the draft before it can be used as the default
+preview. See "[Start a draft file upload](#start-draft-file-uploads)" below.
**Request**
@@ -285,7 +287,7 @@ Content-Type: application/json
| Name | Type | Location | Description |
| ---------- | ------ | -------- | ------------------------------------------------------------ |
| `id` | string | path | Identifier of the record, e.g. `4d0ns-ntd89` |
-| `access` | object | body | [Access options](metadata.md#access-information) for the record. |
+| `access` | object | body | [Access options](metadata.md#access) for the record. |
| `files` | object | body | [Files options](#files-options) for the record. |
| `metadata` | object | body | [Metadata](metadata.md#metadata) of the record. |
| `custom_fields` | object | body | [Custom fields](../customize/metadata/custom_fields/records.md#declaring-custom-fields) metadata for the record. (v10 and newer) |
@@ -1591,7 +1593,7 @@ Access links are URLs that can be shared with others to give them access and per
| -------- | ------ | -------- | ------------------------------------------------------------ |
| `id` | string | path | Identifier of the record, e.g. `cbc2k-q9x58` |
| `accept` | string | header | - `application/json` (default)
- `application/vnd.inveniordm.v1+json` |
-| `expires_at` | string | body | Date time string. When the link expires. |
+| `expires_at` | string | body | `ISO 8601 Date`Format (YYYY-MM-DD) When the link expires. |
| `permission` | string | body | Required. Action that can be undertaken with the link (``view``, ``preview`` or ``edit``). |
@@ -1602,7 +1604,8 @@ POST /api/records/{id}/access/links HTTP/1.1
Content-Type: application/json
{
- "permission": "view"
+ "permission": "view",
+ "expires_at": "2024-11-06"
}
```
@@ -1613,11 +1616,12 @@ HTTP/1.1 201 CREATED
Content-Type: application/json
{
- "permission": "view",
- "created_at": "2021-03-25T21:06:29.563235",
- "token": "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6IjNkMzMyMGVhLTA3NTUtNGQ5My1hNzZlLWUyZjJmYzY1NWQyYSIsImRhdGEiOnt9LCJyYW5kb20iOiI2NzZhYTk3OTczMzgwMjkyNTJiM2MwZDBjNjliMTVkYSJ9.dBqk7YzIZ7kwG4oijNgH1VU-cjQmBiQlMQKMoB2y-YjVWmgnZetFAESsqRP6VpGTtaKdftrtob1PVZJF4YGpfg",
- "id": "3d3320ea-0755-4d93-a76e-e2f2fc655d2a",
- "expires_at": null
+ "id": "07fb00f3-928c-4ce9-8d2e-8e9c4dca3092",
+ "created_at": "2024-06-12T13:07:09.951029+00:00",
+ "expires_at": "2024-11-06",
+ "permission": "view",
+ "description": "",
+ "token": "eyJhbGciOiJIUzUxMiIsImlhdCI6MTcxODE5NzYyOSwiZXhwIjoxNzMwODUxMTk5fQ.eyJpZCI6IjA3ZmIwMGYzLTkyOGMtNGNlOS04ZDJlLThlOWM0ZGNhMzA5MiIsImRhdGEiOnt9LCJyYW5kb20iOiI1NzVjNzEwY2QwNWI3YWFhMTM2MzY3ZmMzZWFkYzA0MSJ9.GPfPBvrbvEu-JMddFXjb5MZKNWRnzAK53oTVOSgfdZOcMIoRfszO39GEglko74dohZiUcJ11jWXj0fwfdq1WnQ"
}
```
@@ -1647,11 +1651,12 @@ HTTP/1.1 200 OK
Content-Type: application/json
{
- "permission": "view",
- "created_at": "2021-03-25T21:06:29.563235",
- "token": "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6IjNkMzMyMGVhLTA3NTUtNGQ5My1hNzZlLWUyZjJmYzY1NWQyYSIsImRhdGEiOnt9LCJyYW5kb20iOiI2NzZhYTk3OTczMzgwMjkyNTJiM2MwZDBjNjliMTVkYSJ9.dBqk7YzIZ7kwG4oijNgH1VU-cjQmBiQlMQKMoB2y-YjVWmgnZetFAESsqRP6VpGTtaKdftrtob1PVZJF4YGpfg",
- "id": "3d3320ea-0755-4d93-a76e-e2f2fc655d2a",
- "expires_at": null
+ "id": "61c2d20f-4c88-440d-9978-dd16a69bf97e",
+ "created_at": "2024-06-12T13:23:11.271139+00:00",
+ "expires_at": "2024-11-06",
+ "permission": "view",
+ "description": "",
+ "token": "eyJhbGciOiJIUzUxMiIsImlhdCI6MTcxODE5ODU5MSwiZXhwIjoxNzMwODUxMTk5fQ.eyJpZCI6IjYxYzJkMjBmLTRjODgtNDQwZC05OTc4LWRkMTZhNjliZjk3ZSIsImRhdGEiOnt9LCJyYW5kb20iOiI2MWYwZTg4YjgzY2E2ZDhkMjJiMTY0MGFjNmIzMmEwZiJ9.AFEmgQ8_gtEj7dvlZ2MHD9qneKy0UEC1HMByo8J5xVGMYG8PXwuRsyUgeq_k_ZeHybO5W4_Do_P4NVGXsrjHyg"
}
```
@@ -1663,10 +1668,10 @@ Content-Type: application/json
| Name | Type | Location | Description |
| -------- | ------ | -------- | ------------------------------------------------------------ |
-| `id` | string | path | Identifier of the record, e.g. `cbc2k-q9x58` |
-| `link-id` | string | path | Identifier of the link, e.g. `3d3320ea-0755-4d93-a76e-e2f2fc655d2a` |
+| `id` | string | path | Identifier of the record, e.g. `cbc2k-q9x58` |
+| `link-id` | string | path | Identifier of the link, e.g. `3d3320ea-0755-4d93-a76e-e2f2fc655d2a` |
| `accept` | string | header | - `application/json` (default)
- `application/vnd.inveniordm.v1+json` |
-| `expires_at` | string | body | Date time string. When the link expires. |
+| `expires_at` | string | body | `ISO 8601 Date`Format (YYYY-MM-DD) When the link expires. |
| `permission` | string | body | Required. Action that can be undertaken with the link. |
**Request**
@@ -1677,7 +1682,7 @@ Content-Type: application/json
{
"permission": "edit",
- "expires_at": "2121-03-25T21:06:29.563235"
+ "expires_at": "2024-11-06"
}
```
@@ -1688,11 +1693,12 @@ HTTP/1.1 200 OK
Content-Type: application/json
{
- "permission": "edit",
- "created_at": "2021-03-25T21:06:29.563235",
- "token": "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6IjNkMzMyMGVhLTA3NTUtNGQ5My1hNzZlLWUyZjJmYzY1NWQyYSIsImRhdGEiOnt9LCJyYW5kb20iOiI2NzZhYTk3OTczMzgwMjkyNTJiM2MwZDBjNjliMTVkYSJ9.dBqk7YzIZ7kwG4oijNgH1VU-cjQmBiQlMQKMoB2y-YjVWmgnZetFAESsqRP6VpGTtaKdftrtob1PVZJF4YGpfg",
- "id": "3d3320ea-0755-4d93-a76e-e2f2fc655d2a",
- "expires_at": "2121-03-25T21:06:29.563235"
+ "id": "df672812-6b23-411a-b40a-9bb22787f0a2",
+ "created_at": "2024-06-12T12:48:43.724970+00:00",
+ "expires_at": "2024-11-06",
+ "permission": "edit",
+ "description": "",
+ "token": "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6ImRmNjcyODEyLTZiMjMtNDExYS1iNDBhLTliYjIyNzg3ZjBhMiIsImRhdGEiOnt9LCJyYW5kb20iOiIwZWE3ZWQ5YTBiZTE3N2ZjMjE4YjNjYzY3M2RiOTI5OSJ9.kqJ_gTvgjEc_-1Jxv-XHqSCUmOpcQDdBzx-T5BP7ybvQItK91wGxmVT_gfHxyHHDQ_7e8_LH1A5TotAZCA8q_w"
}
```
@@ -1747,16 +1753,17 @@ Content-Type: application/json
{
"hits": {
- "hits": [
- {
- "permission": "view",
- "id": "140f69c9-a8a5-41d4-8ae2-3dfbfe0e2796",
- "created_at": "2021-03-25T21:48:03.289198",
- "expires_at": null,
- "token": "eyJhbGciOiJIUzUxMiJ9.eyJpZCI6IjE0MGY2OWM5LWE4YTUtNDFkNC04YWUyLTNkZmJmZTBlMjc5NiIsImRhdGEiOnt9LCJyYW5kb20iOiI2NzE3MmY4MTNkYzhkNGJjZDAwOWFlOTlhOWM3NjU1MSJ9.1O9MwTmt_nfvsCm4qvlkUH0Rpe5bK3hT422A879DJSblOCONsNxPe_feNHrgTV3s6ZA6t6vLziXjhAwgKjHhIQ"
- }
- ],
- "total": 1
+ "hits": [
+ {
+ "id": "61c2d20f-4c88-440d-9978-dd16a69bf97e",
+ "created_at": "2024-06-12T13:23:11.271139+00:00",
+ "expires_at": "2024-11-06",
+ "permission": "edit",
+ "description": "",
+ "token": "eyJhbGciOiJIUzUxMiIsImlhdCI6MTcxODE5ODU5MSwiZXhwIjoxNzMwODUxMTk5fQ.eyJpZCI6IjYxYzJkMjBmLTRjODgtNDQwZC05OTc4LWRkMTZhNjliZjk3ZSIsImRhdGEiOnt9LCJyYW5kb20iOiI2MWYwZTg4YjgzY2E2ZDhkMjJiMTY0MGFjNmIzMmEwZiJ9.AFEmgQ8_gtEj7dvlZ2MHD9qneKy0UEC1HMByo8J5xVGMYG8PXwuRsyUgeq_k_ZeHybO5W4_Do_P4NVGXsrjHyg"
+ }
+ ],
+ "total": 1
}
}
```
diff --git a/docs/reference/rest_api_requests.md b/docs/reference/rest_api_requests.md
index a0c1aa30..4de5f8ad 100644
--- a/docs/reference/rest_api_requests.md
+++ b/docs/reference/rest_api_requests.md
@@ -80,16 +80,13 @@ PUT /api/requests/{request_id} HTTP/1.1
Content-Type: application/json
{
- "created_by": {"user": "1"},
"expires_at": null,
"id": "{request_id}",
"number": "{request_number}",
- "receiver": {"user": "2"},
"revision_id": 1,
"status": "draft",
"title": "A new title",
- "topic": {"record": "abcd-1234"},
- "type": "default-request",
+ "type": "default-request"
}
```
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
index c358c25f..a679ff8d 100644
--- a/docs/stylesheets/extra.css
+++ b/docs/stylesheets/extra.css
@@ -1,249 +1,156 @@
-.md-typeset a,
-.md-nav__link--active {
- color: #000000;
- opacity: 0.54;
-}
-
-.md-typeset a:hover,
-.md-nav__link:hover {
- color: #000000;
-}
-
-.md-nav__title {
- color: unset;
-}
-
-.md-typeset table code {
- word-break: normal;
-}
-
-[data-md-color-primary="white"] .md-header {
- background: linear-gradient(
- 90deg,
- rgba(3, 119, 205, 1),
- rgba(3, 119, 205, 1) 52.52%,
- rgba(251, 130, 115, 0.69))
- no-repeat;
- color: #ffffff;
-}
-[data-md-color-primary="white"] .md-tabs {
- background: linear-gradient(
+/*
+ Copyright (C) 2018-2024 CERN.
+ Copyright (C) 2018-2024 Northwestern University.
+ Copyright (C) 2022-2024 KTH Royal Institute of Technology.
+
+ Invenio is free software; you can redistribute it and/or modify it
+ under the terms of the MIT License; see LICENSE file for more details.
+*/
+/* Color variables
+https://github.com/squidfunk/mkdocs-material/blob/master/src/templates/assets/stylesheets/main/_colors.scss
+*/
+:root {
+ --color-invenio: #0377cd;
+ --color-black: #000000;
+ --color-white: #ffffff;
+ --color-gray: #707070;
+ --color-dark-blue: #003258;
+ --color-light-coral: rgba(251, 130, 115, 0.69);
+}
+
+[data-md-color-scheme='default'] {
+ --md-primary-fg-color: var(--color-gray);
+ --md-primary-fg-color--light: var(--color-invenio);
+ --md-primary-fg-color--dark: var(--color-dark-blue);
+ --gradient-header: linear-gradient(
90deg,
- rgba(3, 119, 205, 1),
- rgba(3, 119, 205, 1) 52.52%,
- rgba(251, 130, 115, 0.69))
- no-repeat;
- color: #ffffff;
-}
-
-.md-search form.md-search__form {
- background-color: rgba(255,255,255, 0.1);
- color: #fff;
- transition: 0.3 ease-in;
-}
-
-.md-search form.md-search__form:hover {
- background-color: rgba(255,255,255, 0.5);
- color: rgba(0,0,0,0.54);
-}
-
-.md-search form.md-search__form:hover .md-search__input::placeholder {
- color: rgba(0,0,0,0.54);
-}
-
-.md-search form.md-search__form:hover .md-search__icon.md-icon svg {
- fill: rgba(0,0,0,0.54);
-}
-
-[data-md-toggle=search]:checked~.md-header .md-search__inner .md-search__icon.md-icon svg {
- fill: rgba(0,0,0,0.54);
-}
-
-.md-search form.md-search__form .md-search__input::placeholder {
- color: #fff;
-}
-
-.md-search form.md-search__form .md-search__icon.md-icon svg {
- fill: #fff;
- transition: 0.3s;
-}
-
-.md-header[data-md-state="shadow"] {
- box-shadow: none;
- border-bottom: 0.05rem solid #ffffff;
-}
-
-.md-header__topic:first-child {
- font-weight: unset;
-}
-
-.md-source__facts {
- display: none;
-}
-
-.md-logo img {
- width: 131px !important;
- height: 28px !important;
-}
-
-.md-footer {
- border-top: 0.05rem solid #ffffff;
- background-color: #0377cd;
-}
-
-.md-footer__link {
- padding-top: 0.8rem;
- padding-bottom: 0;
- color: #ffffff;
- opacity: 0.75;
- margin-bottom: 0;
- margin-top: 0;
-}
-
-.md-footer__direction {
- color: #ffffff;
- opacity: 0.75;
- font-size: .64rem;
- left: 0;
- position: absolute;
- right: 0;
- padding: 0 1rem;
- margin-top: -1rem;
-}
-
-.md-footer__title {
- line-height: 2.4rem;
- position: relative;
- margin-bottom: 0;
-}
-
-.md-footer .made-with {
- color: var(--md-footer-fg-color--lighter);
- font-size: .64rem;
-}
-
-.md-footer__link:hover,
-.md-footer__direction:hover {
- opacity: 1;
-}
+ var(--color-invenio),
+ var(--color-invenio) 52.52%,
+ var(--color-light-coral)
+ ) no-repeat;
+
+ .md-nav__link--active {
+ color: var(--color-black);
+ opacity: 0.54;
+ }
-.md-footer-meta {
- background-color: rgb(1, 98, 170);
-}
+ .md-typeset a:hover,
+ .md-nav__link:hover {
+ color: var(--color-black);
+ }
-html .md-footer-meta .md-footer-meta__inner a {
- color: #ffffff;
-}
+ .md-nav__title {
+ color: unset;
+ }
-.md-footer-meta__inner {
- padding: 0 0.2rem;
-}
+ .md-tabs__link {
+ color: inherit;
+ }
-.md-footer-copyright {
- padding: 0.7rem 0;
- color: var(--md-footer-fg-color--lighter);
- font-size: .64rem;
- width: auto;
- margin: auto .6rem;
-}
+ .md-header,
+ .md-tabs {
+ background: var(--gradient-header);
+ color: var(--color-white);
+ }
-.md-footer-copyright__highlight {
- color: var(--md-footer-fg-color--light);
-}
+ .md-search form.md-search__form {
+ background-color: rgba(255, 255, 255, 0.1);
+ color: var(--color-white);
+ transition: 0.3 ease-in;
+ }
-.md-footer-social {
- padding: 0.4rem 0;
- margin: 0 .4rem;
-}
+ .md-search form.md-search__form:hover {
+ color: rgba(0, 0, 0, 0.54);
+ }
-.md-footer-social__link svg {
- fill: currentColor;
- max-height: .8rem;
- vertical-align: -25%;
-}
+ .md-header[data-md-state='shadow'] {
+ box-shadow: none;
+ border-bottom: 0.05rem solid var(--color-white);
+ }
-.md-search-result__link[data-md-state="active"] {
- background-color: #ffffff;
-}
+ .md-footer {
+ background-color: var(--color-invenio);
+ }
-.md-typeset h1[id] .headerlink:focus,
-.md-typeset h1[id]:hover .headerlink:hover,
-.md-typeset h1[id]:target .headerlink,
-.md-typeset h2[id] .headerlink:focus,
-.md-typeset h2[id]:hover .headerlink:hover,
-.md-typeset h2[id]:target .headerlink,
-.md-typeset h3[id] .headerlink:focus,
-.md-typeset h3[id]:hover .headerlink:hover,
-.md-typeset h3[id]:target .headerlink,
-.md-typeset h4[id] .headerlink:focus,
-.md-typeset h4[id]:hover .headerlink:hover,
-.md-typeset h4[id]:target .headerlink,
-.md-typeset h5[id] .headerlink:focus,
-.md-typeset h5[id]:hover .headerlink:hover,
-.md-typeset h5[id]:target .headerlink,
-.md-typeset h6[id] .headerlink:focus,
-.md-typeset h6[id]:hover .headerlink:hover,
-.md-typeset h6[id]:target .headerlink {
- color: #0377cd;
-}
+ .rdm-hero-bg {
+ background: linear-gradient(
+ 12deg,
+ rgba(3, 119, 205, 1),
+ rgba(3, 119, 205, 1) 52.52%,
+ rgba(251, 130, 115, 0.69)
+ );
+ }
-.md-typeset .md-button--primary {
- color: #0377cd;
-}
+ .rdm-hero .rdm-hero-subtitle {
+ color: rgba(255, 255, 255, 0.6);
+ }
-[data-md-color-primary="white"] .md-typeset .md-button.md-button--primary {
- background-color: var(--md-primary-fg-color);
- border-color: var(--md-primary-fg-color);
- color: #0377cd;
+ body[data-md-color-scheme] .md-main {
+ background-color: var(--color-white);
+ }
}
-[data-md-color-primary="white"] .md-typeset .md-button {
- color: var(--md-primary-fg-color);
+/* Dark mode */
+/* --------- */
+[data-md-color-scheme='slate'] {
+ .rdm-hero-bg {
+ background: linear-gradient(
+ 12deg,
+ hsla(205, 99%, 30%, 0.432),
+ rgba(1, 88, 150, 0.438) 52.52%,
+ rgba(179, 93, 81, 0.329)
+ );
+ }
}
-::placeholder {
- color: #ffffff;
-}
+/* Common styles */
+/* ------------- */
-.rdm-toc {
- display: flex;
- justify-content: center;
-}
+.rdm-hero {
+ height: 557px;
+ text-align: center;
+ margin-bottom: -2px;
-.rdm-toc-item.level1 {
- display: inline-flex;
-}
+ > img {
+ margin-top: 75px;
+ height: 80px;
+ }
-.rdm-toc-item.level1 > div > a {
- font-weight: bolder;
-}
+ > a.md-button:hover {
+ background-color: var(--color-white);
+ border-color: var(--color-white);
+ color: var(--color-invenio);
+ }
-.rdm-toc-item.level1 > div {
- width: 200px;
+ .rdm-hero-subtitle {
+ font-size: 30px;
+ font-weight: 300;
+ font-family: Oswald, 'Open Sans', sans-serif;
+ margin: 15px 0px 20px 0px;
+ }
}
-.rdm-toc-item.level2 {
- font-size: small;
+.rdm-hero > a.md-button.md-button--primary:hover {
+ background-color: transparent;
+ border-color: var(--color-white);
+ color: var(--color-white);
}
.rdm-hero-bg {
display: block;
width: 100%;
height: 673px;
- background: linear-gradient(
- 12deg,
- rgba(3, 119, 205, 1),
- rgba(3, 119, 205, 1) 52.52%,
- rgba(251, 130, 115, 0.69));
position: absolute;
top: 0;
z-index: -1;
}
.rdm-hero-bg .wave-svg {
+ fill: var(--md-default-bg-color);
width: 100%;
position: absolute;
bottom: 0;
+ transform: translateY(1px);
}
@media screen and (min-width: 1920px) {
@@ -264,74 +171,53 @@ html .md-footer-meta .md-footer-meta__inner a {
}
}
-@media screen and (min-width: 3500px) {
- .rdm-hero-bg {
- height: 900px;
- }
-}
-
-@media screen and (min-width: 4000px) {
+@media screen and (min-width: 4500px) {
.rdm-hero-bg {
- height: 950px;
- }
-}
+ height: 1000px;
-@media screen and (min-width: 4500px) {
- .rdm-hero-bg .wave-svg {
- display: none;
+ .wave-svg {
+ display: none;
+ }
}
}
-.rdm-hero {
- height: 557px;
- text-align: center;
- margin-bottom: -2px;
-}
-
-.rdm-hero > img {
- margin-top: 75px;
- height: 80px;
+.md-typeset table code {
+ word-break: normal;
}
-.rdm-hero .rdm-hero-subtitle {
- font-size: 30px;
- font-weight: 300;
- font-family: Oswald, "Open Sans", sans-serif;
- color: rgba(255, 255, 255, 0.6);
- margin: 15px 0px 20px 0px;
+.md-typeset .md-button.md-button--primary {
+ background-color: var(--color-white);
+ border-color: var(--color-white);
+ color: var(--color-invenio);
+ opacity: 100%;
}
-.rdm-hero > a {
- opacity: 1;
+.md-typeset .md-button--primary {
+ color: var(--color-white);
+ opacity: 100%;
}
-.rdm-hero > a.md-button.md-button--primary:hover {
- background-color: transparent;
- border-color: white;
- color: white;
+.md-typeset .md-button {
+ color: var(--color-white);
}
-.rdm-hero > a.md-button:hover {
- background-color: white;
- border-color: white;
- color: #0377cd;
+.rdm-toc {
+ display: flex;
+ justify-content: center;
}
-.frontpage .md-main > .md-main__inner, .frontpage .md-main .md-content__inner {
- margin-top: 0;
- padding-top: 0;
+.rdm-toc-item.level1 {
+ display: inline-flex;
}
-.frontpage .md-header {
- background: transparent;
- position: static;
+.rdm-toc-item.level1 > div > a {
+ font-weight: bolder;
}
-.frontpage .md-tabs {
- border-bottom: none;
- background: transparent;
+.rdm-toc-item.level1 > div {
+ width: 200px;
}
-.frontpage .md-main {
- background-color: white;
+.rdm-toc-item.level2 {
+ font-size: small;
}
diff --git a/mkdocs.yml b/mkdocs.yml
index 26c77687..c8e4262b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -10,11 +10,28 @@ copyright: "Copyright © 2019-2024 CERN, Northwestern University and contrib
# Configuration
theme:
- name: "material"
- custom_dir: "theme/"
+ name: material
+ custom_dir: theme
palette:
- primary: "white"
- accent: "white"
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ primary: custom
+ accent: custom
+ extra_css:
+ - stylesheets/extra.css
+ toggle:
+ icon: material/brightness-7
+ name: Switch to dark mode
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ primary: black
+ accent: orange
+ toggle:
+ accent: orange
+ icon: material/brightness-4
+ name: Switch to light mode
font: false
logo: "images/logo-rdm.png"
favicon: "images/favicon.svg"
@@ -55,6 +72,7 @@ nav:
- Change templates: "customize/look-and-feel/templates.md"
- Change theme: "customize/look-and-feel/theme.md"
- Change font: "customize/look-and-feel/font.md"
+ - Change menus: "customize/look-and-feel/menus.md"
- Authentication: "customize/authentication.md"
- Sending emails: "customize/emails.md"
- Search:
@@ -121,6 +139,7 @@ nav:
- Test emails locally: develop/howtos/dev_email.md
- Migrate legacy routes: develop/howtos/route_migration.md
- Back up search indices: develop/howtos/backup_search_indices.md
+ - Restrict access to pages: develop/howtos/restrict_access.md
- Architecture:
- Introduction: develop/architecture/index.md
- Infrastructure: develop/architecture/infrastructure.md
@@ -224,8 +243,8 @@ nav:
# Customization
extra:
social:
- - icon: "fontawesome/brands/github"
- link: "https://github.com/inveniosoftware"
+ - icon: fontawesome/brands/github
+ link: https://github.com/inveniosoftware
extra_css:
- stylesheets/extra.css
diff --git a/theme/features_base.html b/theme/features_base.html
index e31b0e6b..f9ba4549 100644
--- a/theme/features_base.html
+++ b/theme/features_base.html
@@ -1,4 +1,14 @@
-{% extends "frontpage_base.html" %}
+
+{% extends "main.html" %}
{% block styles %}
{{ super() }}
@@ -6,10 +16,25 @@
{% endblock %}
-{% block hero %}
+{% block tabs %}
+{{ super() }}
+
+