Task #613: replace per-app hide toggles with single Dock visibility switch

The per-app hidden feature shipped in #609 was rejected — user wanted one
toggle that hides/shows the entire bottom AppDock bar, leaving Home apps
untouched.

Removed:
- lib/db/src/schema/user-hidden-apps.ts (and index.ts export); table
  dropped via `pnpm --filter @workspace/db run push`
- GET /me/apps and PUT /me/apps/:appId/hidden routes
- getHiddenAppIdsForUser + getVisibleNonHiddenAppsForUser helpers
- MyApp + UpdateMyAppHiddenBody OpenAPI schemas
- MyAppsBody settings UI + related i18n keys
- Regenerated api-client-react + api-zod from the trimmed spec
- Reverted GET /apps back to getVisibleAppsForUser

Added:
- artifacts/tx-os/src/hooks/use-dock-visible.ts — localStorage-backed
  preference with a custom window event for in-tab sync and the native
  `storage` event for cross-tab sync. Default = true.
- DockBody in settings-panel: single ToggleRow under a new "App dock"
  section ("settingsPanel.section.dock" / "settingsPanel.dock.show")
- AppDock now returns null when the preference is off and clears
  `--app-dock-height` so page padding doesn't stay reserved.

Code review: PASS (architect). No remaining references to the removed
infra. Typecheck shows only pre-existing errors in executive-meetings.ts
and push.ts unrelated to this change.

Follow-up: publish to Gitea + redeploy on Mac (proposed as a follow-up
task).
This commit is contained in:
riyadhafraa
2026-05-19 11:35:13 +00:00
parent f1536cb4db
commit 3f6a0fb02f
13 changed files with 95 additions and 638 deletions
-1
View File
@@ -6,7 +6,6 @@ export * from "./service-orders";
export * from "./notifications";
export * from "./settings";
export * from "./user-app-orders";
export * from "./user-hidden-apps";
export * from "./app-opens";
export * from "./password-reset-tokens";
export * from "./notes";
-21
View File
@@ -1,21 +0,0 @@
import { pgTable, integer, primaryKey, timestamp } from "drizzle-orm/pg-core";
import { usersTable } from "./users";
import { appsTable } from "./apps";
export const userHiddenAppsTable = pgTable(
"user_hidden_apps",
{
userId: integer("user_id")
.notNull()
.references(() => usersTable.id, { onDelete: "cascade" }),
appId: integer("app_id")
.notNull()
.references(() => appsTable.id, { onDelete: "cascade" }),
hiddenAt: timestamp("hidden_at", { withTimezone: true })
.notNull()
.defaultNow(),
},
(t) => [primaryKey({ columns: [t.userId, t.appId] })],
);
export type UserHiddenApp = typeof userHiddenAppsTable.$inferSelect;