Miscellaneous fixes (#20833)

* remove frigate+ icon from explore grid footer

* add margin

* pointer cursor on event menu items in detail stream

* don't show submit to plus for non-objects and if plus is disabled

* tweak spacing in annotation settings popover

* Fix deletion of classification images and library

* Ensure after creating a class that things are correct

* Fix dialog getting stuck

* Only show the genai summary popup on mobile when timeline is open

* fix audio transcription embedding

* spacing

* hide x icon on restart sheet to prevent closure issues

* prevent x overflow in detail stream on mobile safari

* ensure name is valid for search effect trigger

* add trigger to detail actions menu

* move find similar to actions menu

* Use a column layout for MobilePageContent in PlatformAwareSheet

 This is so the header is outside the scrolling area and the content can grow/scroll independently. This now matches the way it's done in classification

* Skip azure execution provider

* add optional ref to always scroll to top

the more filters in explore was not scrolled to the top on open due to the use of framer motion

* fix title classes on desktop

---------

Co-authored-by: Nicolas Mowen <nickmowen213@gmail.com>
This commit is contained in:
Josh Hawkins
2025-11-07 06:53:27 -07:00
committed by GitHub
co-authored by Nicolas Mowen
parent a15399fed5
commit 530b69b877
22 changed files with 249 additions and 237 deletions
@@ -118,6 +118,11 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
const [trainFilter, setTrainFilter] = useApiFilter<TrainFilter>();
const refreshAll = useCallback(() => {
refreshTrain();
refreshDataset();
}, [refreshTrain, refreshDataset]);
// image multiselect
const [selectedImages, setSelectedImages] = useState<string[]>([]);
@@ -183,11 +188,12 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
);
const onDelete = useCallback(
(ids: string[], isName: boolean = false) => {
(ids: string[], isName: boolean = false, category?: string) => {
const targetCategory = category || pageToggle;
const api =
pageToggle == "train"
targetCategory == "train"
? `/classification/${model.name}/train/delete`
: `/classification/${model.name}/dataset/${pageToggle}/delete`;
: `/classification/${model.name}/dataset/${targetCategory}/delete`;
axios
.post(api, { ids })
@@ -408,7 +414,7 @@ export default function ModelTrainingView({ model }: ModelTrainingViewProps) {
trainImages={trainImages || []}
trainFilter={trainFilter}
selectedImages={selectedImages}
onRefresh={refreshTrain}
onRefresh={refreshAll}
onClickImages={onClickImages}
onDelete={onDelete}
/>
@@ -432,7 +438,7 @@ type LibrarySelectorProps = {
dataset: { [id: string]: string[] };
trainImages: string[];
setPageToggle: (toggle: string) => void;
onDelete: (ids: string[], isName: boolean) => void;
onDelete: (ids: string[], isName: boolean, category?: string) => void;
onRename: (old_name: string, new_name: string) => void;
};
function LibrarySelector({
@@ -448,7 +454,7 @@ function LibrarySelector({
// data
const [confirmDelete, setConfirmDelete] = useState<string | null>(null);
const [renameClass, setRenameFace] = useState<string | null>(null);
const [renameClass, setRenameClass] = useState<string | null>(null);
const pageTitle = useMemo(() => {
if (pageToggle != "train") {
return pageToggle;
@@ -463,12 +469,12 @@ function LibrarySelector({
// interaction
const handleDeleteFace = useCallback(
const handleDeleteCategory = useCallback(
(name: string) => {
// Get all image IDs for this face
// Get all image IDs for this category
const imageIds = dataset?.[name] || [];
onDelete(imageIds, true);
onDelete(imageIds, true, name);
setPageToggle("train");
},
[dataset, onDelete, setPageToggle],
@@ -476,7 +482,7 @@ function LibrarySelector({
const handleSetOpen = useCallback(
(open: boolean) => {
setRenameFace(open ? renameClass : null);
setRenameClass(open ? renameClass : null);
},
[renameClass],
);
@@ -503,7 +509,7 @@ function LibrarySelector({
className="text-white"
onClick={() => {
if (confirmDelete) {
handleDeleteFace(confirmDelete);
handleDeleteCategory(confirmDelete);
setConfirmDelete(null);
}
}}
@@ -521,7 +527,7 @@ function LibrarySelector({
description={t("renameCategory.desc", { name: renameClass })}
onSave={(newName) => {
onRename(renameClass!, newName);
setRenameFace(null);
setRenameClass(null);
}}
defaultValue={renameClass || ""}
regexPattern={/^[\p{L}\p{N}\s'_-]{1,50}$/u}
@@ -588,7 +594,7 @@ function LibrarySelector({
className="size-7 lg:opacity-0 lg:transition-opacity lg:group-hover:opacity-100"
onClick={(e) => {
e.stopPropagation();
setRenameFace(id);
setRenameClass(id);
}}
>
<LuPencil className="size-4 text-primary" />