Просмотр исходного кода

Show the AI buttons for a provider connected in the catalog (#404)

The vehicle page and the work order page decided whether to offer AI from
the settings rows the removed AI settings page used to write. A provider
connected through the integrations catalog never writes those rows, so
the buttons stayed hidden on any install set up that way. Both pages now
ask isAiConfigured, the same check the document analysis uses.
Bernt Christian Egeland 2 недель назад
Родитель
Сommit
bc3e213651

+ 6 - 14
src/app/(authenticated)/vehicles/[id]/page.tsx

@@ -12,8 +12,8 @@ import { getVehicleQuotes } from '@/features/quotes/Actions/quoteActions'
 import { getVehicleFindings } from '@/features/vehicles/Actions/findingActions'
 import { getFeatures } from '@/lib/features'
 import { findSafetyConnection } from '@/features/integrations/Lib/vehicle-safety'
+import { isAiConfigured } from '@/features/integrations/Lib/ai'
 import { getAuthContext } from '@/lib/get-auth-context'
-import { db } from '@/lib/db'
 import { getTireSetsForVehicle } from '@/features/tire-hotel/Actions/tireJobActions'
 import { VehicleDetailClient } from './vehicle-detail-client'
 import { PageHeader } from '@/components/page-header'
@@ -169,15 +169,11 @@ export default async function VehicleDetailPage({
   let aiEnabled = false
   let safetyAvailable = false
   if (orgId) {
-    const [features, aiSettings, safetyConnection] = await Promise.all([
+    const [features, aiConfigured, safetyConnection] = await Promise.all([
       getFeatures(orgId),
-      db.appSetting.findMany({
-        where: {
-          organizationId: orgId,
-          key: { in: [SETTING_KEYS.AI_ENABLED, SETTING_KEYS.AI_API_KEY] },
-        },
-        select: { key: true, value: true },
-      }),
+      // An AI vendor connected in the catalog, or the settings a workshop
+      // saved before AI moved there. Nothing is adopted from a page render.
+      isAiConfigured(orgId).catch(() => false),
       // An integration must never take the vehicle page down with it: a
       // failed lookup means no panel, nothing more.
       findSafetyConnection(orgId).catch(() => null),
@@ -188,11 +184,7 @@ export default async function VehicleDetailPage({
       features?.integrations === true &&
       safetyConnection !== null &&
       Boolean(result.data.make && result.data.model && result.data.year)
-    const aiMap = Object.fromEntries(aiSettings.map((s) => [s.key, s.value]))
-    aiEnabled =
-      features?.ai === true &&
-      aiMap[SETTING_KEYS.AI_ENABLED] === 'true' &&
-      !!aiMap[SETTING_KEYS.AI_API_KEY]
+    aiEnabled = features?.ai === true && aiConfigured
   }
 
   return (

+ 6 - 15
src/features/vehicles/Components/service-page/ServiceRecordPage.tsx

@@ -17,6 +17,7 @@ import {
   findRuleDesign,
 } from '@/features/invoice-designer/Lib/designRules.server'
 import { getFeatures } from '@/lib/features'
+import { isAiConfigured } from '@/features/integrations/Lib/ai'
 import { getTireHotelSettings } from '@/features/tire-hotel/Lib/tireHotelSettings'
 import { getStatusReportsForService } from '@/features/status-reports/Actions/getStatusReportsForService'
 import { getServiceFindings } from '@/features/vehicles/Actions/findingActions'
@@ -136,7 +137,7 @@ export async function ServiceRecordPage({
   const membership = session?.user?.id ? await getCachedMembership(session.user.id) : null
   const orgId = membership?.organizationId
 
-  const [currentUser, features, aiSettings, tireHotel] = await Promise.all([
+  const [currentUser, features, aiConfigured, tireHotel] = await Promise.all([
     session?.user?.id
       ? db.user.findUnique({
           where: { id: session.user.id },
@@ -144,15 +145,9 @@ export async function ServiceRecordPage({
         })
       : Promise.resolve(null),
     orgId ? getFeatures(orgId) : Promise.resolve(null),
-    orgId
-      ? db.appSetting.findMany({
-          where: {
-            organizationId: orgId,
-            key: { in: [SETTING_KEYS.AI_ENABLED, SETTING_KEYS.AI_API_KEY] },
-          },
-          select: { key: true, value: true },
-        })
-      : Promise.resolve([]),
+    // An AI vendor connected in the catalog, or the settings a workshop saved
+    // before AI moved there. Nothing is adopted from a page render.
+    orgId ? isAiConfigured(orgId).catch(() => false) : Promise.resolve(false),
     // The whole config, not just the switch: checking a set in from here
     // grades tread, and it has to grade against this workshop's own limits.
     getTireHotelSettings(orgId ?? ''),
@@ -185,11 +180,7 @@ export async function ServiceRecordPage({
     null
   const designFollowsRule = ruleDesign?.autoRule ?? null
   const designPinnedAt = rendersFromIssue(record) ? (record.issuedAt?.toISOString() ?? null) : null
-  const aiSettingsMap = Object.fromEntries(aiSettings.map((s) => [s.key, s.value]))
-  const aiEnabled =
-    features?.ai === true &&
-    aiSettingsMap[SETTING_KEYS.AI_ENABLED] === 'true' &&
-    !!aiSettingsMap[SETTING_KEYS.AI_API_KEY]
+  const aiEnabled = features?.ai === true && aiConfigured
 
   // A timestamp outside JS date range (bad legacy data) must degrade to a
   // fallback date, not crash the page on toISOString().