feat : remove dupe code of codition code
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import type { ComponentProps } from "react";
|
||||
import { Trash2Icon } from "lucide-react";
|
||||
|
||||
import { DeleteConfirmationDialog } from "@/components/admin/delete-confirmation-dialog";
|
||||
|
||||
type DeleteConditionDialogProps = Pick<
|
||||
ComponentProps<typeof DeleteConfirmationDialog>,
|
||||
"trigger" | "onConfirm"
|
||||
> & {
|
||||
iconOnly?: boolean;
|
||||
};
|
||||
|
||||
export function DeleteConditionDialog({
|
||||
trigger,
|
||||
onConfirm,
|
||||
iconOnly = false,
|
||||
}: DeleteConditionDialogProps) {
|
||||
return (
|
||||
<DeleteConfirmationDialog
|
||||
trigger={trigger}
|
||||
triggerTooltip={iconOnly ? "ลบ Condition นี้" : undefined}
|
||||
title="ลบ Condition นี้?"
|
||||
description="ข้อมูลทั้งหมดใน Condition นี้จะถูกลบออก"
|
||||
showSuccessToast
|
||||
onConfirm={onConfirm}
|
||||
>
|
||||
<Trash2Icon data-icon={iconOnly ? undefined : "inline-start"} />
|
||||
<span className={iconOnly ? "sr-only" : undefined}>ลบ Condition นี้</span>
|
||||
</DeleteConfirmationDialog>
|
||||
);
|
||||
}
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
Trash2Icon,
|
||||
XIcon,
|
||||
} from "lucide-react";
|
||||
import { useEffect, useMemo, useState, type ReactNode, type SetStateAction } from "react";
|
||||
import { useEffect, useMemo, useState, type ComponentProps, type ReactNode, type SetStateAction } from "react";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
closestCenter,
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
} from "@/app/admin/actions";
|
||||
import { AutosaveStatus } from "@/components/admin/autosave-status";
|
||||
import { DeleteConfirmationDialog } from "@/components/admin/delete-confirmation-dialog";
|
||||
import { DeleteConditionDialog } from "@/components/admin/delete-condition-dialog";
|
||||
import { MediaUploader } from "@/components/admin/media-uploader";
|
||||
import { ScrollableNav } from "@/components/public/scrollable-nav";
|
||||
import { TeamArtifactIcon } from "@/components/public/team-search";
|
||||
@@ -1256,6 +1257,45 @@ function SortableConditionSwitcher({
|
||||
);
|
||||
}
|
||||
|
||||
function ConditionControls({
|
||||
onAdd,
|
||||
onDuplicate,
|
||||
onDelete,
|
||||
...switcherProps
|
||||
}: ComponentProps<typeof SortableConditionSwitcher> & {
|
||||
onAdd: () => void;
|
||||
onDuplicate?: () => void;
|
||||
onDelete: () => void;
|
||||
}) {
|
||||
const { items, activeIndex } = switcherProps;
|
||||
const atLimit = items.length >= 20;
|
||||
|
||||
return (
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher {...switcherProps} />
|
||||
<SimpleTooltip text="เพิ่ม Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="เพิ่ม Condition" disabled={atLimit} onClick={onAdd}>
|
||||
<PlusIcon />
|
||||
</Button>
|
||||
</SimpleTooltip>
|
||||
{onDuplicate ? (
|
||||
<SimpleTooltip text="Duplicate Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="Duplicate Condition" disabled={atLimit || !items[activeIndex]} onClick={onDuplicate}>
|
||||
<CopyIcon />
|
||||
</Button>
|
||||
</SimpleTooltip>
|
||||
) : null}
|
||||
{items.length > 1 ? (
|
||||
<DeleteConditionDialog
|
||||
trigger={<Button type="button" size="icon" variant="outline" aria-label="ลบ Condition นี้" />}
|
||||
onConfirm={onDelete}
|
||||
iconOnly
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function reorderConditions<T extends ConditionNavItem>(
|
||||
items: T[],
|
||||
activeIndex: number,
|
||||
@@ -1390,50 +1430,44 @@ function WeaponEditor({ guide, weapons, characters, initial }: EditorBase) {
|
||||
onChange={(event) => setNote(event.target.value)}
|
||||
/>
|
||||
</Field>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher
|
||||
ariaLabel="เลือกเงื่อนไขอาวุธ"
|
||||
items={groups}
|
||||
activeIndex={activeGroupIndex}
|
||||
onActiveIndexChange={setActiveGroupIndex}
|
||||
onRename={setRenamingWeaponGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(groups, activeGroupIndex, from, to);
|
||||
setGroups(reordered.items);
|
||||
setActiveGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
/>
|
||||
<Button type="button" variant="outline" disabled={groups.length >= 20} onClick={() => {
|
||||
<ConditionControls
|
||||
ariaLabel="เลือกเงื่อนไขอาวุธ"
|
||||
items={groups}
|
||||
activeIndex={activeGroupIndex}
|
||||
onActiveIndexChange={setActiveGroupIndex}
|
||||
onRename={setRenamingWeaponGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(groups, activeGroupIndex, from, to);
|
||||
setGroups(reordered.items);
|
||||
setActiveGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
onAdd={() => {
|
||||
setGroups([...groups, { clientId: createClientId("weapon-condition"), name: "", note: "", rows: [] }]);
|
||||
setActiveGroupIndex(groups.length);
|
||||
}}>
|
||||
<PlusIcon data-icon="inline-start" />เพิ่ม Condition
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={groups.length >= 20 || !groups[activeGroupIndex]}
|
||||
onClick={() => {
|
||||
const source = groups[activeGroupIndex];
|
||||
if (!source) return;
|
||||
setGroups([
|
||||
...groups,
|
||||
{
|
||||
clientId: createClientId("weapon-condition"),
|
||||
name: source.name,
|
||||
note: source.note,
|
||||
rows: source.rows.map((row) => ({
|
||||
...row,
|
||||
clientId: createClientId("weapon"),
|
||||
})),
|
||||
},
|
||||
]);
|
||||
setActiveGroupIndex(groups.length);
|
||||
}}
|
||||
>
|
||||
<CopyIcon data-icon="inline-start" />Duplicate Condition
|
||||
</Button>
|
||||
</div>
|
||||
}}
|
||||
onDuplicate={() => {
|
||||
const source = groups[activeGroupIndex];
|
||||
if (!source) return;
|
||||
setGroups([
|
||||
...groups,
|
||||
{
|
||||
clientId: createClientId("weapon-condition"),
|
||||
name: source.name,
|
||||
note: source.note,
|
||||
rows: source.rows.map((row) => ({
|
||||
...row,
|
||||
clientId: createClientId("weapon"),
|
||||
})),
|
||||
},
|
||||
]);
|
||||
setActiveGroupIndex(groups.length);
|
||||
}}
|
||||
onDelete={() => {
|
||||
const next = groups.filter((_, index) => index !== activeGroupIndex);
|
||||
setGroups(next);
|
||||
setActiveGroupIndex(Math.min(activeGroupIndex, next.length - 1));
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingWeaponGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingWeaponGroupIndex ?? 0) + 1}`}
|
||||
@@ -1704,15 +1738,6 @@ function WeaponEditor({ guide, weapons, characters, initial }: EditorBase) {
|
||||
<PlusIcon data-icon="inline-start" />
|
||||
เพิ่มอาวุธ
|
||||
</Button>
|
||||
{groups.length > 1 ? (
|
||||
<Button type="button" variant="ghost" onClick={() => {
|
||||
const next = groups.filter((_, index) => index !== activeGroupIndex);
|
||||
setGroups(next);
|
||||
setActiveGroupIndex(Math.min(activeGroupIndex, next.length - 1));
|
||||
}}>
|
||||
<Trash2Icon data-icon="inline-start" />ลบ Condition นี้
|
||||
</Button>
|
||||
) : null}
|
||||
<AutosaveStatus
|
||||
state={autosave.state}
|
||||
issues={
|
||||
@@ -2200,41 +2225,39 @@ function ArtifactEditor({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<FieldGroup>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher
|
||||
ariaLabel="เลือกเงื่อนไขค่าสถานะแนะนำ"
|
||||
items={recommendedGroups}
|
||||
activeIndex={activeRecommendedGroupIndex}
|
||||
onActiveIndexChange={setActiveRecommendedGroupIndex}
|
||||
onRename={setRenamingRecommendedGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(recommendedGroups, activeRecommendedGroupIndex, from, to);
|
||||
setRecommendedGroups(reordered.items);
|
||||
setActiveRecommendedGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingRecommendedGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingRecommendedGroupIndex ?? 0) + 1}`}
|
||||
value={renamingRecommendedGroupIndex === null ? "" : recommendedGroups[renamingRecommendedGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingRecommendedGroupIndex(null); }}
|
||||
onChange={(name) => setRecommendedGroups(recommendedGroups.map((group, index) => index === renamingRecommendedGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<SimpleTooltip text="เพิ่ม Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="เพิ่ม Condition" disabled={recommendedGroups.length >= 20} onClick={() => {
|
||||
setRecommendedGroups([...recommendedGroups, { clientId: createClientId("recommended-condition"), name: "", note: "", sands: [], goblet: [], circlet: [], substats: [] }]);
|
||||
setActiveRecommendedGroupIndex(recommendedGroups.length);
|
||||
}}><PlusIcon /></Button>
|
||||
</SimpleTooltip>
|
||||
<SimpleTooltip text="Duplicate Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="Duplicate Condition" disabled={recommendedGroups.length >= 20} onClick={() => {
|
||||
const source = recommendedGroups[activeRecommendedGroupIndex];
|
||||
if (!source) return;
|
||||
setRecommendedGroups([...recommendedGroups, { clientId: createClientId("recommended-condition"), name: source.name, note: source.note, sands: [...source.sands], goblet: [...source.goblet], circlet: [...source.circlet], substats: [...source.substats] }]);
|
||||
setActiveRecommendedGroupIndex(recommendedGroups.length);
|
||||
}}><CopyIcon /></Button>
|
||||
</SimpleTooltip>
|
||||
</div>
|
||||
<ConditionControls
|
||||
ariaLabel="เลือกเงื่อนไขค่าสถานะแนะนำ"
|
||||
items={recommendedGroups}
|
||||
activeIndex={activeRecommendedGroupIndex}
|
||||
onActiveIndexChange={setActiveRecommendedGroupIndex}
|
||||
onRename={setRenamingRecommendedGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(recommendedGroups, activeRecommendedGroupIndex, from, to);
|
||||
setRecommendedGroups(reordered.items);
|
||||
setActiveRecommendedGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
onAdd={() => {
|
||||
setRecommendedGroups([...recommendedGroups, { clientId: createClientId("recommended-condition"), name: "", note: "", sands: [], goblet: [], circlet: [], substats: [] }]);
|
||||
setActiveRecommendedGroupIndex(recommendedGroups.length);
|
||||
}}
|
||||
onDuplicate={() => {
|
||||
const source = recommendedGroups[activeRecommendedGroupIndex];
|
||||
if (!source) return;
|
||||
setRecommendedGroups([...recommendedGroups, { clientId: createClientId("recommended-condition"), name: source.name, note: source.note, sands: [...source.sands], goblet: [...source.goblet], circlet: [...source.circlet], substats: [...source.substats] }]);
|
||||
setActiveRecommendedGroupIndex(recommendedGroups.length);
|
||||
}}
|
||||
onDelete={() => {
|
||||
setRecommendedGroups(recommendedGroups.filter((_, index) => index !== activeRecommendedGroupIndex));
|
||||
setActiveRecommendedGroupIndex(Math.max(0, activeRecommendedGroupIndex - 1));
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingRecommendedGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingRecommendedGroupIndex ?? 0) + 1}`}
|
||||
value={renamingRecommendedGroupIndex === null ? "" : recommendedGroups[renamingRecommendedGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingRecommendedGroupIndex(null); }}
|
||||
onChange={(name) => setRecommendedGroups(recommendedGroups.map((group, index) => index === renamingRecommendedGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<Field>
|
||||
<FieldLabel htmlFor={`recommended-condition-note-${recommendedGroups[activeRecommendedGroupIndex]?.clientId}`}>Condition note (optional)</FieldLabel>
|
||||
<Textarea id={`recommended-condition-note-${recommendedGroups[activeRecommendedGroupIndex]?.clientId}`} value={recommendedGroups[activeRecommendedGroupIndex]?.note ?? ""} onChange={(event) => setRecommendedGroups(recommendedGroups.map((group, index) => index === activeRecommendedGroupIndex ? { ...group, note: event.target.value } : group))} />
|
||||
@@ -2278,12 +2301,6 @@ function ArtifactEditor({
|
||||
elementIconUrls={elementIconUrls}
|
||||
priorityColors
|
||||
/>
|
||||
{recommendedGroups.length > 1 ? (
|
||||
<Button type="button" variant="ghost" onClick={() => {
|
||||
setRecommendedGroups(recommendedGroups.filter((_, index) => index !== activeRecommendedGroupIndex));
|
||||
setActiveRecommendedGroupIndex(Math.max(0, activeRecommendedGroupIndex - 1));
|
||||
}}><Trash2Icon data-icon="inline-start" />ลบ Condition นี้</Button>
|
||||
) : null}
|
||||
</FieldGroup>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -2298,41 +2315,39 @@ function ArtifactEditor({
|
||||
<FieldGroup>
|
||||
<FieldSet>
|
||||
<FieldLegend>Target Stats</FieldLegend>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher
|
||||
ariaLabel="เลือกเงื่อนไขค่าสถานะเป้าหมาย"
|
||||
items={targetGroups}
|
||||
activeIndex={activeTargetGroupIndex}
|
||||
onActiveIndexChange={setActiveTargetGroupIndex}
|
||||
onRename={setRenamingTargetGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(targetGroups, activeTargetGroupIndex, from, to);
|
||||
setTargetGroups(reordered.items);
|
||||
setActiveTargetGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingTargetGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingTargetGroupIndex ?? 0) + 1}`}
|
||||
value={renamingTargetGroupIndex === null ? "" : targetGroups[renamingTargetGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingTargetGroupIndex(null); }}
|
||||
onChange={(name) => setTargetGroups(targetGroups.map((group, index) => index === renamingTargetGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<SimpleTooltip text="เพิ่ม Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="เพิ่ม Condition" disabled={targetGroups.length >= 20} onClick={() => {
|
||||
setTargetGroups([...targetGroups, { clientId: createClientId("target-condition"), name: "", note: "", rows: targetStatDefaults.map((target) => ({ ...target })) }]);
|
||||
setActiveTargetGroupIndex(targetGroups.length);
|
||||
}}><PlusIcon /></Button>
|
||||
</SimpleTooltip>
|
||||
<SimpleTooltip text="Duplicate Condition">
|
||||
<Button type="button" size="icon" variant="outline" aria-label="Duplicate Condition" disabled={targetGroups.length >= 20} onClick={() => {
|
||||
const source = targetGroups[activeTargetGroupIndex];
|
||||
if (!source) return;
|
||||
setTargetGroups([...targetGroups, { clientId: createClientId("target-condition"), name: source.name, note: source.note, rows: source.rows.map((row) => ({ ...row })) }]);
|
||||
setActiveTargetGroupIndex(targetGroups.length);
|
||||
}}><CopyIcon /></Button>
|
||||
</SimpleTooltip>
|
||||
</div>
|
||||
<ConditionControls
|
||||
ariaLabel="เลือกเงื่อนไขค่าสถานะเป้าหมาย"
|
||||
items={targetGroups}
|
||||
activeIndex={activeTargetGroupIndex}
|
||||
onActiveIndexChange={setActiveTargetGroupIndex}
|
||||
onRename={setRenamingTargetGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(targetGroups, activeTargetGroupIndex, from, to);
|
||||
setTargetGroups(reordered.items);
|
||||
setActiveTargetGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
onAdd={() => {
|
||||
setTargetGroups([...targetGroups, { clientId: createClientId("target-condition"), name: "", note: "", rows: targetStatDefaults.map((target) => ({ ...target })) }]);
|
||||
setActiveTargetGroupIndex(targetGroups.length);
|
||||
}}
|
||||
onDuplicate={() => {
|
||||
const source = targetGroups[activeTargetGroupIndex];
|
||||
if (!source) return;
|
||||
setTargetGroups([...targetGroups, { clientId: createClientId("target-condition"), name: source.name, note: source.note, rows: source.rows.map((row) => ({ ...row })) }]);
|
||||
setActiveTargetGroupIndex(targetGroups.length);
|
||||
}}
|
||||
onDelete={() => {
|
||||
setTargetGroups(targetGroups.filter((_, index) => index !== activeTargetGroupIndex));
|
||||
setActiveTargetGroupIndex(Math.max(0, activeTargetGroupIndex - 1));
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingTargetGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingTargetGroupIndex ?? 0) + 1}`}
|
||||
value={renamingTargetGroupIndex === null ? "" : targetGroups[renamingTargetGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingTargetGroupIndex(null); }}
|
||||
onChange={(name) => setTargetGroups(targetGroups.map((group, index) => index === renamingTargetGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<Field>
|
||||
<FieldLabel htmlFor={`target-condition-note-${targetGroups[activeTargetGroupIndex]?.clientId}`}>Condition note (optional)</FieldLabel>
|
||||
<Textarea id={`target-condition-note-${targetGroups[activeTargetGroupIndex]?.clientId}`} value={targetGroups[activeTargetGroupIndex]?.note ?? ""} onChange={(event) => setTargetGroups(targetGroups.map((group, index) => index === activeTargetGroupIndex ? { ...group, note: event.target.value } : group))} />
|
||||
@@ -2379,12 +2394,6 @@ function ArtifactEditor({
|
||||
กรอกเฉพาะค่าเป็นตัวเลข เปอร์เซ็นต์ หรือข้อความ เช่น -%
|
||||
หากไม่กรอกค่า ระบบจะไม่แสดงส่วนค่าสถานะเป้าหมาย
|
||||
</FieldDescription>
|
||||
{targetGroups.length > 1 ? (
|
||||
<Button type="button" variant="ghost" onClick={() => {
|
||||
setTargetGroups(targetGroups.filter((_, index) => index !== activeTargetGroupIndex));
|
||||
setActiveTargetGroupIndex(Math.max(0, activeTargetGroupIndex - 1));
|
||||
}}><Trash2Icon data-icon="inline-start" />ลบ Condition นี้</Button>
|
||||
) : null}
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
</CardContent>
|
||||
@@ -2608,40 +2617,34 @@ function ConstellationEditor({
|
||||
onChange={(event) => setNote(event.target.value)}
|
||||
/>
|
||||
</Field>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher
|
||||
ariaLabel="เลือกเงื่อนไขกลุ่มดาว"
|
||||
items={groups}
|
||||
activeIndex={activeConstellationGroupIndex}
|
||||
onActiveIndexChange={setActiveConstellationGroupIndex}
|
||||
onRename={setRenamingConstellationGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(groups, activeConstellationGroupIndex, from, to);
|
||||
setGroups(reordered.items);
|
||||
setActiveConstellationGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={groups.length >= 20}
|
||||
onClick={() => {
|
||||
setGroups([
|
||||
...groups,
|
||||
{
|
||||
clientId: createClientId("constellation-condition"),
|
||||
name: "",
|
||||
note: "",
|
||||
rows: makeRows(),
|
||||
},
|
||||
]);
|
||||
setActiveConstellationGroupIndex(groups.length);
|
||||
}}
|
||||
>
|
||||
<PlusIcon data-icon="inline-start" />
|
||||
เพิ่ม Condition
|
||||
</Button>
|
||||
</div>
|
||||
<ConditionControls
|
||||
ariaLabel="เลือกเงื่อนไขกลุ่มดาว"
|
||||
items={groups}
|
||||
activeIndex={activeConstellationGroupIndex}
|
||||
onActiveIndexChange={setActiveConstellationGroupIndex}
|
||||
onRename={setRenamingConstellationGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(groups, activeConstellationGroupIndex, from, to);
|
||||
setGroups(reordered.items);
|
||||
setActiveConstellationGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
onAdd={() => {
|
||||
setGroups([
|
||||
...groups,
|
||||
{
|
||||
clientId: createClientId("constellation-condition"),
|
||||
name: "",
|
||||
note: "",
|
||||
rows: makeRows(),
|
||||
},
|
||||
]);
|
||||
setActiveConstellationGroupIndex(groups.length);
|
||||
}}
|
||||
onDelete={() => {
|
||||
setGroups(groups.filter((_, index) => index !== activeConstellationGroupIndex));
|
||||
setActiveConstellationGroupIndex(Math.max(0, activeConstellationGroupIndex - 1));
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingConstellationGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingConstellationGroupIndex ?? 0) + 1}`}
|
||||
@@ -2658,26 +2661,6 @@ function ConstellationEditor({
|
||||
<CardDescription>
|
||||
ใช้ note เพื่ออธิบายอาวุธ ทีม หรือเงื่อนไขที่ใช้เปรียบเทียบ
|
||||
</CardDescription>
|
||||
{groups.length > 1 ? (
|
||||
<CardAction>
|
||||
<DeleteConfirmationDialog
|
||||
trigger={
|
||||
<Button type="button" variant="ghost" size="icon-sm" />
|
||||
}
|
||||
title={`ลบ Condition ${groupIndex + 1}?`}
|
||||
description="เปอร์เซ็นต์กลุ่มดาวทั้งหมดในเงื่อนไขนี้จะถูกลบออก"
|
||||
onConfirm={() => {
|
||||
setGroups(groups.filter((item) => item.clientId !== group.clientId));
|
||||
setActiveConstellationGroupIndex(Math.max(0, groupIndex - 1));
|
||||
}}
|
||||
>
|
||||
<Trash2Icon />
|
||||
<span className="sr-only">
|
||||
ลบ Condition {groupIndex + 1}
|
||||
</span>
|
||||
</DeleteConfirmationDialog>
|
||||
</CardAction>
|
||||
) : null}
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-4">
|
||||
<Field>
|
||||
@@ -3292,39 +3275,30 @@ function TeamEditor({
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-4">
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<SortableConditionSwitcher
|
||||
ariaLabel="เลือกเงื่อนไข Team"
|
||||
items={teamGroups}
|
||||
activeIndex={activeTeamGroupIndex}
|
||||
onActiveIndexChange={(nextIndex) => {
|
||||
const group = teamGroups[nextIndex];
|
||||
if (!group) return;
|
||||
setActiveTeamGroupIndex(nextIndex);
|
||||
setSelectedTeamIds(new Set());
|
||||
setSourceTeamId(group.teams[0]?.clientId ?? "");
|
||||
}}
|
||||
onRename={setRenamingTeamGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(teamGroups, activeTeamGroupIndex, from, to);
|
||||
setTeamGroups(reordered.items);
|
||||
setActiveTeamGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingTeamGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingTeamGroupIndex ?? 0) + 1}`}
|
||||
value={renamingTeamGroupIndex === null ? "" : teamGroups[renamingTeamGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingTeamGroupIndex(null); }}
|
||||
onChange={(name) => setTeamGroups(teamGroups.map((group, index) => index === renamingTeamGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<Button type="button" variant="outline" disabled={teamGroups.length >= 20} onClick={() => {
|
||||
<ConditionControls
|
||||
ariaLabel="เลือกเงื่อนไข Team"
|
||||
items={teamGroups}
|
||||
activeIndex={activeTeamGroupIndex}
|
||||
onActiveIndexChange={(nextIndex) => {
|
||||
const group = teamGroups[nextIndex];
|
||||
if (!group) return;
|
||||
setActiveTeamGroupIndex(nextIndex);
|
||||
setSelectedTeamIds(new Set());
|
||||
setSourceTeamId(group.teams[0]?.clientId ?? "");
|
||||
}}
|
||||
onRename={setRenamingTeamGroupIndex}
|
||||
onReorder={(from, to) => {
|
||||
const reordered = reorderConditions(teamGroups, activeTeamGroupIndex, from, to);
|
||||
setTeamGroups(reordered.items);
|
||||
setActiveTeamGroupIndex(reordered.activeIndex);
|
||||
}}
|
||||
onAdd={() => {
|
||||
setTeamGroups([...teamGroups, { clientId: createClientId("team-condition"), name: "", note: "", teams: [] }]);
|
||||
setActiveTeamGroupIndex(teamGroups.length);
|
||||
setSelectedTeamIds(new Set());
|
||||
setSourceTeamId("");
|
||||
}}><PlusIcon data-icon="inline-start" />เพิ่ม Condition</Button>
|
||||
<Button type="button" variant="outline" disabled={teamGroups.length >= 20} onClick={() => {
|
||||
}}
|
||||
onDuplicate={() => {
|
||||
const source = teamGroups[activeTeamGroupIndex];
|
||||
if (!source) return;
|
||||
const copiedTeams = source.teams.map((team) => ({ ...team, clientId: createClientId("team"), members: team.members.map((member) => ({ ...member })) }));
|
||||
@@ -3332,17 +3306,24 @@ function TeamEditor({
|
||||
setActiveTeamGroupIndex(teamGroups.length);
|
||||
setSelectedTeamIds(new Set());
|
||||
setSourceTeamId(copiedTeams[0]?.clientId ?? "");
|
||||
}}><CopyIcon data-icon="inline-start" />Duplicate Condition</Button>
|
||||
</div>
|
||||
}}
|
||||
onDelete={() => {
|
||||
setTeamGroups(teamGroups.filter((_, index) => index !== activeTeamGroupIndex));
|
||||
setActiveTeamGroupIndex(Math.max(0, activeTeamGroupIndex - 1));
|
||||
setSelectedTeamIds(new Set());
|
||||
}}
|
||||
/>
|
||||
<ConditionRenameDialog
|
||||
open={renamingTeamGroupIndex !== null}
|
||||
fallback={`Condition ${(renamingTeamGroupIndex ?? 0) + 1}`}
|
||||
value={renamingTeamGroupIndex === null ? "" : teamGroups[renamingTeamGroupIndex]?.name ?? ""}
|
||||
onOpenChange={(open) => { if (!open) setRenamingTeamGroupIndex(null); }}
|
||||
onChange={(name) => setTeamGroups(teamGroups.map((group, index) => index === renamingTeamGroupIndex ? { ...group, name } : group))}
|
||||
/>
|
||||
<Field>
|
||||
<FieldLabel htmlFor={`team-condition-note-${teamGroups[activeTeamGroupIndex]?.clientId}`}>Condition note (optional)</FieldLabel>
|
||||
<Textarea id={`team-condition-note-${teamGroups[activeTeamGroupIndex]?.clientId}`} value={teamGroups[activeTeamGroupIndex]?.note ?? ""} onChange={(event) => setTeamGroups(teamGroups.map((group, index) => index === activeTeamGroupIndex ? { ...group, note: event.target.value } : group))} />
|
||||
</Field>
|
||||
{teamGroups.length > 1 ? <Button className="self-start" type="button" variant="ghost" onClick={() => {
|
||||
setTeamGroups(teamGroups.filter((_, index) => index !== activeTeamGroupIndex));
|
||||
setActiveTeamGroupIndex(Math.max(0, activeTeamGroupIndex - 1));
|
||||
setSelectedTeamIds(new Set());
|
||||
}}><Trash2Icon data-icon="inline-start" />ลบ Condition นี้</Button> : null}
|
||||
<div className="flex min-w-0 flex-wrap items-center gap-2 rounded-lg border bg-muted/30 p-3">
|
||||
<Checkbox
|
||||
checked={selectedTeamIds.size === teams.length && teams.length > 0}
|
||||
|
||||
Reference in New Issue
Block a user