Skip to content

Declarative Settings UI API (Nextcloud 29) #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
### Added

- set_handlers: `models_to_fetch` can now accept direct links to a files to download. #217
- DeclarativeSettings API for Nextcloud 29. #222

### Changed

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ Python library that provides a robust and well-documented API that allows develo
| User & Weather status | ✅ | ✅ | ✅ | ✅ |
| Other APIs*** | ✅ | ✅ | ✅ | ✅ |
| Talk Bot API* | N/A | ✅ | ✅ | ✅ |
| Settings UI API* | N/A | N/A | N/A | ✅ |
| AI Providers API** | N/A | N/A | N/A | ✅ |

&ast;_available only for **NextcloudApp**_<br>
Expand Down
7 changes: 7 additions & 0 deletions docs/NextcloudUiApp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,20 @@ Here we will simply describe in detail what happens in the example.
)
nc.ui.resources.set_script("top_menu", "first_menu", "js/ui_example-main")
nc.ui.top_menu.register("first_menu", "UI example", "img/icon.svg")
if nc.srv_version["major"] >= 29:
nc.ui.settings.register_form(SETTINGS_EXAMPLE)

**set_initial_state** is analogue of PHP ``OCP\AppFramework\Services\IInitialState::provideInitialState``

**set_script** is analogue of PHP ``Util::addScript``

There is also **set_style** (``Util::addStyle``) that can be used for CSS files and works the same way as **set_script**.

Starting with Nextcloud **29** AppAPI supports declaring Settings UI, with very simple and robust API.

Settings values you declare will be saved to ``preferences_ex`` or ``appconfig_ex`` tables and can be retrieved using
:py:class:`nc_py_api._preferences_ex.PreferencesExAPI` or :py:class:`nc_py_api._preferences_ex.AppConfigExAPI` APIs.

Backend
-------

