11import { t } from "@app/locale"
22import { Download , Refresh , Upload } from "@element-plus/icons-vue"
3- import { ElIcon , ElMessage , ElMessageBox , ElTabPane , ElTabs , TabPaneName } from "element-plus"
3+ import Flex from "@pages/components/Flex"
4+ import { ElLink , ElMessage , ElMessageBox , ElTabPane , ElTabs , ElTooltip , TabPaneName } from "element-plus"
45import { defineComponent , h , ref , useSlots } from "vue"
56import { useRouter } from "vue-router"
67import ContentContainer from "../common/ContentContainer"
78import { CATE_LABELS , changeQuery , type OptionCategory , parseQuery } from "./common"
8- import { exportSettings , importSettings , createFileInput } from "./export-import"
9+ import { createFileInput , exportSettings , importSettings } from "./export-import"
910
10- const resetButtonName = "reset"
11- const exportButtonName = "export"
12- const importButtonName = "import"
11+ const TOOLBAR_NAME = "toolbar"
1312
14- const _default = defineComponent ( {
15- emits : {
16- reset : ( _cate : OptionCategory , _callback : ( ) => void ) => Promise . resolve ( true ) ,
17- } ,
18- setup : ( _ , ctx ) => {
19- const tab = ref ( parseQuery ( ) || 'appearance' )
20- const router = useRouter ( )
13+ type TooltipProps = {
14+ onReset ?: NoArgCallback
15+ }
2116
22- const handleBeforeLeave = async ( activeName : TabPaneName , oldActiveName : TabPaneName ) : Promise < boolean > => {
23- if ( activeName === resetButtonName ) {
24- const cate : OptionCategory = oldActiveName as OptionCategory
25- await new Promise < void > ( res => ctx . emit ( 'reset' , cate , res ) )
26- ElMessage . success ( t ( msg => msg . option . resetSuccess ) )
27- return Promise . reject ( )
28- } else if ( activeName === exportButtonName ) {
29- try {
30- await exportSettings ( )
31- ElMessage . success ( t ( msg => msg . option . exportSuccess ) )
32- } catch ( error ) {
33- ElMessage . error ( 'Export failed: ' + ( error as Error ) . message )
34- }
35- return Promise . reject ( )
36- } else if ( activeName === importButtonName ) {
37- try {
38- const fileContent = await createFileInput ( )
39- if ( fileContent === null ) {
40- // User cancelled file selection, don't show any message
41- return Promise . reject ( )
42- }
17+ const Toolbar = defineComponent < TooltipProps > ( props => {
18+ const handleExport = async ( ) => {
19+ try {
20+ await exportSettings ( )
21+ ElMessage . success ( t ( msg => msg . option . exportSuccess ) )
22+ } catch ( error ) {
23+ ElMessage . error ( 'Export failed: ' + ( error as Error ) . message )
24+ }
25+ }
26+
27+ const handleImport = async ( ) => {
28+ try {
29+ const fileContent = await createFileInput ( )
30+ // User cancelled, don't show error message
31+ if ( ! fileContent ) return
32+ await importSettings ( fileContent )
33+ ElMessageBox ( {
34+ message : t ( msg => msg . option . importConfirm ) ,
35+ type : "success" ,
36+ confirmButtonText : t ( msg => msg . option . reloadButton ) ,
37+ closeOnPressEscape : false ,
38+ closeOnClickModal : false
39+ } ) . then ( ( ) => {
40+ window . location . reload ( )
41+ } ) . catch ( ( ) => { /* do nothing */ } )
42+ } catch ( error ) {
43+ ElMessage . error ( t ( msg => msg . option . importError ) )
44+ }
45+ }
46+
47+ return ( ) => (
48+ < Flex align = "center" gap = { 10 } onClick = { ev => ev . stopPropagation ( ) } >
49+ < ElTooltip content = { t ( msg => msg . option . exportButton ) } >
50+ < ElLink
51+ icon = { Download }
52+ underline = "never"
53+ onClick = { handleExport }
54+ />
55+ </ ElTooltip >
56+ < ElTooltip content = { t ( msg => msg . option . importButton ) } >
57+ < ElLink
58+ icon = { Upload }
59+ underline = "never"
60+ onClick = { handleImport }
61+ />
62+ </ ElTooltip >
63+ < ElLink
64+ icon = { Refresh }
65+ underline = "never"
66+ onClick = { ( ) => props . onReset ?.( ) }
67+ >
68+ { t ( msg => msg . option . resetButton ) }
69+ </ ElLink >
70+ </ Flex >
71+ )
72+ } , {
73+ props : [ 'onReset' ]
74+ } )
4375
44- await importSettings ( fileContent )
45- ElMessageBox ( {
46- message : t ( msg => msg . option . importConfirm ) ,
47- type : "success" ,
48- confirmButtonText : t ( msg => msg . option . reloadButton ) ,
49- closeOnPressEscape : false ,
50- closeOnClickModal : false
51- } ) . then ( ( ) => {
52- window . location . reload ( )
53- } ) . catch ( ( ) => { /* do nothing */ } )
54- } catch ( error ) {
55- ElMessage . error ( t ( msg => msg . option . importError ) )
56- }
76+ type Props = { onReset : ( cate : OptionCategory ) => Promise < void > | void }
77+
78+ const _default = defineComponent < Props > (
79+ props => {
80+ const tab = ref ( parseQuery ( ) ?? 'appearance' )
81+ const router = useRouter ( )
82+ const handleReset = ( ) => props . onReset ?.( tab . value )
83+
84+ const handleBeforeLeave = ( activeName : TabPaneName ) : Promise < boolean > => {
85+ if ( activeName === TOOLBAR_NAME ) {
86+ // do nothing, and never happen
5787 return Promise . reject ( )
5888 }
5989 // Change the query of current route
6090 changeQuery ( activeName as OptionCategory , router )
61- return true
91+ return Promise . resolve ( true )
6292 }
6393 return ( ) => (
6494 < ContentContainer >
@@ -74,46 +104,12 @@ const _default = defineComponent({
74104 </ ElTabPane >
75105 ) ) }
76106 < ElTabPane
77- name = { resetButtonName }
78- v-slots = { {
79- label : ( ) => (
80- < div >
81- < ElIcon >
82- < Refresh />
83- </ ElIcon >
84- { t ( msg => msg . option . resetButton ) }
85- </ div >
86- )
87- } }
88- />
89- < ElTabPane
90- name = { exportButtonName }
91- v-slots = { {
92- label : ( ) => (
93- < div title = { t ( msg => msg . option . exportButton ) } >
94- < ElIcon >
95- < Download />
96- </ ElIcon >
97- </ div >
98- )
99- } }
100- />
101- < ElTabPane
102- name = { importButtonName }
103- v-slots = { {
104- label : ( ) => (
105- < div title = { t ( msg => msg . option . importButton ) } >
106- < ElIcon >
107- < Upload />
108- </ ElIcon >
109- </ div >
110- )
111- } }
107+ name = { TOOLBAR_NAME }
108+ v-slots = { { label : ( ) => < Toolbar onReset = { handleReset } /> } }
112109 />
113110 </ ElTabs >
114111 </ ContentContainer >
115112 )
116- }
117- } )
113+ } , { props : [ 'onReset' ] } )
118114
119115export default _default
0 commit comments