Create & edit release

This commit is contained in:
LittleSheep 2025-01-11 00:02:16 +08:00
parent 10191c04e0
commit 9a265c9887
5 changed files with 97 additions and 9 deletions

View File

@ -7,7 +7,7 @@
"name": "LittleSheep", "name": "LittleSheep",
"email": "littlesheep.code@hotmail.com" "email": "littlesheep.code@hotmail.com"
}, },
"version": "0.0.3", "version": "0.0.5",
"tsup": { "tsup": {
"entry": [ "entry": [
"src/index.ts" "src/index.ts"

View File

@ -1,4 +1,5 @@
export * from './matrix/product' export * from './matrix/product'
export * from './matrix/release'
export * from './attachment' export * from './attachment'
export * from './auth' export * from './auth'
export * from './checkIn' export * from './checkIn'

View File

@ -13,12 +13,13 @@ import {
IconButton, IconButton,
} from '@mui/material' } from '@mui/material'
import { useRouter } from 'next-nprogress-bar' import { useRouter } from 'next-nprogress-bar'
import { useState } from 'react' import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form' import { useForm } from 'react-hook-form'
import ErrorIcon from '@mui/icons-material/Error' import ErrorIcon from '@mui/icons-material/Error'
import CloseIcon from '@mui/icons-material/Close' import CloseIcon from '@mui/icons-material/Close'
import { MaProduct } from 'solar-js-sdk' import { MaProduct } from 'solar-js-sdk'
import { version } from 'node:os'
export interface MatrixReleaseForm { export interface MatrixReleaseForm {
version: string version: string
@ -39,13 +40,27 @@ export default function MaReleaseForm({
}: { }: {
onSubmit: (data: MatrixReleaseForm) => Promise<any> onSubmit: (data: MatrixReleaseForm) => Promise<any>
onSuccess?: () => void onSuccess?: () => void
parent: MaProduct parent: Partial<MaProduct>
defaultValue?: unknown defaultValue?: any
}) { }) {
const { handleSubmit, register } = useForm<MatrixReleaseForm>({ const { handleSubmit, register } = useForm<MatrixReleaseForm>({
defaultValues: {}, defaultValues: {
title: defaultValue?.meta.title,
version: defaultValue?.version,
type: defaultValue?.type ?? 0,
channel: defaultValue?.channel,
description: defaultValue?.meta.description,
content: defaultValue?.meta.content,
attachments: defaultValue?.meta.attachments,
},
}) })
useEffect(() => {
if (defaultValue) {
setAssets(Object.keys(defaultValue.assets).map((k) => ({ k, v: defaultValue.assets[k] })))
}
}, [])
const router = useRouter() const router = useRouter()
const [assets, setAssets] = useState<{ k: string; v: string }[]>([]) const [assets, setAssets] = useState<{ k: string; v: string }[]>([])
@ -61,7 +76,7 @@ export default function MaReleaseForm({
if (onSuccess) { if (onSuccess) {
onSuccess() onSuccess()
} else { } else {
router.push(`/console/matrix/products/${parent.id}`) router.push(`/console/matrix/products/${parent?.id}`)
} }
} }

View File

@ -1,5 +1,5 @@
import { ConsoleLayout, getConsoleStaticProps } from '@/components/layouts/ConsoleLayout' import { ConsoleLayout, getConsoleStaticProps } from '@/components/layouts/ConsoleLayout'
import { Box, Button, Container, Typography } from '@mui/material' import { Box, Button, Container, Typography, Grid2 as Grid, Card, CardContent, CardActions } from '@mui/material'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next' import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import { sni, MaProduct } from 'solar-js-sdk' import { sni, MaProduct } from 'solar-js-sdk'
import NextLink from 'next/link' import NextLink from 'next/link'
@ -9,15 +9,22 @@ export const getServerSideProps: GetServerSideProps = (async (context) => {
const { data } = await sni.get<MaProduct>('/cgi/ma/products/' + id) const { data } = await sni.get<MaProduct>('/cgi/ma/products/' + id)
const { data: resp } = await sni.get<{ data: any[] }>('/cgi/ma/products/' + id + '/releases', {
params: {
take: 10,
},
})
return getConsoleStaticProps({ return getConsoleStaticProps({
props: { props: {
title: `Product "${data.name}"`, title: `Product "${data.name}"`,
product: data, product: data,
releases: resp.data,
}, },
}) })
}) satisfies GetServerSideProps<{ product: MaProduct }> }) satisfies GetServerSideProps<{ product: MaProduct; releases: any[] }>
export default function ProductDetails({ product }: InferGetServerSidePropsType<typeof getServerSideProps>) { export default function ProductDetails({ product, releases }: InferGetServerSidePropsType<typeof getServerSideProps>) {
return ( return (
<ConsoleLayout> <ConsoleLayout>
<Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 8 }}> <Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 8 }}>
@ -36,6 +43,31 @@ export default function ProductDetails({ product }: InferGetServerSidePropsType<
<NextLink passHref href={`/console/matrix/products/${product.id}/releases/new`}> <NextLink passHref href={`/console/matrix/products/${product.id}/releases/new`}>
<Button variant="contained">Create a release</Button> <Button variant="contained">Create a release</Button>
</NextLink> </NextLink>
<Grid container columns={{ xs: 1, sm: 2, md: 3 }} spacing={2}>
{releases.map((r: any) => (
<Grid size={1}>
<Card>
<CardContent>
<Typography variant="caption">{r.version}</Typography>
<Typography variant="h5" component="h2">
{r.meta.title}
</Typography>
<Typography variant="body1" gutterBottom>
{r.type == 0 ? 'Full Release' : 'Patch Release'}
</Typography>
<Typography variant="body1">{r.meta.description}</Typography>
</CardContent>
<CardActions>
<NextLink passHref href={`/console/matrix/products/${r.productId}/releases/${r.id}/edit`}>
<Button size="small">Edit</Button>
</NextLink>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Box> </Box>
</Container> </Container>
</ConsoleLayout> </ConsoleLayout>

View File

@ -0,0 +1,40 @@
import { ConsoleLayout, getConsoleStaticProps } from '@/components/layouts/ConsoleLayout'
import { Typography, Container, Box } from '@mui/material'
import { sni } from 'solar-js-sdk'
import { GetServerSideProps, InferGetServerSidePropsType } from 'next'
import MaReleaseForm, { MatrixReleaseForm } from '@/components/matrix/MaReleaseForm'
export const getServerSideProps: GetServerSideProps = (async (context) => {
const id = context.params!.id
const releaseId = context.params!.release
const { data } = await sni.get<any>('/cgi/ma/products/' + id + '/releases/' + releaseId)
return getConsoleStaticProps({
props: {
title: `Edit Release "${data.name}"`,
release: data,
},
})
}) satisfies GetServerSideProps<{ release: any }>
export default function ProductEdit({ release }: InferGetServerSidePropsType<typeof getServerSideProps>) {
async function onSubmit(data: MatrixReleaseForm) {
await sni.put('/cgi/ma/products/' + release.id + '/releases/' + release.productId, data)
}
return (
<ConsoleLayout>
<Container sx={{ py: 16, display: 'flex', flexDirection: 'column', gap: 4 }}>
<Box>
<Typography variant="h3" component="h1">
Edit releases
</Typography>
<Typography variant="subtitle1">{release.meta.title}</Typography>
</Box>
<MaReleaseForm onSubmit={onSubmit} defaultValue={release} parent={{ id: release.productId }} />
</Container>
</ConsoleLayout>
)
}