mirror of
				https://github.com/blakeblackshear/frigate.git
				synced 2025-10-27 10:52:11 +01:00 
			
		
		
		
	Fixes (#18354)
* Rename classification to enrichments * Clean up config updating checks * Add Portugese --------- Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
		
							parent
							
								
									c16e536b46
								
							
						
					
					
						commit
						858c1241db
					
				| @ -19,7 +19,7 @@ For best performance, 16GB or more of RAM and a dedicated GPU are recommended. | |||||||
| 
 | 
 | ||||||
| ## Configuration | ## Configuration | ||||||
| 
 | 
 | ||||||
| Semantic Search is disabled by default, and must be enabled in your config file or in the UI's Classification Settings page before it can be used. Semantic Search is a global configuration setting. | Semantic Search is disabled by default, and must be enabled in your config file or in the UI's Enrichments Settings page before it can be used. Semantic Search is a global configuration setting. | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| semantic_search: | semantic_search: | ||||||
| @ -29,7 +29,7 @@ semantic_search: | |||||||
| 
 | 
 | ||||||
| :::tip | :::tip | ||||||
| 
 | 
 | ||||||
| The embeddings database can be re-indexed from the existing tracked objects in your database by pressing the "Reindex" button in the Classification Settings in the UI or by adding `reindex: True` to your `semantic_search` configuration and restarting Frigate. Depending on the number of tracked objects you have, it can take a long while to complete and may max out your CPU while indexing. | The embeddings database can be re-indexed from the existing tracked objects in your database by pressing the "Reindex" button in the Enrichments Settings in the UI or by adding `reindex: True` to your `semantic_search` configuration and restarting Frigate. Depending on the number of tracked objects you have, it can take a long while to complete and may max out your CPU while indexing. | ||||||
| 
 | 
 | ||||||
| If you are enabling Semantic Search for the first time, be advised that Frigate does not automatically index older tracked objects. You will need to reindex as described above. | If you are enabling Semantic Search for the first time, be advised that Frigate does not automatically index older tracked objects. You will need to reindex as described above. | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -111,7 +111,7 @@ def output_frames( | |||||||
|     move_preview_frames("cache") |     move_preview_frames("cache") | ||||||
| 
 | 
 | ||||||
|     for camera, cam_config in config.cameras.items(): |     for camera, cam_config in config.cameras.items(): | ||||||
|         if not cam_config.enabled: |         if not cam_config.enabled_in_config: | ||||||
|             continue |             continue | ||||||
| 
 | 
 | ||||||
|         jsmpeg_cameras[camera] = JsmpegCamera(cam_config, stop_event, websocket_server) |         jsmpeg_cameras[camera] = JsmpegCamera(cam_config, stop_event, websocket_server) | ||||||
|  | |||||||
| @ -403,6 +403,7 @@ class PreviewRecorder: | |||||||
|             self.reset_frame_cache(frame_time) |             self.reset_frame_cache(frame_time) | ||||||
| 
 | 
 | ||||||
|     def stop(self) -> None: |     def stop(self) -> None: | ||||||
|  |         self.config_subscriber.stop() | ||||||
|         self.requestor.stop() |         self.requestor.stop() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
|     "default": "Settings - Frigate", |     "default": "Settings - Frigate", | ||||||
|     "authentication": "Authentication Settings - Frigate", |     "authentication": "Authentication Settings - Frigate", | ||||||
|     "camera": "Camera Settings - Frigate", |     "camera": "Camera Settings - Frigate", | ||||||
|     "classification": "Classification Settings - Frigate", |     "enrichments": "Enrichments Settings - Frigate", | ||||||
|     "masksAndZones": "Mask and Zone Editor - Frigate", |     "masksAndZones": "Mask and Zone Editor - Frigate", | ||||||
|     "motionTuner": "Motion Tuner - Frigate", |     "motionTuner": "Motion Tuner - Frigate", | ||||||
|     "object": "Debug - Frigate", |     "object": "Debug - Frigate", | ||||||
| @ -13,7 +13,7 @@ | |||||||
|   }, |   }, | ||||||
|   "menu": { |   "menu": { | ||||||
|     "ui": "UI", |     "ui": "UI", | ||||||
|     "classification": "Classification", |     "enrichments": "Enrichments", | ||||||
|     "cameras": "Camera Settings", |     "cameras": "Camera Settings", | ||||||
|     "masksAndZones": "Masks / Zones", |     "masksAndZones": "Masks / Zones", | ||||||
|     "motionTuner": "Motion Tuner", |     "motionTuner": "Motion Tuner", | ||||||
| @ -82,9 +82,9 @@ | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   "classification": { |   "enrichments": { | ||||||
|     "title": "Classification Settings", |     "title": "Enrichments Settings", | ||||||
|     "unsavedChanges": "Unsaved Classification settings changes", |     "unsavedChanges": "Unsaved Enrichments settings changes", | ||||||
|     "birdClassification": { |     "birdClassification": { | ||||||
|       "title": "Bird Classification", |       "title": "Bird Classification", | ||||||
|       "desc": "Bird classification identifies known birds using a quantized Tensorflow model. When a known bird is recognized, its common name will be added as a sub_label. This information is included in the UI, filters, as well as in notifications." |       "desc": "Bird classification identifies known birds using a quantized Tensorflow model. When a known bird is recognized, its common name will be added as a sub_label. This information is included in the UI, filters, as well as in notifications." | ||||||
| @ -138,9 +138,9 @@ | |||||||
|       "desc": "Frigate can recognize license plates on vehicles and automatically add the detected characters to the recognized_license_plate field or a known name as a sub_label to objects that are of type car. A common use case may be to read the license plates of cars pulling into a driveway or cars passing by on a street.", |       "desc": "Frigate can recognize license plates on vehicles and automatically add the detected characters to the recognized_license_plate field or a known name as a sub_label to objects that are of type car. A common use case may be to read the license plates of cars pulling into a driveway or cars passing by on a street.", | ||||||
|       "readTheDocumentation": "Read the Documentation" |       "readTheDocumentation": "Read the Documentation" | ||||||
|     }, |     }, | ||||||
|     "restart_required": "Restart required (Classification settings changed)", |     "restart_required": "Restart required (Enrichments settings changed)", | ||||||
|     "toast": { |     "toast": { | ||||||
|       "success": "Classification settings have been saved. Restart Frigate to apply your changes.", |       "success": "Enrichments settings have been saved. Restart Frigate to apply your changes.", | ||||||
|       "error": "Failed to save config changes: {{errorMessage}}" |       "error": "Failed to save config changes: {{errorMessage}}" | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| export const supportedLanguageKeys = [ | export const supportedLanguageKeys = [ | ||||||
|   "en", |   "en", | ||||||
|   "es", |   "es", | ||||||
|  |   "pt", | ||||||
|   "fr", |   "fr", | ||||||
|   "de", |   "de", | ||||||
|   "it", |   "it", | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ import MotionTunerView from "@/views/settings/MotionTunerView"; | |||||||
| import MasksAndZonesView from "@/views/settings/MasksAndZonesView"; | import MasksAndZonesView from "@/views/settings/MasksAndZonesView"; | ||||||
| import AuthenticationView from "@/views/settings/AuthenticationView"; | import AuthenticationView from "@/views/settings/AuthenticationView"; | ||||||
| import NotificationView from "@/views/settings/NotificationsSettingsView"; | import NotificationView from "@/views/settings/NotificationsSettingsView"; | ||||||
| import ClassificationSettingsView from "@/views/settings/ClassificationSettingsView"; | import EnrichmentsSettingsView from "@/views/settings/EnrichmentsSettingsView"; | ||||||
| import UiSettingsView from "@/views/settings/UiSettingsView"; | import UiSettingsView from "@/views/settings/UiSettingsView"; | ||||||
| import FrigatePlusSettingsView from "@/views/settings/FrigatePlusSettingsView"; | import FrigatePlusSettingsView from "@/views/settings/FrigatePlusSettingsView"; | ||||||
| import { useSearchEffect } from "@/hooks/use-overlay-state"; | import { useSearchEffect } from "@/hooks/use-overlay-state"; | ||||||
| @ -48,7 +48,7 @@ import { useTranslation } from "react-i18next"; | |||||||
| 
 | 
 | ||||||
| const allSettingsViews = [ | const allSettingsViews = [ | ||||||
|   "ui", |   "ui", | ||||||
|   "classification", |   "enrichments", | ||||||
|   "cameras", |   "cameras", | ||||||
|   "masksAndZones", |   "masksAndZones", | ||||||
|   "motionTuner", |   "motionTuner", | ||||||
| @ -249,8 +249,8 @@ export default function Settings() { | |||||||
|       </div> |       </div> | ||||||
|       <div className="mt-2 flex h-full w-full flex-col items-start md:h-dvh md:pb-24"> |       <div className="mt-2 flex h-full w-full flex-col items-start md:h-dvh md:pb-24"> | ||||||
|         {page == "ui" && <UiSettingsView />} |         {page == "ui" && <UiSettingsView />} | ||||||
|         {page == "classification" && ( |         {page == "enrichments" && ( | ||||||
|           <ClassificationSettingsView setUnsavedChanges={setUnsavedChanges} /> |           <EnrichmentsSettingsView setUnsavedChanges={setUnsavedChanges} /> | ||||||
|         )} |         )} | ||||||
|         {page == "debug" && ( |         {page == "debug" && ( | ||||||
|           <ObjectSettingsView selectedCamera={selectedCamera} /> |           <ObjectSettingsView selectedCamera={selectedCamera} /> | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ import { | |||||||
| } from "@/components/ui/alert-dialog"; | } from "@/components/ui/alert-dialog"; | ||||||
| import { buttonVariants } from "@/components/ui/button"; | import { buttonVariants } from "@/components/ui/button"; | ||||||
| 
 | 
 | ||||||
| type ClassificationSettings = { | type EnrichmentsSettings = { | ||||||
|   search: { |   search: { | ||||||
|     enabled?: boolean; |     enabled?: boolean; | ||||||
|     model_size?: SearchModelSize; |     model_size?: SearchModelSize; | ||||||
| @ -50,12 +50,12 @@ type ClassificationSettings = { | |||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| type ClassificationSettingsViewProps = { | type EnrichmentsSettingsViewProps = { | ||||||
|   setUnsavedChanges: React.Dispatch<React.SetStateAction<boolean>>; |   setUnsavedChanges: React.Dispatch<React.SetStateAction<boolean>>; | ||||||
| }; | }; | ||||||
| export default function ClassificationSettingsView({ | export default function EnrichmentsSettingsView({ | ||||||
|   setUnsavedChanges, |   setUnsavedChanges, | ||||||
| }: ClassificationSettingsViewProps) { | }: EnrichmentsSettingsViewProps) { | ||||||
|   const { t } = useTranslation("views/settings"); |   const { t } = useTranslation("views/settings"); | ||||||
|   const { data: config, mutate: updateConfig } = |   const { data: config, mutate: updateConfig } = | ||||||
|     useSWR<FrigateConfig>("config"); |     useSWR<FrigateConfig>("config"); | ||||||
| @ -65,8 +65,8 @@ export default function ClassificationSettingsView({ | |||||||
| 
 | 
 | ||||||
|   const { addMessage, removeMessage } = useContext(StatusBarMessagesContext)!; |   const { addMessage, removeMessage } = useContext(StatusBarMessagesContext)!; | ||||||
| 
 | 
 | ||||||
|   const [classificationSettings, setClassificationSettings] = |   const [enrichmentsSettings, setEnrichmentsSettings] = | ||||||
|     useState<ClassificationSettings>({ |     useState<EnrichmentsSettings>({ | ||||||
|       search: { enabled: undefined, model_size: undefined }, |       search: { enabled: undefined, model_size: undefined }, | ||||||
|       face: { enabled: undefined, model_size: undefined }, |       face: { enabled: undefined, model_size: undefined }, | ||||||
|       lpr: { enabled: undefined }, |       lpr: { enabled: undefined }, | ||||||
| @ -74,7 +74,7 @@ export default function ClassificationSettingsView({ | |||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|   const [origSearchSettings, setOrigSearchSettings] = |   const [origSearchSettings, setOrigSearchSettings] = | ||||||
|     useState<ClassificationSettings>({ |     useState<EnrichmentsSettings>({ | ||||||
|       search: { enabled: undefined, model_size: undefined }, |       search: { enabled: undefined, model_size: undefined }, | ||||||
|       face: { enabled: undefined, model_size: undefined }, |       face: { enabled: undefined, model_size: undefined }, | ||||||
|       lpr: { enabled: undefined }, |       lpr: { enabled: undefined }, | ||||||
| @ -83,8 +83,8 @@ export default function ClassificationSettingsView({ | |||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (config) { |     if (config) { | ||||||
|       if (classificationSettings?.search.enabled == undefined) { |       if (enrichmentsSettings?.search.enabled == undefined) { | ||||||
|         setClassificationSettings({ |         setEnrichmentsSettings({ | ||||||
|           search: { |           search: { | ||||||
|             enabled: config.semantic_search.enabled, |             enabled: config.semantic_search.enabled, | ||||||
|             model_size: config.semantic_search.model_size, |             model_size: config.semantic_search.model_size, | ||||||
| @ -117,10 +117,10 @@ export default function ClassificationSettingsView({ | |||||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps
 |     // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||||||
|   }, [config]); |   }, [config]); | ||||||
| 
 | 
 | ||||||
|   const handleClassificationConfigChange = ( |   const handleEnrichmentsConfigChange = ( | ||||||
|     newConfig: Partial<ClassificationSettings>, |     newConfig: Partial<EnrichmentsSettings>, | ||||||
|   ) => { |   ) => { | ||||||
|     setClassificationSettings((prevConfig) => ({ |     setEnrichmentsSettings((prevConfig) => ({ | ||||||
|       search: { ...prevConfig.search, ...newConfig.search }, |       search: { ...prevConfig.search, ...newConfig.search }, | ||||||
|       face: { ...prevConfig.face, ...newConfig.face }, |       face: { ...prevConfig.face, ...newConfig.face }, | ||||||
|       lpr: { ...prevConfig.lpr, ...newConfig.lpr }, |       lpr: { ...prevConfig.lpr, ...newConfig.lpr }, | ||||||
| @ -135,19 +135,19 @@ export default function ClassificationSettingsView({ | |||||||
| 
 | 
 | ||||||
|     axios |     axios | ||||||
|       .put( |       .put( | ||||||
|         `config/set?semantic_search.enabled=${classificationSettings.search.enabled ? "True" : "False"}&semantic_search.model_size=${classificationSettings.search.model_size}&face_recognition.enabled=${classificationSettings.face.enabled ? "True" : "False"}&face_recognition.model_size=${classificationSettings.face.model_size}&lpr.enabled=${classificationSettings.lpr.enabled ? "True" : "False"}&classification.bird.enabled=${classificationSettings.bird.enabled ? "True" : "False"}`, |         `config/set?semantic_search.enabled=${enrichmentsSettings.search.enabled ? "True" : "False"}&semantic_search.model_size=${enrichmentsSettings.search.model_size}&face_recognition.enabled=${enrichmentsSettings.face.enabled ? "True" : "False"}&face_recognition.model_size=${enrichmentsSettings.face.model_size}&lpr.enabled=${enrichmentsSettings.lpr.enabled ? "True" : "False"}&classification.bird.enabled=${enrichmentsSettings.bird.enabled ? "True" : "False"}`, | ||||||
|         { requires_restart: 0 }, |         { requires_restart: 0 }, | ||||||
|       ) |       ) | ||||||
|       .then((res) => { |       .then((res) => { | ||||||
|         if (res.status === 200) { |         if (res.status === 200) { | ||||||
|           toast.success(t("classification.toast.success"), { |           toast.success(t("enrichments.toast.success"), { | ||||||
|             position: "top-center", |             position: "top-center", | ||||||
|           }); |           }); | ||||||
|           setChangedValue(false); |           setChangedValue(false); | ||||||
|           updateConfig(); |           updateConfig(); | ||||||
|         } else { |         } else { | ||||||
|           toast.error( |           toast.error( | ||||||
|             t("classification.toast.error", { errorMessage: res.statusText }), |             t("enrichments.toast.error", { errorMessage: res.statusText }), | ||||||
|             { position: "top-center" }, |             { position: "top-center" }, | ||||||
|           ); |           ); | ||||||
|         } |         } | ||||||
| @ -164,19 +164,19 @@ export default function ClassificationSettingsView({ | |||||||
|       }) |       }) | ||||||
|       .finally(() => { |       .finally(() => { | ||||||
|         addMessage( |         addMessage( | ||||||
|           "search_settings_restart", |           "enrichments_settings_restart", | ||||||
|           t("classification.restart_required"), |           t("enrichments.restart_required"), | ||||||
|           undefined, |           undefined, | ||||||
|           "search_settings", |           "enrichments_settings", | ||||||
|         ); |         ); | ||||||
|         setIsLoading(false); |         setIsLoading(false); | ||||||
|       }); |       }); | ||||||
|   }, [classificationSettings, t, addMessage, updateConfig]); |   }, [enrichmentsSettings, t, addMessage, updateConfig]); | ||||||
| 
 | 
 | ||||||
|   const onCancel = useCallback(() => { |   const onCancel = useCallback(() => { | ||||||
|     setClassificationSettings(origSearchSettings); |     setEnrichmentsSettings(origSearchSettings); | ||||||
|     setChangedValue(false); |     setChangedValue(false); | ||||||
|     removeMessage("search_settings", "search_settings"); |     removeMessage("enrichments_settings", "enrichments_settings"); | ||||||
|   }, [origSearchSettings, removeMessage]); |   }, [origSearchSettings, removeMessage]); | ||||||
| 
 | 
 | ||||||
|   const onReindex = useCallback(() => { |   const onReindex = useCallback(() => { | ||||||
| @ -186,12 +186,12 @@ export default function ClassificationSettingsView({ | |||||||
|       .put("/reindex") |       .put("/reindex") | ||||||
|       .then((res) => { |       .then((res) => { | ||||||
|         if (res.status === 202) { |         if (res.status === 202) { | ||||||
|           toast.success(t("classification.semanticSearch.reindexNow.success"), { |           toast.success(t("enrichments.semanticSearch.reindexNow.success"), { | ||||||
|             position: "top-center", |             position: "top-center", | ||||||
|           }); |           }); | ||||||
|         } else { |         } else { | ||||||
|           toast.error( |           toast.error( | ||||||
|             t("classification.semanticSearch.reindexNow.error", { |             t("enrichments.semanticSearch.reindexNow.error", { | ||||||
|               errorMessage: res.statusText, |               errorMessage: res.statusText, | ||||||
|             }), |             }), | ||||||
|             { position: "top-center" }, |             { position: "top-center" }, | ||||||
| @ -204,7 +204,7 @@ export default function ClassificationSettingsView({ | |||||||
|           error.response?.data?.detail || |           error.response?.data?.detail || | ||||||
|           "Unknown error"; |           "Unknown error"; | ||||||
|         toast.error( |         toast.error( | ||||||
|           t("classification.semanticSearch.reindexNow.error", { |           t("enrichments.semanticSearch.reindexNow.error", { | ||||||
|             errorMessage, |             errorMessage, | ||||||
|           }), |           }), | ||||||
|           { position: "top-center" }, |           { position: "top-center" }, | ||||||
| @ -219,20 +219,20 @@ export default function ClassificationSettingsView({ | |||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     if (changedValue) { |     if (changedValue) { | ||||||
|       addMessage( |       addMessage( | ||||||
|         "search_settings", |         "enrichments_settings", | ||||||
|         t("classification.unsavedChanges"), |         t("enrichments.unsavedChanges"), | ||||||
|         undefined, |         undefined, | ||||||
|         "search_settings", |         "enrichments_settings", | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       removeMessage("search_settings", "search_settings"); |       removeMessage("enrichments_settings", "enrichments_settings"); | ||||||
|     } |     } | ||||||
|     // we know that these deps are correct
 |     // we know that these deps are correct
 | ||||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps
 |     // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||||||
|   }, [changedValue]); |   }, [changedValue]); | ||||||
| 
 | 
 | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     document.title = t("documentTitle.classification"); |     document.title = t("documentTitle.enrichments"); | ||||||
|   }, [t]); |   }, [t]); | ||||||
| 
 | 
 | ||||||
|   if (!config) { |   if (!config) { | ||||||
| @ -244,15 +244,15 @@ export default function ClassificationSettingsView({ | |||||||
|       <Toaster position="top-center" closeButton={true} /> |       <Toaster position="top-center" closeButton={true} /> | ||||||
|       <div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0"> |       <div className="scrollbar-container order-last mb-10 mt-2 flex h-full w-full flex-col overflow-y-auto rounded-lg border-[1px] border-secondary-foreground bg-background_alt p-2 md:order-none md:mb-0 md:mr-2 md:mt-0"> | ||||||
|         <Heading as="h3" className="my-2"> |         <Heading as="h3" className="my-2"> | ||||||
|           {t("classification.title")} |           {t("enrichments.title")} | ||||||
|         </Heading> |         </Heading> | ||||||
|         <Separator className="my-2 flex bg-secondary" /> |         <Separator className="my-2 flex bg-secondary" /> | ||||||
|         <Heading as="h4" className="my-2"> |         <Heading as="h4" className="my-2"> | ||||||
|           {t("classification.semanticSearch.title")} |           {t("enrichments.semanticSearch.title")} | ||||||
|         </Heading> |         </Heading> | ||||||
|         <div className="max-w-6xl"> |         <div className="max-w-6xl"> | ||||||
|           <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> |           <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> | ||||||
|             <p>{t("classification.semanticSearch.desc")}</p> |             <p>{t("enrichments.semanticSearch.desc")}</p> | ||||||
| 
 | 
 | ||||||
|             <div className="flex items-center text-primary"> |             <div className="flex items-center text-primary"> | ||||||
|               <Link |               <Link | ||||||
| @ -261,7 +261,7 @@ export default function ClassificationSettingsView({ | |||||||
|                 rel="noopener noreferrer" |                 rel="noopener noreferrer" | ||||||
|                 className="inline" |                 className="inline" | ||||||
|               > |               > | ||||||
|                 {t("classification.semanticSearch.readTheDocumentation")} |                 {t("enrichments.semanticSearch.readTheDocumentation")} | ||||||
|                 <LuExternalLink className="ml-2 inline-flex size-3" /> |                 <LuExternalLink className="ml-2 inline-flex size-3" /> | ||||||
|               </Link> |               </Link> | ||||||
|             </div> |             </div> | ||||||
| @ -273,10 +273,10 @@ export default function ClassificationSettingsView({ | |||||||
|             <Switch |             <Switch | ||||||
|               id="enabled" |               id="enabled" | ||||||
|               className="mr-3" |               className="mr-3" | ||||||
|               disabled={classificationSettings.search.enabled === undefined} |               disabled={enrichmentsSettings.search.enabled === undefined} | ||||||
|               checked={classificationSettings.search.enabled === true} |               checked={enrichmentsSettings.search.enabled === true} | ||||||
|               onCheckedChange={(isChecked) => { |               onCheckedChange={(isChecked) => { | ||||||
|                 handleClassificationConfigChange({ |                 handleEnrichmentsConfigChange({ | ||||||
|                   search: { enabled: isChecked }, |                   search: { enabled: isChecked }, | ||||||
|                 }); |                 }); | ||||||
|               }} |               }} | ||||||
| @ -290,54 +290,54 @@ export default function ClassificationSettingsView({ | |||||||
|           <div className="space-y-3"> |           <div className="space-y-3"> | ||||||
|             <Button |             <Button | ||||||
|               variant="default" |               variant="default" | ||||||
|               disabled={isLoading || !classificationSettings.search.enabled} |               disabled={isLoading || !enrichmentsSettings.search.enabled} | ||||||
|               onClick={() => setIsReindexDialogOpen(true)} |               onClick={() => setIsReindexDialogOpen(true)} | ||||||
|               aria-label={t("classification.semanticSearch.reindexNow.label")} |               aria-label={t("enrichments.semanticSearch.reindexNow.label")} | ||||||
|             > |             > | ||||||
|               {t("classification.semanticSearch.reindexNow.label")} |               {t("enrichments.semanticSearch.reindexNow.label")} | ||||||
|             </Button> |             </Button> | ||||||
|             <div className="mt-3 text-sm text-muted-foreground"> |             <div className="mt-3 text-sm text-muted-foreground"> | ||||||
|               <Trans ns="views/settings"> |               <Trans ns="views/settings"> | ||||||
|                 classification.semanticSearch.reindexNow.desc |                 enrichments.semanticSearch.reindexNow.desc | ||||||
|               </Trans> |               </Trans> | ||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|           <div className="mt-2 flex flex-col space-y-6"> |           <div className="mt-2 flex flex-col space-y-6"> | ||||||
|             <div className="space-y-0.5"> |             <div className="space-y-0.5"> | ||||||
|               <div className="text-md"> |               <div className="text-md"> | ||||||
|                 {t("classification.semanticSearch.modelSize.label")} |                 {t("enrichments.semanticSearch.modelSize.label")} | ||||||
|               </div> |               </div> | ||||||
|               <div className="space-y-1 text-sm text-muted-foreground"> |               <div className="space-y-1 text-sm text-muted-foreground"> | ||||||
|                 <p> |                 <p> | ||||||
|                   <Trans ns="views/settings"> |                   <Trans ns="views/settings"> | ||||||
|                     classification.semanticSearch.modelSize.desc |                     enrichments.semanticSearch.modelSize.desc | ||||||
|                   </Trans> |                   </Trans> | ||||||
|                 </p> |                 </p> | ||||||
|                 <ul className="list-disc pl-5 text-sm"> |                 <ul className="list-disc pl-5 text-sm"> | ||||||
|                   <li> |                   <li> | ||||||
|                     <Trans ns="views/settings"> |                     <Trans ns="views/settings"> | ||||||
|                       classification.semanticSearch.modelSize.small.desc |                       enrichments.semanticSearch.modelSize.small.desc | ||||||
|                     </Trans> |                     </Trans> | ||||||
|                   </li> |                   </li> | ||||||
|                   <li> |                   <li> | ||||||
|                     <Trans ns="views/settings"> |                     <Trans ns="views/settings"> | ||||||
|                       classification.semanticSearch.modelSize.large.desc |                       enrichments.semanticSearch.modelSize.large.desc | ||||||
|                     </Trans> |                     </Trans> | ||||||
|                   </li> |                   </li> | ||||||
|                 </ul> |                 </ul> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <Select |             <Select | ||||||
|               value={classificationSettings.search.model_size} |               value={enrichmentsSettings.search.model_size} | ||||||
|               onValueChange={(value) => |               onValueChange={(value) => | ||||||
|                 handleClassificationConfigChange({ |                 handleEnrichmentsConfigChange({ | ||||||
|                   search: { model_size: value as SearchModelSize }, |                   search: { model_size: value as SearchModelSize }, | ||||||
|                 }) |                 }) | ||||||
|               } |               } | ||||||
|             > |             > | ||||||
|               <SelectTrigger className="w-20"> |               <SelectTrigger className="w-20"> | ||||||
|                 {t( |                 {t( | ||||||
|                   `classification.semanticSearch.modelSize.${classificationSettings.search.model_size}.title`, |                   `enrichments.semanticSearch.modelSize.${enrichmentsSettings.search.model_size}.title`, | ||||||
|                 )} |                 )} | ||||||
|               </SelectTrigger> |               </SelectTrigger> | ||||||
|               <SelectContent> |               <SelectContent> | ||||||
| @ -349,7 +349,7 @@ export default function ClassificationSettingsView({ | |||||||
|                       value={size} |                       value={size} | ||||||
|                     > |                     > | ||||||
|                       {t( |                       {t( | ||||||
|                         "classification.semanticSearch.modelSize." + |                         "enrichments.semanticSearch.modelSize." + | ||||||
|                           size + |                           size + | ||||||
|                           ".title", |                           ".title", | ||||||
|                       )} |                       )} | ||||||
| @ -368,11 +368,11 @@ export default function ClassificationSettingsView({ | |||||||
|           <AlertDialogContent> |           <AlertDialogContent> | ||||||
|             <AlertDialogHeader> |             <AlertDialogHeader> | ||||||
|               <AlertDialogTitle> |               <AlertDialogTitle> | ||||||
|                 {t("classification.semanticSearch.reindexNow.confirmTitle")} |                 {t("enrichments.semanticSearch.reindexNow.confirmTitle")} | ||||||
|               </AlertDialogTitle> |               </AlertDialogTitle> | ||||||
|               <AlertDialogDescription> |               <AlertDialogDescription> | ||||||
|                 <Trans ns="views/settings"> |                 <Trans ns="views/settings"> | ||||||
|                   classification.semanticSearch.reindexNow.confirmDesc |                   enrichments.semanticSearch.reindexNow.confirmDesc | ||||||
|                 </Trans> |                 </Trans> | ||||||
|               </AlertDialogDescription> |               </AlertDialogDescription> | ||||||
|             </AlertDialogHeader> |             </AlertDialogHeader> | ||||||
| @ -384,7 +384,7 @@ export default function ClassificationSettingsView({ | |||||||
|                 onClick={onReindex} |                 onClick={onReindex} | ||||||
|                 className={buttonVariants({ variant: "select" })} |                 className={buttonVariants({ variant: "select" })} | ||||||
|               > |               > | ||||||
|                 {t("classification.semanticSearch.reindexNow.confirmButton")} |                 {t("enrichments.semanticSearch.reindexNow.confirmButton")} | ||||||
|               </AlertDialogAction> |               </AlertDialogAction> | ||||||
|             </AlertDialogFooter> |             </AlertDialogFooter> | ||||||
|           </AlertDialogContent> |           </AlertDialogContent> | ||||||
| @ -394,11 +394,11 @@ export default function ClassificationSettingsView({ | |||||||
|           <Separator className="my-2 flex bg-secondary" /> |           <Separator className="my-2 flex bg-secondary" /> | ||||||
| 
 | 
 | ||||||
|           <Heading as="h4" className="my-2"> |           <Heading as="h4" className="my-2"> | ||||||
|             {t("classification.faceRecognition.title")} |             {t("enrichments.faceRecognition.title")} | ||||||
|           </Heading> |           </Heading> | ||||||
|           <div className="max-w-6xl"> |           <div className="max-w-6xl"> | ||||||
|             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> |             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> | ||||||
|               <p>{t("classification.faceRecognition.desc")}</p> |               <p>{t("enrichments.faceRecognition.desc")}</p> | ||||||
| 
 | 
 | ||||||
|               <div className="flex items-center text-primary"> |               <div className="flex items-center text-primary"> | ||||||
|                 <Link |                 <Link | ||||||
| @ -407,7 +407,7 @@ export default function ClassificationSettingsView({ | |||||||
|                   rel="noopener noreferrer" |                   rel="noopener noreferrer" | ||||||
|                   className="inline" |                   className="inline" | ||||||
|                 > |                 > | ||||||
|                   {t("classification.faceRecognition.readTheDocumentation")} |                   {t("enrichments.faceRecognition.readTheDocumentation")} | ||||||
|                   <LuExternalLink className="ml-2 inline-flex size-3" /> |                   <LuExternalLink className="ml-2 inline-flex size-3" /> | ||||||
|                 </Link> |                 </Link> | ||||||
|               </div> |               </div> | ||||||
| @ -419,10 +419,10 @@ export default function ClassificationSettingsView({ | |||||||
|               <Switch |               <Switch | ||||||
|                 id="enabled" |                 id="enabled" | ||||||
|                 className="mr-3" |                 className="mr-3" | ||||||
|                 disabled={classificationSettings.face.enabled === undefined} |                 disabled={enrichmentsSettings.face.enabled === undefined} | ||||||
|                 checked={classificationSettings.face.enabled === true} |                 checked={enrichmentsSettings.face.enabled === true} | ||||||
|                 onCheckedChange={(isChecked) => { |                 onCheckedChange={(isChecked) => { | ||||||
|                   handleClassificationConfigChange({ |                   handleEnrichmentsConfigChange({ | ||||||
|                     face: { enabled: isChecked }, |                     face: { enabled: isChecked }, | ||||||
|                   }); |                   }); | ||||||
|                 }} |                 }} | ||||||
| @ -435,32 +435,32 @@ export default function ClassificationSettingsView({ | |||||||
|             </div> |             </div> | ||||||
|             <div className="space-y-0.5"> |             <div className="space-y-0.5"> | ||||||
|               <div className="text-md"> |               <div className="text-md"> | ||||||
|                 {t("classification.faceRecognition.modelSize.label")} |                 {t("enrichments.faceRecognition.modelSize.label")} | ||||||
|               </div> |               </div> | ||||||
|               <div className="space-y-1 text-sm text-muted-foreground"> |               <div className="space-y-1 text-sm text-muted-foreground"> | ||||||
|                 <p> |                 <p> | ||||||
|                   <Trans ns="views/settings"> |                   <Trans ns="views/settings"> | ||||||
|                     classification.faceRecognition.modelSize.desc |                     enrichments.faceRecognition.modelSize.desc | ||||||
|                   </Trans> |                   </Trans> | ||||||
|                 </p> |                 </p> | ||||||
|                 <ul className="list-disc pl-5 text-sm"> |                 <ul className="list-disc pl-5 text-sm"> | ||||||
|                   <li> |                   <li> | ||||||
|                     <Trans ns="views/settings"> |                     <Trans ns="views/settings"> | ||||||
|                       classification.faceRecognition.modelSize.small.desc |                       enrichments.faceRecognition.modelSize.small.desc | ||||||
|                     </Trans> |                     </Trans> | ||||||
|                   </li> |                   </li> | ||||||
|                   <li> |                   <li> | ||||||
|                     <Trans ns="views/settings"> |                     <Trans ns="views/settings"> | ||||||
|                       classification.faceRecognition.modelSize.large.desc |                       enrichments.faceRecognition.modelSize.large.desc | ||||||
|                     </Trans> |                     </Trans> | ||||||
|                   </li> |                   </li> | ||||||
|                 </ul> |                 </ul> | ||||||
|               </div> |               </div> | ||||||
|             </div> |             </div> | ||||||
|             <Select |             <Select | ||||||
|               value={classificationSettings.face.model_size} |               value={enrichmentsSettings.face.model_size} | ||||||
|               onValueChange={(value) => |               onValueChange={(value) => | ||||||
|                 handleClassificationConfigChange({ |                 handleEnrichmentsConfigChange({ | ||||||
|                   face: { |                   face: { | ||||||
|                     model_size: value as SearchModelSize, |                     model_size: value as SearchModelSize, | ||||||
|                   }, |                   }, | ||||||
| @ -469,7 +469,7 @@ export default function ClassificationSettingsView({ | |||||||
|             > |             > | ||||||
|               <SelectTrigger className="w-20"> |               <SelectTrigger className="w-20"> | ||||||
|                 {t( |                 {t( | ||||||
|                   `classification.faceRecognition.modelSize.${classificationSettings.face.model_size}.title`, |                   `enrichments.faceRecognition.modelSize.${enrichmentsSettings.face.model_size}.title`, | ||||||
|                 )} |                 )} | ||||||
|               </SelectTrigger> |               </SelectTrigger> | ||||||
|               <SelectContent> |               <SelectContent> | ||||||
| @ -481,7 +481,7 @@ export default function ClassificationSettingsView({ | |||||||
|                       value={size} |                       value={size} | ||||||
|                     > |                     > | ||||||
|                       {t( |                       {t( | ||||||
|                         "classification.faceRecognition.modelSize." + |                         "enrichments.faceRecognition.modelSize." + | ||||||
|                           size + |                           size + | ||||||
|                           ".title", |                           ".title", | ||||||
|                       )} |                       )} | ||||||
| @ -495,11 +495,11 @@ export default function ClassificationSettingsView({ | |||||||
|           <Separator className="my-2 flex bg-secondary" /> |           <Separator className="my-2 flex bg-secondary" /> | ||||||
| 
 | 
 | ||||||
|           <Heading as="h4" className="my-2"> |           <Heading as="h4" className="my-2"> | ||||||
|             {t("classification.licensePlateRecognition.title")} |             {t("enrichments.licensePlateRecognition.title")} | ||||||
|           </Heading> |           </Heading> | ||||||
|           <div className="max-w-6xl"> |           <div className="max-w-6xl"> | ||||||
|             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> |             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> | ||||||
|               <p>{t("classification.licensePlateRecognition.desc")}</p> |               <p>{t("enrichments.licensePlateRecognition.desc")}</p> | ||||||
| 
 | 
 | ||||||
|               <div className="flex items-center text-primary"> |               <div className="flex items-center text-primary"> | ||||||
|                 <Link |                 <Link | ||||||
| @ -509,7 +509,7 @@ export default function ClassificationSettingsView({ | |||||||
|                   className="inline" |                   className="inline" | ||||||
|                 > |                 > | ||||||
|                   {t( |                   {t( | ||||||
|                     "classification.licensePlateRecognition.readTheDocumentation", |                     "enrichments.licensePlateRecognition.readTheDocumentation", | ||||||
|                   )} |                   )} | ||||||
|                   <LuExternalLink className="ml-2 inline-flex size-3" /> |                   <LuExternalLink className="ml-2 inline-flex size-3" /> | ||||||
|                 </Link> |                 </Link> | ||||||
| @ -522,10 +522,10 @@ export default function ClassificationSettingsView({ | |||||||
|               <Switch |               <Switch | ||||||
|                 id="enabled" |                 id="enabled" | ||||||
|                 className="mr-3" |                 className="mr-3" | ||||||
|                 disabled={classificationSettings.lpr.enabled === undefined} |                 disabled={enrichmentsSettings.lpr.enabled === undefined} | ||||||
|                 checked={classificationSettings.lpr.enabled === true} |                 checked={enrichmentsSettings.lpr.enabled === true} | ||||||
|                 onCheckedChange={(isChecked) => { |                 onCheckedChange={(isChecked) => { | ||||||
|                   handleClassificationConfigChange({ |                   handleEnrichmentsConfigChange({ | ||||||
|                     lpr: { enabled: isChecked }, |                     lpr: { enabled: isChecked }, | ||||||
|                   }); |                   }); | ||||||
|                 }} |                 }} | ||||||
| @ -541,11 +541,11 @@ export default function ClassificationSettingsView({ | |||||||
|           <Separator className="my-2 flex bg-secondary" /> |           <Separator className="my-2 flex bg-secondary" /> | ||||||
| 
 | 
 | ||||||
|           <Heading as="h4" className="my-2"> |           <Heading as="h4" className="my-2"> | ||||||
|             {t("classification.birdClassification.title")} |             {t("enrichments.birdClassification.title")} | ||||||
|           </Heading> |           </Heading> | ||||||
|           <div className="max-w-6xl"> |           <div className="max-w-6xl"> | ||||||
|             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> |             <div className="mb-5 mt-2 flex max-w-5xl flex-col gap-2 text-sm text-primary-variant"> | ||||||
|               <p>{t("classification.birdClassification.desc")}</p> |               <p>{t("enrichments.birdClassification.desc")}</p> | ||||||
| 
 | 
 | ||||||
|               <div className="flex items-center text-primary"> |               <div className="flex items-center text-primary"> | ||||||
|                 <Link |                 <Link | ||||||
| @ -554,7 +554,7 @@ export default function ClassificationSettingsView({ | |||||||
|                   rel="noopener noreferrer" |                   rel="noopener noreferrer" | ||||||
|                   className="inline" |                   className="inline" | ||||||
|                 > |                 > | ||||||
|                   {t("classification.semanticSearch.readTheDocumentation")} |                   {t("enrichments.semanticSearch.readTheDocumentation")} | ||||||
|                   <LuExternalLink className="ml-2 inline-flex size-3" /> |                   <LuExternalLink className="ml-2 inline-flex size-3" /> | ||||||
|                 </Link> |                 </Link> | ||||||
|               </div> |               </div> | ||||||
| @ -566,10 +566,10 @@ export default function ClassificationSettingsView({ | |||||||
|               <Switch |               <Switch | ||||||
|                 id="enabled" |                 id="enabled" | ||||||
|                 className="mr-3" |                 className="mr-3" | ||||||
|                 disabled={classificationSettings.bird.enabled === undefined} |                 disabled={enrichmentsSettings.bird.enabled === undefined} | ||||||
|                 checked={classificationSettings.bird.enabled === true} |                 checked={enrichmentsSettings.bird.enabled === true} | ||||||
|                 onCheckedChange={(isChecked) => { |                 onCheckedChange={(isChecked) => { | ||||||
|                   handleClassificationConfigChange({ |                   handleEnrichmentsConfigChange({ | ||||||
|                     bird: { enabled: isChecked }, |                     bird: { enabled: isChecked }, | ||||||
|                   }); |                   }); | ||||||
|                 }} |                 }} | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user