use column for default view

This commit is contained in:
miloschwartz
2026-07-03 09:59:49 -04:00
parent a89509c8bd
commit b53f80d317
8 changed files with 19 additions and 33 deletions
+1
View File
@@ -232,6 +232,7 @@ export const launcherViews = pgTable("launcherViews", {
}),
name: varchar("name").notNull(),
config: text("config").notNull(),
isDefault: boolean("isDefault").notNull().default(false),
createdAt: varchar("createdAt").notNull(),
updatedAt: varchar("updatedAt").notNull()
});
+3
View File
@@ -233,6 +233,9 @@ export const launcherViews = sqliteTable("launcherViews", {
}),
name: text("name").notNull(),
config: text("config").notNull(),
isDefault: integer("isDefault", { mode: "boolean" })
.notNull()
.default(false),
createdAt: text("createdAt").notNull(),
updatedAt: text("updatedAt").notNull()
});
+2 -11
View File
@@ -7,7 +7,6 @@ import moment from "moment";
import { fromZodError } from "zod-validation-error";
import { z } from "zod";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
import { launcherViewConfigSchema } from "./types";
const createLauncherViewBodySchema = z.strictObject({
@@ -41,15 +40,6 @@ export async function createLauncherView(
);
}
if (isLauncherDefaultOverrideViewName(parsed.data.name)) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"This view name is reserved"
)
);
}
if (parsed.data.orgWide) {
const canCreateOrgWide = await checkUserActionPermission(
ActionsEnum.createOrgWideLauncherView,
@@ -89,7 +79,8 @@ export async function createLauncherView(
),
createdAt: created.createdAt,
updatedAt: created.updatedAt,
isOrgWide: created.userId == null
isOrgWide: created.userId == null,
isDefault: created.isDefault
},
success: true,
error: false,
@@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import { NextFunction, Request, Response } from "express";
import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
export async function deleteLauncherView(
req: Request,
@@ -47,7 +46,7 @@ export async function deleteLauncherView(
);
}
if (isLauncherDefaultOverrideViewName(existing.name)) {
if (existing.isDefault) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
+7 -14
View File
@@ -2,17 +2,12 @@ import { db, launcherViews } from "@server/db";
import { and, eq, isNull } from "drizzle-orm";
import moment from "moment";
import {
LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME,
launcherViewConfigSchema,
type LauncherDefaultViewOverrides,
type LauncherViewConfig,
type LauncherViewRecord
} from "./types";
export function isLauncherDefaultOverrideViewName(name: string) {
return name === LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME;
}
export function mapViewRow(
row: typeof launcherViews.$inferSelect
): LauncherViewRecord {
@@ -24,16 +19,15 @@ export function mapViewRow(
config: launcherViewConfigSchema.parse(JSON.parse(row.config)),
createdAt: row.createdAt,
updatedAt: row.updatedAt,
isOrgWide: row.userId == null
isOrgWide: row.userId == null,
isDefault: row.isDefault
};
}
export function extractDefaultViewOverrides(
rows: Array<typeof launcherViews.$inferSelect>
): LauncherDefaultViewOverrides {
const overrideRows = rows.filter((row) =>
isLauncherDefaultOverrideViewName(row.name)
);
const overrideRows = rows.filter((row) => row.isDefault);
const personalRow = overrideRows.find((row) => row.userId !== null);
const orgWideRow = overrideRows.find((row) => row.userId === null);
@@ -47,9 +41,7 @@ export function extractDefaultViewOverrides(
export function listVisibleLauncherViews(
rows: Array<typeof launcherViews.$inferSelect>
): LauncherViewRecord[] {
return rows
.filter((row) => !isLauncherDefaultOverrideViewName(row.name))
.map(mapViewRow);
return rows.filter((row) => !row.isDefault).map(mapViewRow);
}
export async function findDefaultViewOverride(
@@ -63,7 +55,7 @@ export async function findDefaultViewOverride(
.where(
and(
eq(launcherViews.orgId, orgId),
eq(launcherViews.name, LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME),
eq(launcherViews.isDefault, true),
orgWide
? isNull(launcherViews.userId)
: eq(launcherViews.userId, userId)
@@ -106,7 +98,8 @@ export async function upsertDefaultViewOverride({
.values({
orgId,
userId: orgWide ? null : userId,
name: LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME,
name: "",
isDefault: true,
config: JSON.stringify(config),
createdAt: now,
updatedAt: now
+1 -2
View File
@@ -89,6 +89,7 @@ export type LauncherViewRecord = {
createdAt: string;
updatedAt: string;
isOrgWide: boolean;
isDefault: boolean;
};
export type LauncherDefaultViewOverrides = {
@@ -181,8 +182,6 @@ export function parseIdListParam(value: string | undefined): number[] {
export const DEFAULT_LAUNCHER_VIEW_ID = "default" as const;
export const LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME = "__default__";
export type LauncherViewSelection =
| { type: "default" }
| { type: "saved"; viewId: number };
@@ -9,7 +9,6 @@ import moment from "moment";
import { fromZodError } from "zod-validation-error";
import { z } from "zod";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
import { launcherViewConfigSchema } from "./types";
const updateLauncherViewBodySchema = z.strictObject({
@@ -67,7 +66,7 @@ export async function updateLauncherView(
);
}
if (isLauncherDefaultOverrideViewName(existing.name)) {
if (existing.isDefault) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
@@ -145,7 +144,8 @@ export async function updateLauncherView(
),
createdAt: updated.createdAt,
updatedAt: updated.updatedAt,
isOrgWide: updated.userId == null
isOrgWide: updated.userId == null,
isDefault: updated.isDefault
},
success: true,
error: false,