feat(quick-261003-387): Verwaltungsseite Kategorien, Marktplatz-Reihenfolge, Formular, Texte, CHANGELOG und Handbuch
- Administrator -> Module -> Kategorien: anlegen, umbenennen, sortieren, Eintraege zuordnen und sortieren, loeschen mit Zielauswahl - Marktplatz-Filter folgen der Kategorienreihenfolge, Kategorieseite und Modulliste zeigen gespeicherte Namen - Formular fuer eigene Module bietet alle Kategorien der Organisation an - Texte de/en, CHANGELOG, Handbuch Administration und Anwender Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { CUSTOM_MODULE_CATEGORIES, CUSTOM_MODULE_CATEGORY } from '@tessera/shared';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import {
|
||||
type CustomModule,
|
||||
CustomModuleRequestError,
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
updateCustomModule,
|
||||
} from '@/lib/custom-modules-api';
|
||||
import { useCustomModuleCacheStore } from '@/lib/stores/custom-module-cache-store';
|
||||
import { useModuleCategoryStore } from '@/lib/stores/module-category-store';
|
||||
import { useCategoryLabel } from '@/lib/use-category-label';
|
||||
|
||||
interface CustomModuleFormModalProps {
|
||||
@@ -63,6 +64,8 @@ export function CustomModuleFormModal({
|
||||
const t = useTranslations('customModules.form');
|
||||
const tCommon = useTranslations('common');
|
||||
const categoryLabel = useCategoryLabel();
|
||||
const storeCategories = useModuleCategoryStore((s) => s.categories);
|
||||
const ensureCategories = useModuleCategoryStore((s) => s.ensureLoaded);
|
||||
|
||||
const [name, setName] = useState(mod?.name ?? '');
|
||||
const [url, setUrl] = useState(mod?.url ?? '');
|
||||
@@ -72,6 +75,20 @@ export function CustomModuleFormModal({
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Alle Kategorien der Organisation in der eingestellten Reihenfolge
|
||||
// (quick-261003-387). Solange der Speicher leer ist, gilt die Standardliste;
|
||||
// ein vorhandener Wert, der (noch) nicht im Speicher steht, bleibt Option.
|
||||
useEffect(() => {
|
||||
ensureCategories();
|
||||
}, [ensureCategories]);
|
||||
const categoryOptions = useMemo(() => {
|
||||
const keys: string[] =
|
||||
storeCategories.length > 0
|
||||
? storeCategories.map((c) => c.key)
|
||||
: [...CUSTOM_MODULE_CATEGORIES];
|
||||
return keys.includes(category) ? keys : [...keys, category];
|
||||
}, [storeCategories, category]);
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setError(null);
|
||||
@@ -167,7 +184,7 @@ export function CustomModuleFormModal({
|
||||
onChange={(e) => setCategory(e.target.value)}
|
||||
className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
|
||||
>
|
||||
{CUSTOM_MODULE_CATEGORIES.map((c) => (
|
||||
{categoryOptions.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{categoryLabel(c)}
|
||||
</option>
|
||||
|
||||
Reference in New Issue
Block a user