mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-21 04:56:40 +02:00
✨ label filter column
This commit is contained in:
@@ -123,7 +123,27 @@ const listResourcesSchema = z.object({
|
|||||||
type: "integer",
|
type: "integer",
|
||||||
description:
|
description:
|
||||||
"When set, only resources that have at least one target on this site are returned"
|
"When set, only resources that have at least one target on this site are returned"
|
||||||
})
|
}),
|
||||||
|
labels: z
|
||||||
|
.preprocess((val) => {
|
||||||
|
if (val === undefined || val === null || val === "") {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
// the array is returned as this
|
||||||
|
if (typeof val === "string") {
|
||||||
|
return val.split(",");
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}, z.array(z.string()))
|
||||||
|
.optional()
|
||||||
|
.catch([])
|
||||||
|
.openapi({
|
||||||
|
type: "array",
|
||||||
|
description: "Filter by resource labels"
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// grouped by resource with targets[])
|
// grouped by resource with targets[])
|
||||||
@@ -261,7 +281,8 @@ export async function listResources(
|
|||||||
healthStatus,
|
healthStatus,
|
||||||
sort_by,
|
sort_by,
|
||||||
order,
|
order,
|
||||||
siteId
|
siteId,
|
||||||
|
labels: labelFilter
|
||||||
} = parsedQuery.data;
|
} = parsedQuery.data;
|
||||||
|
|
||||||
const parsedParams = listResourcesParamsSchema.safeParse(req.params);
|
const parsedParams = listResourcesParamsSchema.safeParse(req.params);
|
||||||
@@ -379,6 +400,23 @@ export async function listResources(
|
|||||||
.where(and(eq(sites.orgId, orgId), eq(sites.siteId, siteId)));
|
.where(and(eq(sites.orgId, orgId), eq(sites.siteId, siteId)));
|
||||||
conditions.push(inArray(resources.resourceId, resourcesWithSite));
|
conditions.push(inArray(resources.resourceId, resourcesWithSite));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isLabelFeatureEnabled && labelFilter && labelFilter.length > 0) {
|
||||||
|
conditions.push(
|
||||||
|
inArray(
|
||||||
|
resources.resourceId,
|
||||||
|
db
|
||||||
|
.select({ id: resourceLabels.resourceId })
|
||||||
|
.from(resourceLabels)
|
||||||
|
.innerJoin(
|
||||||
|
labels,
|
||||||
|
eq(labels.labelId, resourceLabels.labelId)
|
||||||
|
)
|
||||||
|
.where(inArray(labels.name, labelFilter))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (query) {
|
if (query) {
|
||||||
const q = "%" + query.toLowerCase() + "%";
|
const q = "%" + query.toLowerCase() + "%";
|
||||||
const queryList = [
|
const queryList = [
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ import { ControlledDataTable } from "./ui/controlled-data-table";
|
|||||||
import UptimeMiniBar from "./UptimeMiniBar";
|
import UptimeMiniBar from "./UptimeMiniBar";
|
||||||
import { LabelsSelector, type SelectedLabel } from "./labels-selector";
|
import { LabelsSelector, type SelectedLabel } from "./labels-selector";
|
||||||
import { LabelBadge } from "./label-badge";
|
import { LabelBadge } from "./label-badge";
|
||||||
|
import { LabelColumnFilterButton } from "./LabelColumnFilterButton";
|
||||||
|
|
||||||
export type TargetHealth = {
|
export type TargetHealth = {
|
||||||
targetId: number;
|
targetId: number;
|
||||||
@@ -640,9 +641,15 @@ export default function ProxyResourcesTable({
|
|||||||
id: "labels",
|
id: "labels",
|
||||||
accessorKey: "labels",
|
accessorKey: "labels",
|
||||||
header: () => (
|
header: () => (
|
||||||
<span className="p-3 text-end w-full inline-block">
|
<LabelColumnFilterButton
|
||||||
{t("labels")}
|
orgId={orgId}
|
||||||
</span>
|
selectedValues={searchParams.getAll("labels")}
|
||||||
|
onSelectedValuesChange={(value) =>
|
||||||
|
handleFilterChange("labels", value)
|
||||||
|
}
|
||||||
|
label={t("labels")}
|
||||||
|
className="p-3"
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
cell: ({ row }: { row: { original: ResourceRow } }) => (
|
cell: ({ row }: { row: { original: ResourceRow } }) => (
|
||||||
<ResourceLabelCell resource={row.original} orgId={orgId} />
|
<ResourceLabelCell resource={row.original} orgId={orgId} />
|
||||||
@@ -655,13 +662,15 @@ export default function ProxyResourcesTable({
|
|||||||
|
|
||||||
function handleFilterChange(
|
function handleFilterChange(
|
||||||
column: string,
|
column: string,
|
||||||
value: string | undefined | null
|
value: string | undefined | null | string[]
|
||||||
) {
|
) {
|
||||||
searchParams.delete(column);
|
searchParams.delete(column);
|
||||||
searchParams.delete("page");
|
searchParams.delete("page");
|
||||||
|
|
||||||
if (value) {
|
if (typeof value === "string") {
|
||||||
searchParams.set(column, value);
|
searchParams.set(column, value);
|
||||||
|
} else if (value) {
|
||||||
|
value.forEach((val) => searchParams.append(column, val));
|
||||||
}
|
}
|
||||||
filter({
|
filter({
|
||||||
searchParams
|
searchParams
|
||||||
|
|||||||
Reference in New Issue
Block a user