mirror of
https://github.com/freedbygrace/ActiveDirectoryManager.git
synced 2026-08-27 19:17:07 +00:00
Implement visual query builder for LDAP queries.
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/d3bfc54a-a138-42fd-96eb-a3e55f140922.jpg
This commit is contained in:
@@ -236,6 +236,11 @@ const LdapQueryBuilderPage = () => {
|
|||||||
setFilterDescription("");
|
setFilterDescription("");
|
||||||
setFilterQuery("");
|
setFilterQuery("");
|
||||||
setIsActive(true);
|
setIsActive(true);
|
||||||
|
// Reset filter builder to default state
|
||||||
|
setFilterBuilder({
|
||||||
|
operator: "and",
|
||||||
|
conditions: [{ attribute: "", operator: "equals", value: "" }]
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select filter
|
// Select filter
|
||||||
@@ -245,6 +250,24 @@ const LdapQueryBuilderPage = () => {
|
|||||||
setFilterDescription(filter.description || "");
|
setFilterDescription(filter.description || "");
|
||||||
setFilterQuery(filter.ldapFilter);
|
setFilterQuery(filter.ldapFilter);
|
||||||
setIsActive(filter.isActive);
|
setIsActive(filter.isActive);
|
||||||
|
|
||||||
|
// Load filter builder data if available
|
||||||
|
if (filter.filter) {
|
||||||
|
try {
|
||||||
|
const filterData = typeof filter.filter === 'string'
|
||||||
|
? JSON.parse(filter.filter)
|
||||||
|
: filter.filter;
|
||||||
|
|
||||||
|
// Make sure it has valid structure
|
||||||
|
if (filterData &&
|
||||||
|
filterData.operator &&
|
||||||
|
Array.isArray(filterData.conditions)) {
|
||||||
|
setFilterBuilder(filterData);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Failed to parse filter builder data", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Save filter
|
// Save filter
|
||||||
@@ -580,8 +603,8 @@ const LdapQueryBuilderPage = () => {
|
|||||||
<Tabs defaultValue="manual" className="w-full">
|
<Tabs defaultValue="manual" className="w-full">
|
||||||
<TabsList className="grid w-full grid-cols-2">
|
<TabsList className="grid w-full grid-cols-2">
|
||||||
<TabsTrigger value="manual">Manual LDAP Query</TabsTrigger>
|
<TabsTrigger value="manual">Manual LDAP Query</TabsTrigger>
|
||||||
<TabsTrigger value="builder" disabled>
|
<TabsTrigger value="builder">
|
||||||
Visual Query Builder (Coming Soon)
|
Visual Query Builder
|
||||||
</TabsTrigger>
|
</TabsTrigger>
|
||||||
</TabsList>
|
</TabsList>
|
||||||
<TabsContent value="manual" className="py-4">
|
<TabsContent value="manual" className="py-4">
|
||||||
@@ -596,9 +619,165 @@ const LdapQueryBuilderPage = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
<TabsContent value="builder">
|
<TabsContent value="builder" className="py-4">
|
||||||
<div className="py-8 text-center text-muted-foreground">
|
<div className="space-y-4">
|
||||||
<p>Visual query builder will be available in a future update</p>
|
<div className="flex justify-between items-center">
|
||||||
|
<Label>Query Conditions</Label>
|
||||||
|
<div className="space-x-2">
|
||||||
|
<Select
|
||||||
|
value={filterBuilder.operator}
|
||||||
|
onValueChange={(value) => setFilterBuilder({
|
||||||
|
...filterBuilder,
|
||||||
|
operator: value
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<SelectTrigger className="w-32">
|
||||||
|
<SelectValue placeholder="Operator" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectItem value="and">AND</SelectItem>
|
||||||
|
<SelectItem value="or">OR</SelectItem>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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: "" }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Add Condition
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-4">
|
||||||
|
<Button
|
||||||
|
variant="secondary"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
// Generate LDAP filter from visual builder
|
||||||
|
const operatorSymbol = filterBuilder.operator === 'and' ? '&' : '|';
|
||||||
|
|
||||||
|
const conditions = 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})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (conditions.length === 0) {
|
||||||
|
setFilterQuery('');
|
||||||
|
} else if (conditions.length === 1) {
|
||||||
|
setFilterQuery(conditions[0]);
|
||||||
|
} else {
|
||||||
|
setFilterQuery(`(${operatorSymbol}${conditions.join('')})`);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ArrowLeftRight className="h-4 w-4 mr-2" />
|
||||||
|
Generate LDAP Filter
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TabsContent>
|
</TabsContent>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
Reference in New Issue
Block a user