mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-05 22:57:40 +03:00
Revert "feat: add personal camera groups with per-user visibility"
This commit is contained in:
parent
4f786910e7
commit
d8ecc1a9cc
@ -171,18 +171,6 @@ def config(request: Request):
|
||||
|
||||
config["go2rtc"]["streams"][stream_name] = cleaned
|
||||
|
||||
# filter camera_groups by current user
|
||||
username = request.headers.get("remote-user")
|
||||
role = request.headers.get("remote-role")
|
||||
|
||||
if username and role and role != "admin":
|
||||
filtered_groups = {}
|
||||
for group_name, group_config in config.get("camera_groups", {}).items():
|
||||
group_users = group_config.get("users")
|
||||
if not group_users or username in group_users:
|
||||
filtered_groups[group_name] = group_config
|
||||
config["camera_groups"] = filtered_groups
|
||||
|
||||
config["plus"] = {"enabled": request.app.frigate_config.plus_api.is_active()}
|
||||
config["model"]["colormap"] = config_obj.model.colormap
|
||||
config["model"]["all_attributes"] = config_obj.model.all_attributes
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from typing import Optional, Union
|
||||
from typing import Union
|
||||
|
||||
from pydantic import Field, field_validator
|
||||
|
||||
@ -23,11 +23,6 @@ class CameraGroupConfig(FrigateBaseModel):
|
||||
title="Sort order",
|
||||
description="Numeric order used to sort camera groups in the UI; larger numbers appear later.",
|
||||
)
|
||||
users: Optional[list[str]] = Field(
|
||||
default=None,
|
||||
title="Allowed users",
|
||||
description="List of usernames who can see this group. If not set or empty, the group is visible to all users.",
|
||||
)
|
||||
|
||||
@field_validator("cameras", mode="before")
|
||||
@classmethod
|
||||
|
||||
@ -679,11 +679,6 @@ export function CameraGroupEdit({
|
||||
const allowedCameras = useAllowedCameras();
|
||||
const isAdmin = useIsAdmin();
|
||||
|
||||
// fetch users list for the users multi-select (admin only)
|
||||
const { data: usersList } = useSWR<{ username: string; role: string }[]>(
|
||||
isAdmin ? "users" : null,
|
||||
);
|
||||
|
||||
const [openCamera, setOpenCamera] = useState<string | null>();
|
||||
|
||||
const birdseyeConfig = useMemo(() => config?.birdseye, [config]);
|
||||
@ -726,7 +721,6 @@ export function CameraGroupEdit({
|
||||
.refine((value) => Object.keys(LuIcons).includes(value), {
|
||||
message: "Invalid icon",
|
||||
}),
|
||||
users: z.array(z.string()).optional(),
|
||||
});
|
||||
|
||||
const onSubmit = useCallback(
|
||||
@ -762,18 +756,10 @@ export function CameraGroupEdit({
|
||||
const cameraQueries = values.cameras
|
||||
.map((cam) => `&camera_groups.${values.name}.cameras=${cam}`)
|
||||
.join("");
|
||||
const usersQueries =
|
||||
values.users && values.users.length > 0
|
||||
? values.users
|
||||
.map(
|
||||
(user) => `&camera_groups.${values.name}.users=${user}`,
|
||||
)
|
||||
.join("")
|
||||
: "";
|
||||
|
||||
axios
|
||||
.put(
|
||||
`config/set?${renamingQuery}${orderQuery}&${iconQuery}${cameraQueries}${usersQueries}`,
|
||||
`config/set?${renamingQuery}${orderQuery}&${iconQuery}${cameraQueries}`,
|
||||
{
|
||||
requires_restart: 0,
|
||||
},
|
||||
@ -842,7 +828,6 @@ export function CameraGroupEdit({
|
||||
name: (editingGroup && editingGroup[0]) ?? "",
|
||||
icon: editingGroup && (editingGroup[1].icon as IconName),
|
||||
cameras: editingGroup && editingGroup[1].cameras,
|
||||
users: (editingGroup && editingGroup[1].users) ?? [],
|
||||
},
|
||||
});
|
||||
|
||||
@ -985,56 +970,6 @@ export function CameraGroupEdit({
|
||||
)}
|
||||
/>
|
||||
|
||||
{isAdmin && usersList && usersList.length > 0 && (
|
||||
<>
|
||||
<Separator className="my-2 flex bg-secondary" />
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="users"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t("group.users.label", { defaultValue: "Assigned Users" })}</FormLabel>
|
||||
<FormDescription>
|
||||
{t("group.users.desc", { defaultValue: "If no users are selected, the group is visible to all users." })}
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
<div className="scrollbar-container max-h-[30dvh] overflow-y-auto">
|
||||
{usersList.map((user) => (
|
||||
<FormControl key={user.username}>
|
||||
<div className="flex items-center justify-between gap-1">
|
||||
<label
|
||||
className="mx-2 w-full cursor-pointer text-primary"
|
||||
htmlFor={`user-${user.username}`}
|
||||
>
|
||||
{user.username}
|
||||
<span className="ml-2 text-xs text-muted-foreground">
|
||||
({user.role})
|
||||
</span>
|
||||
</label>
|
||||
<Switch
|
||||
id={`user-${user.username}`}
|
||||
checked={
|
||||
field.value?.includes(user.username) ?? false
|
||||
}
|
||||
onCheckedChange={(checked) => {
|
||||
const updatedUsers = checked
|
||||
? [...(field.value || []), user.username]
|
||||
: (field.value || []).filter(
|
||||
(u) => u !== user.username,
|
||||
);
|
||||
form.setValue("users", updatedUsers);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</FormControl>
|
||||
))}
|
||||
</div>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Separator className="my-2 flex bg-secondary" />
|
||||
|
||||
<div className="flex flex-row gap-2 py-5 md:pb-0">
|
||||
|
||||
@ -312,7 +312,6 @@ export type CameraGroupConfig = {
|
||||
cameras: string[];
|
||||
icon: IconName;
|
||||
order: number;
|
||||
users?: string[];
|
||||
};
|
||||
|
||||
export type StreamType = "no-streaming" | "smart" | "continuous";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user