diff --git a/package.json b/package.json index e0de93e..b9f89f9 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "linkify-react": "^3.0.4", "linkifyjs": "^3.0.5", "lodash-es": "^4.17.21", - "maa-copilot-client": "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.758.dbc2eb1", + "maa-copilot-client": "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.784.58f96e5", "normalize.css": "^8.0.1", "prettier": "^3.2.5", "react": "^18.0.0", diff --git a/src/apis/operation-set.ts b/src/apis/operation-set.ts index 573ae81..59ffaa8 100644 --- a/src/apis/operation-set.ts +++ b/src/apis/operation-set.ts @@ -4,6 +4,7 @@ import { CopilotSetPageRes, CopilotSetQuery, CopilotSetStatus, + CopilotSetUpdateReq, } from 'maa-copilot-client' import useSWR from 'swr' import useSWRInfinite from 'swr/infinite' @@ -184,12 +185,7 @@ export async function createOperationSet(req: { }) } -export async function updateOperationSet(req: { - id: number - name: string - description: string - status: CopilotSetStatus -}) { +export async function updateOperationSet(req: CopilotSetUpdateReq) { await new OperationSetApi().updateCopilotSet({ copilotSetUpdateReq: req }) } diff --git a/src/apis/operation.ts b/src/apis/operation.ts index 2e127cf..2e81602 100644 --- a/src/apis/operation.ts +++ b/src/apis/operation.ts @@ -114,7 +114,14 @@ export function useOperations({ const isReachingEnd = !!pages?.some((page) => !page.hasNext) - const operations = pages?.map((page) => page.data).flat() + const _operations = pages?.map((page) => page.data).flat() ?? [] + + // 按 operationIds 的顺序排序 + const operations = operationIds?.length + ? operationIds + ?.map((id) => _operations?.find((v) => v.id === id)) + .filter((v) => !!v) + : _operations return { error, diff --git a/src/components/operation-set/AddToOperationSet.tsx b/src/components/operation-set/AddToOperationSet.tsx index 0eeb202..4a2a42d 100644 --- a/src/components/operation-set/AddToOperationSet.tsx +++ b/src/components/operation-set/AddToOperationSet.tsx @@ -142,7 +142,7 @@ export function AddToOperationSet({ return ( <> -
+
{error && ( {formatError(error)} @@ -165,7 +165,7 @@ export function AddToOperationSet({
{ const updateInfo = async () => { if (isEdit) { - await updateOperationSet({ + const params: UpdateCopilotSetRequest['copilotSetUpdateReq'] = { id: operationSet!.id, name, description, status, - }) + copilotIds, + } + + await updateOperationSet(params) AppToaster.show({ intent: 'success', @@ -102,35 +124,7 @@ export function OperationSetEditorDialog({ } } - const addOperations = async () => { - if (operationSet && idsToAdd?.length) { - await addToOperationSet({ - operationSetId: operationSet.id, - operationIds: idsToAdd, - }) - - AppToaster.show({ - intent: 'success', - message: `添加作业成功`, - }) - } - } - - const removeOperations = async () => { - if (operationSet && idsToRemove?.length) { - await removeFromOperationSet({ - operationSetId: operationSet.id, - operationIds: idsToRemove, - }) - - AppToaster.show({ - intent: 'success', - message: `移除作业成功`, - }) - } - } - - await Promise.all([updateInfo(), addOperations(), removeOperations()]) + await updateInfo() onClose() } @@ -168,6 +162,7 @@ interface FormValues { idsToAdd?: number[] idsToRemove?: number[] + copilotIds?: number[] } function OperationSetForm({ operationSet, onSubmit }: FormProps) { @@ -207,7 +202,7 @@ function OperationSetForm({ operationSet, onSubmit }: FormProps) { return (
@@ -330,7 +326,9 @@ interface OperationSelectorProps { } interface OperationSelectorRef { - getValues(): { idsToAdd: number[]; idsToRemove: number[] } + getValues(): { + copilotIds?: number[] + } } function OperationSelector({ @@ -341,6 +339,12 @@ function OperationSelector({ operationIds: operationSet.copilotIds, }) + const [renderedOperations, setRenderedOperations] = useState([]) + useEffect(() => { + setRenderedOperations([...(operations ?? [])]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [operations.length]) + const [checkboxOverrides, setCheckboxOverrides] = useState( {} as Record, ) @@ -354,26 +358,34 @@ function OperationSelector({ selectorRef, () => ({ getValues() { - const idsToAdd: number[] = [] - const idsToRemove: number[] = [] - - Object.entries(checkboxOverrides).forEach(([idKey, checked]) => { - const id = +idKey - if (isNaN(id)) return - - if (checked && !alreadyAdded(id)) { - idsToAdd.push(id) - } else if (!checked && alreadyAdded(id)) { - idsToRemove.push(id) - } - }) - - return { idsToAdd, idsToRemove } + const copilotIds: number[] = [] + copilotIds.push( + ...renderedOperations + .map(({ id }) => (checkboxOverrides[id] === false ? 0 : id)) + .filter((id) => !!id), + ) + + return { copilotIds } }, }), - [checkboxOverrides, alreadyAdded], + [checkboxOverrides, renderedOperations], ) + const sensors = useSensors(useSensor(PointerSensor)) + + const handleDragEnd = (event: DragEndEvent) => { + const { active, over } = event + + if (active.id !== over?.id) { + setRenderedOperations((items) => { + const oldIndex = items.findIndex((v) => v.id === active.id) + const newIndex = items.findIndex((v) => v.id === over?.id) + + return arrayMove(items, oldIndex, newIndex) + }) + } + } + return (
{error && ( @@ -382,28 +394,53 @@ function OperationSelector({ )} - {operations?.map(({ id, parsedContent }) => ( -
- { - const checked = (e.target as HTMLInputElement).checked - setCheckboxOverrides((prev) => ({ ...prev, [id]: checked })) - }} - > -
{id}: 
-
- {parsedContent.doc.title} -
-
-
- ))} + + id)} + strategy={verticalListSortingStrategy} + > + {renderedOperations?.map(({ id, parsedContent }) => ( + + {({ listeners, attributes }) => ( +
+ + { + const checked = (e.target as HTMLInputElement).checked + setCheckboxOverrides((prev) => ({ + ...prev, + [id]: checked, + })) + }} + > +
+ {id}:  +
+
+ {parsedContent.doc.title} +
+
+
+ )} +
+ ))} +
+
) } diff --git a/yarn.lock b/yarn.lock index 5986c87..e046387 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3642,9 +3642,9 @@ lru-cache@^6.0.0: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== -"maa-copilot-client@https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.758.dbc2eb1": - version "0.1.0-SNAPSHOT.758.dbc2eb1" - resolved "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#d6750070b90fec2cac02d3f3d718a3165fd5d55a" +"maa-copilot-client@https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.784.58f96e5": + version "0.1.0-SNAPSHOT.784.58f96e5" + resolved "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#cecb29af32fa36d6f11ed46469765abe56caafaf" make-dir@^2.1.0: version "2.1.0"