mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-12 23:40:40 +02:00
use column for default view
This commit is contained in:
+1
-1
@@ -3621,7 +3621,7 @@
|
|||||||
"resourceLauncherSiteGroupingDisabled": "Site grouping is unavailable at this scale. Filter by site to group a smaller set.",
|
"resourceLauncherSiteGroupingDisabled": "Site grouping is unavailable at this scale. Filter by site to group a smaller set.",
|
||||||
"resourceLauncherLabelGroupingDisabled": "Label grouping is unavailable at this scale.",
|
"resourceLauncherLabelGroupingDisabled": "Label grouping is unavailable at this scale.",
|
||||||
"resourceLauncherCompactModeHint": "Showing a simplified list for faster browsing. Use search or filters to narrow results.",
|
"resourceLauncherCompactModeHint": "Showing a simplified list for faster browsing. Use search or filters to narrow results.",
|
||||||
"resourceLauncherCompactGroupingHint": "Apply site or label filters to enable grouping in compact mode.",
|
"resourceLauncherCompactGroupingHint": "Apply site or label filters to enable grouping.",
|
||||||
"resourceLauncherCopiedToClipboard": "Copied to clipboard",
|
"resourceLauncherCopiedToClipboard": "Copied to clipboard",
|
||||||
"resourceLauncherCopiedAccessDescription": "Resource access has been copied to your clipboard.",
|
"resourceLauncherCopiedAccessDescription": "Resource access has been copied to your clipboard.",
|
||||||
"resourceLauncherViewNamePlaceholder": "View name",
|
"resourceLauncherViewNamePlaceholder": "View name",
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ export const launcherViews = pgTable("launcherViews", {
|
|||||||
}),
|
}),
|
||||||
name: varchar("name").notNull(),
|
name: varchar("name").notNull(),
|
||||||
config: text("config").notNull(),
|
config: text("config").notNull(),
|
||||||
|
isDefault: boolean("isDefault").notNull().default(false),
|
||||||
createdAt: varchar("createdAt").notNull(),
|
createdAt: varchar("createdAt").notNull(),
|
||||||
updatedAt: varchar("updatedAt").notNull()
|
updatedAt: varchar("updatedAt").notNull()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -233,6 +233,9 @@ export const launcherViews = sqliteTable("launcherViews", {
|
|||||||
}),
|
}),
|
||||||
name: text("name").notNull(),
|
name: text("name").notNull(),
|
||||||
config: text("config").notNull(),
|
config: text("config").notNull(),
|
||||||
|
isDefault: integer("isDefault", { mode: "boolean" })
|
||||||
|
.notNull()
|
||||||
|
.default(false),
|
||||||
createdAt: text("createdAt").notNull(),
|
createdAt: text("createdAt").notNull(),
|
||||||
updatedAt: text("updatedAt").notNull()
|
updatedAt: text("updatedAt").notNull()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import moment from "moment";
|
|||||||
import { fromZodError } from "zod-validation-error";
|
import { fromZodError } from "zod-validation-error";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
||||||
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
|
|
||||||
import { launcherViewConfigSchema } from "./types";
|
import { launcherViewConfigSchema } from "./types";
|
||||||
|
|
||||||
const createLauncherViewBodySchema = z.strictObject({
|
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) {
|
if (parsed.data.orgWide) {
|
||||||
const canCreateOrgWide = await checkUserActionPermission(
|
const canCreateOrgWide = await checkUserActionPermission(
|
||||||
ActionsEnum.createOrgWideLauncherView,
|
ActionsEnum.createOrgWideLauncherView,
|
||||||
@@ -89,7 +79,8 @@ export async function createLauncherView(
|
|||||||
),
|
),
|
||||||
createdAt: created.createdAt,
|
createdAt: created.createdAt,
|
||||||
updatedAt: created.updatedAt,
|
updatedAt: created.updatedAt,
|
||||||
isOrgWide: created.userId == null
|
isOrgWide: created.userId == null,
|
||||||
|
isDefault: created.isDefault
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
error: false,
|
error: false,
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
|
|||||||
import { NextFunction, Request, Response } from "express";
|
import { NextFunction, Request, Response } from "express";
|
||||||
import createHttpError from "http-errors";
|
import createHttpError from "http-errors";
|
||||||
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
||||||
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
|
|
||||||
|
|
||||||
export async function deleteLauncherView(
|
export async function deleteLauncherView(
|
||||||
req: Request,
|
req: Request,
|
||||||
@@ -47,7 +46,7 @@ export async function deleteLauncherView(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLauncherDefaultOverrideViewName(existing.name)) {
|
if (existing.isDefault) {
|
||||||
return next(
|
return next(
|
||||||
createHttpError(
|
createHttpError(
|
||||||
HttpCode.BAD_REQUEST,
|
HttpCode.BAD_REQUEST,
|
||||||
|
|||||||
@@ -2,17 +2,12 @@ import { db, launcherViews } from "@server/db";
|
|||||||
import { and, eq, isNull } from "drizzle-orm";
|
import { and, eq, isNull } from "drizzle-orm";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import {
|
import {
|
||||||
LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME,
|
|
||||||
launcherViewConfigSchema,
|
launcherViewConfigSchema,
|
||||||
type LauncherDefaultViewOverrides,
|
type LauncherDefaultViewOverrides,
|
||||||
type LauncherViewConfig,
|
type LauncherViewConfig,
|
||||||
type LauncherViewRecord
|
type LauncherViewRecord
|
||||||
} from "./types";
|
} from "./types";
|
||||||
|
|
||||||
export function isLauncherDefaultOverrideViewName(name: string) {
|
|
||||||
return name === LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapViewRow(
|
export function mapViewRow(
|
||||||
row: typeof launcherViews.$inferSelect
|
row: typeof launcherViews.$inferSelect
|
||||||
): LauncherViewRecord {
|
): LauncherViewRecord {
|
||||||
@@ -24,16 +19,15 @@ export function mapViewRow(
|
|||||||
config: launcherViewConfigSchema.parse(JSON.parse(row.config)),
|
config: launcherViewConfigSchema.parse(JSON.parse(row.config)),
|
||||||
createdAt: row.createdAt,
|
createdAt: row.createdAt,
|
||||||
updatedAt: row.updatedAt,
|
updatedAt: row.updatedAt,
|
||||||
isOrgWide: row.userId == null
|
isOrgWide: row.userId == null,
|
||||||
|
isDefault: row.isDefault
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractDefaultViewOverrides(
|
export function extractDefaultViewOverrides(
|
||||||
rows: Array<typeof launcherViews.$inferSelect>
|
rows: Array<typeof launcherViews.$inferSelect>
|
||||||
): LauncherDefaultViewOverrides {
|
): LauncherDefaultViewOverrides {
|
||||||
const overrideRows = rows.filter((row) =>
|
const overrideRows = rows.filter((row) => row.isDefault);
|
||||||
isLauncherDefaultOverrideViewName(row.name)
|
|
||||||
);
|
|
||||||
|
|
||||||
const personalRow = overrideRows.find((row) => row.userId !== null);
|
const personalRow = overrideRows.find((row) => row.userId !== null);
|
||||||
const orgWideRow = overrideRows.find((row) => row.userId === null);
|
const orgWideRow = overrideRows.find((row) => row.userId === null);
|
||||||
@@ -47,9 +41,7 @@ export function extractDefaultViewOverrides(
|
|||||||
export function listVisibleLauncherViews(
|
export function listVisibleLauncherViews(
|
||||||
rows: Array<typeof launcherViews.$inferSelect>
|
rows: Array<typeof launcherViews.$inferSelect>
|
||||||
): LauncherViewRecord[] {
|
): LauncherViewRecord[] {
|
||||||
return rows
|
return rows.filter((row) => !row.isDefault).map(mapViewRow);
|
||||||
.filter((row) => !isLauncherDefaultOverrideViewName(row.name))
|
|
||||||
.map(mapViewRow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function findDefaultViewOverride(
|
export async function findDefaultViewOverride(
|
||||||
@@ -63,7 +55,7 @@ export async function findDefaultViewOverride(
|
|||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(launcherViews.orgId, orgId),
|
eq(launcherViews.orgId, orgId),
|
||||||
eq(launcherViews.name, LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME),
|
eq(launcherViews.isDefault, true),
|
||||||
orgWide
|
orgWide
|
||||||
? isNull(launcherViews.userId)
|
? isNull(launcherViews.userId)
|
||||||
: eq(launcherViews.userId, userId)
|
: eq(launcherViews.userId, userId)
|
||||||
@@ -106,7 +98,8 @@ export async function upsertDefaultViewOverride({
|
|||||||
.values({
|
.values({
|
||||||
orgId,
|
orgId,
|
||||||
userId: orgWide ? null : userId,
|
userId: orgWide ? null : userId,
|
||||||
name: LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME,
|
name: "",
|
||||||
|
isDefault: true,
|
||||||
config: JSON.stringify(config),
|
config: JSON.stringify(config),
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now
|
updatedAt: now
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export type LauncherViewRecord = {
|
|||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
isOrgWide: boolean;
|
isOrgWide: boolean;
|
||||||
|
isDefault: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type LauncherDefaultViewOverrides = {
|
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 DEFAULT_LAUNCHER_VIEW_ID = "default" as const;
|
||||||
|
|
||||||
export const LAUNCHER_DEFAULT_OVERRIDE_VIEW_NAME = "__default__";
|
|
||||||
|
|
||||||
export type LauncherViewSelection =
|
export type LauncherViewSelection =
|
||||||
| { type: "default" }
|
| { type: "default" }
|
||||||
| { type: "saved"; viewId: number };
|
| { type: "saved"; viewId: number };
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import moment from "moment";
|
|||||||
import { fromZodError } from "zod-validation-error";
|
import { fromZodError } from "zod-validation-error";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
|
||||||
import { isLauncherDefaultOverrideViewName } from "./launcherDefaultView";
|
|
||||||
import { launcherViewConfigSchema } from "./types";
|
import { launcherViewConfigSchema } from "./types";
|
||||||
|
|
||||||
const updateLauncherViewBodySchema = z.strictObject({
|
const updateLauncherViewBodySchema = z.strictObject({
|
||||||
@@ -67,7 +66,7 @@ export async function updateLauncherView(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLauncherDefaultOverrideViewName(existing.name)) {
|
if (existing.isDefault) {
|
||||||
return next(
|
return next(
|
||||||
createHttpError(
|
createHttpError(
|
||||||
HttpCode.BAD_REQUEST,
|
HttpCode.BAD_REQUEST,
|
||||||
@@ -145,7 +144,8 @@ export async function updateLauncherView(
|
|||||||
),
|
),
|
||||||
createdAt: updated.createdAt,
|
createdAt: updated.createdAt,
|
||||||
updatedAt: updated.updatedAt,
|
updatedAt: updated.updatedAt,
|
||||||
isOrgWide: updated.userId == null
|
isOrgWide: updated.userId == null,
|
||||||
|
isDefault: updated.isDefault
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
error: false,
|
error: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user