Yuki Takei 6 лет назад
Родитель
Сommit
f6e36fd1fa

+ 25 - 17
src/client/js/components/Admin/ImportData/GrowiZipImportForm.jsx

@@ -8,7 +8,9 @@ import AppContainer from '../../../services/AppContainer';
 import WebsocketContainer from '../../../services/WebsocketContainer';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 
-import GrowiZipImportItem from './GrowiZipImportItem';
+import GrowiZipImportOption from '../../../models/GrowiZipImportOption';
+
+import GrowiZipImportItem, { DEFAULT_MODE } from './GrowiZipImportItem';
 
 
 const GROUPS_PAGE = [
@@ -35,11 +37,7 @@ class GrowiImportForm extends React.Component {
 
       collectionNameToFileNameMap: {},
       selectedCollections: new Set(),
-      schema: {
-        pages: {},
-        revisions: {},
-        // ...
-      },
+      optionMap: {},
 
       canImport: false,
       errorsForPageGroups: [],
@@ -51,6 +49,7 @@ class GrowiImportForm extends React.Component {
     this.props.innerFileStats.forEach((fileStat) => {
       const { fileName, collectionName } = fileStat;
       this.initialState.collectionNameToFileNameMap[collectionName] = fileName;
+      this.initialState.optionMap[collectionName] = new GrowiZipImportOption(DEFAULT_MODE);
     });
 
     this.state = this.initialState;
@@ -58,6 +57,7 @@ class GrowiImportForm extends React.Component {
     this.toggleCheckbox = this.toggleCheckbox.bind(this);
     this.checkAll = this.checkAll.bind(this);
     this.uncheckAll = this.uncheckAll.bind(this);
+    this.updateOption = this.updateOption.bind(this);
     this.validate = this.validate.bind(this);
     this.import = this.import.bind(this);
   }
@@ -97,16 +97,15 @@ class GrowiImportForm extends React.Component {
   }
 
   async toggleCheckbox(collectionName, bool) {
-    await this.setState((prevState) => {
-      const selectedCollections = new Set(prevState.selectedCollections);
-      if (bool) {
-        selectedCollections.add(collectionName);
-      }
-      else {
-        selectedCollections.delete(collectionName);
-      }
-      return { selectedCollections };
-    });
+    const selectedCollections = new Set(this.state.selectedCollections);
+    if (bool) {
+      selectedCollections.add(collectionName);
+    }
+    else {
+      selectedCollections.delete(collectionName);
+    }
+
+    await this.setState({ selectedCollections });
 
     this.validate();
   }
@@ -121,6 +120,12 @@ class GrowiImportForm extends React.Component {
     this.validate();
   }
 
+  updateOption(collectionName, option) {
+    const newOptionMap = { ...this.state.optionMap };
+    newOptionMap[collectionName] = option;
+    this.setState({ optionMap: newOptionMap });
+  }
+
   async validate() {
     // init errors
     await this.setState({
@@ -308,6 +313,7 @@ class GrowiImportForm extends React.Component {
 
   renderCheckboxes(collectionNames, color) {
     const checkboxColor = color ? `checkbox-${color}` : 'checkbox-info';
+    const { selectedCollections, optionMap } = this.state;
 
     return (
       <div className={`row checkbox ${checkboxColor}`}>
@@ -316,8 +322,10 @@ class GrowiImportForm extends React.Component {
             <div className="col-xs-6 my-1" key={collectionName}>
               <GrowiZipImportItem
                 collectionName={collectionName}
-                isSelected={this.state.selectedCollections.has(collectionName)}
+                isSelected={selectedCollections.has(collectionName)}
+                option={optionMap[collectionName]}
                 onChange={this.toggleCheckbox}
+                onOptionChange={this.updateOption}
               />
             </div>
           );

+ 45 - 15
src/client/js/components/Admin/ImportData/GrowiZipImportItem.jsx

@@ -6,12 +6,26 @@ import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 
 
-export default class GrowiZipImportItem extends React.PureComponent {
+import GrowiZipImportOption from '../../../models/GrowiZipImportOption';
+
+
+export const DEFAULT_MODE = 'insert';
+
+export default class GrowiZipImportItem extends React.Component {
 
   constructor(props) {
     super(props);
 
     this.changeHandler = this.changeHandler.bind(this);
+    this.modeSelectedHandler = this.modeSelectedHandler.bind(this);
+  }
+
+  get currentModeLabel() {
+    const { option } = this.props;
+    const { mode } = option;
+
+    // convert 'insert' -> 'Insert'
+    return mode.substring(0, 1).toUpperCase() + mode.substring(1);
   }
 
   changeHandler(e) {
@@ -22,13 +36,26 @@ export default class GrowiZipImportItem extends React.PureComponent {
     }
   }
 
+  modeSelectedHandler(mode) {
+    const { collectionName, onOptionChange } = this.props;
+
+    if (onOptionChange == null) {
+      return;
+    }
+
+    const { option } = this.props;
+    option.mode = mode;
+
+    onOptionChange(collectionName, option);
+  }
+
   renderControls() {
     const {
       collectionName, isSelected,
     } = this.props;
 
     return (
-      <div className="d-flex justify-content-between">
+      <div className="d-flex justify-content-between align-items-center">
         {/* left */}
         <div>
           <input
@@ -45,19 +72,20 @@ export default class GrowiZipImportItem extends React.PureComponent {
           </label>
         </div>
         {/* right */}
-        <div className="dropdown">
-          <button className="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
-            Dropdown
-            <span className="caret"></span>
-          </button>
-          <ul className="dropdown-menu" aria-labelledby="dropdownMenu1">
-            <li><a href="#">Action</a></li>
-            <li><a href="#">Another action</a></li>
-            <li><a href="#">Something else here</a></li>
-            <li role="separator" className="divider"></li>
-            <li><a href="#">Separated link</a></li>
-          </ul>
-        </div>
+        <span className="d-inline-flex align-items-center">
+          Mode:
+          <div className="dropdown d-inline-block">
+            <button className="btn btn-default btn-xs dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
+              {this.currentModeLabel}
+              <span className="caret ml-2"></span>
+            </button>
+            <ul className="dropdown-menu" aria-labelledby="dropdownMenu1">
+              <li><a href="#" onClick={() => this.modeSelectedHandler('insert')}>Insert</a></li>
+              <li><a href="#" onClick={() => this.modeSelectedHandler('upsert')}>Upsert</a></li>
+              <li><a href="#" onClick={() => this.modeSelectedHandler('flushAndInsert')}>Flush and Insert</a></li>
+            </ul>
+          </div>
+        </span>
       </div>
     );
   }
@@ -88,6 +116,8 @@ export default class GrowiZipImportItem extends React.PureComponent {
 GrowiZipImportItem.propTypes = {
   collectionName: PropTypes.string.isRequired,
   isSelected: PropTypes.bool.isRequired,
+  option: PropTypes.instanceOf(GrowiZipImportOption).isRequired,
 
   onChange: PropTypes.func,
+  onOptionChange: PropTypes.func,
 };

+ 8 - 0
src/client/js/models/GrowiZipImportOption.js

@@ -0,0 +1,8 @@
+export default class ImportOption {
+
+  constructor(mode, schema = {}) {
+    this.mode = mode;
+    this.schema = schema;
+  }
+
+}