mirror of
https://github.com/mdnice/markdown-resume.git
synced 2025-10-15 23:16:37 +00:00
feat(保存和导入) 新增保存到本地和从本地导入功能
This commit is contained in:
17
.travis.yml
17
.travis.yml
@@ -1,17 +0,0 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '10'
|
||||
branchs:
|
||||
only:
|
||||
- master
|
||||
install:
|
||||
- yarn install
|
||||
script:
|
||||
- yarn build
|
||||
addons:
|
||||
ssh_known_hosts: 39.96.191.154
|
||||
before_install:
|
||||
- openssl aes-256-cbc -K $encrypted_e6c41ade86ae_key -iv $encrypted_e6c41ade86ae_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d
|
||||
after_success:
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- ssh travis@39.96.191.154 -o StrictHostKeyChecking=no 'cd ~/markdown-resume && git pull && yarn install && yarn build'
|
BIN
id_rsa.enc
BIN
id_rsa.enc
Binary file not shown.
@@ -34,6 +34,14 @@ class App extends Component {
|
||||
this.props.navbar.setBtnDisable(true);
|
||||
}
|
||||
};
|
||||
|
||||
window.onbeforeunload = e => {
|
||||
e = e || window.event;
|
||||
if (e) {
|
||||
e.returnValue = "数据目前存储在浏览器中,记得保存到本地备份!";
|
||||
}
|
||||
return "数据目前存储在浏览器中,记得保存到本地备份!";
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
|
165
src/components/Button/Export.js
Normal file
165
src/components/Button/Export.js
Normal file
@@ -0,0 +1,165 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { withStyles } from "@material-ui/core/styles";
|
||||
|
||||
import Menu from "@material-ui/core/Menu";
|
||||
import Button from "@material-ui/core/Button";
|
||||
import MenuItem from "@material-ui/core/MenuItem";
|
||||
import Tooltip from "@material-ui/core/Tooltip";
|
||||
|
||||
import corner from "../../icons/corner.svg";
|
||||
|
||||
import { ENTER_DELAY, LEAVE_DELAY, STORAGE_LAYOUT } from "../../utils/constant";
|
||||
import { downloadFile } from "../../utils/helper";
|
||||
|
||||
import { observer, inject } from "mobx-react";
|
||||
|
||||
@inject("navbar")
|
||||
@inject("dialog")
|
||||
@observer
|
||||
class Export extends Component {
|
||||
state = {
|
||||
exportAnchorEl: null
|
||||
};
|
||||
|
||||
openModeMenu = event => {
|
||||
event.stopPropagation();
|
||||
this.setState({ exportAnchorEl: event.currentTarget });
|
||||
};
|
||||
|
||||
closeModeMenu = event => {
|
||||
event.stopPropagation();
|
||||
this.setState({ exportAnchorEl: null });
|
||||
};
|
||||
|
||||
handleExport = event => {
|
||||
event.stopPropagation();
|
||||
this.props.navbar.setExported(true);
|
||||
this.setState({ exportAnchorEl: null });
|
||||
};
|
||||
|
||||
saveToLocal = event => {
|
||||
event.stopPropagation();
|
||||
const layout = window.localStorage.getItem(STORAGE_LAYOUT);
|
||||
const filename = `markdown-resume-${new Date().getTime()}.json`;
|
||||
downloadFile(filename, layout);
|
||||
this.setState({ exportAnchorEl: null });
|
||||
};
|
||||
|
||||
importFromLocal = event => {
|
||||
event.stopPropagation();
|
||||
const file = event.target.files[0];
|
||||
this.fileReader = new FileReader();
|
||||
this.fileReader.onloadend = this.handleFileRead;
|
||||
this.fileReader.readAsText(file);
|
||||
this.setState({ exportAnchorEl: null });
|
||||
};
|
||||
|
||||
handleFileRead = e => {
|
||||
const content = this.fileReader.result;
|
||||
window.localStorage.setItem(STORAGE_LAYOUT, content);
|
||||
window.location.href = "/";
|
||||
};
|
||||
|
||||
openHelpDialog = event => {
|
||||
event.stopPropagation();
|
||||
this.props.dialog.setHelpOpened(true);
|
||||
this.setState({ exportAnchorEl: null });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
const { exportAnchorEl } = this.state;
|
||||
const exportOpen = Boolean(exportAnchorEl);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tooltip
|
||||
title="导入导出"
|
||||
placement="bottom"
|
||||
enterDelay={ENTER_DELAY}
|
||||
leaveDelay={LEAVE_DELAY}
|
||||
disableFocusListener
|
||||
>
|
||||
<Button
|
||||
className={classes.btn}
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
onClick={this.openModeMenu}
|
||||
>
|
||||
导入导出
|
||||
<img src={corner} alt="logo" className={classes.corner} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
{/* 模板选择器菜单 */}
|
||||
<Menu
|
||||
id="template-menu"
|
||||
anchorEl={exportAnchorEl}
|
||||
open={exportOpen}
|
||||
onClose={this.closeModeMenu}
|
||||
classes={{
|
||||
paper: classes.menu
|
||||
}}
|
||||
>
|
||||
<MenuItem className={classes.menuItem} style={{ display: "none" }} />
|
||||
<MenuItem className={classes.menuItem} onClick={this.handleExport}>
|
||||
导出PDF
|
||||
</MenuItem>
|
||||
<MenuItem className={classes.menuItem} onClick={this.saveToLocal}>
|
||||
保存到本地
|
||||
</MenuItem>
|
||||
<label htmlFor="outlined-button-file">
|
||||
<MenuItem className={classes.menuItem}>
|
||||
<input
|
||||
accept="application/json"
|
||||
className={classes.input}
|
||||
id="outlined-button-file"
|
||||
type="file"
|
||||
onChange={this.importFromLocal}
|
||||
/>
|
||||
从本地导入
|
||||
</MenuItem>
|
||||
</label>
|
||||
<MenuItem className={classes.menuItem} onClick={this.openHelpDialog}>
|
||||
帮助
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = theme => ({
|
||||
btn: {
|
||||
padding: "0px 10px",
|
||||
height: "100%",
|
||||
width: "100px"
|
||||
},
|
||||
menu: {
|
||||
top: "40px !important"
|
||||
},
|
||||
menuItem: {
|
||||
fontSize: "0.95em"
|
||||
},
|
||||
corner: {
|
||||
position: "absolute",
|
||||
bottom: 2,
|
||||
right: 2
|
||||
},
|
||||
input: {
|
||||
display: "none"
|
||||
},
|
||||
label: {
|
||||
width: "100%",
|
||||
height: "100%"
|
||||
}
|
||||
});
|
||||
|
||||
Export.propTypes = {
|
||||
classes: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default withStyles(styles)(Export);
|
@@ -61,9 +61,9 @@ class DialogHelp extends Component {
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
>
|
||||
<Tab label="注意" />
|
||||
<Tab label="使用规则" />
|
||||
<Tab label="Markdown语法" />
|
||||
<Tab label="细节" />
|
||||
</Tabs>
|
||||
{value === 0 && (
|
||||
<DialogContentText
|
||||
@@ -75,7 +75,11 @@ class DialogHelp extends Component {
|
||||
dangerouslySetInnerHTML={{ __html: this.md.render(HELP_INFO[1]) }}
|
||||
/>
|
||||
)}
|
||||
{value === 2 && <p>Item Three</p>}
|
||||
{value === 2 && (
|
||||
<DialogContentText
|
||||
dangerouslySetInnerHTML={{ __html: this.md.render(HELP_INFO[2]) }}
|
||||
/>
|
||||
)}
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={this.handleClose} color="primary">
|
||||
|
@@ -2,14 +2,15 @@ import React, { Component } from "react";
|
||||
|
||||
import PropTypes from "prop-types";
|
||||
import { withStyles } from "@material-ui/core/styles";
|
||||
import Button from "@material-ui/core/Button";
|
||||
// import Button from "@material-ui/core/Button";
|
||||
import List from "@material-ui/core/List";
|
||||
import ListItem from "@material-ui/core/ListItem";
|
||||
import Tooltip from "@material-ui/core/Tooltip";
|
||||
// import ListItem from "@material-ui/core/ListItem";
|
||||
// import Tooltip from "@material-ui/core/Tooltip";
|
||||
|
||||
import github from "../../icons/github.svg";
|
||||
// import github from "../../icons/github.svg";
|
||||
import Export from "../Button/Export"
|
||||
|
||||
import { ENTER_DELAY, LEAVE_DELAY } from "../../utils/constant";
|
||||
// import { ENTER_DELAY, LEAVE_DELAY } from "../../utils/constant";
|
||||
|
||||
import { observer, inject } from "mobx-react";
|
||||
|
||||
@@ -17,29 +18,25 @@ import { observer, inject } from "mobx-react";
|
||||
@inject("navbar")
|
||||
@observer
|
||||
class ListStorage extends Component {
|
||||
handleSave = () => {};
|
||||
|
||||
handleExport = () => {
|
||||
this.props.navbar.setExported(true);
|
||||
this.setState({ anchorEl: null });
|
||||
};
|
||||
// handleSave = () => {};
|
||||
|
||||
render() {
|
||||
const { classes } = this.props;
|
||||
|
||||
return (
|
||||
<List className={classes.list}>
|
||||
<ListItem
|
||||
{/* <ListItem
|
||||
className={classes.listExport}
|
||||
button
|
||||
onClick={this.handleExport}
|
||||
>
|
||||
<Button variant="outlined" color="primary" className={classes.btn}>
|
||||
> */}
|
||||
<Export/>
|
||||
{/* <Button variant="outlined" color="primary" className={classes.btn}>
|
||||
导出PDF
|
||||
</Button>
|
||||
</ListItem>
|
||||
</Button> */}
|
||||
{/* </ListItem> */}
|
||||
|
||||
<Tooltip
|
||||
{/* <Tooltip
|
||||
title="登录"
|
||||
placement="bottom"
|
||||
enterDelay={ENTER_DELAY}
|
||||
@@ -53,7 +50,7 @@ class ListStorage extends Component {
|
||||
>
|
||||
<img src={github} alt="logo" />
|
||||
</ListItem>
|
||||
</Tooltip>
|
||||
</Tooltip> */}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
|
@@ -77,6 +77,10 @@ export const HELP_MARKDOWN = `
|
||||
\`\`\`
|
||||
`;
|
||||
|
||||
export const HELP_INFO = [HELP_USE, HELP_MARKDOWN];
|
||||
export const HELP_NOTICE = `
|
||||
### 简历数据目前自动保存在浏览器中,如果清理浏览器将会丢失!
|
||||
### 记得编辑后保存到本地备份!
|
||||
`
|
||||
export const HELP_INFO = [HELP_NOTICE, HELP_USE, HELP_MARKDOWN];
|
||||
|
||||
export const THEMES = [THEME0, THEME1, THEME2, THEME3, THEME4];
|
||||
|
@@ -224,3 +224,17 @@ const solveLine = value => {
|
||||
}
|
||||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* 创建并下载文件
|
||||
* @param {String} fileName 文件名
|
||||
* @param {String} content 文件内容
|
||||
*/
|
||||
export const downloadFile = (fileName, content) => {
|
||||
var aTag = document.createElement('a');
|
||||
var blob = new Blob([content]);
|
||||
aTag.download = fileName;
|
||||
aTag.href = URL.createObjectURL(blob);
|
||||
aTag.click();
|
||||
URL.revokeObjectURL(blob);
|
||||
}
|
Reference in New Issue
Block a user