feat: show Redis and Valkey icons for Redis/Valkey backend variant

This commit is contained in:
Steven RYDELL
2026-07-30 15:31:16 +02:00
parent 49b3d60378
commit b9489a795b
3 changed files with 26 additions and 6 deletions
+20
View File
@@ -99,3 +99,23 @@ export function isBackendIconKnown(backend: string | null | undefined): boolean
const key = backend.toLowerCase().replace(/[^a-z0-9]/g, ''); const key = backend.toLowerCase().replace(/[^a-z0-9]/g, '');
return Boolean(BACKEND_ICONS[key] ?? BACKEND_ICONS[backend.toLowerCase()]); return Boolean(BACKEND_ICONS[key] ?? BACKEND_ICONS[backend.toLowerCase()]);
} }
interface BackendVariantIconProps {
variant: { name: string; label: string };
className?: string;
}
export function BackendVariantIcon({ variant, className }: BackendVariantIconProps): React.ReactElement | null {
const nameLower = variant.name.toLowerCase();
const labelLower = variant.label?.toLowerCase() ?? '';
const isRedisValkey = nameLower === 'redis' && labelLower.includes('valkey');
if (isRedisValkey) {
return (
<span className="flex items-center gap-1">
<BackendIcon backend="redis" className={className} />
<BackendIcon backend="valkey" className={className} />
</span>
);
}
return <BackendIcon backend={variant.name} className={className} />;
}
+3 -3
View File
@@ -53,7 +53,7 @@ import { SECRET_MASK } from '@/lib/jmapUtils';
import { toast } from '@/hooks/use-toast'; import { toast } from '@/hooks/use-toast';
import { logFormChange } from '@/lib/debug'; import { logFormChange } from '@/lib/debug';
import { FieldWidget } from '@/components/forms/FieldWidget'; import { FieldWidget } from '@/components/forms/FieldWidget';
import { BackendIcon } from '@/components/common/BackendIcon'; import { BackendVariantIcon } from '@/components/common/BackendIcon';
import type { Field, Fields, Form, FormField, Schema } from '@/types/schema'; import type { Field, Fields, Form, FormField, Schema } from '@/types/schema';
import type { JmapSetResponse, JmapSetError, JmapMethodCall } from '@/types/jmap'; import type { JmapSetResponse, JmapSetError, JmapMethodCall } from '@/types/jmap';
@@ -781,7 +781,7 @@ export function DynamicForm({ viewName, objectId }: DynamicFormProps) {
<Select value={selectedVariant} onValueChange={handleVariantChange} disabled={readOnly}> <Select value={selectedVariant} onValueChange={handleVariantChange} disabled={readOnly}>
<SelectTrigger> <SelectTrigger>
<div className="flex flex-1 items-center gap-2 overflow-hidden"> <div className="flex flex-1 items-center gap-2 overflow-hidden">
<BackendIcon backend={selectedVariant} /> <BackendVariantIcon variant={{ name: selectedVariant, label: selectedVariantLabel ?? selectedVariant }} />
<span className="truncate"> <span className="truncate">
{selectedVariantLabel || t('form.selectType', 'Select type...')} {selectedVariantLabel || t('form.selectType', 'Select type...')}
</span> </span>
@@ -791,7 +791,7 @@ export function DynamicForm({ viewName, objectId }: DynamicFormProps) {
{sch.variants.map((v) => ( {sch.variants.map((v) => (
<SelectItem key={v.name} value={v.name}> <SelectItem key={v.name} value={v.name}>
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">
<BackendIcon backend={v.name} /> <BackendVariantIcon variant={v} />
{v.label} {v.label}
</span> </span>
</SelectItem> </SelectItem>
+3 -3
View File
@@ -45,7 +45,7 @@ import { cn } from '@/lib/utils';
import { useAccountStore } from '@/stores/accountStore'; import { useAccountStore } from '@/stores/accountStore';
import { useEffectiveEdition } from '@/components/forms/FormEditionContext'; import { useEffectiveEdition } from '@/components/forms/FormEditionContext';
import { useObjectList, useObjectLabel, useNoPermissionMessage, type ObjectOption } from '@/lib/objectOptions'; import { useObjectList, useObjectLabel, useNoPermissionMessage, type ObjectOption } from '@/lib/objectOptions';
import { BackendIcon } from '@/components/common/BackendIcon'; import { BackendVariantIcon } from '@/components/common/BackendIcon';
import { SECRET_MASK } from '@/lib/jmapUtils'; import { SECRET_MASK } from '@/lib/jmapUtils';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { jmapGet, getAccountId } from '@/services/jmap/client'; import { jmapGet, getAccountId } from '@/services/jmap/client';
@@ -1478,7 +1478,7 @@ function EmbeddedObjectField({
<Select value={currentType} onValueChange={handleVariantChange} disabled={readOnly}> <Select value={currentType} onValueChange={handleVariantChange} disabled={readOnly}>
<SelectTrigger> <SelectTrigger>
<div className="flex flex-1 items-center gap-2 overflow-hidden"> <div className="flex flex-1 items-center gap-2 overflow-hidden">
<BackendIcon backend={currentType} /> <BackendVariantIcon variant={{ name: currentType, label: selectedVariantLabel ?? currentType }} />
<span className="truncate"> <span className="truncate">
{selectedVariantLabel || t('form.selectType', 'Select type...')} {selectedVariantLabel || t('form.selectType', 'Select type...')}
</span> </span>
@@ -1488,7 +1488,7 @@ function EmbeddedObjectField({
{resolvedSchema.variants.map((v) => ( {resolvedSchema.variants.map((v) => (
<SelectItem key={v.name} value={v.name}> <SelectItem key={v.name} value={v.name}>
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">
<BackendIcon backend={v.name} /> <BackendVariantIcon variant={v} />
{v.label} {v.label}
</span> </span>
</SelectItem> </SelectItem>