mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-23 07:21:53 +08:00
feat: support i18n namespace
This commit is contained in:
@@ -1,20 +0,0 @@
|
||||
import { InfoIcon } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip.tsx";
|
||||
|
||||
export function JreTip() {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<InfoIcon className="cursor-pointer h-4" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>{t("tips.jreTip")}</p>
|
||||
<p>{t("tips.jreTip2")}</p>
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
);
|
||||
}
|
||||
@@ -92,7 +92,7 @@ export default function MainConfigCard({
|
||||
]);
|
||||
const [shellTypes, setShellTypes] = useState<string[]>([]);
|
||||
const shellTool = form.watch("shellTool");
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation(["common", "memshell"]);
|
||||
|
||||
const [serverVersionOptions, setServerVersionOptions] = useState(
|
||||
defaultServerVersionOptions,
|
||||
@@ -137,7 +137,7 @@ export default function MainConfigCard({
|
||||
) {
|
||||
form.setValue("targetJdkVersion", "52");
|
||||
} else {
|
||||
form.resetField("targetJdkVersion");
|
||||
form.setValue("targetJdkVersion", "50");
|
||||
}
|
||||
|
||||
// 特殊的服务需要指定版本
|
||||
@@ -259,7 +259,7 @@ export default function MainConfigCard({
|
||||
<CardHeader className="pb-1">
|
||||
<CardTitle className="text-md flex items-center gap-2">
|
||||
<ServerIcon className="h-5" />
|
||||
<span>{t("configs.main-config")}</span>
|
||||
<span>{t("common:mainConfig.title")}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
@@ -269,7 +269,7 @@ export default function MainConfigCard({
|
||||
name="server"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("mainConfig.server")}</FormFieldLabel>
|
||||
<FormFieldLabel>{t("common:server")}</FormFieldLabel>
|
||||
<Select
|
||||
onValueChange={(v) => {
|
||||
field.onChange(v);
|
||||
@@ -279,7 +279,9 @@ export default function MainConfigCard({
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("placeholders.select")} />
|
||||
<SelectValue
|
||||
placeholder={t("common:placeholders.select")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
@@ -291,14 +293,14 @@ export default function MainConfigCard({
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription className="flex items-center">
|
||||
{t("tips.targetServerNotFound")}
|
||||
{t("memshell:tips.targetServerNotFound")}
|
||||
<a
|
||||
href="https://github.com/ReaJason/MemShellParty/issues/new?template=%E8%AF%B7%E6%B1%82%E9%80%82%E9%85%8D.md"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="flex items-center underline"
|
||||
>
|
||||
{t("tips.targetServerRequest")}
|
||||
{t("memshell:tips.targetServerRequest")}
|
||||
<ArrowUpRightIcon className="h-4" />
|
||||
</a>
|
||||
</FormDescription>
|
||||
@@ -310,11 +312,13 @@ export default function MainConfigCard({
|
||||
name="serverVersion"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("mainConfig.serverVersion")}</FormFieldLabel>
|
||||
<FormFieldLabel>{t("common:serverVersion")}</FormFieldLabel>
|
||||
<Select onValueChange={field.onChange} value={field.value}>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("placeholders.select")} />
|
||||
<SelectValue
|
||||
placeholder={t("common:placeholders.select")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
@@ -337,9 +341,13 @@ export default function MainConfigCard({
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Switch id={debugId} checked={field.value} onCheckedChange={field.onChange} />
|
||||
<Switch
|
||||
id="debug"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormLabel htmlFor={debugId}>{t("mainConfig.debug")}</FormLabel>
|
||||
<FormLabel htmlFor="debug">{t("common:debug")}</FormLabel>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
@@ -349,9 +357,13 @@ export default function MainConfigCard({
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Switch id={bypassId} checked={field.value} onCheckedChange={field.onChange} />
|
||||
<Switch
|
||||
id="bypass"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<Label htmlFor={bypassId}>{t("mainConfig.byPassJavaModule")}</Label>
|
||||
<Label htmlFor="bypass">{t("common:byPassJavaModule")}</Label>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
@@ -361,9 +373,13 @@ export default function MainConfigCard({
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex items-center space-x-2 space-y-0">
|
||||
<FormControl>
|
||||
<Switch id={shrinkId} checked={field.value} onCheckedChange={field.onChange} />
|
||||
<Switch
|
||||
id="shrink"
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
<Label htmlFor={shrinkId}>{t("mainConfig.shrink")}</Label>
|
||||
<Label htmlFor="shrink">{t("common:shrink")}</Label>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -34,7 +34,7 @@ export default function PackageConfigCard({
|
||||
|
||||
const shellType = form.watch("shellType");
|
||||
const server = form.watch("server");
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation("common");
|
||||
|
||||
useEffect(() => {
|
||||
const filteredOptions = (packerConfig ?? []).filter((name) => {
|
||||
@@ -52,7 +52,7 @@ export default function PackageConfigCard({
|
||||
|
||||
const mappedOptions = filteredOptions.map((name) => {
|
||||
return {
|
||||
name: t(`packageConfig.packer.${name}`),
|
||||
name: t(name),
|
||||
value: name,
|
||||
};
|
||||
});
|
||||
@@ -72,7 +72,7 @@ export default function PackageConfigCard({
|
||||
<CardHeader className="pb-1">
|
||||
<CardTitle className="text-md flex items-center gap-2">
|
||||
<PackageIcon className="h-5" />
|
||||
<span>{t("configs.package-config")}</span>
|
||||
<span>{t("packerConfig.title")}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
@@ -83,7 +83,7 @@ export default function PackageConfigCard({
|
||||
name="packingMethod"
|
||||
render={({ field }) => (
|
||||
<FormItem className="space-y-3">
|
||||
<FormLabel>{t("packageConfig.title")}</FormLabel>
|
||||
<FormLabel>{t("packerMethod")}</FormLabel>
|
||||
<FormControl>
|
||||
<RadioGroup
|
||||
onValueChange={field.onChange}
|
||||
|
||||
@@ -8,22 +8,22 @@ import {
|
||||
} from "@/components/ui/card.tsx";
|
||||
|
||||
export function QuickUsage() {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation(["common", "memshell"]);
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="text-md flex items-center gap-2">
|
||||
<ScrollTextIcon className="h-5" />
|
||||
<span>{t("quickUsage.title")}</span>
|
||||
<span>{t("common:quickUsage.title")}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ol className="list-decimal list-inside space-y-4 text-sm">
|
||||
<li>{t("quickUsage.step1")}</li>
|
||||
<li>{t("quickUsage.step2")}</li>
|
||||
<li>{t("quickUsage.step3")}</li>
|
||||
<li>{t("quickUsage.step4")}</li>
|
||||
<li>{t("quickUsage.step5")}</li>
|
||||
<li>{t("memshell:quickUsage.step1")}</li>
|
||||
<li>{t("memshell:quickUsage.step2")}</li>
|
||||
<li>{t("memshell:quickUsage.step3")}</li>
|
||||
<li>{t("memshell:quickUsage.step4")}</li>
|
||||
<li>{t("memshell:quickUsage.step5")}</li>
|
||||
</ol>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -10,7 +10,11 @@ export function AgentResult({
|
||||
packMethod,
|
||||
packResult,
|
||||
generateResult,
|
||||
}: Readonly<{ packMethod: string; packResult: string; generateResult?: MemShellResult }>) {
|
||||
}: Readonly<{
|
||||
packMethod: string;
|
||||
packResult: string;
|
||||
generateResult?: MemShellResult;
|
||||
}>) {
|
||||
const { t } = useTranslation();
|
||||
const isPureAgent = packMethod === "AgentJar";
|
||||
return (
|
||||
@@ -18,14 +22,15 @@ export function AgentResult({
|
||||
<CardHeader>
|
||||
<CardTitle className="text-md flex items-center gap-2">
|
||||
<ScrollTextIcon className="h-5" />
|
||||
<span>{t("generateResult.usage")}</span>
|
||||
<span>{t("common:usage")}</span>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<ol className="list-decimal list-inside space-y-4 text-sm">
|
||||
<li className="flex items-center justify-between">
|
||||
<span>
|
||||
{t("download")} MemShellAgent.jar ({formatBytes(atob(packResult).length)})
|
||||
{t("common:download")} MemShellAgent.jar (
|
||||
{formatBytes(atob(packResult).length)})
|
||||
</span>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -40,28 +45,38 @@ export function AgentResult({
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("download")}
|
||||
{t("common:download")}
|
||||
</Button>
|
||||
</li>
|
||||
{isPureAgent && (
|
||||
<li className="flex items-center justify-between">
|
||||
<span>{t("tips.download-jattach")}</span>
|
||||
<span>{t("memshell:tips.download-jattach")}</span>
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="w-28"
|
||||
type="button"
|
||||
onClick={() => window.open("https://github.com/jattach/jattach/releases")}
|
||||
onClick={() =>
|
||||
window.open("https://github.com/jattach/jattach/releases")
|
||||
}
|
||||
>
|
||||
{t("download")}
|
||||
{t("common:download")}
|
||||
</Button>
|
||||
</li>
|
||||
)}
|
||||
<Separator />
|
||||
<li>{isPureAgent ? t("tips.agent-move-to-target") : t("tips.agent-move-to-target1")}</li>
|
||||
<li>{t("tips.get-pid")}</li>
|
||||
<li>{isPureAgent ? t("tips.execute-command") : t("tips.execute-command1")}</li>
|
||||
<li>{t("tips.try-to-use-shell")}</li>
|
||||
<li>
|
||||
{isPureAgent
|
||||
? t("memshell:tips.agent-move-to-target")
|
||||
: t("memshell:tips.agent-move-to-target1")}
|
||||
</li>
|
||||
<li>{t("memshell:tips.get-pid")}</li>
|
||||
<li>
|
||||
{isPureAgent
|
||||
? t("memshell:tips.execute-command")
|
||||
: t("memshell:tips.execute-command1")}
|
||||
</li>
|
||||
<li>{t("memshell:tips.try-to-use-shell")}</li>
|
||||
</ol>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@@ -16,24 +16,35 @@ import {
|
||||
import { CopyableField } from "../../copyable-field";
|
||||
import { FeedbackAlert } from "./feedback-alert";
|
||||
|
||||
export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShellResult }>) {
|
||||
const { t } = useTranslation();
|
||||
export function BasicInfo({
|
||||
generateResult,
|
||||
}: Readonly<{ generateResult?: MemShellResult }>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center justify-between">
|
||||
<div className="text-md flex items-center gap-2">
|
||||
<FileTextIcon className="h-5" />
|
||||
<span>{t("generateResult.basicInfo")}</span>
|
||||
<span>{t("common:basicInfo")}</span>
|
||||
</div>
|
||||
<FeedbackAlert />
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
<CopyableField label={t("mainConfig.server")} text={generateResult?.shellConfig.server} />
|
||||
<CopyableField label={t("mainConfig.shellTool")} text={generateResult?.shellConfig.shellTool} />
|
||||
<CopyableField label={t("mainConfig.shellMountType")} text={generateResult?.shellConfig.shellType} />
|
||||
<CopyableField
|
||||
label={t("common:server")}
|
||||
text={generateResult?.shellConfig.server}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("mainConfig.shellTool")}
|
||||
text={generateResult?.shellConfig.shellTool}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("mainConfig.shellMountType")}
|
||||
text={generateResult?.shellConfig.shellType}
|
||||
/>
|
||||
{!shouldHidden(generateResult?.shellConfig?.shellType) && (
|
||||
<CopyableField
|
||||
label={t("mainConfig.urlPattern")}
|
||||
@@ -42,22 +53,33 @@ export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShe
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{generateResult?.shellConfig.shellTool !== ShellToolType.Custom && <Separator className="my-1" />}
|
||||
{generateResult?.shellConfig.shellTool !== ShellToolType.Custom && (
|
||||
<Separator className="my-1" />
|
||||
)}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2">
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.Behinder && (
|
||||
<>
|
||||
<CopyableField label={t("shellToolConfig.behinderScriptType")} text="jsp" />
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.behinderScriptType")}
|
||||
text="jsp"
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.behinderEncryptType")}
|
||||
text={t("shellToolConfig.behinderDefaultEncryptType")}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.behinderPass")}
|
||||
text={(generateResult?.shellToolConfig as BehinderShellToolConfig).pass}
|
||||
value={(generateResult?.shellToolConfig as BehinderShellToolConfig).pass}
|
||||
label={t("shellToolConfig.behinder.pass")}
|
||||
text={
|
||||
(generateResult?.shellToolConfig as BehinderShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
value={
|
||||
(generateResult?.shellToolConfig as BehinderShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.customHeader")}
|
||||
label={t("shellToolConfig.behinder.header")}
|
||||
text={`${(generateResult?.shellToolConfig as BehinderShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as BehinderShellToolConfig).headerValue}`}
|
||||
value={`${(generateResult?.shellToolConfig as BehinderShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as BehinderShellToolConfig).headerValue}`}
|
||||
/>
|
||||
@@ -66,18 +88,33 @@ export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShe
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.Godzilla && (
|
||||
<>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.pass")}
|
||||
text={(generateResult?.shellToolConfig as GodzillaShellToolConfig).pass}
|
||||
value={(generateResult?.shellToolConfig as GodzillaShellToolConfig).pass}
|
||||
label={t("shellToolConfig.godzilla.pass")}
|
||||
text={
|
||||
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
value={
|
||||
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.key")}
|
||||
text={(generateResult?.shellToolConfig as GodzillaShellToolConfig).key}
|
||||
value={(generateResult?.shellToolConfig as GodzillaShellToolConfig).key}
|
||||
label={t("shellToolConfig.godzilla.key")}
|
||||
text={
|
||||
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
|
||||
.key
|
||||
}
|
||||
value={
|
||||
(generateResult?.shellToolConfig as GodzillaShellToolConfig)
|
||||
.key
|
||||
}
|
||||
/>
|
||||
<CopyableField label={t("shellToolConfig.godzillaEncryptor")} text="JAVA_AES_BASE64" />
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.godzillaHeader")}
|
||||
label={t("shellToolConfig.godzilla.encryptor")}
|
||||
text="JAVA_AES_BASE64"
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.godzilla.header")}
|
||||
text={`${(generateResult?.shellToolConfig as GodzillaShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as GodzillaShellToolConfig).headerValue}`}
|
||||
value={`${(generateResult?.shellToolConfig as GodzillaShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as GodzillaShellToolConfig).headerValue}`}
|
||||
/>
|
||||
@@ -85,9 +122,15 @@ export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShe
|
||||
)}
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.Command && (
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.paramName")}
|
||||
text={(generateResult?.shellToolConfig as CommandShellToolConfig).paramName}
|
||||
value={(generateResult?.shellToolConfig as CommandShellToolConfig).paramName}
|
||||
label={t("common:paramName")}
|
||||
text={
|
||||
(generateResult?.shellToolConfig as CommandShellToolConfig)
|
||||
.paramName
|
||||
}
|
||||
value={
|
||||
(generateResult?.shellToolConfig as CommandShellToolConfig)
|
||||
.paramName
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.Suo5 && (
|
||||
@@ -100,9 +143,15 @@ export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShe
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.AntSword && (
|
||||
<>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.antSwordPass")}
|
||||
text={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
|
||||
value={(generateResult?.shellToolConfig as AntSwordShellToolConfig).pass}
|
||||
label={t("shellToolConfig.antSword.pass")}
|
||||
text={
|
||||
(generateResult?.shellToolConfig as AntSwordShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
value={
|
||||
(generateResult?.shellToolConfig as AntSwordShellToolConfig)
|
||||
.pass
|
||||
}
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.httpHeader")}
|
||||
@@ -111,9 +160,14 @@ export function BasicInfo({ generateResult }: Readonly<{ generateResult?: MemShe
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{generateResult?.shellConfig.shellTool === ShellToolType.NeoreGeorg && (
|
||||
{generateResult?.shellConfig.shellTool ===
|
||||
ShellToolType.NeoreGeorg && (
|
||||
<>
|
||||
<CopyableField label={t("shellToolConfig.neoreGeorgKey")} text="key" value="key" />
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.neoreGeorgKey")}
|
||||
text="key"
|
||||
value="key"
|
||||
/>
|
||||
<CopyableField
|
||||
label={t("shellToolConfig.neoreGeorgHeader")}
|
||||
text={`${(generateResult?.shellToolConfig as NeoreGeorgShellToolConfig).headerName}: ${(generateResult?.shellToolConfig as NeoreGeorgShellToolConfig).headerValue}`}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
export function FeedbackAlert() {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation("memshell");
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger asChild>
|
||||
@@ -33,7 +33,7 @@ export function FeedbackAlert() {
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{t("cancel")}</AlertDialogCancel>
|
||||
<AlertDialogCancel>{t("common:cancel")}</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() =>
|
||||
window.open(
|
||||
@@ -41,7 +41,7 @@ export function FeedbackAlert() {
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("feedback")}
|
||||
{t("common:feedback")}
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
|
||||
@@ -20,7 +20,7 @@ export function JarResult({
|
||||
)
|
||||
}
|
||||
>
|
||||
{t("download")} Jar
|
||||
{t("common:download")} Jar
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -17,16 +17,20 @@ export function MultiPackResult({
|
||||
packMethod: string;
|
||||
}>) {
|
||||
const showCode = packMethod === "JSP";
|
||||
const {t} = useTranslation();
|
||||
const { t } = useTranslation();
|
||||
const packMethods = Object.keys(allPackResults ?? {});
|
||||
const [selectedMethod, setSelectedMethod] = useState(packMethods[0]);
|
||||
const [packResult, setPackResult] = useState(allPackResults?.[selectedMethod as keyof typeof allPackResults] ?? "");
|
||||
const [packResult, setPackResult] = useState(
|
||||
allPackResults?.[selectedMethod as keyof typeof allPackResults] ?? "",
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const methods = Object.keys(allPackResults ?? {});
|
||||
const firstMethod = methods[0];
|
||||
setSelectedMethod(firstMethod);
|
||||
setPackResult(allPackResults?.[firstMethod as keyof typeof allPackResults] ?? "");
|
||||
setPackResult(
|
||||
allPackResults?.[firstMethod as keyof typeof allPackResults] ?? "",
|
||||
);
|
||||
}, [allPackResults]);
|
||||
|
||||
return (
|
||||
@@ -44,7 +48,9 @@ export function MultiPackResult({
|
||||
value={selectedMethod}
|
||||
>
|
||||
<SelectTrigger className="h-7 text-xs [&_svg]:h-4 [&_svg]:w-4">
|
||||
<span className="text-muted-foreground">{t("packageConfig.title")}: </span>
|
||||
<span className="text-muted-foreground">
|
||||
{t("common:packerMethod")}:
|
||||
</span>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
||||
@@ -53,9 +53,11 @@ export function ResultComponent({
|
||||
header={
|
||||
<div className="flex items-center justify-between text-xs gap-2">
|
||||
<span>
|
||||
{t("packageConfig.title")}:{packMethod}
|
||||
{t("common:packerMethod")}:{packMethod}
|
||||
</span>
|
||||
<span className="text-muted-foreground">
|
||||
({packResult?.length})
|
||||
</span>
|
||||
<span className="text-muted-foreground">({packResult?.length})</span>
|
||||
</div>
|
||||
}
|
||||
wrapLongLines={!showCode}
|
||||
|
||||
@@ -27,16 +27,20 @@ export default function ShellResult({
|
||||
packMethod: string;
|
||||
generateResult?: MemShellResult;
|
||||
}>) {
|
||||
const { t } = useTranslation();
|
||||
const { t } = useTranslation(["common", "memshell"]);
|
||||
if (!generateResult) {
|
||||
return <QuickUsage />;
|
||||
}
|
||||
return (
|
||||
<Tabs defaultValue="packResult">
|
||||
<TabsList className="grid w-full grid-cols-3">
|
||||
<TabsTrigger value="packResult">{t("generateResult.title1")}</TabsTrigger>
|
||||
<TabsTrigger value="shell">{t("generateResult.title2")}</TabsTrigger>
|
||||
<TabsTrigger value="injector">{t("generateResult.title3")}</TabsTrigger>
|
||||
<TabsTrigger value="packResult">
|
||||
{t("common:generateResult")}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="shell">{t("memshell:shellClass")}</TabsTrigger>
|
||||
<TabsTrigger value="injector">
|
||||
{t("memshell:injectorClass")}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="packResult" className="my-2 space-y-4">
|
||||
<BasicInfo generateResult={generateResult} />
|
||||
@@ -50,7 +54,11 @@ export default function ShellResult({
|
||||
<TabsContent value="shell" className="mt-4">
|
||||
<CodeViewer
|
||||
showLineNumbers={false}
|
||||
header={<div className="text-xs truncate">{generateResult?.shellClassName}</div>}
|
||||
header={
|
||||
<div className="text-xs truncate">
|
||||
{generateResult?.shellClassName}
|
||||
</div>
|
||||
}
|
||||
button={
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -59,10 +67,13 @@ export default function ShellResult({
|
||||
className="h-7 w-7 [&_svg]:h-4 [&_svg]:w-4"
|
||||
onClick={() => {
|
||||
if (!generateResult?.shellBytesBase64Str) {
|
||||
toast.warning(t("tips.shellBytesEmpty"));
|
||||
toast.warning(t("memshell:tips.shellBytesEmpty"));
|
||||
return;
|
||||
}
|
||||
downloadBytes(generateResult?.shellBytesBase64Str, generateResult?.shellClassName);
|
||||
downloadBytes(
|
||||
generateResult?.shellBytesBase64Str,
|
||||
generateResult?.shellClassName,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<DownloadIcon className="h-4 w-4" />
|
||||
@@ -78,7 +89,9 @@ export default function ShellResult({
|
||||
<CodeViewer
|
||||
showLineNumbers={false}
|
||||
wrapLongLines={true}
|
||||
header={<div className="text-xs">{generateResult?.injectorClassName}</div>}
|
||||
header={
|
||||
<div className="text-xs">{generateResult?.injectorClassName}</div>
|
||||
}
|
||||
button={
|
||||
<Button
|
||||
variant="ghost"
|
||||
@@ -87,10 +100,13 @@ export default function ShellResult({
|
||||
className="h-7 w-7 [&_svg]:h-4 [&_svg]:w-4"
|
||||
onClick={() => {
|
||||
if (!generateResult?.injectorBytesBase64Str) {
|
||||
toast.warning(t("tips.shellBytesEmpty"));
|
||||
toast.warning(t("memshell:tips.shellBytesEmpty"));
|
||||
return;
|
||||
}
|
||||
downloadBytes(generateResult?.injectorBytesBase64Str, generateResult?.injectorClassName);
|
||||
downloadBytes(
|
||||
generateResult?.injectorBytesBase64Str,
|
||||
generateResult?.injectorClassName,
|
||||
);
|
||||
}}
|
||||
>
|
||||
<DownloadIcon className="h-4 w-4" />
|
||||
|
||||
@@ -17,8 +17,11 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function AntSwordTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="AntSword">
|
||||
@@ -34,9 +37,12 @@ export function AntSwordTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.antSwordPass")} {t("optional")}
|
||||
{t("shellToolConfig.antSword.pass")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -46,9 +52,12 @@ export function AntSwordTabContent({
|
||||
name="headerName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.headerName")}</FormFieldLabel>
|
||||
<FormFieldLabel>{t("common:headerName")}</FormFieldLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
@@ -59,9 +68,12 @@ export function AntSwordTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.headerValue")} {t("optional")}
|
||||
{t("common:headerValue")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -12,8 +12,11 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function BehinderTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="Behinder">
|
||||
@@ -29,9 +32,12 @@ export function BehinderTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.behinderPass")} {t("optional")}
|
||||
{t("shellToolConfig.behinder.pass")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -41,8 +47,11 @@ export function BehinderTabContent({
|
||||
name="headerName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.headerName")}</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<FormFieldLabel>{t("common:headerName")}</FormFieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -52,9 +61,12 @@ export function BehinderTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.headerValue")} {t("optional")}
|
||||
{t("common:headerValue")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -11,11 +11,11 @@ import {
|
||||
import { Input } from "@/components/ui/input.tsx";
|
||||
import type { MemShellFormSchema } from "@/types/schema.ts";
|
||||
|
||||
export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn<MemShellFormSchema> }>) {
|
||||
const { t } = useTranslation();
|
||||
export function OptionalClassFormField({
|
||||
form,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema> }>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
const [showAdvanced, setShowAdvanced] = useState(false);
|
||||
const shellClassNameId = useId();
|
||||
const injectClassNameId = useId();
|
||||
return (
|
||||
<Fragment>
|
||||
<div className="pt-2">
|
||||
@@ -28,7 +28,11 @@ export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn<
|
||||
>
|
||||
<Settings className="h-4 w-4" />
|
||||
{t("classNameOptions")}
|
||||
{showAdvanced ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
||||
{showAdvanced ? (
|
||||
<ChevronUp className="h-4 w-4" />
|
||||
) : (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
{showAdvanced && (
|
||||
@@ -38,10 +42,14 @@ export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn<
|
||||
name="shellClassName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel htmlFor={shellClassNameId}>
|
||||
{t("mainConfig.shellClassName")} {t("optional")}
|
||||
<FormFieldLabel htmlFor="shellClassName">
|
||||
{t("mainConfig.shellClassName")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input id={shellClassNameId} {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
id="shellClassName"
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -50,10 +58,14 @@ export function OptionalClassFormField({ form }: Readonly<{ form: UseFormReturn<
|
||||
name="injectorClassName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel htmlFor={injectClassNameId}>
|
||||
{t("mainConfig.injectorClassName")} {t("optional")}
|
||||
<FormFieldLabel htmlFor="injectClassName">
|
||||
{t("mainConfig.injectorClassName")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input id={injectClassNameId} {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
id="injectClassName"
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -26,9 +26,15 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function CommandTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
const { data } = useQuery<{ encryptors: Array<string>; implementationClasses: Array<string> }>({
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
const { data } = useQuery<{
|
||||
encryptors: Array<string>;
|
||||
implementationClasses: Array<string>;
|
||||
}>({
|
||||
queryKey: ["commandConfigs"],
|
||||
queryFn: async () => {
|
||||
const response = await fetch(`${env.API_URL}/config/command/configs`);
|
||||
@@ -51,10 +57,13 @@ export function CommandTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.paramName")} {t("optional")}
|
||||
{t("common:paramName")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<FormControl>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
@@ -65,11 +74,17 @@ export function CommandTabContent({
|
||||
name="encryptor"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.encryptor")}</FormFieldLabel>
|
||||
<Select onValueChange={field.onChange} value={field.value} defaultValue="RAW">
|
||||
<FormFieldLabel>{t("common:encryptor")}</FormFieldLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
defaultValue="RAW"
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("placeholders.select")} />
|
||||
<SelectValue
|
||||
placeholder={t("common:placeholders.select")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
@@ -88,11 +103,19 @@ export function CommandTabContent({
|
||||
name="implementationClass"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.implementationClass")}</FormFieldLabel>
|
||||
<Select onValueChange={field.onChange} value={field.value} defaultValue="RuntimeExec">
|
||||
<FormFieldLabel>
|
||||
{t("common:implementationClass")}
|
||||
</FormFieldLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
value={field.value}
|
||||
defaultValue="RuntimeExec"
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("placeholders.select")} />
|
||||
<SelectValue
|
||||
placeholder={t("common:placeholders.select")}
|
||||
/>
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
|
||||
@@ -22,10 +22,12 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export default function CustomTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const [isFile, setIsFile] = useState(false);
|
||||
const optionOneId = useId();
|
||||
const optionTwoId = useId();
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="Custom">
|
||||
@@ -40,7 +42,7 @@ export default function CustomTabContent({
|
||||
name="shellClassBase64"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.base64String")}</FormFieldLabel>
|
||||
<FormFieldLabel>{t("shellClass")}</FormFieldLabel>
|
||||
<RadioGroup
|
||||
value={isFile ? "file" : "base64"}
|
||||
onValueChange={(value) => {
|
||||
@@ -50,12 +52,12 @@ export default function CustomTabContent({
|
||||
className="flex items-center space-x-2"
|
||||
>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="base64" id={optionOneId} />
|
||||
<Label htmlFor={optionOneId}>Base64</Label>
|
||||
<RadioGroupItem value="base64" id="optionOne" />
|
||||
<Label htmlFor="optionOne">Base64</Label>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<RadioGroupItem value="file" id={optionTwoId} />
|
||||
<Label htmlFor={optionTwoId}>File</Label>
|
||||
<RadioGroupItem value="file" id="optionTwo" />
|
||||
<Label htmlFor="optionTwo">File</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
<FormControl className="mt-2">
|
||||
@@ -66,18 +68,25 @@ export default function CustomTabContent({
|
||||
if (file) {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const base64String = (event.target?.result as string)?.split(",")[1] || "";
|
||||
const base64String =
|
||||
(event.target?.result as string)?.split(
|
||||
",",
|
||||
)[1] || "";
|
||||
field.onChange(base64String);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
}}
|
||||
accept=".class"
|
||||
placeholder={t("placeholders.input")}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
type="file"
|
||||
/>
|
||||
) : (
|
||||
<Textarea {...field} placeholder={t("placeholders.input")} className="h-24" />
|
||||
<Textarea
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
className="h-24"
|
||||
/>
|
||||
)}
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
|
||||
@@ -12,8 +12,11 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function GodzillaTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="Godzilla">
|
||||
@@ -30,9 +33,13 @@ export function GodzillaTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.pass")} {t("optional")}
|
||||
{t("shellToolConfig.godzilla.pass")}{" "}
|
||||
{t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -42,9 +49,12 @@ export function GodzillaTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.key")} {t("optional")}
|
||||
{t("shellToolConfig.godzilla.key")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -53,8 +63,11 @@ export function GodzillaTabContent({
|
||||
name="headerName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.headerName")}</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<FormFieldLabel>{t("common:headerName")}</FormFieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -64,9 +77,12 @@ export function GodzillaTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.headerValue")} {t("optional")}
|
||||
{t("common:headerValue")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -12,8 +12,11 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function NeoRegTabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="NeoreGeorg">
|
||||
@@ -29,8 +32,11 @@ export function NeoRegTabContent({
|
||||
name="headerName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.headerName")}</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<FormFieldLabel>{t("common:headerName")}</FormFieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -40,9 +46,12 @@ export function NeoRegTabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.headerValue")} {t("optional")}
|
||||
{t("common:headerValue")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -18,8 +18,11 @@ import type { MemShellFormSchema } from "@/types/schema.ts";
|
||||
export function ShellTypeFormField({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<FormField
|
||||
@@ -37,7 +40,7 @@ export function ShellTypeFormField({
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={t("placeholders.select")} />
|
||||
<SelectValue placeholder={t("common:placeholders.select")} />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent key={shellTypes?.join(",")}>
|
||||
@@ -48,7 +51,9 @@ export function ShellTypeFormField({
|
||||
</SelectItem>
|
||||
))
|
||||
) : (
|
||||
<SelectItem value=" ">{t("tips.shellToolNotSelected")}</SelectItem>
|
||||
<SelectItem value=" ">
|
||||
{t("tips.shellToolNotSelected")}
|
||||
</SelectItem>
|
||||
)}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
@@ -12,8 +12,11 @@ import { UrlPatternFormField } from "./urlpattern-field";
|
||||
export function Suo5TabContent({
|
||||
form,
|
||||
shellTypes,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema>; shellTypes: Array<string> }>) {
|
||||
const { t } = useTranslation();
|
||||
}: Readonly<{
|
||||
form: UseFormReturn<MemShellFormSchema>;
|
||||
shellTypes: Array<string>;
|
||||
}>) {
|
||||
const { t } = useTranslation(["memshell", "common"]);
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<TabsContent value="Suo5">
|
||||
@@ -29,8 +32,11 @@ export function Suo5TabContent({
|
||||
name="headerName"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>{t("shellToolConfig.headerName")}</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<FormFieldLabel>{t("common:headerName")}</FormFieldLabel>
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
@@ -40,9 +46,12 @@ export function Suo5TabContent({
|
||||
render={({ field }) => (
|
||||
<FormFieldItem>
|
||||
<FormFieldLabel>
|
||||
{t("shellToolConfig.headerValue")} {t("optional")}
|
||||
{t("common:headerValue")} {t("common:optional")}
|
||||
</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<Input
|
||||
{...field}
|
||||
placeholder={t("common:placeholders.input")}
|
||||
/>
|
||||
</FormFieldItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -10,8 +10,10 @@ import { Input } from "@/components/ui/input.tsx";
|
||||
import { shouldHidden } from "@/lib/utils";
|
||||
import type { MemShellFormSchema } from "@/types/schema.ts";
|
||||
|
||||
export function UrlPatternFormField({ form }: Readonly<{ form: UseFormReturn<MemShellFormSchema> }>) {
|
||||
const { t } = useTranslation();
|
||||
export function UrlPatternFormField({
|
||||
form,
|
||||
}: Readonly<{ form: UseFormReturn<MemShellFormSchema> }>) {
|
||||
const { t } = useTranslation("common");
|
||||
const shellType = form.watch("shellType");
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
@@ -19,8 +21,10 @@ export function UrlPatternFormField({ form }: Readonly<{ form: UseFormReturn<Mem
|
||||
control={form.control}
|
||||
name="urlPattern"
|
||||
render={({ field }) => (
|
||||
<FormFieldItem className={shouldHidden(shellType) ? "hidden" : "grid"}>
|
||||
<FormFieldLabel>{t("mainConfig.urlPattern")}</FormFieldLabel>
|
||||
<FormFieldItem
|
||||
className={shouldHidden(shellType) ? "hidden" : "grid"}
|
||||
>
|
||||
<FormFieldLabel>{t("urlPattern")}</FormFieldLabel>
|
||||
<Input {...field} placeholder={t("placeholders.input")} />
|
||||
<FormMessage />
|
||||
</FormFieldItem>
|
||||
|
||||
Reference in New Issue
Block a user