Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web): add file upload code template #844

Merged
merged 3 commits into from
Mar 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion web/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -262,5 +262,6 @@
"Back": "Return",
"Personal Access Token": "Personal Access Token",
"SwitchLanguage": "Switch Language",
"Storage": "Storage"
"Storage": "Storage",
"upload example": "file upload"
}
11 changes: 6 additions & 5 deletions web/public/locales/zh-CN/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@
"Storage": "存储",
"StorageList": "云存储列表",
"Policy": "权限",
"Private": "私有",
"Readonly": "公共读",
"ReadWrite": "公共读写",
"Private": "私有 (private)",
"Readonly": "公共读 (readonly)",
"ReadWrite": "公共读写 (readwrite)",
"Upload": "上传",
"Drag": "拖放到此处或者",
"File": "文件",
Expand Down Expand Up @@ -262,5 +262,6 @@
"Back": "返回",
"Personal Access Token": "访问凭证 (PAT)",
"SwitchLanguage": "切换语言",
"Storage": "云存储"
}
"Storage": "云存储",
"upload example": "文件上传示例"
}
11 changes: 6 additions & 5 deletions web/public/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@
"FolderName": "文件夹名称",
"NameTip": "请输入文件夹名称",
"Policy": "权限",
"Private": "私有",
"Readonly": "公共读",
"ReadWrite": "公共读写",
"Private": "私有 (private)",
"Readonly": "公共读 (readonly)",
"ReadWrite": "公共读写 (readwrite)",
"SearchBucket": "输入 bucket 名进行搜索",
"Size": "大小",
"Storage": "存储",
Expand Down Expand Up @@ -262,5 +262,6 @@
"Back": "返回",
"Personal Access Token": "访问凭证 (PAT)",
"SwitchLanguage": "切换语言",
"Storage": "云存储"
}
"Storage": "云存储",
"upload example": "文件上传示例"
}
38 changes: 19 additions & 19 deletions web/src/components/FileUpload/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import React, { useEffect } from "react";
import React from "react";
import { useTranslation } from "react-i18next";
import clsx from "clsx";

import styles from "./index.module.scss";

type UploadType = "file" | "folder";

