mirror of
https://github.com/freedbygrace/ActiveDirectoryManager.git
synced 2026-08-24 08:56:26 +00:00
Add auto-update feature to LDAP query builder. This allows users to automatically generate and update LDAP filters based on changes made in the builder.
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 705f2157-ef97-4fbd-89e4-8c7f2ecaea90 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7ed01c5f-a82d-405a-b728-b2e3d127c60c/780f41b5-94d1-4167-880d-b8a8a3fce389.jpg
This commit is contained in:
@@ -4,6 +4,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||||
@@ -73,9 +74,9 @@ const LdapQueryBuilderPage = () => {
|
|||||||
const [showTestResultsDialog, setShowTestResultsDialog] = useState(false);
|
const [showTestResultsDialog, setShowTestResultsDialog] = useState(false);
|
||||||
const [testResults, setTestResults] = useState<any[]>([]);
|
const [testResults, setTestResults] = useState<any[]>([]);
|
||||||
const [isActive, setIsActive] = useState(true);
|
const [isActive, setIsActive] = useState(true);
|
||||||
|
const [autoUpdateEnabled, setAutoUpdateEnabled] = useState(false);
|
||||||
const [filterBuilder, setFilterBuilder] = useState<any>({
|
const [filterBuilder, setFilterBuilder] = useState<any>({
|
||||||
operator: "and",
|
operator: "and",
|
||||||
conditions: [{ attribute: "", operator: "equals", value: "" }],
|
|
||||||
groups: []
|
groups: []
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -240,7 +241,6 @@ const LdapQueryBuilderPage = () => {
|
|||||||
// Reset filter builder to default state
|
// Reset filter builder to default state
|
||||||
setFilterBuilder({
|
setFilterBuilder({
|
||||||
operator: "and",
|
operator: "and",
|
||||||
conditions: [{ attribute: "", operator: "equals", value: "" }],
|
|
||||||
groups: []
|
groups: []
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -272,6 +272,62 @@ const LdapQueryBuilderPage = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Generate LDAP filter from the builder
|
||||||
|
const generateLdapFilter = () => {
|
||||||
|
const mainOperatorSymbol = filterBuilder.operator === 'and' ? '&' : '|';
|
||||||
|
|
||||||
|
// Generate group conditions
|
||||||
|
const groupsLdap = filterBuilder.groups
|
||||||
|
.map((group: any) => {
|
||||||
|
const groupOperatorSymbol = group.operator === 'and' ? '&' : '|';
|
||||||
|
|
||||||
|
const groupConditions = group.conditions
|
||||||
|
.filter((c: any) => c.attribute.trim() !== '')
|
||||||
|
.map((c: any) => {
|
||||||
|
switch (c.operator) {
|
||||||
|
case 'equals':
|
||||||
|
return `(${c.attribute}=${c.value})`;
|
||||||
|
case 'contains':
|
||||||
|
return `(${c.attribute}=*${c.value}*)`;
|
||||||
|
case 'startsWith':
|
||||||
|
return `(${c.attribute}=${c.value}*)`;
|
||||||
|
case 'endsWith':
|
||||||
|
return `(${c.attribute}=*${c.value})`;
|
||||||
|
case 'present':
|
||||||
|
return `(${c.attribute}=*)`;
|
||||||
|
case 'notEquals':
|
||||||
|
return `(!(${c.attribute}=${c.value}))`;
|
||||||
|
default:
|
||||||
|
return `(${c.attribute}=${c.value})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (groupConditions.length === 0) {
|
||||||
|
return '';
|
||||||
|
} else if (groupConditions.length === 1) {
|
||||||
|
return groupConditions[0];
|
||||||
|
} else {
|
||||||
|
return `(${groupOperatorSymbol}${groupConditions.join('')})`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter((ldap: string) => ldap !== '');
|
||||||
|
|
||||||
|
if (groupsLdap.length === 0) {
|
||||||
|
setFilterQuery('');
|
||||||
|
} else if (groupsLdap.length === 1) {
|
||||||
|
setFilterQuery(groupsLdap[0]);
|
||||||
|
} else {
|
||||||
|
setFilterQuery(`(${mainOperatorSymbol}${groupsLdap.join('')})`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Auto-update the LDAP filter when changes are made (if enabled)
|
||||||
|
useEffect(() => {
|
||||||
|
if (autoUpdateEnabled) {
|
||||||
|
generateLdapFilter();
|
||||||
|
}
|
||||||
|
}, [filterBuilder, autoUpdateEnabled]);
|
||||||
|
|
||||||
// Save filter
|
// Save filter
|
||||||
const handleSaveFilter = () => {
|
const handleSaveFilter = () => {
|
||||||
if (!filterName || !filterQuery) {
|
if (!filterName || !filterQuery) {
|
||||||
@@ -644,102 +700,6 @@ const LdapQueryBuilderPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Main conditions section */}
|
|
||||||
<div className="border rounded-md p-4 space-y-4 bg-background">
|
|
||||||
{filterBuilder.conditions.map((condition: any, index: number) => (
|
|
||||||
<div key={index} className="grid grid-cols-12 gap-2 items-center">
|
|
||||||
<div className="col-span-4">
|
|
||||||
<Input
|
|
||||||
placeholder="Attribute"
|
|
||||||
value={condition.attribute}
|
|
||||||
onChange={(e) => {
|
|
||||||
const updatedConditions = [...filterBuilder.conditions];
|
|
||||||
updatedConditions[index].attribute = e.target.value;
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
conditions: updatedConditions
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-3">
|
|
||||||
<Select
|
|
||||||
value={condition.operator}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
const updatedConditions = [...filterBuilder.conditions];
|
|
||||||
updatedConditions[index].operator = value;
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
conditions: updatedConditions
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Operator" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="equals">Equals</SelectItem>
|
|
||||||
<SelectItem value="contains">Contains</SelectItem>
|
|
||||||
<SelectItem value="startsWith">Starts With</SelectItem>
|
|
||||||
<SelectItem value="endsWith">Ends With</SelectItem>
|
|
||||||
<SelectItem value="present">Is Present</SelectItem>
|
|
||||||
<SelectItem value="notEquals">Not Equals</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-4">
|
|
||||||
<Input
|
|
||||||
placeholder="Value"
|
|
||||||
value={condition.value}
|
|
||||||
disabled={condition.operator === 'present'}
|
|
||||||
onChange={(e) => {
|
|
||||||
const updatedConditions = [...filterBuilder.conditions];
|
|
||||||
updatedConditions[index].value = e.target.value;
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
conditions: updatedConditions
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-1 flex justify-end">
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => {
|
|
||||||
const updatedConditions = [...filterBuilder.conditions];
|
|
||||||
updatedConditions.splice(index, 1);
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
conditions: updatedConditions
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
disabled={filterBuilder.conditions.length <= 1}
|
|
||||||
>
|
|
||||||
<Trash className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
conditions: [
|
|
||||||
...filterBuilder.conditions,
|
|
||||||
{ attribute: "", operator: "equals", value: "" }
|
|
||||||
]
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Plus className="h-4 w-4 mr-2" />
|
|
||||||
Add Condition
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Condition groups section */}
|
{/* Condition groups section */}
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<div className="flex justify-between items-center mb-2">
|
<div className="flex justify-between items-center mb-2">
|
||||||
@@ -767,231 +727,201 @@ const LdapQueryBuilderPage = () => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{filterBuilder.groups && filterBuilder.groups.map((group: any, groupIndex: number) => (
|
{filterBuilder.groups && filterBuilder.groups.length > 0 ? (
|
||||||
<div key={groupIndex} className="border rounded-md p-4 mb-4 bg-background">
|
filterBuilder.groups.map((group: any, groupIndex: number) => (
|
||||||
<div className="flex justify-between items-center mb-3">
|
<div key={groupIndex} className="border rounded-md p-4 mb-4 bg-background">
|
||||||
<div className="flex items-center">
|
<div className="flex justify-between items-center mb-3">
|
||||||
<Label className="mr-2">Group Operator:</Label>
|
<div className="flex items-center">
|
||||||
<Select
|
<Label className="mr-2">Group Operator:</Label>
|
||||||
value={group.operator}
|
<Select
|
||||||
onValueChange={(value) => {
|
value={group.operator}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].operator = value;
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-24">
|
||||||
|
<SelectValue placeholder="Operator" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="and">AND</SelectItem>
|
||||||
|
<SelectItem value="or">OR</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => {
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
updatedGroups[groupIndex].operator = value;
|
updatedGroups.splice(groupIndex, 1);
|
||||||
setFilterBuilder({
|
setFilterBuilder({
|
||||||
...filterBuilder,
|
...filterBuilder,
|
||||||
groups: updatedGroups
|
groups: updatedGroups
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SelectTrigger className="w-24">
|
<X className="h-4 w-4" />
|
||||||
<SelectValue placeholder="Operator" />
|
</Button>
|
||||||
</SelectTrigger>
|
</div>
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="and">AND</SelectItem>
|
<div className="space-y-3">
|
||||||
<SelectItem value="or">OR</SelectItem>
|
{group.conditions.map((condition: any, condIndex: number) => (
|
||||||
</SelectContent>
|
<div key={condIndex} className="grid grid-cols-12 gap-2 items-center">
|
||||||
</Select>
|
<div className="col-span-4">
|
||||||
|
<Input
|
||||||
|
placeholder="Attribute"
|
||||||
|
value={condition.attribute}
|
||||||
|
onChange={(e) => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].conditions[condIndex].attribute = e.target.value;
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3">
|
||||||
|
<Select
|
||||||
|
value={condition.operator}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].conditions[condIndex].operator = value;
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="Operator" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="equals">Equals</SelectItem>
|
||||||
|
<SelectItem value="contains">Contains</SelectItem>
|
||||||
|
<SelectItem value="startsWith">Starts With</SelectItem>
|
||||||
|
<SelectItem value="endsWith">Ends With</SelectItem>
|
||||||
|
<SelectItem value="present">Is Present</SelectItem>
|
||||||
|
<SelectItem value="notEquals">Not Equals</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-4">
|
||||||
|
<Input
|
||||||
|
placeholder="Value"
|
||||||
|
value={condition.value}
|
||||||
|
disabled={condition.operator === 'present'}
|
||||||
|
onChange={(e) => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].conditions[condIndex].value = e.target.value;
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-1 flex justify-end">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
onClick={() => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].conditions.splice(condIndex, 1);
|
||||||
|
if (updatedGroups[groupIndex].conditions.length === 0) {
|
||||||
|
updatedGroups.splice(groupIndex, 1);
|
||||||
|
}
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
disabled={group.conditions.length <= 1}
|
||||||
|
>
|
||||||
|
<Trash className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
const updatedGroups = [...filterBuilder.groups];
|
||||||
|
updatedGroups[groupIndex].conditions.push(
|
||||||
|
{ attribute: "", operator: "equals", value: "" }
|
||||||
|
);
|
||||||
|
setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
groups: updatedGroups
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4 mr-2" />
|
||||||
|
Add Condition to Group
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => {
|
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
|
||||||
updatedGroups.splice(groupIndex, 1);
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
groups: updatedGroups
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<X className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
))
|
||||||
<div className="space-y-3">
|
) : (
|
||||||
{group.conditions.map((condition: any, condIndex: number) => (
|
<div className="p-8 text-center border rounded-md bg-background">
|
||||||
<div key={condIndex} className="grid grid-cols-12 gap-2 items-center">
|
<p className="text-muted-foreground mb-4">No condition groups added yet</p>
|
||||||
<div className="col-span-4">
|
<Button
|
||||||
<Input
|
variant="outline"
|
||||||
placeholder="Attribute"
|
size="sm"
|
||||||
value={condition.attribute}
|
onClick={() => {
|
||||||
onChange={(e) => {
|
setFilterBuilder({
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
...filterBuilder,
|
||||||
updatedGroups[groupIndex].conditions[condIndex].attribute = e.target.value;
|
groups: [
|
||||||
setFilterBuilder({
|
...filterBuilder.groups,
|
||||||
...filterBuilder,
|
{
|
||||||
groups: updatedGroups
|
operator: "and",
|
||||||
});
|
conditions: [
|
||||||
}}
|
{ attribute: "", operator: "equals", value: "" }
|
||||||
/>
|
]
|
||||||
</div>
|
|
||||||
<div className="col-span-3">
|
|
||||||
<Select
|
|
||||||
value={condition.operator}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
|
||||||
updatedGroups[groupIndex].conditions[condIndex].operator = value;
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
groups: updatedGroups
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="Operator" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectItem value="equals">Equals</SelectItem>
|
|
||||||
<SelectItem value="contains">Contains</SelectItem>
|
|
||||||
<SelectItem value="startsWith">Starts With</SelectItem>
|
|
||||||
<SelectItem value="endsWith">Ends With</SelectItem>
|
|
||||||
<SelectItem value="present">Is Present</SelectItem>
|
|
||||||
<SelectItem value="notEquals">Not Equals</SelectItem>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-4">
|
|
||||||
<Input
|
|
||||||
placeholder="Value"
|
|
||||||
value={condition.value}
|
|
||||||
disabled={condition.operator === 'present'}
|
|
||||||
onChange={(e) => {
|
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
|
||||||
updatedGroups[groupIndex].conditions[condIndex].value = e.target.value;
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
groups: updatedGroups
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-1 flex justify-end">
|
|
||||||
<Button
|
|
||||||
variant="ghost"
|
|
||||||
size="icon"
|
|
||||||
onClick={() => {
|
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
|
||||||
updatedGroups[groupIndex].conditions.splice(condIndex, 1);
|
|
||||||
if (updatedGroups[groupIndex].conditions.length === 0) {
|
|
||||||
updatedGroups.splice(groupIndex, 1);
|
|
||||||
}
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
groups: updatedGroups
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
disabled={group.conditions.length <= 1}
|
|
||||||
>
|
|
||||||
<Trash className="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
const updatedGroups = [...filterBuilder.groups];
|
|
||||||
updatedGroups[groupIndex].conditions.push(
|
|
||||||
{ attribute: "", operator: "equals", value: "" }
|
|
||||||
);
|
|
||||||
setFilterBuilder({
|
|
||||||
...filterBuilder,
|
|
||||||
groups: updatedGroups
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Plus className="h-4 w-4 mr-2" />
|
|
||||||
Add Condition to Group
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-4">
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => {
|
|
||||||
// Generate LDAP filter from visual builder
|
|
||||||
const mainOperatorSymbol = filterBuilder.operator === 'and' ? '&' : '|';
|
|
||||||
|
|
||||||
const mainConditions = filterBuilder.conditions
|
|
||||||
.filter((c: any) => c.attribute.trim() !== '')
|
|
||||||
.map((c: any) => {
|
|
||||||
switch (c.operator) {
|
|
||||||
case 'equals':
|
|
||||||
return `(${c.attribute}=${c.value})`;
|
|
||||||
case 'contains':
|
|
||||||
return `(${c.attribute}=*${c.value}*)`;
|
|
||||||
case 'startsWith':
|
|
||||||
return `(${c.attribute}=${c.value}*)`;
|
|
||||||
case 'endsWith':
|
|
||||||
return `(${c.attribute}=*${c.value})`;
|
|
||||||
case 'present':
|
|
||||||
return `(${c.attribute}=*)`;
|
|
||||||
case 'notEquals':
|
|
||||||
return `(!(${c.attribute}=${c.value}))`;
|
|
||||||
default:
|
|
||||||
return `(${c.attribute}=${c.value})`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generate group conditions
|
|
||||||
const groupsLdap = filterBuilder.groups
|
|
||||||
.map((group: any) => {
|
|
||||||
const groupOperatorSymbol = group.operator === 'and' ? '&' : '|';
|
|
||||||
|
|
||||||
const groupConditions = group.conditions
|
|
||||||
.filter((c: any) => c.attribute.trim() !== '')
|
|
||||||
.map((c: any) => {
|
|
||||||
switch (c.operator) {
|
|
||||||
case 'equals':
|
|
||||||
return `(${c.attribute}=${c.value})`;
|
|
||||||
case 'contains':
|
|
||||||
return `(${c.attribute}=*${c.value}*)`;
|
|
||||||
case 'startsWith':
|
|
||||||
return `(${c.attribute}=${c.value}*)`;
|
|
||||||
case 'endsWith':
|
|
||||||
return `(${c.attribute}=*${c.value})`;
|
|
||||||
case 'present':
|
|
||||||
return `(${c.attribute}=*)`;
|
|
||||||
case 'notEquals':
|
|
||||||
return `(!(${c.attribute}=${c.value}))`;
|
|
||||||
default:
|
|
||||||
return `(${c.attribute}=${c.value})`;
|
|
||||||
}
|
}
|
||||||
});
|
]
|
||||||
|
});
|
||||||
if (groupConditions.length === 0) {
|
}}
|
||||||
return '';
|
>
|
||||||
} else if (groupConditions.length === 1) {
|
<FolderPlus className="h-4 w-4 mr-2" />
|
||||||
return groupConditions[0];
|
Add First Group
|
||||||
} else {
|
</Button>
|
||||||
return `(${groupOperatorSymbol}${groupConditions.join('')})`;
|
</div>
|
||||||
}
|
)}
|
||||||
})
|
|
||||||
.filter((ldap: string) => ldap !== '');
|
|
||||||
|
|
||||||
// Combine main conditions and group conditions
|
|
||||||
const allConditions = [...mainConditions, ...groupsLdap];
|
|
||||||
|
|
||||||
if (allConditions.length === 0) {
|
|
||||||
setFilterQuery('');
|
|
||||||
} else if (allConditions.length === 1) {
|
|
||||||
setFilterQuery(allConditions[0]);
|
|
||||||
} else {
|
|
||||||
setFilterQuery(`(${mainOperatorSymbol}${allConditions.join('')})`);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<ArrowLeftRight className="h-4 w-4 mr-2" />
|
|
||||||
Generate LDAP Filter
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Additional feature 1: Auto-generate filter on changes */}
|
||||||
|
<div className="mt-4 flex items-center space-x-2">
|
||||||
|
<Switch
|
||||||
|
id="autoUpdate"
|
||||||
|
checked={autoUpdateEnabled}
|
||||||
|
onCheckedChange={setAutoUpdateEnabled}
|
||||||
|
/>
|
||||||
|
<Label htmlFor="autoUpdate">Auto-generate LDAP filter on changes</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Generate button (if not auto-update) */}
|
||||||
|
{!autoUpdateEnabled && (
|
||||||
|
<div className="mt-4">
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="sm"
|
||||||
|
onClick={generateLdapFilter}
|
||||||
|
>
|
||||||
|
<ArrowLeftRight className="h-4 w-4 mr-2" />
|
||||||
|
Generate LDAP Filter
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Display LDAP Filter */}
|
||||||
{filterQuery && (
|
{filterQuery && (
|
||||||
<div className="mt-4 p-3 border rounded-md bg-muted">
|
<div className="mt-4 p-3 border rounded-md bg-muted">
|
||||||
<Label className="text-xs mb-1 block">Generated LDAP Filter:</Label>
|
<Label className="text-xs mb-1 block">Generated LDAP Filter:</Label>
|
||||||
|
|||||||
Reference in New Issue
Block a user