mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-05 19:59:43 +00:00
show sites and labels for non admins
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
||||
CommandItem,
|
||||
CommandList
|
||||
} from "@app/components/ui/command";
|
||||
import { orgQueries } from "@app/lib/queries";
|
||||
import { launcherQueries, orgQueries } from "@app/lib/queries";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useState } from "react";
|
||||
@@ -27,6 +27,7 @@ type LabelsFilterSelectorProps = {
|
||||
onToggle: (label: LabelFilterOption) => void;
|
||||
onClear?: () => void;
|
||||
showClear?: boolean;
|
||||
scope?: "org" | "launcher";
|
||||
};
|
||||
|
||||
export function LabelsFilterSelector({
|
||||
@@ -34,19 +35,33 @@ export function LabelsFilterSelector({
|
||||
isSelected,
|
||||
onToggle,
|
||||
onClear,
|
||||
showClear = false
|
||||
showClear = false,
|
||||
scope = "org"
|
||||
}: LabelsFilterSelectorProps) {
|
||||
const t = useTranslations();
|
||||
const [labelSearchQuery, setlabelsSearchQuery] = useState("");
|
||||
const [debouncedQuery] = useDebounce(labelSearchQuery, 150);
|
||||
|
||||
const { data: labels = [] } = useQuery(
|
||||
orgQueries.labels({
|
||||
const orgLabelsQuery = useQuery({
|
||||
...orgQueries.labels({
|
||||
orgId,
|
||||
query: debouncedQuery,
|
||||
perPage: 500
|
||||
})
|
||||
);
|
||||
}),
|
||||
enabled: scope === "org"
|
||||
});
|
||||
const launcherLabelsQuery = useQuery({
|
||||
...launcherQueries.labels({
|
||||
orgId,
|
||||
query: debouncedQuery,
|
||||
perPage: 500
|
||||
}),
|
||||
enabled: scope === "launcher"
|
||||
});
|
||||
const labels =
|
||||
scope === "launcher"
|
||||
? (launcherLabelsQuery.data ?? [])
|
||||
: (orgLabelsQuery.data ?? []);
|
||||
|
||||
return (
|
||||
<Command shouldFilter={false}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { orgQueries } from "@app/lib/queries";
|
||||
import { launcherQueries, orgQueries } from "@app/lib/queries";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useMemo, useState } from "react";
|
||||
import {
|
||||
@@ -19,6 +19,7 @@ export type MultiSitesSelectorProps = {
|
||||
selectedSites: Selectedsite[];
|
||||
onSelectionChange: (sites: Selectedsite[]) => void;
|
||||
filterTypes?: string[];
|
||||
scope?: "org" | "launcher";
|
||||
};
|
||||
|
||||
export function formatMultiSitesSelectorLabel(
|
||||
@@ -40,19 +41,33 @@ export function MultiSitesSelector({
|
||||
orgId,
|
||||
selectedSites,
|
||||
onSelectionChange,
|
||||
filterTypes
|
||||
filterTypes,
|
||||
scope = "org"
|
||||
}: MultiSitesSelectorProps) {
|
||||
const t = useTranslations();
|
||||
const [siteSearchQuery, setSiteSearchQuery] = useState("");
|
||||
const [debouncedQuery] = useDebounce(siteSearchQuery, 150);
|
||||
|
||||
const { data: sites = [] } = useQuery(
|
||||
orgQueries.sites({
|
||||
const orgSitesQuery = useQuery({
|
||||
...orgQueries.sites({
|
||||
orgId,
|
||||
query: debouncedQuery,
|
||||
perPage: 10
|
||||
})
|
||||
);
|
||||
}),
|
||||
enabled: scope === "org"
|
||||
});
|
||||
const launcherSitesQuery = useQuery({
|
||||
...launcherQueries.sites({
|
||||
orgId,
|
||||
query: debouncedQuery,
|
||||
perPage: 500
|
||||
}),
|
||||
enabled: scope === "launcher"
|
||||
});
|
||||
const sites =
|
||||
scope === "launcher"
|
||||
? (launcherSitesQuery.data ?? [])
|
||||
: (orgSitesQuery.data ?? []);
|
||||
|
||||
const sitesShown = useMemo(() => {
|
||||
const base = filterTypes
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
PopoverTrigger
|
||||
} from "@app/components/ui/popover";
|
||||
import { cn } from "@app/lib/cn";
|
||||
import { orgQueries } from "@app/lib/queries";
|
||||
import { launcherQueries } from "@app/lib/queries";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { ChevronsUpDown, Funnel } from "lucide-react";
|
||||
@@ -44,12 +44,37 @@ export function LauncherFilterPopover({
|
||||
const [labelsOpen, setLabelsOpen] = useState(false);
|
||||
|
||||
const { data: labels = [] } = useQuery(
|
||||
orgQueries.labels({
|
||||
launcherQueries.labels({
|
||||
orgId,
|
||||
perPage: 500
|
||||
})
|
||||
);
|
||||
|
||||
const { data: sites = [] } = useQuery(
|
||||
launcherQueries.sites({
|
||||
orgId,
|
||||
perPage: 500
|
||||
})
|
||||
);
|
||||
|
||||
const resolvedSelectedSites: Selectedsite[] = useMemo(
|
||||
() =>
|
||||
selectedSites.map((selected) => {
|
||||
const found = sites.find(
|
||||
(site) => site.siteId === selected.siteId
|
||||
);
|
||||
return found
|
||||
? {
|
||||
siteId: found.siteId,
|
||||
name: found.name,
|
||||
type: found.type,
|
||||
online: found.online
|
||||
}
|
||||
: selected;
|
||||
}),
|
||||
[sites, selectedSites]
|
||||
);
|
||||
|
||||
const selectedLabelIds = useMemo(
|
||||
() => new Set(selectedLabels.map((label) => label.labelId)),
|
||||
[selectedLabels]
|
||||
@@ -98,7 +123,7 @@ export function LauncherFilterPopover({
|
||||
>
|
||||
<span className="truncate text-left">
|
||||
{formatMultiSitesSelectorLabel(
|
||||
selectedSites,
|
||||
resolvedSelectedSites,
|
||||
t
|
||||
)}
|
||||
</span>
|
||||
@@ -111,8 +136,9 @@ export function LauncherFilterPopover({
|
||||
>
|
||||
<MultiSitesSelector
|
||||
orgId={orgId}
|
||||
selectedSites={selectedSites}
|
||||
selectedSites={resolvedSelectedSites}
|
||||
onSelectionChange={onSitesChange}
|
||||
scope="launcher"
|
||||
/>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
@@ -145,6 +171,7 @@ export function LauncherFilterPopover({
|
||||
>
|
||||
<LabelsFilterSelector
|
||||
orgId={orgId}
|
||||
scope="launcher"
|
||||
isSelected={(label) =>
|
||||
selectedLabelIds.has(label.labelId)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,9 @@ import type { ListResourcePoliciesResponse } from "@server/routers/resource/type
|
||||
import type { GetResourcePolicyResponse } from "@server/routers/policy";
|
||||
import type {
|
||||
ListLauncherGroupsResponse,
|
||||
ListLauncherLabelsResponse,
|
||||
ListLauncherResourcesResponse,
|
||||
ListLauncherSitesResponse,
|
||||
ListLauncherViewsResponse,
|
||||
LauncherListQuery,
|
||||
LauncherViewConfig
|
||||
@@ -1190,6 +1192,72 @@ export const launcherQueries = {
|
||||
return res.data.data.views;
|
||||
}
|
||||
}),
|
||||
sites: ({
|
||||
orgId,
|
||||
query,
|
||||
perPage = 500
|
||||
}: {
|
||||
orgId: string;
|
||||
query?: string;
|
||||
perPage?: number;
|
||||
}) =>
|
||||
queryOptions({
|
||||
queryKey: [
|
||||
"ORG",
|
||||
orgId,
|
||||
"LAUNCHER",
|
||||
"SITES",
|
||||
{ query, perPage }
|
||||
] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const sp = new URLSearchParams({
|
||||
pageSize: perPage.toString()
|
||||
});
|
||||
|
||||
if (query?.trim()) {
|
||||
sp.set("query", query);
|
||||
}
|
||||
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<ListLauncherSitesResponse>
|
||||
>(`/org/${orgId}/launcher/sites?${sp.toString()}`, { signal });
|
||||
return res.data.data.sites;
|
||||
}
|
||||
}),
|
||||
labels: ({
|
||||
orgId,
|
||||
query,
|
||||
perPage = 500
|
||||
}: {
|
||||
orgId: string;
|
||||
query?: string;
|
||||
perPage?: number;
|
||||
}) =>
|
||||
queryOptions({
|
||||
queryKey: [
|
||||
"ORG",
|
||||
orgId,
|
||||
"LAUNCHER",
|
||||
"LABELS",
|
||||
{ query, perPage }
|
||||
] as const,
|
||||
queryFn: async ({ signal, meta }) => {
|
||||
const sp = new URLSearchParams({
|
||||
pageSize: perPage.toString()
|
||||
});
|
||||
|
||||
if (query?.trim()) {
|
||||
sp.set("query", query);
|
||||
}
|
||||
|
||||
const res = await meta!.api.get<
|
||||
AxiosResponse<ListLauncherLabelsResponse>
|
||||
>(`/org/${orgId}/launcher/labels?${sp.toString()}`, {
|
||||
signal
|
||||
});
|
||||
return res.data.data.labels;
|
||||
}
|
||||
}),
|
||||
groups: (orgId: string, filters: LauncherQueryFilters) =>
|
||||
infiniteQueryOptions({
|
||||
queryKey: ["ORG", orgId, "LAUNCHER", "GROUPS", filters] as const,
|
||||
|
||||
Reference in New Issue
Block a user