Initial commit

This commit is contained in:
Jarek Krochmalski
2025-12-28 21:16:03 +01:00
commit 62e3c6439e
552 changed files with 104858 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
import { json, type RequestHandler } from '@sveltejs/kit';
import { getUserPreference, setUserPreference } from '$lib/server/db';
import { authorize } from '$lib/server/authorize';
const LOGS_FAVORITE_GROUPS_KEY = 'logs_favorite_groups';
// Favorite groups are stored as an array of { name: string, containers: string[] }
// Per environment, so environmentId is required
export interface FavoriteGroup {
name: string;
containers: string[]; // Container names (not IDs, since IDs change on recreate)
}
export const GET: RequestHandler = async ({ url, cookies }) => {
const auth = await authorize(cookies);
try {
const envId = url.searchParams.get('env');
if (!envId) {
return json({ error: 'Environment ID is required' }, { status: 400 });
}
const environmentId = parseInt(envId);
if (isNaN(environmentId)) {
return json({ error: 'Invalid environment ID' }, { status: 400 });
}
// userId is null for free edition (shared prefs), set for enterprise
const userId = auth.user?.id ?? null;
const groups = await getUserPreference<FavoriteGroup[]>({
userId,
environmentId,
key: LOGS_FAVORITE_GROUPS_KEY
});
return json({ groups: groups ?? [] });
} catch (error) {
console.error('Failed to get favorite groups:', error);
return json({ error: 'Failed to get favorite groups' }, { status: 500 });
}
};
export const POST: RequestHandler = async ({ request, cookies }) => {
const auth = await authorize(cookies);
try {
const body = await request.json();
const { environmentId, action, name, containers, newName } = body;
if (!environmentId || typeof environmentId !== 'number') {
return json({ error: 'Environment ID is required' }, { status: 400 });
}
if (!action || !['add', 'remove', 'update', 'reorder'].includes(action)) {
return json({ error: 'Action must be "add", "remove", "update", or "reorder"' }, { status: 400 });
}
// userId is null for free edition (shared prefs), set for enterprise
const userId = auth.user?.id ?? null;
// Get current groups
const currentGroups = await getUserPreference<FavoriteGroup[]>({
userId,
environmentId,
key: LOGS_FAVORITE_GROUPS_KEY
}) ?? [];
let newGroups: FavoriteGroup[];
if (action === 'add') {
// Add a new group
if (!name || typeof name !== 'string') {
return json({ error: 'Group name is required' }, { status: 400 });
}
if (!Array.isArray(containers) || containers.length === 0) {
return json({ error: 'Containers array is required and must not be empty' }, { status: 400 });
}
// Check for duplicate name
if (currentGroups.some(g => g.name === name)) {
return json({ error: 'A group with this name already exists' }, { status: 400 });
}
newGroups = [...currentGroups, { name, containers }];
} else if (action === 'remove') {
// Remove a group by name
if (!name || typeof name !== 'string') {
return json({ error: 'Group name is required' }, { status: 400 });
}
newGroups = currentGroups.filter(g => g.name !== name);
} else if (action === 'update') {
// Update a group (rename or change containers)
if (!name || typeof name !== 'string') {
return json({ error: 'Group name is required' }, { status: 400 });
}
const groupIndex = currentGroups.findIndex(g => g.name === name);
if (groupIndex === -1) {
return json({ error: 'Group not found' }, { status: 404 });
}
// Check for duplicate name if renaming
if (newName && newName !== name && currentGroups.some(g => g.name === newName)) {
return json({ error: 'A group with this name already exists' }, { status: 400 });
}
newGroups = [...currentGroups];
newGroups[groupIndex] = {
name: newName || name,
containers: Array.isArray(containers) ? containers : currentGroups[groupIndex].containers
};
} else {
// Reorder: replace entire array
if (!Array.isArray(body.groups)) {
return json({ error: 'groups array is required for reorder action' }, { status: 400 });
}
newGroups = body.groups;
}
// Save updated groups
await setUserPreference(
{ userId, environmentId, key: LOGS_FAVORITE_GROUPS_KEY },
newGroups
);
return json({ groups: newGroups });
} catch (error) {
console.error('Failed to update favorite groups:', error);
return json({ error: 'Failed to update favorite groups' }, { status: 500 });
}
};

View File

