- disabled boolean on components table (default false) - Component list filters out disabled components - Component detail returns 404 for disabled - Delete button with confirmation on component detail page - Installation form filters out instances of disabled components Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -138,6 +138,7 @@ export const components = pgTable(
|
||||
defaultCondition: text('default_condition').notNull().default('Working'),
|
||||
defaultFirmwareVersion: text('default_firmware_version'),
|
||||
defaultLocationId: uuid('default_location_id').references(() => locations.id),
|
||||
disabled: boolean('disabled').default(false).notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ export const load: PageServerLoad = async ({ url }) => {
|
||||
const page = Math.max(1, Number(url.searchParams.get('page') ?? 1));
|
||||
const pageSize = 24;
|
||||
|
||||
const conditions = [];
|
||||
const conditions = [eq(components.disabled, false)];
|
||||
if (type) conditions.push(eq(components.componentType, type));
|
||||
if (search) {
|
||||
conditions.push(
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { PageServerLoad, Actions } from './$types';
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { components, componentInstances, devices, locations, installationLog, componentImages, componentDocuments } from '$lib/server/db/schema.js';
|
||||
import { eq, desc } from 'drizzle-orm';
|
||||
import { error, fail } from '@sveltejs/kit';
|
||||
import { error, fail, redirect } from '@sveltejs/kit';
|
||||
import { saveDocument, deleteFile } from '$lib/server/uploads.js';
|
||||
|
||||
export const load: PageServerLoad = async ({ params }) => {
|
||||
@@ -12,6 +12,7 @@ export const load: PageServerLoad = async ({ params }) => {
|
||||
.where(eq(components.id, params.id));
|
||||
|
||||
if (!component) error(404, 'Component not found');
|
||||
if (component.disabled) error(404, 'Component not found');
|
||||
|
||||
// All instances with their device/location info
|
||||
const instances = await db
|
||||
@@ -161,5 +162,14 @@ export const actions: Actions = {
|
||||
}
|
||||
|
||||
return { documentDeleted: true };
|
||||
},
|
||||
|
||||
disable: async ({ params }) => {
|
||||
await db
|
||||
.update(components)
|
||||
.set({ disabled: true, updatedAt: new Date() })
|
||||
.where(eq(components.id, params.id));
|
||||
|
||||
redirect(303, '/components');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
let editingInstanceId = $state<string | null>(null);
|
||||
let showAddInstances = $state(false);
|
||||
let showDocForm = $state(false);
|
||||
let showDeleteConfirm = $state(false);
|
||||
|
||||
const totalCount = $derived(data.instances.length);
|
||||
const installedCount = $derived(data.instances.filter((i) => i.currentDeviceId).length);
|
||||
@@ -56,9 +57,28 @@
|
||||
class="rounded-md border border-gray-300 px-3 py-1.5 text-sm text-gray-600 hover:bg-gray-100 dark:border-gray-600 dark:text-gray-400 dark:hover:bg-gray-700">
|
||||
Print
|
||||
</button>
|
||||
<button type="button" onclick={() => (showDeleteConfirm = !showDeleteConfirm)}
|
||||
class="rounded-md border border-red-300 px-3 py-1.5 text-sm text-red-600 hover:bg-red-50 dark:border-red-700 dark:text-red-400 dark:hover:bg-red-900/20">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if showDeleteConfirm}
|
||||
<div class="mb-6 rounded-lg border border-red-200 bg-red-50 p-5 dark:border-red-800 dark:bg-red-900/20">
|
||||
<p class="mb-3 text-sm text-red-700 dark:text-red-300">Are you sure you want to delete <strong>{c.title}</strong>? This will hide it from all listings.</p>
|
||||
<div class="flex gap-2">
|
||||
<form method="POST" action="?/disable" use:enhance>
|
||||
<button type="submit" class="rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700">Yes, delete</button>
|
||||
</form>
|
||||
<button type="button" onclick={() => (showDeleteConfirm = false)}
|
||||
class="rounded-md px-3 py-2 text-sm text-gray-600 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700">
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if form?.error}
|
||||
<div class="mb-4 rounded-md bg-red-50 p-3 text-sm text-red-700 dark:bg-red-900/30 dark:text-red-300">{form.error}</div>
|
||||
{/if}
|
||||
|
||||
@@ -35,6 +35,7 @@ export const load: PageServerLoad = async ({ url }) => {
|
||||
})
|
||||
.from(componentInstances)
|
||||
.innerJoin(components, eq(componentInstances.componentId, components.id))
|
||||
.where(eq(components.disabled, false))
|
||||
.orderBy(components.title, componentInstances.instanceNumber);
|
||||
|
||||
const locationList = await db
|
||||
|
||||
Reference in New Issue
Block a user