Skip to content

Commit 265f601

Browse files
committed
Adapt query builder for small horizontal space
Arrange query element vertically to fit well in the query builder in both Filter and Node edit forms
1 parent 09ab49d commit 265f601

File tree

2 files changed

+63
-53
lines changed

2 files changed

+63
-53
lines changed

src/app/page-client.tsx

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,12 @@ function filterTree(
100100
}
101101
const parent = parentInfo.parent;
102102
if (parent.templateId === relationTemplateId) {
103+
if (!relationRules || relationRules.length === 0) return true; // Match if just template id is specified
103104
const matches = (relationRules || []).every(rule => {
104105
const fieldValue = (parent.data || {})[rule.fieldId];
105106
return evaluateCondition(rule.operator, fieldValue, rule.value);
106107
});
107-
if (matches || !relationRules || relationRules.length === 0) return true;
108+
if (matches) return true;
108109
}
109110
current = parent;
110111
}
@@ -115,11 +116,12 @@ function filterTree(
115116
while (queue.length > 0) {
116117
const currentNode = queue.shift()!;
117118
if (currentNode.templateId === relationTemplateId) {
119+
if (!relationRules || relationRules.length === 0) return true;
118120
const matches = (relationRules || []).every(rule => {
119121
const fieldValue = (currentNode.data || {})[rule.fieldId!];
120122
return evaluateCondition(rule.operator, fieldValue, rule.value!);
121123
});
122-
if (matches || !relationRules || relationRules.length === 0) return true;
124+
if (matches) return true;
123125
}
124126
if (currentNode.children) {
125127
queue.push(...currentNode.children);
@@ -178,11 +180,11 @@ function filterTree(
178180
}
179181
if (type === 'ancestor') {
180182
if (!rule.relationTemplateId) return false;
181-
return hasMatchingAncestor(node, rule.relationTemplateId, rule.relationRules!);
183+
return hasMatchingAncestor(node, rule.relationTemplateId, rule.relationRules);
182184
}
183185
if (type === 'descendant') {
184186
if (!rule.relationTemplateId) return false;
185-
return hasMatchingDescendant(node, rule.relationTemplateId, rule.relationRules!);
187+
return hasMatchingDescendant(node, rule.relationTemplateId, rule.relationRules);
186188
}
187189
return false;
188190
});
@@ -661,66 +663,70 @@ export function TreePage() {
661663
const relationTemplate = rule.relationTemplateId ? getTemplateById(rule.relationTemplateId) : null;
662664
return (
663665
<Card key={rule.id || ruleIndex} className="p-2 bg-background space-y-2">
664-
<div className="flex items-center gap-2">
665-
<Select value={ruleType} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'type', val)}>
666-
<SelectTrigger className="w-32"><SelectValue/></SelectTrigger>
667-
<SelectContent>
668-
<SelectItem value="field">Field</SelectItem>
669-
<SelectItem value="ancestor">Ancestor</SelectItem>
670-
<SelectItem value="descendant">Descendant</SelectItem>
671-
</SelectContent>
672-
</Select>
666+
<div className="space-y-4">
667+
<div className="flex items-center justify-between">
668+
<Select value={ruleType} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'type', val as any)}>
669+
<SelectTrigger className="w-auto"><SelectValue/></SelectTrigger>
670+
<SelectContent>
671+
<SelectItem value="field">Field</SelectItem>
672+
<SelectItem value="ancestor">Ancestor</SelectItem>
673+
<SelectItem value="descendant">Descendant</SelectItem>
674+
</SelectContent>
675+
</Select>
676+
<Button type="button" variant="ghost" size="icon" className="text-destructive h-8 w-8" onClick={() => removeRule(queryIndex, ruleIndex)}>
677+
<Trash2 className="h-4 w-4"/>
678+
</Button>
679+
</div>
673680
{ruleType === 'field' ? (
674-
<>
681+
<div className="space-y-2">
675682
<Select value={rule.fieldId || ''} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'fieldId', val)} disabled={!targetTemplate}>
676683
<SelectTrigger><SelectValue placeholder="Field..."/></SelectTrigger>
677684
<SelectContent>
678685
{targetTemplate?.fields.map(f => <SelectItem key={f.id} value={f.id}>{f.name}</SelectItem>)}
679686
</SelectContent>
680687
</Select>
681-
<Select value={rule.operator || 'equals'} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'operator', val)}>
682-
<SelectTrigger className="w-48"><SelectValue placeholder="Operator..."/></SelectTrigger>
688+
<Select value={rule.operator || 'equals'} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'operator', val as any)}>
689+
<SelectTrigger><SelectValue placeholder="Operator..."/></SelectTrigger>
683690
<SelectContent>
684691
{Object.entries(operatorLabels).map(([op, label]) => <SelectItem key={op} value={op}>{label}</SelectItem>)}
685692
</SelectContent>
686693
</Select>
687694
<Input value={rule.value || ''} onChange={(e) => handleRuleChange(queryIndex, ruleIndex, 'value', e.target.value)} placeholder="Value..."/>
688-
</>
695+
</div>
689696
) : (
690-
<>
691-
<span className="text-sm">has {ruleType} with template:</span>
697+
<div className="space-y-2">
698+
<span className="text-sm p-2 block">has {ruleType} with template:</span>
692699
<Select value={rule.relationTemplateId || ''} onValueChange={(val) => handleRuleChange(queryIndex, ruleIndex, 'relationTemplateId', val)}>
693700
<SelectTrigger><SelectValue placeholder="Template..."/></SelectTrigger>
694701
<SelectContent>
695702
{templates.map(t => <SelectItem key={t.id} value={t.id}>{t.name}</SelectItem>)}
696703
</SelectContent>
697704
</Select>
698-
</>
705+
</div>
699706
)}
700-
<Button type="button" variant="ghost" size="icon" className="text-destructive h-8 w-8" onClick={() => removeRule(queryIndex, ruleIndex)}>
701-
<Trash2 className="h-4 w-4"/>
702-
</Button>
703707
</div>
704708
{ (ruleType === 'ancestor' || ruleType === 'descendant') && rule.relationTemplateId && (
705709
<div className="pl-6 space-y-2">
706710
<Label className="text-xs text-muted-foreground">Where...</Label>
707711
{(rule.relationRules || []).map((relRule, relRuleIndex) => (
708712
<Card key={relRule.id} className="p-2 bg-muted/50">
709-
<div className="flex items-center gap-2">
713+
<div className="space-y-2">
710714
<Select value={relRule.fieldId} onValueChange={(val) => handleRelationRuleChange(queryIndex, ruleIndex, relRuleIndex, 'fieldId', val)}>
711715
<SelectTrigger><SelectValue placeholder="Field..." /></SelectTrigger>
712716
<SelectContent>{relationTemplate?.fields.map(f => <SelectItem key={f.id} value={f.id}>{f.name}</SelectItem>)}</SelectContent>
713717
</Select>
714-
<Select value={relRule.operator} onValueChange={(val) => handleRelationRuleChange(queryIndex, ruleIndex, relRuleIndex, 'operator', val)}>
715-
<SelectTrigger className="w-48"><SelectValue placeholder="Operator..."/></SelectTrigger>
718+
<Select value={relRule.operator} onValueChange={(val) => handleRelationRuleChange(queryIndex, ruleIndex, relRuleIndex, 'operator', val as any)}>
719+
<SelectTrigger><SelectValue placeholder="Operator..."/></SelectTrigger>
716720
<SelectContent>
717721
{Object.entries(operatorLabels).map(([op, label]) => <SelectItem key={op} value={op}>{label}</SelectItem>)}
718722
</SelectContent>
719723
</Select>
720724
<Input value={relRule.value} onChange={(e) => handleRelationRuleChange(queryIndex, ruleIndex, relRuleIndex, 'value', e.target.value)} placeholder="Value..."/>
721-
<Button type="button" variant="ghost" size="icon" className="text-destructive h-8 w-8" onClick={() => removeRelationRule(queryIndex, ruleIndex, relRuleIndex)}>
722-
<Trash2 className="h-4 w-4" />
723-
</Button>
725+
<div className="flex justify-end">
726+
<Button type="button" variant="ghost" size="icon" className="text-destructive h-8 w-8" onClick={() => removeRelationRule(queryIndex, ruleIndex, relRuleIndex)}>
727+
<Trash2 className="h-4 w-4" />
728+
</Button>
729+
</div>
724730
</div>
725731
</Card>
726732
))}

0 commit comments

Comments
 (0)