Propagate MC version ranges from VersionTable to PublishModal

This commit is contained in:
CPTProgrammer 2026-07-16 16:05:13 +08:00
parent 9a2305d5e0
commit 54d6a7659a
No known key found for this signature in database
3 changed files with 59 additions and 22 deletions

View File

@ -8,6 +8,7 @@ import { VersionTable } from "./VersionTable";
import { PublishModal } from "./PublishModal"; import { PublishModal } from "./PublishModal";
import type { Config } from "@/types"; import type { Config } from "@/types";
import type { ParsedProject } from "@/services/project"; import type { ParsedProject } from "@/services/project";
import type { McVersionEntry } from "@/lib/utils/mcVersion";
const { Title } = Typography; const { Title } = Typography;
@ -27,6 +28,7 @@ export function MainPage({ initialConfigs }: MainPageProps) {
null, null,
); );
const [projectLoading, setProjectLoading] = useState(false); const [projectLoading, setProjectLoading] = useState(false);
const [versionRanges, setVersionRanges] = useState<McVersionEntry[] | null>(null);
// ------- ConfigSelector callbacks ------- // ------- ConfigSelector callbacks -------
@ -92,6 +94,7 @@ export function MainPage({ initialConfigs }: MainPageProps) {
project={parsedProject} project={parsedProject}
loading={projectLoading} loading={projectLoading}
onLoadingChange={setProjectLoading} onLoadingChange={setProjectLoading}
onRangesChange={setVersionRanges}
/> />
{/* Publish button */} {/* Publish button */}
@ -122,6 +125,7 @@ export function MainPage({ initialConfigs }: MainPageProps) {
open={publishOpen} open={publishOpen}
config={selectedConfig} config={selectedConfig}
project={parsedProject} project={parsedProject}
versionRanges={versionRanges}
onClose={handlePublishClose} onClose={handlePublishClose}
/> />
)} )}

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useCallback } from "react"; import { useState, useCallback, useMemo } from "react";
import { import {
Modal, Modal,
Steps, Steps,
@ -21,6 +21,8 @@ import { ReloadOutlined } from "@ant-design/icons";
import type { BaseVersion, Config, UploadReleaseType } from "@/types"; import type { BaseVersion, Config, UploadReleaseType } from "@/types";
import type { ParsedProject } from "@/services/project"; import type { ParsedProject } from "@/services/project";
import { platforms } from "@/services/publish.schemas"; import { platforms } from "@/services/publish.schemas";
import { Template } from "@/lib/utils/template";
import type { McVersionEntry } from "@/lib/utils/mcVersion";
const { Text } = Typography; const { Text } = Typography;
@ -33,9 +35,8 @@ interface PublishVersion {
mc_version: string; mc_version: string;
artifact: string | null; artifact: string | null;
sources: string | null; sources: string | null;
// version label that matches the platform's versioning modrinthVersion: string;
label: string; modrinthVersionName: string;
// already exists on this platform?
existsModrinth: boolean; existsModrinth: boolean;
existsCurseforge: boolean; existsCurseforge: boolean;
} }
@ -44,6 +45,7 @@ interface PublishModalProps {
open: boolean; open: boolean;
config: Config; config: Config;
project: ParsedProject; project: ParsedProject;
versionRanges: McVersionEntry[] | null;
onClose: () => void; onClose: () => void;
} }
@ -68,6 +70,7 @@ export function PublishModal({
open, open,
config, config,
project, project,
versionRanges,
onClose, onClose,
}: PublishModalProps) { }: PublishModalProps) {
const { token } = theme.useToken(); const { token } = theme.useToken();
@ -117,16 +120,41 @@ export function PublishModal({
} }
}, []); }, []);
// Pre-compute version display values
const versionTmpl = useMemo(() => new Template(config.modrinth.version), [config.modrinth.version]);
const versionNameTmpl = useMemo(() => new Template(config.modrinth.version_name), [config.modrinth.version_name]);
const rangeMap = useMemo(() => {
const map = new Map<string, string>();
if (versionRanges) {
for (const entry of versionRanges) {
map.set(entry.version, entry.wildcard);
}
}
return map;
}, [versionRanges]);
// Build publish version rows from project artifacts // Build publish version rows from project artifacts
const publishVersions: PublishVersion[] = project.artifacts.map((a) => ({ const publishVersions: PublishVersion[] = useMemo(() =>
project.artifacts.map((a) => {
const tmplValues = {
version: project.version,
mc_version: a.mc_version,
mc_version_range: rangeMap.get(a.mc_version) ?? a.mc_version,
};
return {
key: a.mc_version, key: a.mc_version,
mc_version: a.mc_version, mc_version: a.mc_version,
artifact: a.artifact, artifact: a.artifact,
sources: a.sources, sources: a.sources,
label: "", // TODO: compute from version template modrinthVersion: versionTmpl.format(tmplValues),
modrinthVersionName: versionNameTmpl.format(tmplValues),
existsModrinth: existingModrinth.includes(a.mc_version), existsModrinth: existingModrinth.includes(a.mc_version),
existsCurseforge: existingCurseforge.includes(a.mc_version), existsCurseforge: existingCurseforge.includes(a.mc_version),
})); };
}),
[project, versionTmpl, versionNameTmpl, rangeMap, existingModrinth, existingCurseforge],
);
// --------------- Steps handling --------------- // --------------- Steps handling ---------------
@ -175,16 +203,14 @@ export function PublishModal({
const renderStep1 = () => { const renderStep1 = () => {
const modrinthColumns = [ const modrinthColumns = [
{ {
title: "MC 版本", title: "版本号",
dataIndex: "mc_version", dataIndex: "modrinthVersion",
key: "mc_version", key: "modrinthVersion",
width: 100,
}, },
{ {
title: "构建产物", title: "版本名称",
dataIndex: "artifact", dataIndex: "modrinthVersionName",
key: "artifact", key: "modrinthVersionName",
ellipsis: true,
}, },
{ {
title: "", title: "",
@ -215,7 +241,7 @@ export function PublishModal({
width: 100, width: 100,
}, },
{ {
title: "构建产物", title: "显示名称",
dataIndex: "artifact", dataIndex: "artifact",
key: "artifact", key: "artifact",
ellipsis: true, ellipsis: true,

View File

@ -17,12 +17,14 @@ interface VersionTableProps {
project: ParsedProject | null; project: ParsedProject | null;
loading: boolean; loading: boolean;
onLoadingChange: (loading: boolean) => void; onLoadingChange: (loading: boolean) => void;
onRangesChange?: (ranges: McVersionEntry[] | null) => void;
} }
export function VersionTable({ export function VersionTable({
project, project,
loading, loading,
onLoadingChange, onLoadingChange,
onRangesChange,
}: VersionTableProps) { }: VersionTableProps) {
const { token } = theme.useToken(); const { token } = theme.useToken();
// ── MC version union from both platforms ── // ── MC version union from both platforms ──
@ -95,6 +97,11 @@ export function VersionTable({
.map((v) => ({ value: v, label: v })); .map((v) => ({ value: v, label: v }));
}, [project, allMcVersions]); }, [project, allMcVersions]);
// Report ranges to parent when they change
useEffect(() => {
onRangesChange?.(versionRanges);
}, [versionRanges, onRangesChange]);
// Reset lastVersionEnd to latest in the same series // Reset lastVersionEnd to latest in the same series
useEffect(() => { useEffect(() => {
if (allMcVersions.length === 0 || !project) return; if (allMcVersions.length === 0 || !project) return;