From 2fa3505310ea33c2ab3c7e930ad6dfc5c0a8af67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mose=20M=C3=BCller?= Date: Wed, 24 Jul 2024 14:54:03 +0200 Subject: [PATCH] updates Readme with displayOrder customization --- README.md | 50 +++++++++++++++++- .../Tailoring_frontend_component_layout.png | Bin 0 -> 18368 bytes 2 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 docs/images/Tailoring_frontend_component_layout.png diff --git a/README.md b/README.md index 9537bb1..6b194b8 100644 --- a/README.md +++ b/README.md @@ -910,10 +910,58 @@ Please ensure that the CSS file path is accessible from the server's running loc - **Custom Display Names**: Modify the `"displayName"` value in the file to change how each component appears in the frontend. - **Control Component Visibility**: Utilize the `"display"` key-value pair to control whether a component is rendered in the frontend. Set the value to `true` to make the component visible or `false` to hide it. - +- **Adjustable Component Order**: The `"displayOrder"` values determine the order of components. Alter these values to rearrange the components as desired. The value defaults to [`Number.MAX_SAFE_INTEGER`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER). The `web_settings.json` file will be stored in the directory specified by `SERVICE_CONFIG_DIR`. You can generate a `web_settings.json` file by setting the `GENERATE_WEB_SETTINGS` to `True`. For more information, see the [configuration section](#configuring-pydase-via-environment-variables). +For example, styling the following service + +```python +import pydase + + +class Device(pydase.DataService): + name = "My Device" + some_float = 1.0 + some_int = 1 + + +class Service(pydase.DataService): + device = Device() + state = "RUNNING" + + +service_instance = Service() +pydase.Server(service_instance).run() +``` + +with the following `web_settings.json` + +```json +{ + "device": { + "displayName": "My Device", + "displayOrder": 1 + }, + "device.name": { + "display": false + }, + "device.some_float": { + "displayOrder": 1 + }, + "device.some_int": { + "displayOrder": 0 + }, + "state": { + "displayOrder": 0 + } +} +``` + +looks like this: + +![Tailoring frontend component layout](./docs/images/Tailoring_frontend_component_layout.png) + ### Specifying a Custom Frontend Source To further personalize your web interface, you can provide `pydase` with a custom frontend GUI. To do so, you can use the `frontend_src` keyword in the `pydase.Server`: diff --git a/docs/images/Tailoring_frontend_component_layout.png b/docs/images/Tailoring_frontend_component_layout.png new file mode 100644 index 0000000000000000000000000000000000000000..02c34c1d8164c3e0fdef025ff250a1f05f3094a9 GIT binary patch literal 18368 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 literal 0 HcmV?d00001