@@ -0,0 +1,103 @@
import { json, type RequestHandler } from '@sveltejs/kit';
import { getUserPreference, setUserPreference } from '$lib/server/db';
import { authorize } from '$lib/server/authorize';
const LOGS_FAVORITES_KEY = 'logs_favorites';
// Favorites are stored as an array of container names (strings)
// Per environment, so environmentId is required
export const GET: RequestHandler = async ({ url, cookies }) => {
const auth = await authorize(cookies);
try {
const envId = url.searchParams.get('env');
if (!envId) {
return json({ error: 'Environment ID is required' }, { status: 400 });
}
const environmentId = parseInt(envId);
if (isNaN(environmentId)) {
return json({ error: 'Invalid environment ID' }, { status: 400 });
}
// userId is null for free edition (shared prefs), set for enterprise
const userId = auth.user?.id ?? null;
const favorites = await getUserPreference<string[]>({
userId,
environmentId,
key: LOGS_FAVORITES_KEY
});
return json({ favorites: favorites ?? [] });
} catch (error) {
console.error('Failed to get favorites:', error);
return json({ error: 'Failed to get favorites' }, { status: 500 });
}
};
export const POST: RequestHandler = async ({ request, cookies }) => {
const auth = await authorize(cookies);
try {
const body = await request.json();
const { containerName, environmentId, action, favorites: newOrder } = body;
if (!environmentId || typeof environmentId !== 'number') {
return json({ error: 'Environment ID is required' }, { status: 400 });
}
if (!action || (action !== 'add' && action !== 'remove' && action !== 'reorder')) {
return json({ error: 'Action must be "add", "remove", or "reorder"' }, { status: 400 });
}
// userId is null for free edition (shared prefs), set for enterprise
const userId = auth.user?.id ?? null;
let newFavorites: string[];
if (action === 'reorder') {
// Reorder action: replace entire favorites array
if (!Array.isArray(newOrder)) {
return json({ error: 'favorites array is required for reorder action' }, { status: 400 });
}
newFavorites = newOrder;
} else {
// Add/remove actions require containerName
if (!containerName || typeof containerName !== 'string') {
return json({ error: 'Container name is required' }, { status: 400 });
}
// Get current favorites
const currentFavorites = await getUserPreference<string[]>({
userId,
environmentId,
key: LOGS_FAVORITES_KEY
}) ?? [];
if (action === 'add') {
// Add to favorites if not already present
if (!currentFavorites.includes(containerName)) {
newFavorites = [...currentFavorites, containerName];
} else {
newFavorites = currentFavorites;
}
} else {
// Remove from favorites
newFavorites = currentFavorites.filter(name => name !== containerName);
}
}
// Save updated favorites
await setUserPreference(
{ userId, environmentId, key: LOGS_FAVORITES_KEY },
newFavorites
);
return json({ favorites: newFavorites });
} catch (error) {
console.error('Failed to update favorites:', error);
return json({ error: 'Failed to update favorites' }, { status: 500 });
}
};

View File

@@ -0,0 +1,81 @@
import { json, type RequestHandler } from '@sveltejs/kit';
import { getGridPreferences, setGridPreferences, deleteGridPreferences, resetAllGridPreferences } from '$lib/server/db';
import { authorize } from '$lib/server/authorize';
import type { GridColumnPreferences } from '$lib/types';
// GET - retrieve all grid preferences
export const GET: RequestHandler = async ({ cookies }) => {
const auth = await authorize(cookies);
try {
// userId for per-user storage when auth is enabled
const userId = auth.authEnabled ? auth.user?.id : undefined;
const preferences = await getGridPreferences(userId);
return json({ preferences });
} catch (error) {
console.error('Failed to get grid preferences:', error);
return json({ error: 'Failed to get grid preferences' }, { status: 500 });
}
};
// POST - update grid preferences for a specific grid
export const POST: RequestHandler = async ({ request, cookies }) => {
const auth = await authorize(cookies);
try {
const body = await request.json();
const { gridId, columns } = body;
if (!gridId || typeof gridId !== 'string') {
return json({ error: 'gridId is required' }, { status: 400 });
}
if (!columns || !Array.isArray(columns)) {
return json({ error: 'columns array is required' }, { status: 400 });
}
// Validate column structure
for (const col of columns) {
if (typeof col.id !== 'string' || typeof col.visible !== 'boolean') {
return json({ error: 'Each column must have id (string) and visible (boolean)' }, { status: 400 });
}
}
const prefs: GridColumnPreferences = { columns };
// userId for per-user storage when auth is enabled
const userId = auth.authEnabled ? auth.user?.id : undefined;
await setGridPreferences(gridId, prefs, userId);
// Return updated preferences
const preferences = await getGridPreferences(userId);
return json({ preferences });
} catch (error) {
console.error('Failed to save grid preferences:', error);
return json({ error: 'Failed to save grid preferences' }, { status: 500 });
}
};
// DELETE - reset grid preferences (single grid or all)
export const DELETE: RequestHandler = async ({ url, cookies }) => {
const auth = await authorize(cookies);
try {
const gridId = url.searchParams.get('gridId');
const userId = auth.authEnabled ? auth.user?.id : undefined;
if (gridId) {
await deleteGridPreferences(gridId, userId);
} else {
// Reset all grids
await resetAllGridPreferences(userId);
}
const preferences = await getGridPreferences(userId);
return json({ preferences });
} catch (error) {
console.error('Failed to reset grid preferences:', error);
return json({ error: 'Failed to reset grid preferences' }, { status: 500 });
}
};