add Bootstrap working example
• re-organize file structure with one directory per dialog • add index.html file per dialog • add bootstrap styling and dynamic cdn loading • clean up react code and stylesheet npm setup script update adds force flag "setup": "rm -f .clasp.json ..." Update README.md Move clasp to devDependencies update dynamic cdn urls Add repository field
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
dist/main.js
|
main.js
|
||||||
@@ -19,7 +19,7 @@ _The included demo React app for Google Sheets shows insertion, deletion and sel
|
|||||||
> cd React-Google-Apps-Script
|
> cd React-Google-Apps-Script
|
||||||
> npm install
|
> npm install
|
||||||
```
|
```
|
||||||
2. Enable the Google Apps Script API for your account by visiting[(script.google.com/home/usersettings)](https://script.google.com/home/usersettings):
|
2. Enable the Google Apps Script API for your account by visiting [script.google.com/home/usersettings](https://script.google.com/home/usersettings):
|
||||||
|
|
||||||
<img width="215" height="82" src="https://i.imgur.com/vuwkzMU.png">
|
<img width="215" height="82" src="https://i.imgur.com/vuwkzMU.png">
|
||||||
|
|
||||||
@@ -68,12 +68,12 @@ Modify the server-side and client-side source code in the `src` folder. [Add any
|
|||||||
|
|
||||||
## The sample app
|
## The sample app
|
||||||
|
|
||||||
Insert/activate/delete sheets through a simple HTML dialog, built with React. Access the dialog through the new menu item that appears. You may need to refresh the spreadsheet and approve the app's permissions the first time you use it.
|
The included sample app allows inserting/activating/deleting sheets through a simple HTML dialog, built with React. Two versions of the same app are provided with different styling: the first version uses vanilla React, and the second uses the popular bootstrap library (in this case, it uses [`react-bootstrap`](https://react-bootstrap.github.io/)). Access the dialogs through the new menu item that appears. You may need to refresh the spreadsheet and approve the app's permissions the first time you use it.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Includes popular `eslint` and `prettier` configs for clean, standardized code.
|
- Includes popular `eslint` and `prettier` configs for clean, standardized code.
|
||||||
- `import` CSS from another file:
|
- Supports importing CSS from another file:
|
||||||
```js
|
```js
|
||||||
import './styles.css';
|
import './styles.css';
|
||||||
```
|
```
|
||||||
@@ -89,15 +89,14 @@ Insert/activate/delete sheets through a simple HTML dialog, built with React. Ac
|
|||||||
import server from '../server';
|
import server from '../server';
|
||||||
|
|
||||||
// We now have access to all our server functions, which return promises!
|
// We now have access to all our server functions, which return promises!
|
||||||
const { addSheet } = server;
|
server.addSheet(sheetTitle)
|
||||||
addSheet(sheetTitle)
|
.then(response => doSomething(response))
|
||||||
.then(response => doSomething(response))
|
.catch(err => handleError(err));
|
||||||
.catch(handleError(err));
|
|
||||||
|
|
||||||
// Or we can use async/await:
|
// Or we can use async/await. This is the same thing as above:
|
||||||
async () => {
|
async () => {
|
||||||
try {
|
try {
|
||||||
const response = await addSheet(sheetTitle);
|
const response = await server.addSheet(sheetTitle);
|
||||||
doSomething(response);
|
doSomething(response);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
handleError(err)
|
handleError(err)
|
||||||
@@ -122,7 +121,7 @@ To add new client-side libraries for your React app:
|
|||||||
|
|
||||||
Longer explanation:
|
Longer explanation:
|
||||||
|
|
||||||
Google Apps Script requires all HTML to be in a single file that is loaded into the dialog. Therefore, webpack has been configured to inline all generated client JS code into a single HTML file (in this case [main.html](./dist/main.html) and [about.html](./dist/about.html)). Inlining all code into a single file can result in large output files, which take longer to load, and can also sometimes cause the Google Apps Script editor to crash when you open it. So to reduce bundle size this project takes advantage of [dynamic-cdn-webpack-plugin](https://github.com/mastilver/dynamic-cdn-webpack-plugin) to automatically load popular libraries found in your app, such as `react` and `react-dom`, from a CDN. It doesn't know about all libraries (only [these](https://github.com/mastilver/module-to-cdn/blob/master/modules.json)), so if you've installed new packages, especially large packages, you should add a CDN url to the [webpack file](./webpack.config.js#L129) to reduce bundle size.
|
Google Apps Script requires all HTML to be in a single file that is loaded into the dialog. Therefore, webpack has been configured to inline all generated client JS code into a single HTML file (in this case [main.html](./dist/main.html) and [about.html](./dist/about.html)). Inlining all code into a single file can result in large output files, which take longer to load, and can also sometimes cause the Google Apps Script editor to crash when you open it. So to reduce bundle size this project takes advantage of [dynamic-cdn-webpack-plugin](https://github.com/mastilver/dynamic-cdn-webpack-plugin) to automatically load popular libraries found in your app, such as `react` and `react-dom`, from a CDN. It doesn't know about all libraries (only [these](https://github.com/mastilver/module-to-cdn/blob/master/modules.json)), so if you've installed new packages, especially large packages, you should add a CDN url to the [webpack file](./webpack.config.js#L129) to reduce bundle size. You will need to know your package's global variable. See the examples provided, and also see [here](https://webpack.js.org/configuration/externals/#externals) for more info on how this works.
|
||||||
|
|
||||||
### Expose all public functions
|
### Expose all public functions
|
||||||
Make sure to expose all public functions, including `onOpen` and any functions you are calling from the client. Example below shows assignment to `global` object:
|
Make sure to expose all public functions, including `onOpen` and any functions you are calling from the client. Example below shows assignment to `global` object:
|
||||||
|
|||||||
Vendored
+33
-26
@@ -2,6 +2,8 @@ function onOpen() {
|
|||||||
}
|
}
|
||||||
function openDialog() {
|
function openDialog() {
|
||||||
}
|
}
|
||||||
|
function openDialogBootstrap() {
|
||||||
|
}
|
||||||
function openAboutSidebar() {
|
function openAboutSidebar() {
|
||||||
}
|
}
|
||||||
function getSheetsData() {
|
function getSheetsData() {
|
||||||
@@ -59,6 +61,29 @@ function setActiveSheet() {
|
|||||||
return Object.prototype.hasOwnProperty.call(object, property);
|
return Object.prototype.hasOwnProperty.call(object, property);
|
||||||
}, __webpack_require__.p = "", __webpack_require__(__webpack_require__.s = 2);
|
}, __webpack_require__.p = "", __webpack_require__(__webpack_require__.s = 2);
|
||||||
}([ function(module, __webpack_exports__, __webpack_require__) {
|
}([ function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
"use strict";
|
||||||
|
__webpack_require__.d(__webpack_exports__, "a", (function() {
|
||||||
|
return onOpen;
|
||||||
|
})), __webpack_require__.d(__webpack_exports__, "c", (function() {
|
||||||
|
return openDialog;
|
||||||
|
})), __webpack_require__.d(__webpack_exports__, "d", (function() {
|
||||||
|
return openDialogBootstrap;
|
||||||
|
})), __webpack_require__.d(__webpack_exports__, "b", (function() {
|
||||||
|
return openAboutSidebar;
|
||||||
|
}));
|
||||||
|
var onOpen = function() {
|
||||||
|
SpreadsheetApp.getUi().createMenu("My Sample React Project").addItem("Sheet Editor", "openDialog").addItem("Sheet Editor (Bootstrap)", "openDialogBootstrap").addItem("About me", "openAboutSidebar").addToUi();
|
||||||
|
}, openDialog = function() {
|
||||||
|
var html = HtmlService.createHtmlOutputFromFile("dialog-demo").setWidth(600).setHeight(600);
|
||||||
|
SpreadsheetApp.getUi().showModalDialog(html, "Sheet Editor");
|
||||||
|
}, openDialogBootstrap = function() {
|
||||||
|
var html = HtmlService.createHtmlOutputFromFile("dialog-demo-bootstrap").setWidth(600).setHeight(600);
|
||||||
|
SpreadsheetApp.getUi().showModalDialog(html, "Sheet Editor (Bootstrap)");
|
||||||
|
}, openAboutSidebar = function() {
|
||||||
|
var html = HtmlService.createHtmlOutputFromFile("sidebar-about-page");
|
||||||
|
SpreadsheetApp.getUi().showSidebar(html);
|
||||||
|
};
|
||||||
|
}, function(module, __webpack_exports__, __webpack_require__) {
|
||||||
"use strict";
|
"use strict";
|
||||||
__webpack_require__.d(__webpack_exports__, "c", (function() {
|
__webpack_require__.d(__webpack_exports__, "c", (function() {
|
||||||
return getSheetsData;
|
return getSheetsData;
|
||||||
@@ -74,11 +99,11 @@ function setActiveSheet() {
|
|||||||
}, getSheetsData = function() {
|
}, getSheetsData = function() {
|
||||||
var activeSheetName = SpreadsheetApp.getActive().getSheetName();
|
var activeSheetName = SpreadsheetApp.getActive().getSheetName();
|
||||||
return getSheets().map((function(sheet, index) {
|
return getSheets().map((function(sheet, index) {
|
||||||
var sheetName = sheet.getName();
|
var name = sheet.getName();
|
||||||
return {
|
return {
|
||||||
text: sheetName,
|
name: name,
|
||||||
sheetIndex: index,
|
index: index,
|
||||||
isActive: sheetName === activeSheetName
|
isActive: name === activeSheetName
|
||||||
};
|
};
|
||||||
}));
|
}));
|
||||||
}, addSheet = function(sheetTitle) {
|
}, addSheet = function(sheetTitle) {
|
||||||
@@ -89,32 +114,14 @@ function setActiveSheet() {
|
|||||||
}, setActiveSheet = function(sheetName) {
|
}, setActiveSheet = function(sheetName) {
|
||||||
return SpreadsheetApp.getActive().getSheetByName(sheetName).activate(), getSheetsData();
|
return SpreadsheetApp.getActive().getSheetByName(sheetName).activate(), getSheetsData();
|
||||||
};
|
};
|
||||||
}, function(module, __webpack_exports__, __webpack_require__) {
|
|
||||||
"use strict";
|
|
||||||
__webpack_require__.d(__webpack_exports__, "a", (function() {
|
|
||||||
return onOpen;
|
|
||||||
})), __webpack_require__.d(__webpack_exports__, "c", (function() {
|
|
||||||
return openDialog;
|
|
||||||
})), __webpack_require__.d(__webpack_exports__, "b", (function() {
|
|
||||||
return openAboutSidebar;
|
|
||||||
}));
|
|
||||||
var onOpen = function() {
|
|
||||||
SpreadsheetApp.getUi().createMenu("My Sample React Project").addItem("Sheet Name Editor", "openDialog").addItem("About me", "openAboutSidebar").addToUi();
|
|
||||||
}, openDialog = function() {
|
|
||||||
var html = HtmlService.createHtmlOutputFromFile("main").setWidth(400).setHeight(600);
|
|
||||||
SpreadsheetApp.getUi().showModalDialog(html, "Sheet Editor");
|
|
||||||
}, openAboutSidebar = function() {
|
|
||||||
var html = HtmlService.createHtmlOutputFromFile("about");
|
|
||||||
SpreadsheetApp.getUi().showSidebar(html);
|
|
||||||
};
|
|
||||||
}, function(module, __webpack_exports__, __webpack_require__) {
|
}, function(module, __webpack_exports__, __webpack_require__) {
|
||||||
"use strict";
|
"use strict";
|
||||||
__webpack_require__.r(__webpack_exports__), function(global) {
|
__webpack_require__.r(__webpack_exports__), function(global) {
|
||||||
var _ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1), _sheets__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(0);
|
var _ui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0), _sheets__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1);
|
||||||
global.onOpen = _ui__WEBPACK_IMPORTED_MODULE_0__["a"], global.openDialog = _ui__WEBPACK_IMPORTED_MODULE_0__["c"],
|
global.onOpen = _ui__WEBPACK_IMPORTED_MODULE_0__["a"], global.openDialog = _ui__WEBPACK_IMPORTED_MODULE_0__["c"],
|
||||||
global.openAboutSidebar = _ui__WEBPACK_IMPORTED_MODULE_0__["b"], global.getSheetsData = _sheets__WEBPACK_IMPORTED_MODULE_1__["c"],
|
global.openDialogBootstrap = _ui__WEBPACK_IMPORTED_MODULE_0__["d"], global.openAboutSidebar = _ui__WEBPACK_IMPORTED_MODULE_0__["b"],
|
||||||
global.addSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["a"], global.deleteSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["b"],
|
global.getSheetsData = _sheets__WEBPACK_IMPORTED_MODULE_1__["c"], global.addSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["a"],
|
||||||
global.setActiveSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["d"];
|
global.deleteSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["b"], global.setActiveSheet = _sheets__WEBPACK_IMPORTED_MODULE_1__["d"];
|
||||||
}.call(this, __webpack_require__(3));
|
}.call(this, __webpack_require__(3));
|
||||||
}, function(module, exports) {
|
}, function(module, exports) {
|
||||||
var g;
|
var g;
|
||||||
|
|||||||
Vendored
+18
File diff suppressed because one or more lines are too long
Vendored
+16
File diff suppressed because one or more lines are too long
Vendored
-11
File diff suppressed because one or more lines are too long
+6
-5
@@ -1,11 +1,12 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<base target="_top">
|
<base target="_top" />
|
||||||
|
<!-- Add any external scripts and stylesheets here -->
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section id="index">
|
<section id="index">
|
||||||
<!-- bundled js and css will get inlined here -->
|
<!-- bundled js and css will get inlined here during build -->
|
||||||
</section>
|
</section>
|
||||||
<script type="text/javascript" src="https://unpkg.com/react@16.13.0/umd/react.production.min.js"></script><script type="text/javascript" src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script><script type="text/javascript">!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=2)}([function(e,t){e.exports=React},function(e,t){e.exports=ReactDOM},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),u=r(1);var a=()=>o.a.createElement("div",{className:"sheetNameText"},o.a.createElement("div",null,"Github repo:"),o.a.createElement("a",{href:"https://www.github.com/enuchi/React-Google-Apps-Script",target:"_blank",rel:"noopener noreferrer"},"React + Google Apps Script"),o.a.createElement("div",null,"-Elisha Nuchi"));r.n(u).a.render(o.a.createElement(a,null),document.getElementById("index"))}]);</script></body>
|
<script type="text/javascript" src="https://unpkg.com/react@16.13.0/umd/react.production.min.js"></script><script type="text/javascript" src="https://unpkg.com/react-dom@16.13.0/umd/react-dom.production.min.js"></script><script type="text/javascript">!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=2)}([function(e,t){e.exports=React},function(e,t){e.exports=ReactDOM},function(e,t,r){"use strict";r.r(t);var n=r(0),o=r.n(n),u=r(1);var l=()=>o.a.createElement("div",null,o.a.createElement("div",null,"Github repo:"),o.a.createElement("a",{href:"https://www.github.com/enuchi/React-Google-Apps-Script",target:"_blank",rel:"noopener noreferrer"},"React + Google Apps Script"),o.a.createElement("div",null,"-Elisha Nuchi"));r.n(u).a.render(o.a.createElement(l,null),document.getElementById("index"))}]);</script></body>
|
||||||
</html>
|
</html>
|
||||||
Generated
+242
-77
@@ -1093,6 +1093,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@popperjs/core": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-JlGTGRYHC2QK+DDbePyXdBdooxFq2+noLfWpRqJtkxcb/oYWzOF0kcbfvvbWrwevCC1l6hLUg1wHYT+ona5BWQ=="
|
||||||
|
},
|
||||||
|
"@restart/context": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q=="
|
||||||
|
},
|
||||||
|
"@restart/hooks": {
|
||||||
|
"version": "0.3.25",
|
||||||
|
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.25.tgz",
|
||||||
|
"integrity": "sha512-m2v3N5pxTsIiSH74/sb1yW8D9RxkJidGW+5Mfwn/lHb2QzhZNlaU1su7abSyT9EGf0xS/0waLjrf7/XxQHUk7w==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.15",
|
||||||
|
"lodash-es": "^4.17.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sindresorhus/is": {
|
"@sindresorhus/is": {
|
||||||
"version": "0.14.0",
|
"version": "0.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
|
||||||
@@ -1120,6 +1139,25 @@
|
|||||||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/prop-types": {
|
||||||
|
"version": "15.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
|
||||||
|
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"version": "16.9.41",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.41.tgz",
|
||||||
|
"integrity": "sha512-6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug==",
|
||||||
|
"requires": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/warning": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI="
|
||||||
|
},
|
||||||
"@webassemblyjs/ast": {
|
"@webassemblyjs/ast": {
|
||||||
"version": "1.8.5",
|
"version": "1.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
|
||||||
@@ -1353,9 +1391,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"agent-base": {
|
"agent-base": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz",
|
||||||
"integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
|
"integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "4"
|
"debug": "4"
|
||||||
@@ -1799,9 +1837,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"bignumber.js": {
|
"bignumber.js": {
|
||||||
"version": "7.2.1",
|
"version": "9.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz",
|
||||||
"integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==",
|
"integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"binary-extensions": {
|
"binary-extensions": {
|
||||||
@@ -2100,11 +2138,6 @@
|
|||||||
"integrity": "sha512-8joOm7BwcpEN4BfVHtfh0hBXSAPVYk+eUIcNntGtMkUWy/6AKRCDZINCLe3kB1vHhT2vBxBF85Hh9VlPXi/qjA==",
|
"integrity": "sha512-8joOm7BwcpEN4BfVHtfh0hBXSAPVYk+eUIcNntGtMkUWy/6AKRCDZINCLe3kB1vHhT2vBxBF85Hh9VlPXi/qjA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"chain-function": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-SxltgMwL9uCko5/ZCLiyG2B7R9fY4pDZUw7hJ4MhirdjBLosoDqkWABi3XMucddHdLiFJMb7PD2MZifZriuMTg=="
|
|
||||||
},
|
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
@@ -2190,6 +2223,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"classnames": {
|
||||||
|
"version": "2.2.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
|
||||||
|
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
|
||||||
|
},
|
||||||
"clean-css": {
|
"clean-css": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
|
||||||
@@ -2632,6 +2670,11 @@
|
|||||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "2.6.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
|
||||||
|
"integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
|
||||||
|
},
|
||||||
"cycle": {
|
"cycle": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
|
||||||
@@ -2788,9 +2831,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dns-socket": {
|
"dns-socket": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.1.tgz",
|
||||||
"integrity": "sha512-4XuD3z28jht3jvHbiom6fAipgG5LkjYeDLrX5OH8cbl0AtzTyUUAxGckcW8T7z0pLfBBV5qOiuC4wUEohk6FrQ==",
|
"integrity": "sha512-fNvDq86lS522+zMbh31X8cQzYQd6xumCNlxsuZF5TKxQThF/e+rJbVM6K8mmlsdcSm6yNjKJQq3Sf38viAJj8g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"dns-packet": "^5.1.2"
|
"dns-packet": "^5.1.2"
|
||||||
@@ -2815,11 +2858,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dom-helpers": {
|
"dom-helpers": {
|
||||||
"version": "3.4.0",
|
"version": "5.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
|
||||||
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
|
"integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.1.2"
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^2.6.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dom-serializer": {
|
"dom-serializer": {
|
||||||
@@ -2872,13 +2916,21 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dotf": {
|
"dotf": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/dotf/-/dotf-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/dotf/-/dotf-1.5.1.tgz",
|
||||||
"integrity": "sha512-t0RzzkjSrc1jDxUde8cbD0q0mB9xk0Hdgt1joeMUwXcWiP9V+Ydw7gHjoeeuBN8aiJbnXAaCiM5/U1C2aN1F1g==",
|
"integrity": "sha512-z/VJm6Z5TfFPahHNPw1B/XrKaGQmy2Z4xrsAvzu9xr4saFXrCvQh8Y4DWcdllp9ciZW0VkkjkJPIixZ1un5oJw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"graceful-fs": "^4.2.3",
|
"graceful-fs": "^4.2.4",
|
||||||
"jsonfile": "^6.0.0"
|
"jsonfile": "^6.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"graceful-fs": {
|
||||||
|
"version": "4.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||||
|
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"duplexer3": {
|
"duplexer3": {
|
||||||
@@ -3938,9 +3990,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fast-text-encoding": {
|
"fast-text-encoding": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz",
|
||||||
"integrity": "sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ==",
|
"integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"figgy-pudding": {
|
"figgy-pudding": {
|
||||||
@@ -4777,9 +4829,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"gaxios": {
|
"gaxios": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.4.tgz",
|
||||||
"integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==",
|
"integrity": "sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"abort-controller": "^3.0.0",
|
"abort-controller": "^3.0.0",
|
||||||
@@ -5505,7 +5557,6 @@
|
|||||||
"version": "2.2.4",
|
"version": "2.2.4",
|
||||||
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
|
||||||
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"loose-envify": "^1.0.0"
|
"loose-envify": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -5677,15 +5728,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-online": {
|
"is-online": {
|
||||||
"version": "8.2.1",
|
"version": "8.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-online/-/is-online-8.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-online/-/is-online-8.4.0.tgz",
|
||||||
"integrity": "sha512-853p45I2b//EDV7n1Rbk60f/fy1KQlp1IkTjV/K2EyAD/h8qXrIAxwIbZ8c4K5p5yDsQlTWUrxocgW/aBtNfYQ==",
|
"integrity": "sha512-i0qGRbtUaQEU5Z7O3LmOnH3yorhG1lnygqY2cv3InlQKKm3nx6XiGXZk49lATR3N7hyxoiuHMR0pKwRuB+s5lg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"got": "^9.6.0",
|
"got": "^9.6.0",
|
||||||
"p-any": "^2.0.0",
|
"p-any": "^2.0.0",
|
||||||
"p-timeout": "^3.0.0",
|
"p-timeout": "^3.0.0",
|
||||||
"public-ip": "^3.0.0"
|
"public-ip": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-plain-object": {
|
"is-plain-object": {
|
||||||
@@ -5818,12 +5869,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"json-bigint": {
|
"json-bigint": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.1.tgz",
|
||||||
"integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
|
"integrity": "sha512-DGWnSzmusIreWlEupsUelHrhwmPPE+FiQvg+drKfk2p+bdEYa5mp4PJ8JsCWqae0M2jQNb0HPvnwvf1qOTThzQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bignumber.js": "^7.0.0"
|
"bignumber.js": "^9.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"json-buffer": {
|
"json-buffer": {
|
||||||
@@ -6066,8 +6117,12 @@
|
|||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.15",
|
"version": "4.17.15",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||||
"dev": true
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
|
||||||
|
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
|
||||||
},
|
},
|
||||||
"loose-envify": {
|
"loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
@@ -6214,9 +6269,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mime": {
|
"mime": {
|
||||||
"version": "2.4.4",
|
"version": "2.4.6",
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
|
||||||
"integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==",
|
"integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mimic-fn": {
|
"mimic-fn": {
|
||||||
@@ -7255,6 +7310,25 @@
|
|||||||
"react-is": "^16.8.1"
|
"react-is": "^16.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prop-types-extra": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
|
||||||
|
"requires": {
|
||||||
|
"react-is": "^16.3.2",
|
||||||
|
"warning": "^4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"warning": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"prr": {
|
"prr": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
|
||||||
@@ -7276,12 +7350,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"public-ip": {
|
"public-ip": {
|
||||||
"version": "3.2.0",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/public-ip/-/public-ip-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.2.tgz",
|
||||||
"integrity": "sha512-DBq4o955zhrhESG4z6GkLN9mtY9NT/JOjEV8pvnYy3bjVQOQF0J5lJNwWLbEWwNstyNFJlY7JxCPFq4bdXSabw==",
|
"integrity": "sha512-ZHqUjaYT/+FuSiy5/o2gBxvj0PF7M3MXGnaLJBsJNMCyXI4jzuXXHJKrk0gDxx1apiF/jYsBwjTQOM9V8G6oCQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"dns-socket": "^4.2.0",
|
"dns-socket": "^4.2.1",
|
||||||
"got": "^9.6.0",
|
"got": "^9.6.0",
|
||||||
"is-ip": "^3.1.0"
|
"is-ip": "^3.1.0"
|
||||||
}
|
}
|
||||||
@@ -7326,9 +7400,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"qs": {
|
"qs": {
|
||||||
"version": "6.9.1",
|
"version": "6.9.4",
|
||||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz",
|
||||||
"integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==",
|
"integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"querystring": {
|
"querystring": {
|
||||||
@@ -7372,6 +7446,56 @@
|
|||||||
"prop-types": "^15.6.2"
|
"prop-types": "^15.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-bootstrap": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-xMHwsvDN7sIv26P9wWiosWjITZije2dRCjEJHVfV2KFoSJY+8uv2zttEw0XMB7xviQcW3zuIGLJXuj8vf6lYEg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.4.2",
|
||||||
|
"@restart/context": "^2.1.4",
|
||||||
|
"@restart/hooks": "^0.3.21",
|
||||||
|
"@types/react": "^16.9.23",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"dom-helpers": "^5.1.2",
|
||||||
|
"invariant": "^2.2.4",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"prop-types-extra": "^1.1.0",
|
||||||
|
"react-overlays": "^3.1.2",
|
||||||
|
"react-transition-group": "^4.0.0",
|
||||||
|
"uncontrollable": "^7.0.0",
|
||||||
|
"warning": "^4.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dom-helpers": {
|
||||||
|
"version": "5.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
|
||||||
|
"integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-transition-group": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"dom-helpers": "^5.0.1",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "16.13.0",
|
"version": "16.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz",
|
||||||
@@ -7388,16 +7512,54 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz",
|
||||||
"integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA=="
|
"integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA=="
|
||||||
},
|
},
|
||||||
"react-transition-group": {
|
"react-lifecycles-compat": {
|
||||||
"version": "1.2.1",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||||
"integrity": "sha512-CWaL3laCmgAFdxdKbhhps+c0HRGF4c+hdM4H23+FI1QBNUyx/AMeIJGWorehPNSaKnQNOAxL7PQmqMu78CDj3Q==",
|
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||||
|
},
|
||||||
|
"react-overlays": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-YTgCmw6l4uBOYylSnc3V8WLX+A0EoGnzDrqkYz0K7MUKbMBZFpaxLXH4EF9eZbspd+syZHQ5XAABI7n/zak1EA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chain-function": "^1.0.0",
|
"@babel/runtime": "^7.4.5",
|
||||||
"dom-helpers": "^3.2.0",
|
"@popperjs/core": "^2.0.0",
|
||||||
"loose-envify": "^1.3.1",
|
"@restart/hooks": "^0.3.12",
|
||||||
"prop-types": "^15.5.6",
|
"@types/warning": "^3.0.0",
|
||||||
"warning": "^3.0.0"
|
"dom-helpers": "^5.1.0",
|
||||||
|
"prop-types": "^15.7.2",
|
||||||
|
"uncontrollable": "^7.0.0",
|
||||||
|
"warning": "^4.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dom-helpers": {
|
||||||
|
"version": "5.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
|
||||||
|
"integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"csstype": "^2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"warning": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-transition-group": {
|
||||||
|
"version": "4.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
|
||||||
|
"integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"dom-helpers": "^5.0.1",
|
||||||
|
"loose-envify": "^1.4.0",
|
||||||
|
"prop-types": "^15.6.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
@@ -8676,12 +8838,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ts2gas": {
|
"ts2gas": {
|
||||||
"version": "3.6.1",
|
"version": "3.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts2gas/-/ts2gas-3.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/ts2gas/-/ts2gas-3.6.2.tgz",
|
||||||
"integrity": "sha512-B/4OZJKslQytpAtRE0Q0MoZ0h8fyXzJDmMu1CIPdP6q3iEAQJHxCFTxUsrZWOCNQMIuFlxsEX/PHn41g8TVSvg==",
|
"integrity": "sha512-vKp6IuH59NQmmd93S+unEPCHZbGTpnXtC8VxRyTf87VCIMMo/qs9zNBU5oxVvVIOyFyqb20KDf94NYN7cbtL5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"typescript": "^3.8.3"
|
"typescript": "^3.9.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
@@ -8718,9 +8880,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "3.8.3",
|
"version": "3.9.6",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.6.tgz",
|
||||||
"integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
|
"integrity": "sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
@@ -8747,6 +8909,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"uncontrollable": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.6.3",
|
||||||
|
"@types/react": "^16.9.11",
|
||||||
|
"invariant": "^2.2.4",
|
||||||
|
"react-lifecycles-compat": "^3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"unicode-canonical-property-names-ecmascript": {
|
"unicode-canonical-property-names-ecmascript": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
|
||||||
@@ -8963,9 +9136,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"version": "7.0.2",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz",
|
||||||
"integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==",
|
"integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
@@ -8990,14 +9163,6 @@
|
|||||||
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"warning": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
|
|
||||||
"integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
|
|
||||||
"requires": {
|
|
||||||
"loose-envify": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"watch": {
|
"watch": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/watch/-/watch-1.0.2.tgz",
|
||||||
|
|||||||
+7
-2
@@ -2,10 +2,14 @@
|
|||||||
"name": "react-google-apps-script",
|
"name": "react-google-apps-script",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Starter project for using React with Google Apps Script",
|
"description": "Starter project for using React with Google Apps Script",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/enuchi/React-Google-Apps-Script.git"
|
||||||
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "test",
|
"test": "test",
|
||||||
"login": "clasp login",
|
"login": "clasp login",
|
||||||
"setup": "rm .clasp.json && clasp create --type sheets --title 'My React Project' --rootDir ./dist",
|
"setup": "rm -f .clasp.json && clasp create --type sheets --title 'My React Project' --rootDir ./dist",
|
||||||
"setup:use-id": "clasp setting scriptId",
|
"setup:use-id": "clasp setting scriptId",
|
||||||
"build": "webpack --mode production",
|
"build": "webpack --mode production",
|
||||||
"deploy": "npm run build && npx clasp push"
|
"deploy": "npm run build && npx clasp push"
|
||||||
@@ -26,8 +30,9 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.0",
|
"react": "^16.13.0",
|
||||||
|
"react-bootstrap": "^1.0.1",
|
||||||
"react-dom": "^16.13.0",
|
"react-dom": "^16.13.0",
|
||||||
"react-transition-group": "^1.2.1"
|
"react-transition-group": "^4.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.8.4",
|
"@babel/cli": "^7.8.4",
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const FormInput = ({ newSheetFormHandler }) => {
|
|
||||||
const [text, setText] = useState('');
|
|
||||||
|
|
||||||
const handleChange = event => setText(event.target.value);
|
|
||||||
|
|
||||||
const handleSubmit = event => {
|
|
||||||
event.preventDefault();
|
|
||||||
if (text.length === 0) return;
|
|
||||||
|
|
||||||
newSheetFormHandler(event, text);
|
|
||||||
setText('');
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="formBlock">
|
|
||||||
<span>Add a sheet: </span>
|
|
||||||
<form onSubmit={handleSubmit}>
|
|
||||||
<input onChange={handleChange} value={text} />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FormInput;
|
|
||||||
|
|
||||||
FormInput.propTypes = {
|
|
||||||
newSheetFormHandler: PropTypes.func,
|
|
||||||
};
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
|
|
||||||
const SheetButton = ({ name, deleteButtonHandler, clickSheetNameHandler }) => {
|
|
||||||
const { sheetIndex, text, isActive } = name;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="sheetLine">
|
|
||||||
<button onClick={e => deleteButtonHandler(e, sheetIndex)}>X</button>
|
|
||||||
<span
|
|
||||||
onClick={e => clickSheetNameHandler(e, text)}
|
|
||||||
className={`sheetNameText ${isActive ? 'active-sheet' : ''}`}
|
|
||||||
>
|
|
||||||
{text}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SheetButton;
|
|
||||||
|
|
||||||
SheetButton.propTypes = {
|
|
||||||
name: PropTypes.shape({
|
|
||||||
sheetIndex: PropTypes.number,
|
|
||||||
text: PropTypes.string,
|
|
||||||
isActive: PropTypes.bool,
|
|
||||||
}),
|
|
||||||
deleteButtonHandler: PropTypes.func,
|
|
||||||
clickSheetNameHandler: PropTypes.func,
|
|
||||||
};
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/* eslint-disable no-alert */
|
|
||||||
import React, { useState, useEffect } from 'react';
|
|
||||||
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
|
||||||
import FormInput from './FormInput';
|
|
||||||
import SheetButton from './SheetButton';
|
|
||||||
|
|
||||||
import server from '../server';
|
|
||||||
|
|
||||||
const SheetEditor = () => {
|
|
||||||
const { getSheetsData, addSheet, deleteSheet, setActiveSheet } = server;
|
|
||||||
|
|
||||||
const [names, setNames] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getSheetsData()
|
|
||||||
.then(setNames)
|
|
||||||
.catch(alert);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const deleteButtonHandler = (e, sheetIndex) => {
|
|
||||||
deleteSheet(sheetIndex)
|
|
||||||
.then(setNames)
|
|
||||||
.catch(alert);
|
|
||||||
};
|
|
||||||
|
|
||||||
const clickSheetNameHandler = (e, sheetName) => {
|
|
||||||
setActiveSheet(sheetName)
|
|
||||||
.then(setNames)
|
|
||||||
.catch(alert);
|
|
||||||
};
|
|
||||||
|
|
||||||
// just for fun, let's use async/await for this one
|
|
||||||
const newSheetFormHandler = async (e, newSheetTitle) => {
|
|
||||||
try {
|
|
||||||
const response = await addSheet(newSheetTitle);
|
|
||||||
setNames(response);
|
|
||||||
} catch (error) {
|
|
||||||
alert(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<FormInput newSheetFormHandler={newSheetFormHandler} />
|
|
||||||
<TransitionGroup className="todo-list">
|
|
||||||
{names.length &&
|
|
||||||
names.map(name => (
|
|
||||||
<CSSTransition
|
|
||||||
transitionName="sheetNames"
|
|
||||||
transitionAppear={true}
|
|
||||||
transitionEnterTimeout={300}
|
|
||||||
transitionLeaveTimeout={300}
|
|
||||||
key={name.sheetName}
|
|
||||||
>
|
|
||||||
<SheetButton
|
|
||||||
name={name}
|
|
||||||
deleteButtonHandler={deleteButtonHandler}
|
|
||||||
clickSheetNameHandler={clickSheetNameHandler}
|
|
||||||
/>
|
|
||||||
</CSSTransition>
|
|
||||||
))}
|
|
||||||
</TransitionGroup>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default SheetEditor;
|
|
||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
||||||
|
import { Form, Button, ListGroup, Col, Row } from 'react-bootstrap';
|
||||||
|
|
||||||
|
// This is a wrapper for google.script.run that lets us use promises.
|
||||||
|
import server from '../../utils/server';
|
||||||
|
|
||||||
|
const SheetEditor = () => {
|
||||||
|
const [newSheetName, setNewSheetName] = useState('');
|
||||||
|
const [names, setNames] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
server
|
||||||
|
.getSheetsData()
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const deleteSheet = sheetIndex => {
|
||||||
|
server
|
||||||
|
.deleteSheet(sheetIndex)
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setActiveSheet = sheetName => {
|
||||||
|
server
|
||||||
|
.setActiveSheet(sheetName)
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitNewSheet = async () => {
|
||||||
|
try {
|
||||||
|
const response = await server.addSheet(newSheetName);
|
||||||
|
setNames(response);
|
||||||
|
} catch (error) {
|
||||||
|
alert(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '3px', overflowX: 'hidden' }}>
|
||||||
|
<Form onSubmit={submitNewSheet}>
|
||||||
|
<Form.Group controlId="formNewSheet">
|
||||||
|
<Form.Label>Add a new sheet</Form.Label>
|
||||||
|
<Row>
|
||||||
|
<Col xs={10}>
|
||||||
|
<Form.Control
|
||||||
|
type="text"
|
||||||
|
placeholder="Sheet name"
|
||||||
|
value={newSheetName}
|
||||||
|
onChange={e => {
|
||||||
|
setNewSheetName(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col xs={2}>
|
||||||
|
<Button variant="primary" type="submit">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Form.Text className="text-muted">
|
||||||
|
Enter the name for your new sheet.
|
||||||
|
</Form.Text>
|
||||||
|
</Form.Group>
|
||||||
|
</Form>
|
||||||
|
<ListGroup>
|
||||||
|
<TransitionGroup className="sheet-list">
|
||||||
|
{names.length > 0 &&
|
||||||
|
names.map(name => (
|
||||||
|
<CSSTransition
|
||||||
|
classNames="sheetNames"
|
||||||
|
timeout={500}
|
||||||
|
key={name.name}
|
||||||
|
>
|
||||||
|
<ListGroup.Item
|
||||||
|
className="d-flex"
|
||||||
|
key={`${name.index}-${name.name}`}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
className="border-0"
|
||||||
|
variant="outline-danger"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => deleteSheet(name.index)}
|
||||||
|
>
|
||||||
|
×
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="border-0 mx-2"
|
||||||
|
variant={name.isActive ? 'success' : 'outline-success'}
|
||||||
|
onClick={() => setActiveSheet(name.name)}
|
||||||
|
>
|
||||||
|
{name.name}
|
||||||
|
</Button>
|
||||||
|
</ListGroup.Item>
|
||||||
|
</CSSTransition>
|
||||||
|
))}
|
||||||
|
</TransitionGroup>
|
||||||
|
</ListGroup>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SheetEditor;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<base target="_top" />
|
||||||
|
<!-- Add any external scripts and stylesheets here -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section id="index">
|
||||||
|
<!-- bundled js and css will get inlined here during build-->
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
CSSTransitionGroup styling
|
||||||
|
*/
|
||||||
|
.sheetNames-enter {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-enter.sheetNames-enter-active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-exit {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-exit.sheetNames-exit-active {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-appear {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-appear.sheetNames-appear-active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.5ms ease-in;
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const FormInput = ({ submitNewSheet }) => {
|
||||||
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
|
||||||
|
const handleChange = event => setInputValue(event.target.value);
|
||||||
|
|
||||||
|
const handleSubmit = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (inputValue.length === 0) return;
|
||||||
|
|
||||||
|
submitNewSheet(inputValue);
|
||||||
|
setInputValue('');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="formBlock">
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div>
|
||||||
|
<span>Add a sheet</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
onChange={handleChange}
|
||||||
|
value={inputValue}
|
||||||
|
placeholder="New sheet name"
|
||||||
|
/>
|
||||||
|
<button className="submit" type="submit">
|
||||||
|
Add
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormInput;
|
||||||
|
|
||||||
|
FormInput.propTypes = {
|
||||||
|
submitNewSheet: PropTypes.func,
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
const SheetButton = ({ sheetDetails, deleteSheet, setActiveSheet }) => {
|
||||||
|
const { index, name, isActive } = sheetDetails;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="sheetLine">
|
||||||
|
<button className="delete" onClick={() => deleteSheet(index)}>
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
<button className="basicButton" onClick={() => setActiveSheet(name)}>
|
||||||
|
<span className={`sheetNameText ${isActive ? 'active-sheet' : ''}`}>
|
||||||
|
{name}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SheetButton;
|
||||||
|
|
||||||
|
SheetButton.propTypes = {
|
||||||
|
sheetDetails: PropTypes.shape({
|
||||||
|
index: PropTypes.number,
|
||||||
|
name: PropTypes.string,
|
||||||
|
isActive: PropTypes.bool,
|
||||||
|
}),
|
||||||
|
deleteSheet: PropTypes.func,
|
||||||
|
setActiveSheet: PropTypes.func,
|
||||||
|
};
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { TransitionGroup, CSSTransition } from 'react-transition-group';
|
||||||
|
import FormInput from './FormInput';
|
||||||
|
import SheetButton from './SheetButton';
|
||||||
|
|
||||||
|
// This is a wrapper for google.script.run that lets us use promises.
|
||||||
|
import server from '../../utils/server';
|
||||||
|
|
||||||
|
const SheetEditor = () => {
|
||||||
|
const [names, setNames] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Call a server global function here and handle the response with .then() and .catch()
|
||||||
|
server
|
||||||
|
.getSheetsData()
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const deleteSheet = sheetIndex => {
|
||||||
|
server
|
||||||
|
.deleteSheet(sheetIndex)
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
const setActiveSheet = sheetName => {
|
||||||
|
server
|
||||||
|
.setActiveSheet(sheetName)
|
||||||
|
.then(setNames)
|
||||||
|
.catch(alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
// You can also use async/await notation for server calls with our server wrapper.
|
||||||
|
// (This does the same thing as .then().catch() in the above handlers.)
|
||||||
|
const submitNewSheet = async newSheetName => {
|
||||||
|
try {
|
||||||
|
const response = await server.addSheet(newSheetName);
|
||||||
|
setNames(response);
|
||||||
|
} catch (error) {
|
||||||
|
alert(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<FormInput submitNewSheet={submitNewSheet} />
|
||||||
|
<TransitionGroup className="sheet-list">
|
||||||
|
{names.length > 0 &&
|
||||||
|
names.map(name => (
|
||||||
|
<CSSTransition
|
||||||
|
classNames="sheetNames"
|
||||||
|
timeout={500}
|
||||||
|
key={name.name}
|
||||||
|
>
|
||||||
|
<SheetButton
|
||||||
|
sheetDetails={name}
|
||||||
|
deleteSheet={deleteSheet}
|
||||||
|
setActiveSheet={setActiveSheet}
|
||||||
|
/>
|
||||||
|
</CSSTransition>
|
||||||
|
))}
|
||||||
|
</TransitionGroup>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SheetEditor;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<base target="_top" />
|
||||||
|
<!-- Add any external scripts and stylesheets here -->
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Nunito"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section id="index">
|
||||||
|
<!-- bundled js and css will get inlined here during build -->
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import SheetEditor from './components/SheetEditor';
|
||||||
|
|
||||||
|
import './styles.css';
|
||||||
|
|
||||||
|
ReactDOM.render(<SheetEditor />, document.getElementById('index'));
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
input {
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
width: 150px;
|
||||||
|
height: 28px;
|
||||||
|
border: 1px solid #6b6b6b;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: 0 none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.submit {
|
||||||
|
background: rgb(234, 234, 255);
|
||||||
|
margin: 0px 10px;
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
border: 1px solid #6b6b6b;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.submit:hover {
|
||||||
|
background: rgb(234, 234, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.delete {
|
||||||
|
width: 17px;
|
||||||
|
-webkit-transition-duration: 0.4s; /* Safari */
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 1px solid #f44336;
|
||||||
|
color: #676767;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
height: 17px;
|
||||||
|
line-height: 15px;
|
||||||
|
margin-left: 3px;
|
||||||
|
margin-right: 11px;
|
||||||
|
padding: 1px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition-duration: 0.6s;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.delete:hover {
|
||||||
|
background-color: #f44336;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.delete:active {
|
||||||
|
background-color: #f44336;
|
||||||
|
|
||||||
|
transform: translateY(1px);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.delete:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.formBlock {
|
||||||
|
display: -webkit-box;
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetLine {
|
||||||
|
padding: 10px 0px;
|
||||||
|
border-bottom: 1px solid #eaeaea;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.basicButton {
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.sheetNameText {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
border-bottom-color: rgba(51, 130, 54, 0);
|
||||||
|
border-bottom-width: 3px solid none;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
transition: border-bottom-color 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.sheetNameText:hover {
|
||||||
|
border-bottom-color: rgba(51, 130, 54, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
span.sheetNameText:active {
|
||||||
|
border-bottom-color: rgba(51, 130, 54, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
span.sheetNameText.active-sheet {
|
||||||
|
border-bottom-color: rgb(51, 130, 54);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
CSSTransitionGroup styling
|
||||||
|
*/
|
||||||
|
.sheetNames-enter {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-enter.sheetNames-enter-active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-exit {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-exit.sheetNames-exit-active {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 300ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-appear {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sheetNames-appear.sheetNames-appear-active {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.5ms ease-in;
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<base target="_top">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<section id="index">
|
|
||||||
<!-- bundled js and css will get inlined here -->
|
|
||||||
</section>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const About = () => (
|
const About = () => (
|
||||||
<div className="sheetNameText">
|
<div>
|
||||||
<div>Github repo:</div>
|
<div>Github repo:</div>
|
||||||
<a
|
<a
|
||||||
href="https://www.github.com/enuchi/React-Google-Apps-Script"
|
href="https://www.github.com/enuchi/React-Google-Apps-Script"
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<base target="_top" />
|
||||||
|
<!-- Add any external scripts and stylesheets here -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section id="index">
|
||||||
|
<!-- bundled js and css will get inlined here during build -->
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
@import url('https://fonts.googleapis.com/css?family=Lora|Mukta');
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 130px;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
-webkit-transition-duration: 0.4s; /* Safari */
|
|
||||||
background-color: #f44336;
|
|
||||||
border: 1px solid #f44336;
|
|
||||||
color: white;
|
|
||||||
display: inline-block;
|
|
||||||
font-family: 'Mukta', sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 15px;
|
|
||||||
margin-left: 3px;
|
|
||||||
margin-right: 11px;
|
|
||||||
padding: 3px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
transition-duration: 0.6s;
|
|
||||||
vertical-align: middle;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:hover {
|
|
||||||
background-color: white;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:active {
|
|
||||||
background-color: #fafafa;
|
|
||||||
transform: translateY(1px);
|
|
||||||
transition-duration: 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
button:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.formBlock {
|
|
||||||
display: -webkit-box;
|
|
||||||
font-family: 'Lora', serif;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetLine {
|
|
||||||
cursor: pointer;
|
|
||||||
line-height: 3;
|
|
||||||
height: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNameText {
|
|
||||||
font-size: 14px;
|
|
||||||
font-family: 'Lora', serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNameText.active-sheet {
|
|
||||||
border-bottom: 3px solid #338236;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
ReactCSSTransitionGroup styling
|
|
||||||
*/
|
|
||||||
.sheetNames-enter {
|
|
||||||
opacity: 0.01;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNames-enter.sheetNames-enter-active {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 800ms ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNames-leave {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNames-leave.sheetNames-leave-active {
|
|
||||||
opacity: 0.01;
|
|
||||||
transition: opacity 100ms ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNames-appear {
|
|
||||||
opacity: 0.01;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sheetNames-appear.sheetNames-appear-active {
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity .5s ease-in;
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@ import * as publicSheetFunctions from './sheets';
|
|||||||
// Expose public functions by attaching to `global`
|
// Expose public functions by attaching to `global`
|
||||||
global.onOpen = publicUiFunctions.onOpen;
|
global.onOpen = publicUiFunctions.onOpen;
|
||||||
global.openDialog = publicUiFunctions.openDialog;
|
global.openDialog = publicUiFunctions.openDialog;
|
||||||
|
global.openDialogBootstrap = publicUiFunctions.openDialogBootstrap;
|
||||||
global.openAboutSidebar = publicUiFunctions.openAboutSidebar;
|
global.openAboutSidebar = publicUiFunctions.openAboutSidebar;
|
||||||
global.getSheetsData = publicSheetFunctions.getSheetsData;
|
global.getSheetsData = publicSheetFunctions.getSheetsData;
|
||||||
global.addSheet = publicSheetFunctions.addSheet;
|
global.addSheet = publicSheetFunctions.addSheet;
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ const getActiveSheetName = () => SpreadsheetApp.getActive().getSheetName();
|
|||||||
export const getSheetsData = () => {
|
export const getSheetsData = () => {
|
||||||
const activeSheetName = getActiveSheetName();
|
const activeSheetName = getActiveSheetName();
|
||||||
return getSheets().map((sheet, index) => {
|
return getSheets().map((sheet, index) => {
|
||||||
const sheetName = sheet.getName();
|
const name = sheet.getName();
|
||||||
return {
|
return {
|
||||||
text: sheetName,
|
name,
|
||||||
sheetIndex: index,
|
index,
|
||||||
isActive: sheetName === activeSheetName,
|
isActive: name === activeSheetName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
+12
-4
@@ -1,19 +1,27 @@
|
|||||||
export const onOpen = () => {
|
export const onOpen = () => {
|
||||||
SpreadsheetApp.getUi()
|
SpreadsheetApp.getUi()
|
||||||
.createMenu('My Sample React Project') // edit me!
|
.createMenu('My Sample React Project') // edit me!
|
||||||
.addItem('Sheet Name Editor', 'openDialog')
|
.addItem('Sheet Editor', 'openDialog')
|
||||||
|
.addItem('Sheet Editor (Bootstrap)', 'openDialogBootstrap')
|
||||||
.addItem('About me', 'openAboutSidebar')
|
.addItem('About me', 'openAboutSidebar')
|
||||||
.addToUi();
|
.addToUi();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openDialog = () => {
|
export const openDialog = () => {
|
||||||
const html = HtmlService.createHtmlOutputFromFile('main')
|
const html = HtmlService.createHtmlOutputFromFile('dialog-demo')
|
||||||
.setWidth(400)
|
.setWidth(600)
|
||||||
.setHeight(600);
|
.setHeight(600);
|
||||||
SpreadsheetApp.getUi().showModalDialog(html, 'Sheet Editor');
|
SpreadsheetApp.getUi().showModalDialog(html, 'Sheet Editor');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const openDialogBootstrap = () => {
|
||||||
|
const html = HtmlService.createHtmlOutputFromFile('dialog-demo-bootstrap')
|
||||||
|
.setWidth(600)
|
||||||
|
.setHeight(600);
|
||||||
|
SpreadsheetApp.getUi().showModalDialog(html, 'Sheet Editor (Bootstrap)');
|
||||||
|
};
|
||||||
|
|
||||||
export const openAboutSidebar = () => {
|
export const openAboutSidebar = () => {
|
||||||
const html = HtmlService.createHtmlOutputFromFile('about');
|
const html = HtmlService.createHtmlOutputFromFile('sidebar-about-page');
|
||||||
SpreadsheetApp.getUi().showSidebar(html);
|
SpreadsheetApp.getUi().showSidebar(html);
|
||||||
};
|
};
|
||||||
|
|||||||
+28
-27
@@ -15,21 +15,28 @@ const moduleToCdn = require('module-to-cdn');
|
|||||||
* define file paths
|
* define file paths
|
||||||
********************************/
|
********************************/
|
||||||
const destination = 'dist';
|
const destination = 'dist';
|
||||||
const htmlTemplate = './src/client/dialog-template.html';
|
|
||||||
|
|
||||||
/*********************************
|
/*********************************
|
||||||
* client entry point paths
|
* client entry point paths
|
||||||
********************************/
|
********************************/
|
||||||
const clientEntrypoints = [
|
const clientEntrypoints = [
|
||||||
{
|
{
|
||||||
name: 'CLIENT - main dialog',
|
name: 'CLIENT - Dialog Demo',
|
||||||
entry: './src/client/MainDialog.jsx',
|
entry: './src/client/dialog-demo/index.js',
|
||||||
filename: 'main.html',
|
filename: 'dialog-demo.html',
|
||||||
|
template: './src/client/dialog-demo/index.html',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'CLIENT - about sidebar',
|
name: 'CLIENT - Dialog Demo Bootstrap',
|
||||||
entry: './src/client/AboutDialog.jsx',
|
entry: './src/client/dialog-demo-bootstrap/index.js',
|
||||||
filename: 'about.html',
|
filename: 'dialog-demo-bootstrap.html',
|
||||||
|
template: './src/client/dialog-demo-bootstrap/index.html',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'CLIENT - Sidebar About Page',
|
||||||
|
entry: './src/client/sidebar-about-page/index.js',
|
||||||
|
filename: 'sidebar-about-page.html',
|
||||||
|
template: './src/client/sidebar-about-page/index.html',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -46,19 +53,6 @@ const sharedConfigSettings = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// eslint settings, to check during build if desired
|
|
||||||
const eslintConfig = {
|
|
||||||
enforce: 'pre',
|
|
||||||
test: /\.jsx?$/,
|
|
||||||
exclude: /node_modules/,
|
|
||||||
loader: 'eslint-loader',
|
|
||||||
options: {
|
|
||||||
cache: false,
|
|
||||||
failOnError: false,
|
|
||||||
fix: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// appscript copy settings, to copy this file over to the destination directory
|
// appscript copy settings, to copy this file over to the destination directory
|
||||||
const appsscriptConfig = {
|
const appsscriptConfig = {
|
||||||
name: 'COPY APPSSCRIPT.JSON',
|
name: 'COPY APPSSCRIPT.JSON',
|
||||||
@@ -83,8 +77,6 @@ const clientConfig = {
|
|||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
// turned off by default, but uncomment below to run linting during build
|
|
||||||
// eslintConfig,
|
|
||||||
{
|
{
|
||||||
test: /\.jsx?$/,
|
test: /\.jsx?$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
@@ -108,16 +100,20 @@ const clientConfigs = clientEntrypoints.map(clientEntrypoint => {
|
|||||||
entry: clientEntrypoint.entry,
|
entry: clientEntrypoint.entry,
|
||||||
plugins: [
|
plugins: [
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: htmlTemplate,
|
template: clientEntrypoint.template,
|
||||||
filename: clientEntrypoint.filename,
|
filename: clientEntrypoint.filename,
|
||||||
inlineSource: '^[^(//)]+.(js|css)$', // embed all js and css inline, exclude packages with '//' for dynamic cdn insertion
|
inlineSource: '^[^(//)]+.(js|css)$', // embed all js and css inline, exclude packages with '//' for dynamic cdn insertion
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackInlineSourcePlugin(),
|
new HtmlWebpackInlineSourcePlugin(),
|
||||||
new WebpackCleanPlugin([path.join(destination, 'main.js')]),
|
new WebpackCleanPlugin(['main.js'], {
|
||||||
|
basePath: path.join(__dirname, destination),
|
||||||
|
}),
|
||||||
|
// this plugin allows us to add dynamically load packages from cdn
|
||||||
new DynamicCdnWebpackPlugin({
|
new DynamicCdnWebpackPlugin({
|
||||||
// set "verbose" to true to print console logs on CDN usage while webpack builds
|
// set "verbose" to true to print console logs on CDN usage while webpack builds
|
||||||
verbose: false,
|
verbose: false,
|
||||||
resolver: (packageName, packageVersion, options) => {
|
resolver: (packageName, packageVersion, options) => {
|
||||||
|
const packageSuffix = options.env === 'production' ? '.min.js' : '.js'
|
||||||
const moduleDetails = moduleToCdn(
|
const moduleDetails = moduleToCdn(
|
||||||
packageName,
|
packageName,
|
||||||
packageVersion,
|
packageVersion,
|
||||||
@@ -132,7 +128,14 @@ const clientConfigs = clientEntrypoints.map(clientEntrypoint => {
|
|||||||
name: packageName,
|
name: packageName,
|
||||||
var: 'ReactTransitionGroup',
|
var: 'ReactTransitionGroup',
|
||||||
version: packageVersion,
|
version: packageVersion,
|
||||||
url: `https://unpkg.com/react-transition-group/dist/react-transition-group.min.js`,
|
url: `https://unpkg.com/react-transition-group@${packageVersion}/dist/react-transition-group${packageSuffix}`,
|
||||||
|
};
|
||||||
|
case 'react-bootstrap':
|
||||||
|
return {
|
||||||
|
name: packageName,
|
||||||
|
var: 'ReactBootstrap',
|
||||||
|
version: packageVersion,
|
||||||
|
url: `https://unpkg.com/react-bootstrap@${packageVersion}/dist/react-bootstrap${packageSuffix}`,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
@@ -154,8 +157,6 @@ const serverConfig = {
|
|||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
// turned off by default, but uncomment below to run linting during build
|
|
||||||
// eslintConfig,
|
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
|||||||
Reference in New Issue
Block a user