Rework tickets filter bar into two-row layout with consistent CTI styling
Split the dense single-row filter bar into two rows: search + saved views on top, filter selectors below. Fix CTI selectors to use design system tokens instead of hardcoded dark classes, and upgrade the saved views button with an icon and badge count. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,9 +4,10 @@ interface CTISelectProps {
|
||||
value: { categoryId: string; typeId: string; itemId: string };
|
||||
onChange: (value: { categoryId: string; typeId: string; itemId: string }) => void;
|
||||
disabled?: boolean;
|
||||
compact?: boolean;
|
||||
}
|
||||
|
||||
export default function CTISelect({ value, onChange, disabled }: CTISelectProps) {
|
||||
export default function CTISelect({ value, onChange, disabled, compact }: CTISelectProps) {
|
||||
const { data: categories = [] } = useCategories();
|
||||
const { data: types = [] } = useTypes(value.categoryId || undefined);
|
||||
const { data: items = [] } = useItems(value.typeId || undefined);
|
||||
@@ -24,12 +25,58 @@ export default function CTISelect({ value, onChange, disabled }: CTISelectProps)
|
||||
};
|
||||
|
||||
const selectClass =
|
||||
'block w-full bg-gray-800 border border-gray-700 text-gray-100 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent disabled:opacity-50 disabled:cursor-not-allowed';
|
||||
'block w-full rounded-md border border-input bg-background px-3 py-1.5 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50';
|
||||
|
||||
if (compact) {
|
||||
return (
|
||||
<div className="flex gap-2">
|
||||
<select
|
||||
value={value.categoryId}
|
||||
onChange={(e) => handleCategory(e.target.value)}
|
||||
disabled={disabled}
|
||||
className={selectClass}
|
||||
>
|
||||
<option value="">Category...</option>
|
||||
{categories.map((c) => (
|
||||
<option key={c.id} value={c.id}>
|
||||
{c.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
value={value.typeId}
|
||||
onChange={(e) => handleType(e.target.value)}
|
||||
disabled={disabled || !value.categoryId}
|
||||
className={selectClass}
|
||||
>
|
||||
<option value="">Type...</option>
|
||||
{types.map((t) => (
|
||||
<option key={t.id} value={t.id}>
|
||||
{t.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<select
|
||||
value={value.itemId}
|
||||
onChange={(e) => handleItem(e.target.value)}
|
||||
disabled={disabled || !value.typeId}
|
||||
className={selectClass}
|
||||
>
|
||||
<option value="">Item...</option>
|
||||
{items.map((i) => (
|
||||
<option key={i.id} value={i.id}>
|
||||
{i.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-3 gap-3">
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-400 mb-1">Category</label>
|
||||
<label className="block text-xs font-medium text-muted-foreground mb-1">Category</label>
|
||||
<select
|
||||
value={value.categoryId}
|
||||
onChange={(e) => handleCategory(e.target.value)}
|
||||
@@ -46,7 +93,7 @@ export default function CTISelect({ value, onChange, disabled }: CTISelectProps)
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-400 mb-1">Type</label>
|
||||
<label className="block text-xs font-medium text-muted-foreground mb-1">Type</label>
|
||||
<select
|
||||
value={value.typeId}
|
||||
onChange={(e) => handleType(e.target.value)}
|
||||
@@ -63,7 +110,7 @@ export default function CTISelect({ value, onChange, disabled }: CTISelectProps)
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-400 mb-1">Item</label>
|
||||
<label className="block text-xs font-medium text-muted-foreground mb-1">Item</label>
|
||||
<select
|
||||
value={value.itemId}
|
||||
onChange={(e) => handleItem(e.target.value)}
|
||||
|
||||
Reference in New Issue
Block a user