PluginProbe
Code Snippets / 3.10.1
Code Snippets v3.10.1
3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 3.0.1 All 64 releases
code-snippets / js / components / Import / FromFileUpload / FileUploadForm.tsx

FileUploadForm.tsx in Code Snippets 3.10.1, at js/components/Import/FromFileUpload/FileUploadForm.tsx

202 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { useState, useRef, useEffect } from 'react'
2 import { __ } from '@wordpress/i18n'
3 import { Button } from '../../common/Button'
4 import {
5 DuplicateActionSelector,
6 DragDropUploadArea,
7 SelectedFilesList,
8 SnippetSelectionTable,
9 ImportResultDisplay
10 } from './components'
11 import { ImportCard } from '../shared'
12 import {
13 useFileSelection,
14 useSnippetSelection,
15 useImportWorkflow
16 } from './hooks'
17
18 type DuplicateAction = 'ignore' | 'replace' | 'skip'
19 type Step = 'upload' | 'select'
20
21 export const FileUploadForm: React.FC = () => {
22 const [duplicateAction, setDuplicateAction] = useState<DuplicateAction>('ignore')
23 const [currentStep, setCurrentStep] = useState<Step>('upload')
24 const selectSectionRef = useRef<HTMLDivElement>(null)
25
26 const fileSelection = useFileSelection()
27 const importWorkflow = useImportWorkflow()
28 const snippetSelection = useSnippetSelection(importWorkflow.availableSnippets)
29
30 useEffect(() => {
31 if (currentStep === 'select' && selectSectionRef.current) {
32 selectSectionRef.current.scrollIntoView({
33 behavior: 'smooth',
34 block: 'start'
35 })
36 }
37 }, [currentStep])
38
39 const handleFileSelect = (files: FileList | null) => {
40 fileSelection.handleFileSelect(files)
41 importWorkflow.clearUploadResult()
42 }
43
44 const handleParseFiles = async () => {
45 if (!fileSelection.selectedFiles) return
46
47 const success = await importWorkflow.parseFiles(fileSelection.selectedFiles)
48 if (success) {
49 snippetSelection.clearSelection()
50 setCurrentStep('select')
51 }
52 }
53
54 const handleImportSelected = async () => {
55 const snippetsToImport = snippetSelection.getSelectedSnippets()
56 await importWorkflow.importSnippets(snippetsToImport, duplicateAction)
57 }
58
59 const handleBackToUpload = () => {
60 setCurrentStep('upload')
61 fileSelection.clearFiles()
62 snippetSelection.clearSelection()
63 importWorkflow.resetWorkflow()
64 }
65
66 const isUploadDisabled = !fileSelection.selectedFiles ||
67 fileSelection.selectedFiles.length === 0 ||
68 importWorkflow.isUploading
69
70 const isImportDisabled = snippetSelection.selectedSnippets.size === 0 ||
71 importWorkflow.isImporting
72
73 return (
74 <div className="wrap">
75 <div className="import-form-container" style={{ maxWidth: '800px' }}>
76 <p>{__('Upload one or more Code Snippets export files and the snippets will be imported.', 'code-snippets')}</p>
77
78 <p>
79 {__('Afterward, you will need to visit the ', 'code-snippets')}
80 <a href="admin.php?page=snippets">
81 {__('All Snippets', 'code-snippets')}
82 </a>
83 {__(' page to activate the imported snippets.', 'code-snippets')}
84 </p>
85
86 {currentStep === 'upload' && (
87 <>
88
89 {(!importWorkflow.uploadResult || !importWorkflow.uploadResult.success) && (
90 <>
91 <DuplicateActionSelector
92 value={duplicateAction}
93 onChange={setDuplicateAction}
94 />
95
96 <ImportCard>
97 <h2 style={{ margin: '0 0 1em 0' }}>{__('Choose Files', 'code-snippets')}</h2>
98 <p className="description" style={{ marginBottom: '1em' }}>
99 {__('Choose one or more Code Snippets (.xml or .json) files to parse and preview.', 'code-snippets')}
100 </p>
101
102 <DragDropUploadArea
103 fileInputRef={fileSelection.fileInputRef}
104 onFileSelect={handleFileSelect}
105 disabled={importWorkflow.isUploading}
106 />
107
108 {fileSelection.selectedFiles && fileSelection.selectedFiles.length > 0 && (
109 <SelectedFilesList
110 files={fileSelection.selectedFiles}
111 onRemoveFile={fileSelection.removeFile}
112 />
113 )}
114
115 <div style={{ textAlign: 'center' }}>
116 <Button
117 primary
118 onClick={handleParseFiles}
119 disabled={isUploadDisabled}
120 style={{ minWidth: '200px' }}
121 >
122 {importWorkflow.isUploading
123 ? __('Uploading files...', 'code-snippets')
124 : __('Upload files', 'code-snippets')
125 }
126 </Button>
127 </div>
128 </ImportCard>
129 </>
130 )}
131 </>
132 )}
133
134 {currentStep === 'select' && importWorkflow.availableSnippets.length > 0 && !importWorkflow.uploadResult?.success && (
135 <ImportCard ref={selectSectionRef}>
136 <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '20px' }}>
137 <Button onClick={handleBackToUpload} className="button-link">
138 {__('← Upload Different Files', 'code-snippets')}
139 </Button>
140 </div>
141 <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '10px' }}>
142 <div>
143 <h3 style={{ margin: '0' }}>{__('Available Snippets', 'code-snippets')} ({importWorkflow.availableSnippets.length})</h3>
144 <p style={{ margin: '0.5em 0 1em 0', color: '#666' }}>
145 {__('Select the snippets you want to import:', 'code-snippets')}
146 </p>
147 </div>
148 <div>
149 <Button onClick={snippetSelection.handleSelectAll} style={{ marginRight: '10px' }}>
150 {snippetSelection.isAllSelected
151 ? __('Deselect All', 'code-snippets')
152 : __('Select All', 'code-snippets')
153 }
154 </Button>
155 <Button
156 primary
157 onClick={handleImportSelected}
158 disabled={isImportDisabled}
159 >
160 {importWorkflow.isImporting
161 ? __('Importing...', 'code-snippets')
162 : __('Import Selected', 'code-snippets')} ({snippetSelection.selectedSnippets.size})
163 </Button>
164 </div>
165 </div>
166
167 <SnippetSelectionTable
168 snippets={importWorkflow.availableSnippets}
169 selectedSnippets={snippetSelection.selectedSnippets}
170 isAllSelected={snippetSelection.isAllSelected}
171 onSnippetToggle={snippetSelection.handleSnippetToggle}
172 onSelectAll={snippetSelection.handleSelectAll}
173 />
174
175 <div style={{ textAlign: 'end', marginTop: '1em' }}>
176 <Button onClick={snippetSelection.handleSelectAll} style={{ marginRight: '10px' }}>
177 {snippetSelection.isAllSelected
178 ? __('Deselect All', 'code-snippets')
179 : __('Select All', 'code-snippets')
180 }
181 </Button>
182 <Button
183 primary
184 onClick={handleImportSelected}
185 disabled={isImportDisabled}
186 >
187 {importWorkflow.isImporting
188 ? __('Importing...', 'code-snippets')
189 : __('Import Selected', 'code-snippets')} ({snippetSelection.selectedSnippets.size})
190 </Button>
191 </div>
192 </ImportCard>
193 )}
194
195 {importWorkflow.uploadResult && (
196 <ImportResultDisplay result={importWorkflow.uploadResult} />
197 )}
198 </div>
199 </div>
200 )
201 }
202