// drag drop file component
function FileUpload(props: { onUpload: (files: any) => void; uploadType: "file" | "folder" }) {
const { onUpload = () => {}, uploadType } = props;
function FileUpload(props: { onUpload: (files: any) => void }) {
const { onUpload = () => {} } = props;
// drag state
const [dragActive, setDragActive] = React.useState(false);
// ref
const inputRef = React.useRef<any>(null);
const { t } = useTranslation();
useEffect(() => {
if (uploadType === "folder") {
inputRef.current.setAttribute("webkitdirectory", "");
inputRef.current.setAttribute("directory", "");
} else {
inputRef.current.removeAttribute("webkitdirectory");
inputRef.current.removeAttribute("directory");
}
}, [uploadType]);

// handle drag events
const handleDrag = function (e: any) {
Expand Down Expand Up @@ -53,7 +46,14 @@ function FileUpload(props: { onUpload: (files: any) => void; uploadType: "file"
};

// triggers the input when the button is clicked
const onButtonClick = () => {
const onButtonClick = (uploadType: UploadType) => {
if (uploadType === "folder") {
inputRef.current.setAttribute("webkitdirectory", "");
inputRef.current.setAttribute("directory", "");
} else {
inputRef.current.removeAttribute("webkitdirectory");
inputRef.current.removeAttribute("directory");
}
inputRef?.current?.click();
};

Expand All @@ -78,12 +78,12 @@ function FileUpload(props: { onUpload: (files: any) => void; uploadType: "file"
htmlFor="input-file-upload"
>
<div>
<p>
{uploadType === "file" ? t("StoragePanel.File") : t("StoragePanel.Folder")}
{t("StoragePanel.Drag")}
</p>
<button className={styles.uploadButton} onClick={onButtonClick}>
{uploadType === "file" ? t("StoragePanel.UploadFile") : t("StoragePanel.UploadFolder")}
<button className={styles.uploadButton} onClick={() => onButtonClick("file")}>
{t("StoragePanel.UploadFile")}
</button>
<span className="mx-2 text-xl">或</span>
<button className={styles.uploadButton} onClick={() => onButtonClick("folder")}>
{t("StoragePanel.UploadFolder")}
</button>
</div>
</label>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/Pagination/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function Pagination(props: {

return (
<HStack alignItems="center" spacing={"1"} display="flex" whiteSpace={"nowrap"}>
<Text as="div" className="text-lg mr-2">
<Text as="div" className="mr-2">
{t("Total")}: {total}
</Text>
<IconWrap showBg tooltip="First Page" size={18}>
Expand Down
1 change: 1 addition & 0 deletions web/src/layouts/Header/UserSetting/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default function UserSetting(props: { name: string; avatar?: string; widt
<Avatar
size="sm"
name={props.name}
src={props.avatar}
bgColor="primary.500"
color="white"
boxShadow="base"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export default function DataPanel() {

return (
<>
<Panel.Header className="w-full h-[60px] flex-shrink-0">
<Panel.Header className="w-full h-[40px] flex-shrink-0">
<div className="flex items-center">
<AddDataModal
schema={currentData.data ? currentData.data : {}}
Expand All @@ -153,20 +153,21 @@ export default function DataPanel() {
}}
>
<Button
size="xs"
variant="textGhost"
leftIcon={<AddIcon fontSize={10} className="text-grayModern-500" />}
disabled={store.currentDB === undefined}
colorScheme="primary"
className="mr-2"
style={{ width: "114px" }}
leftIcon={<AddIcon />}
className="mr-2 font-bold"
>
{t("CollectionPanel.AddData")}
</Button>
</AddDataModal>

<Button
size="xs"
variant="textGhost"
disabled={store.currentDB === undefined}
colorScheme="primary"
className="mr-2"
style={{ width: "114px" }}
isLoading={entryDataQuery.isFetching}
leftIcon={<BiRefresh fontSize={20} />}
onClick={() => refresh(search)}
Expand Down
5 changes: 4 additions & 1 deletion web/src/pages/app/functions/mods/DeployButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ export default function DeployButton() {

return (
<>
<Tooltip label={`快捷键: ${displayName.toUpperCase()},调试可直接点击右侧「运行」按扭`}>
<Tooltip
label={`快捷键: ${displayName.toUpperCase()},调试可直接点击右侧「运行」按扭`}
placement="bottom-end"
>
<Button
variant={"text"}
isLoading={functionDetailQuery.isFetching}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@ export async function main(ctx: FunctionContext) {
}
`,
},
{
label: t("upload example"),
value: `import cloud from '@lafjs/cloud'
import { PutObjectCommand, S3 } from "@aws-sdk/client-s3";

exports.main = async function (ctx: FunctionContext) {
const { auth, body, query } = ctx
const ENDPOINT = cloud.env.OSS_EXTERNAL_ENDPOINT;
const BUCKET = ""; // Create your bucket first

const s3Client = new S3({
region: cloud.env.OSS_REGION,
endpoint: ENDPOINT,
credentials: {
accessKeyId: cloud.env.OSS_ACCESS_KEY,
secretAccessKey: cloud.env.OSS_ACCESS_SECRET,
},
forcePathStyle: true,
});

const file = ctx.files[0]
console.log(file)
const stream = require('fs').createReadStream(file.path)
const cmd = new PutObjectCommand({
Bucket: BUCKET,
Key: ctx.files[0].filename,
Body: stream,
ContentType: file.mimetype,
})
try {
const data = await s3Client.send(cmd);
return {
success: true,
fileName: ctx.files[0].filename,
}
} catch (err) {
return { code: 500, err: err }
}
}
`,
},
];

export default functionTemplates;
1 change: 1 addition & 0 deletions web/src/pages/app/setting/UserInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default function UserInfo() {
<Avatar
size="lg"
name={userInfo?.username}
src={userInfo?.profile.avatar}
bgColor="primary.500"
color="white"
boxShadow="base"
Expand Down
16 changes: 6 additions & 10 deletions web/src/pages/app/storages/mods/FileList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
Button,
Center,
HStack,
MenuButton,
Spinner,
Table,
TableContainer,
Expand Down Expand Up @@ -76,15 +75,14 @@ export default function FileList() {
<Panel.Header>
<HStack spacing={2}>
<UploadButton onUploadSuccess={() => query.refetch()}>
<MenuButton
<Button
size="sm"
variant="textGhost"
as={Button}
leftIcon={<BiCloudUpload fontSize={22} className="text-grayModern-500" />}
disabled={currentStorage === undefined}
>
<p className="font-semibold">{t("StoragePanel.Upload")}</p>
</MenuButton>
</Button>
</UploadButton>
<CreateFolderModal onCreateSuccess={() => query.refetch()} />
<Button
Expand Down Expand Up @@ -121,13 +119,11 @@ export default function FileList() {
(query.data.length === 1 && query.data[0].Key === prefix) ? (
<EmptyBox>
<UploadButton onUploadSuccess={() => query.refetch()}>
<div>
<div className="text-lg">
<span>{t("StoragePanel.UploadTip")}</span>
<MenuButton disabled={currentStorage === undefined}>
<span className="ml-2 text-primary-600 hover:border-b-2 hover:border-primary-600 cursor-pointer">
{t("StoragePanel.InstantUpload")}
</span>
</MenuButton>
<span className="ml-2 text-primary-600 hover:border-b-2 hover:border-primary-600 cursor-pointer">
{t("StoragePanel.InstantUpload")}
</span>
</div>
</UploadButton>
</EmptyBox>
Expand Down
38 changes: 7 additions & 31 deletions web/src/pages/app/storages/mods/UploadButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import React from "react";
import { useTranslation } from "react-i18next";
import { CheckCircleIcon } from "@chakra-ui/icons";
import {
Menu,
MenuItem,
MenuList,
Modal,
ModalCloseButton,
ModalContent,
Expand All @@ -29,46 +26,25 @@ function UploadButton(props: { onUploadSuccess: Function; children: React.ReactE
const { currentStorage, prefix } = useStorageStore();
const { showSuccess } = useGlobalStore();
const { uploadFile } = useAwsS3();
const [uploadType, setUploadType] = React.useState<"file" | "folder">("file");
const [fileList, setFileList] = React.useState<TFileItem[]>([]);
const { t } = useTranslation();
const { onUploadSuccess, children } = props;
return (
<div>
<Menu placement="bottom-start">
{React.cloneElement(children)}
<MenuList minW={24}>
<MenuItem
onClick={() => {
setUploadType("file");
setFileList([]);
onOpen();
}}
>
{t("StoragePanel.File")}
</MenuItem>
<MenuItem
onClick={() => {
setUploadType("folder");
setFileList([]);
onOpen();
}}
>
{t("StoragePanel.Folder")}
</MenuItem>
</MenuList>
</Menu>
{React.cloneElement(children, {
onClick: () => {
setFileList([]);
onOpen();
},
})}

<Modal isOpen={isOpen} onClose={onClose} size="lg">
<ModalOverlay />
<ModalContent>
<ModalHeader>
{uploadType === "file" ? t("StoragePanel.UploadFile") : t("StoragePanel.UploadFolder")}
</ModalHeader>
<ModalHeader>{t("StoragePanel.UploadFile")}</ModalHeader>
<ModalCloseButton />
<div className="p-6">
<FileUpload
uploadType={uploadType}
onUpload={async (files) => {
console.log(files);
const newFileList = Array.from(files).map((item: any) => {
Expand Down