From b51cf01e16456955403c94319155cbbad18c9ae1 Mon Sep 17 00:00:00 2001 From: Alexander Druz Date: Tue, 10 Oct 2023 17:04:00 +0200 Subject: [PATCH] Delete all layouts for dataset from database if a new layout is given in `show` --- renumics/spotlight/app.py | 24 +++++++++++++------ renumics/spotlight/backend/config.py | 11 +++++++++ renumics/spotlight_plugins/core/api/layout.py | 4 +--- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/renumics/spotlight/app.py b/renumics/spotlight/app.py index c2c6758d..62220d2f 100644 --- a/renumics/spotlight/app.py +++ b/renumics/spotlight/app.py @@ -57,6 +57,9 @@ from renumics.spotlight.dtypes import DTypeMap +CURRENT_LAYOUT_KEY = "layout.current" + + class IssuesUpdatedMessage(Message): """ Notify about updated issues. @@ -73,6 +76,7 @@ class SpotlightApp(FastAPI): # lifecycle _startup_complete: bool + _loop: asyncio.AbstractEventLoop # connection _connection: multiprocessing.connection.Connection @@ -125,6 +129,8 @@ def _() -> None: port = int(os.environ["CONNECTION_PORT"]) authkey = os.environ["CONNECTION_AUTHKEY"] + self._loop = asyncio.get_running_loop() + for _ in range(10): try: self._connection = multiprocessing.connection.Client( @@ -301,7 +307,7 @@ def update(self, config: AppConfig) -> None: self._dataset = config.dataset self._data_source = create_datasource(self._dataset) if config.layout is not None: - self.layout = config.layout + self._layout = config.layout or layouts.default() if config.filebrowsing_allowed is not None: self.filebrowsing_allowed = config.filebrowsing_allowed @@ -311,6 +317,15 @@ def update(self, config: AppConfig) -> None: self._data_store = DataStore(data_source, self._user_dtypes) self._broadcast(RefreshMessage()) self._update_issues() + if config.layout is not None: + if self._data_store is not None: + dataset_uid = self._data_store.uid + future = asyncio.run_coroutine_threadsafe( + self.config.remove_all(CURRENT_LAYOUT_KEY, dataset=dataset_uid), + self._loop, + ) + future.result() + self._broadcast(ResetLayoutMessage()) for plugin in load_plugins(): plugin.update(self, config) @@ -370,11 +385,6 @@ def layout(self) -> Layout: """ return self._layout - @layout.setter - def layout(self, layout: Optional[Layout]) -> None: - self._layout = layout or layouts.default() - self._broadcast(ResetLayoutMessage()) - async def get_current_layout_dict(self, user_id: str) -> Optional[Dict]: """ Get the user's current layout (as dict) @@ -385,7 +395,7 @@ async def get_current_layout_dict(self, user_id: str) -> Optional[Dict]: dataset_uid = self._data_store.uid layout = await self.config.get( - "layout.current", dataset=dataset_uid, user=user_id + CURRENT_LAYOUT_KEY, dataset=dataset_uid, user=user_id ) or self.layout.dict(by_alias=True) return cast(Optional[Dict], layout) diff --git a/renumics/spotlight/backend/config.py b/renumics/spotlight/backend/config.py index e2dc3899..c49703ee 100644 --- a/renumics/spotlight/backend/config.py +++ b/renumics/spotlight/backend/config.py @@ -93,3 +93,14 @@ async def remove(self, name: str, *, dataset: str = "", user: str = "") -> None: await self.database.execute( query, values={"name": name, "user": user, "dataset": dataset} ) + + async def remove_all(self, name: str, *, dataset: str = "") -> None: + """ + remove a config value by name for all users + """ + await self._lazy_init() + query = """ + DELETE FROM entries + WHERE name = :name AND dataset = :dataset + """ + await self.database.execute(query, values={"name": name, "dataset": dataset}) diff --git a/renumics/spotlight_plugins/core/api/layout.py b/renumics/spotlight_plugins/core/api/layout.py index 1eeed4fc..f82489f3 100644 --- a/renumics/spotlight_plugins/core/api/layout.py +++ b/renumics/spotlight_plugins/core/api/layout.py @@ -8,12 +8,10 @@ from fastapi import APIRouter, Request, Cookie from pydantic import BaseModel -from renumics.spotlight.app import SpotlightApp +from renumics.spotlight.app import CURRENT_LAYOUT_KEY, SpotlightApp router = APIRouter() -CURRENT_LAYOUT_KEY = "layout.current" - @router.get( "/", tags=["layout"], response_model=Optional[Dict], operation_id="get_layout"