Expand Down
12 changes: 12 additions & 0 deletions docs/reference/ExApp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ UI methods should be accessed with the help of :class:`~nc_py_api.nextcloud.Next
.. autoclass:: nc_py_api.ex_app.ui.resources.UiStyle
:members:

.. autoclass:: nc_py_api.ex_app.ui.settings.SettingsField
:members:

.. autoclass:: nc_py_api.ex_app.ui.settings.SettingsForm
:members:

.. autoclass:: nc_py_api.ex_app.ui.settings.SettingsFieldType
:members:

.. autoclass:: nc_py_api.ex_app.ui.settings._DeclarativeSettingsAPI
:members:

.. autoclass:: nc_py_api.ex_app.providers.providers.ProvidersApi
:members:

Expand Down
135 changes: 134 additions & 1 deletion examples/as_app/ui_example/lib/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
from pydantic import BaseModel

from nc_py_api import NextcloudApp
from nc_py_api.ex_app import nc_app, run_app, set_handlers
from nc_py_api.ex_app import (
SettingsField,
SettingsFieldType,
SettingsForm,
nc_app,
run_app,
set_handlers,
)


@asynccontextmanager
Expand All @@ -19,6 +26,130 @@ async def lifespan(_app: FastAPI):

APP = FastAPI(lifespan=lifespan)

SETTINGS_EXAMPLE = SettingsForm(
id="settings_example",
section_type="admin",
section_id="ai_integration_team",
title="Example of declarative settings",
description="These fields are rendered dynamically from declarative schema",
fields=[
SettingsField(
id="field1",
title="Multi-selection",
description="Select some option setting",
type=SettingsFieldType.MULTI_SELECT,
default=["foo", "bar"],
placeholder="Select some multiple options",
options=["foo", "bar", "baz"],
),
SettingsField(
id="some_real_setting",
title="Choose init status check background job interval",
description="How often ExApp should check for initialization status",
type=SettingsFieldType.RADIO,
default="40m",
placeholder="Choose init status check background job interval",
options={
"Each 40 minutes": "40m",
"Each 60 minutes": "60m",
"Each 120 minutes": "120m",
"Each day": f"{60 * 24}m",
},
),
SettingsField(
id="test_ex_app_field_1",
title="Default text field",
description="Set some simple text setting",
type=SettingsFieldType.TEXT,
default="foo",
placeholder="Enter text setting",
),
SettingsField(
id="test_ex_app_field_1_1",
title="Email field",
description="Set email config",
type=SettingsFieldType.EMAIL,
default="",
placeholder="Enter email",
),
SettingsField(
id="test_ex_app_field_1_2",
title="Tel field",
description="Set tel config",
type=SettingsFieldType.TEL,
default="",
placeholder="Enter your tel",
),
SettingsField(
id="test_ex_app_field_1_3",
title="Url (website) field",
description="Set url config",
type=SettingsFieldType.URL,
default="",
placeholder="Enter url",
),
SettingsField(
id="test_ex_app_field_1_4",
title="Number field",
description="Set number config",
type=SettingsFieldType.NUMBER,
default=0,
placeholder="Enter number value",
),
SettingsField(
id="test_ex_app_field_2",
title="Password",
description="Set some secure value setting",
type=SettingsFieldType.PASSWORD,
default="",
placeholder="Set secure value",
),
SettingsField(
id="test_ex_app_field_3",
title="Selection",
description="Select some option setting",
type=SettingsFieldType.SELECT,
default="foo",
placeholder="Select some option setting",
options=["foo", "bar", "baz"],
),
SettingsField(
id="test_ex_app_field_3",
title="Selection",
description="Select some option setting",
type=SettingsFieldType.SELECT,
default="foo",
placeholder="Select some option setting",
options=["foo", "bar", "baz"],
),
SettingsField(
id="test_ex_app_field_4",
title="Toggle something",
description="Select checkbox option setting",
type=SettingsFieldType.CHECKBOX,
default=False,
label="Verify something if enabled",
),
SettingsField(
id="test_ex_app_field_5",
title="Multiple checkbox toggles, describing one setting",
description="Select checkbox option setting",
type=SettingsFieldType.MULTI_CHECKBOX,
default={"foo": True, "bar": True},
options={"Foo": "foo", "Bar": "bar", "Baz": "baz", "Qux": "qux"},
),
SettingsField(
id="test_ex_app_field_6",
title="Radio toggles, describing one setting like single select",
description="Select radio option setting",
type=SettingsFieldType.RADIO,
label="Select single toggle",
default="foo",
options={"First radio": "foo", "Second radio": "bar", "Third radie": "baz"},
),
],
)


def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
print(f"enabled={enabled}")
Expand All @@ -28,6 +159,8 @@ def enabled_handler(enabled: bool, nc: NextcloudApp) -> str:
)
nc.ui.resources.set_script("top_menu", "first_menu", "js/ui_example-main")
nc.ui.top_menu.register("first_menu", "UI example", "img/icon.svg")
if nc.srv_version["major"] >= 29:
nc.ui.settings.register_form(SETTINGS_EXAMPLE)
return ""


Expand Down
4 changes: 2 additions & 2 deletions nc_py_api/_preferences_ex.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ async def delete(self, keys: str | list[str], not_fail=True) -> None:


class PreferencesExAPI(_BasicAppCfgPref):
"""User specific preferences API."""
"""User specific preferences API, avalaible as **nc.preferences_ex**."""

_url_suffix = "ex-app/preference"

Expand Down Expand Up @@ -134,7 +134,7 @@ async def set_value(self, key: str, value: str) -> None:


class AppConfigExAPI(_BasicAppCfgPref):
"""Non-user(App) specific preferences API."""
"""Non-user(App) specific preferences API, avalaible as **nc.appconfig_ex**."""

_url_suffix = "ex-app/config"

Expand Down
1 change: 1 addition & 0 deletions nc_py_api/ex_app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
)
from .misc import get_model_path, persistent_storage, verify_version
from .ui.files_actions import UiActionFileInfo
from .ui.settings import SettingsField, SettingsFieldType, SettingsForm
from .uvicorn_fastapi import run_app
Loading