diff --git a/public/app.js b/public/app.js index c09e7e2..4888886 100644 --- a/public/app.js +++ b/public/app.js @@ -77,7 +77,7 @@ window.fetch = (input, init = {}) => { const headers = new Headers(init.headers || (typeof input !== "string" ? input.headers : undefined)); const selectedMode = localStorage.getItem("catalog-maker:database-mode") || "local"; const permissions = readDatabasePermissions(selectedMode); - const localWritesEnabled = selectedMode === "local" && [ + const localWritesEnabled = ["local", "scrape"].includes(selectedMode) && [ permissions.allowInsertToggle, permissions.allowUpdateToggle, permissions.allowDeleteToggle, @@ -1181,7 +1181,7 @@ function syncLocalDbFields(mode) { localDbFields.hidden = mode !== "local"; } function syncDatabasePermissions(mode) { - const isReadOnly = mode === "live" || mode === "scrape"; + const isReadOnly = mode === "live"; for (const input of permissionInputs) { input.disabled = isReadOnly; if (isReadOnly) @@ -1205,7 +1205,7 @@ function refreshDatabaseStatusLabel() { const mode = localStorage.getItem("catalog-maker:database-mode") || "local"; const transactionMode = localStorage.getItem("catalog-maker:transaction-mode") || "transaction"; const permissions = readDatabasePermissions(mode); - const writesEnabled = mode === "local" && (permissions.allowInsertToggle || permissions.allowUpdateToggle || permissions.allowDeleteToggle); + const writesEnabled = ["local", "scrape"].includes(mode) && (permissions.allowInsertToggle || permissions.allowUpdateToggle || permissions.allowDeleteToggle); const dbLabel = mode === "live" ? "Live 9bplus DB" : mode === "scrape" ? "Local scrape DB" : "Local 9bplus DB"; const configuredDriver = databaseStatus.dataset.driver; const connectionError = (mode === "local" && configuredDriver !== "mariadb") diff --git a/public/app.ts b/public/app.ts index 6dd027e..0a71f9a 100644 --- a/public/app.ts +++ b/public/app.ts @@ -78,7 +78,7 @@ window.fetch = (input, init = {}) => { const headers = new Headers(init.headers || (typeof input !== "string" ? input.headers : undefined)); const selectedMode = localStorage.getItem("catalog-maker:database-mode") || "local"; const permissions = readDatabasePermissions(selectedMode); - const localWritesEnabled = selectedMode === "local" && [ + const localWritesEnabled = ["local", "scrape"].includes(selectedMode) && [ permissions.allowInsertToggle, permissions.allowUpdateToggle, permissions.allowDeleteToggle, @@ -1270,7 +1270,7 @@ function syncLocalDbFields(mode) { } function syncDatabasePermissions(mode) { - const isReadOnly = mode === "live" || mode === "scrape"; + const isReadOnly = mode === "live"; for (const input of permissionInputs) { input.disabled = isReadOnly; if (isReadOnly) input.checked = false; @@ -1294,7 +1294,7 @@ function refreshDatabaseStatusLabel() { const mode = localStorage.getItem("catalog-maker:database-mode") || "local"; const transactionMode = localStorage.getItem("catalog-maker:transaction-mode") || "transaction"; const permissions = readDatabasePermissions(mode); - const writesEnabled = mode === "local" && ( + const writesEnabled = ["local", "scrape"].includes(mode) && ( permissions.allowInsertToggle || permissions.allowUpdateToggle || permissions.allowDeleteToggle ); const dbLabel = mode === "live" ? "Live 9bplus DB" : mode === "scrape" ? "Local scrape DB" : "Local 9bplus DB"; diff --git a/public/index.html b/public/index.html index faff1a6..79810f4 100644 --- a/public/index.html +++ b/public/index.html @@ -259,7 +259,7 @@ Allow delete -

Write permissions are saved only for Local 9bplus DB. Live and scrape DB stay read-only here.

+

Write permissions are saved separately for Local 9bplus DB and Local scrape DB. Live DB stays read-only.

diff --git a/tests/ui/database.e2e.spec.ts b/tests/ui/database.e2e.spec.ts index c50b53c..b4beafa 100644 --- a/tests/ui/database.e2e.spec.ts +++ b/tests/ui/database.e2e.spec.ts @@ -17,7 +17,7 @@ test.describe("database connection", () => { await expect(page.locator("#localDbTestResult")).toContainText("Connected:"); }); - test("keeps the scrape database as a separate read-only mode", async ({ page }) => { + test("keeps the scrape database as a separate local mode with its own permissions", async ({ page }) => { await page.goto("/"); await page.locator("#settingsButton").click(); @@ -25,6 +25,22 @@ test.describe("database connection", () => { await expect(page.locator('input[name="databaseMode"][value="live"] + span')).toHaveText("Live 9bplus DB"); await page.locator('input[name="databaseMode"][value="scrape"]').check(); await expect(page.locator("#databaseModeNote")).toContainText("Local scrape DB selected"); + await expect(page.locator("#allowInsertToggle")).toBeEnabled(); + await expect(page.locator("#allowUpdateToggle")).toBeEnabled(); + await expect(page.locator("#allowDeleteToggle")).toBeEnabled(); + await page.locator("#allowUpdateToggle").check(); + + await page.reload(); + await page.locator("#settingsButton").click(); + await page.locator('input[name="databaseMode"][value="scrape"]').check(); + await expect(page.locator("#allowUpdateToggle")).toBeChecked(); + + await page.locator('input[name="databaseMode"][value="local"]').check(); + await expect(page.locator("#allowInsertToggle")).not.toBeChecked(); + await expect(page.locator("#allowUpdateToggle")).not.toBeChecked(); + await expect(page.locator("#allowDeleteToggle")).not.toBeChecked(); + + await page.locator('input[name="databaseMode"][value="live"]').check(); await expect(page.locator("#allowInsertToggle")).toBeDisabled(); await expect(page.locator("#allowUpdateToggle")).toBeDisabled(); await expect(page.locator("#allowDeleteToggle")).toBeDisabled();