From a2ee5d302edfd2f075c99fcada817a6bc6a0dc50 Mon Sep 17 00:00:00 2001 From: itsHenry <2671230065@qq.com> Date: Sat, 2 Mar 2024 15:24:06 +0800 Subject: [PATCH] feat: s3 server settings page (#152) --- src/lang/en/global.json | 3 +- src/lang/en/manage.json | 3 +- src/lang/en/settings.json | 9 +- src/pages/manage/settings/S3.tsx | 98 ++++++++++++++++++++++ src/pages/manage/settings/S3BucketItem.tsx | 67 +++++++++++++++ src/pages/manage/settings/S3Buckets.tsx | 63 ++++++++++++++ src/pages/manage/sidemenu_items.tsx | 7 ++ src/types/setting.ts | 1 + 8 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 src/pages/manage/settings/S3.tsx create mode 100644 src/pages/manage/settings/S3BucketItem.tsx create mode 100644 src/pages/manage/settings/S3Buckets.tsx diff --git a/src/lang/en/global.json b/src/lang/en/global.json index 70eea0c92..03c395625 100644 --- a/src/lang/en/global.json +++ b/src/lang/en/global.json @@ -27,5 +27,6 @@ "go_login": "Go to login", "close": "Close", "no_support_now": "Not currently supported", - "empty_input": "Please enter" + "empty_input": "Please enter", + "name": "Name" } diff --git a/src/lang/en/manage.json b/src/lang/en/manage.json index 89568ffb2..bd5407a89 100644 --- a/src/lang/en/manage.json +++ b/src/lang/en/manage.json @@ -21,7 +21,8 @@ "sso": "Single Sign-on", "docs": "Documentation", "offline_download": "Offline Download", - "ldap": "LDAP" + "ldap": "LDAP", + "s3": "S3" }, "title": "AList Manage", "not_admin": "You are not admin user, please login with admin account.", diff --git a/src/lang/en/settings.json b/src/lang/en/settings.json index ee3cac1d9..3287f3f97 100755 --- a/src/lang/en/settings.json +++ b/src/lang/en/settings.json @@ -98,5 +98,12 @@ "version": "Version", "video_autoplay": "Video autoplay", "video_types": "Video types", - "webauthn_login_enabled": "Webauthn login enabled" + "webauthn_login_enabled": "Webauthn login enabled", + "s3_enabled": "S3 enabled", + "s3_access_key_id": "S3 access key id", + "s3_secret_access_key": "S3 secret access key", + "s3_buckets": "S3 buckets", + "s3_buckets_duplicate_name": "Bucket name is duplicate", + "s3_buckets_empty": "Bucket name or path is empty", + "s3_restart_to_apply": "Above settings need restart to apply" } diff --git a/src/pages/manage/settings/S3.tsx b/src/pages/manage/settings/S3.tsx new file mode 100644 index 000000000..d6088e80a --- /dev/null +++ b/src/pages/manage/settings/S3.tsx @@ -0,0 +1,98 @@ +import { useFetch, useT, useManageTitle } from "~/hooks" +import { Group, SettingItem, PResp, PEmptyResp, EmptyResp } from "~/types" +import { r, notify, getTarget, handleResp } from "~/utils" +import { createStore } from "solid-js/store" +import { Button, HStack, Heading, VStack } from "@hope-ui/solid" +import { createSignal, Index, Show } from "solid-js" +import { Item } from "./SettingItem" +import { ResponsiveGrid } from "../common/ResponsiveGrid" +import S3Buckets from "./S3Buckets" + +const bucket_parse = (settings: SettingItem[]) => { + const string = { ...settings.find((i) => i.key === "s3_buckets")! } + if (!string.value) return [] + return JSON.parse(string.value) +} + +const S3Settings = () => { + const t = useT() + useManageTitle(`manage.sidemenu.s3`) + const [settingsLoading, getSettings] = useFetch( + (): PResp => r.get(`/admin/setting/list?group=${Group.S3}`), + ) + const [settings, setSettings] = createStore([]) + const refresh = async () => { + const resp = await getSettings() + handleResp(resp, setSettings) + } + refresh() + const [saveLoading, saveSettings] = useFetch( + (): PEmptyResp => r.post("/admin/setting/save", getTarget(settings)), + ) + const [loading, setLoading] = createSignal(false) + return ( + + + + {(item, _) => ( + + { + setSettings((i) => item().key === i.key, "value", val) + }} + onDelete={async () => { + setLoading(true) + const resp: EmptyResp = await r.post( + `/admin/setting/delete?key=${item().key}`, + ) + setLoading(false) + handleResp(resp, () => { + notify.success(t("global.delete_success")) + refresh() + }) + }} + /> + + )} + + {t("settings.s3_restart_to_apply")} + + + + + + + + ) +} + +export default S3Settings diff --git a/src/pages/manage/settings/S3BucketItem.tsx b/src/pages/manage/settings/S3BucketItem.tsx new file mode 100644 index 000000000..e77828140 --- /dev/null +++ b/src/pages/manage/settings/S3BucketItem.tsx @@ -0,0 +1,67 @@ +import { Button, FormControl, FormLabel, Input, Stack } from "@hope-ui/solid" +import { FolderChooseInput } from "~/components" +import { useT } from "~/hooks" + +export type S3Bucket = { + name: string + path: string +} + +type props = S3Bucket & { + onChange: (val: S3Bucket) => void + onDelete: () => void +} + +export const S3BucketItem = (props: props) => { + const t = useT() + return ( + + + + {t(`global.name`)} + + + props.onChange({ ...props, name: e.currentTarget.value }) + } + /> + + + + + {t(`metas.path`)} + + props.onChange({ ...props, path: e })} + /> + + + + + + + ) +} diff --git a/src/pages/manage/settings/S3Buckets.tsx b/src/pages/manage/settings/S3Buckets.tsx new file mode 100644 index 000000000..20229fa20 --- /dev/null +++ b/src/pages/manage/settings/S3Buckets.tsx @@ -0,0 +1,63 @@ +import { VStack, Button, FormLabel } from "@hope-ui/solid" +import { For } from "solid-js" +import { SetStoreFunction } from "solid-js/store" +import { SettingItem } from "~/types" +import { S3BucketItem, S3Bucket } from "./S3BucketItem" +import { useT } from "~/hooks" + +export type S3BucketsProps = { + buckets: S3Bucket[] + setSettings: SetStoreFunction +} + +const S3Buckets = (props: S3BucketsProps) => { + const t = useT() + console.log(props.buckets) + return ( + + + {t("settings.s3_buckets")} + + + + {(item) => ( + { + console.log(val) + props.setSettings( + (i) => i.key === "s3_buckets", + "value", + JSON.stringify( + props.buckets.map((b) => (b.name === item.name ? val : b)), + ), + ) + }} + onDelete={() => { + props.setSettings( + (i) => i.key === "s3_buckets", + "value", + JSON.stringify( + props.buckets.filter((b) => b.name !== item.name), + ), + ) + }} + /> + )} + + + ) +} + +export default S3Buckets diff --git a/src/pages/manage/sidemenu_items.tsx b/src/pages/manage/sidemenu_items.tsx index b7a2034b3..48f4092a4 100644 --- a/src/pages/manage/sidemenu_items.tsx +++ b/src/pages/manage/sidemenu_items.tsx @@ -11,6 +11,7 @@ import { BsFront, BsCloudUploadFill, BsSearch, + BsBucket, } from "solid-icons/bs" import { FiLogIn } from "solid-icons/fi" import { SiMetabase } from "solid-icons/si" @@ -77,6 +78,12 @@ export const side_menu_items: SideMenuItem[] = [ to: "/@manage/settings/ldap", component: () => , }, + { + title: "manage.sidemenu.s3", + icon: BsBucket, + to: "/@manage/settings/s3", + component: lazy(() => import("./settings/S3")), + }, { title: "manage.sidemenu.other", icon: BsMedium, diff --git a/src/types/setting.ts b/src/types/setting.ts index 7160e7d7b..f5acefa16 100644 --- a/src/types/setting.ts +++ b/src/types/setting.ts @@ -10,6 +10,7 @@ export enum Group { INDEX, SSO, LDAP, + S3, } export enum Flag { PUBLIC,