)}
- noCaret
className='app-menu-button'
- id='app-menu'>
+ id='app-menu'
+ noCaret
+ title={(
)}>
From 398a4bbf50cb2ce1fd4b4ebf39871438d142a25c Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 3 Jun 2021 16:01:49 -0400
Subject: [PATCH 18/89] chore(lint): Remove interference with yarn lint.
---
eslint-precommit.json | 36 ++++++
package.json | 33 +----
yarn.lock | 278 ------------------------------------------
3 files changed, 37 insertions(+), 310 deletions(-)
create mode 100644 eslint-precommit.json
diff --git a/eslint-precommit.json b/eslint-precommit.json
new file mode 100644
index 000000000..63d59b0b2
--- /dev/null
+++ b/eslint-precommit.json
@@ -0,0 +1,36 @@
+{
+ "extends": [
+ "../mastarm/lib/eslintrc.json"
+ ],
+ "parser": "babel-eslint",
+ "plugins": [
+ "sort-destructure-keys"
+ ],
+ "rules": {
+ "react/jsx-sort-props": [
+ "error",
+ {
+ "ignoreCase": true
+ }
+ ],
+ "sort-destructure-keys/sort-destructure-keys": [
+ "error",
+ {
+ "caseSensitive": false
+ }
+ ],
+ "sort-keys": [
+ "error",
+ "asc",
+ {
+ "caseSensitive": false
+ }
+ ],
+ "sort-vars": [
+ "error",
+ {
+ "ignoreCase": true
+ }
+ ]
+ }
+}
diff --git a/package.json b/package.json
index 621582195..4504174e3 100644
--- a/package.json
+++ b/package.json
@@ -110,7 +110,6 @@
"enzyme-adapter-react-16": "^1.4.0",
"enzyme-to-json": "^3.4.0",
"es6-math": "^1.0.0",
- "eslint-plugin-react": "^7.24.0",
"eslint-plugin-sort-destructure-keys": "^1.3.5",
"husky": "^6.0.0",
"leaflet": "^1.6.0",
@@ -137,39 +136,9 @@
],
"testURL": "http://localhost/"
},
- "eslintConfig": {
- "extends": [
- "../mastarm/lib/eslintrc.json"
- ],
- "parser": "babel-eslint",
- "rules": {
- "react/jsx-sort-props": [
- "error",
- {
- "ignoreCase": true
- }
- ],
- "sort-destructure-keys/sort-destructure-keys": ["error", {
- "caseSensitive": false
- }],
- "sort-keys": [
- "error",
- "asc",
- {
- "caseSensitive": false
- }
- ],
- "sort-vars": [
- "error",
- {
- "ignoreCase": true
- }
- ]
- }
- },
"lint-staged": {
"*.{js,jsx}": [
- "eslint --fix"
+ "eslint --config eslint-precommit.json --fix"
]
}
}
diff --git a/yarn.lock b/yarn.lock
index 25bbf3100..71e325cd6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2556,17 +2556,6 @@ array-includes@^3.0.3:
define-properties "^1.1.2"
es-abstract "^1.7.0"
-array-includes@^3.1.2, array-includes@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a"
- integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
- get-intrinsic "^1.1.1"
- is-string "^1.0.5"
-
array-map@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662"
@@ -2614,16 +2603,6 @@ array.prototype.flat@^1.2.1:
es-abstract "^1.10.0"
function-bind "^1.1.1"
-array.prototype.flatmap@^1.2.4:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9"
- integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==
- dependencies:
- call-bind "^1.0.0"
- define-properties "^1.1.3"
- es-abstract "^1.18.0-next.1"
- function-bind "^1.1.1"
-
arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
@@ -4180,14 +4159,6 @@ cachedir@2.1.0:
resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.1.0.tgz#b448c32b44cd9c0cd6ce4c419fa5b3c112c02191"
integrity sha512-xGBpPqoBvn3unBW7oxgb8aJn42K0m9m1/wyjmazah10Fq7bROGG3kRAE6OIyr3U3PIJUqGuebhCEdMk9OKJG0A==
-call-bind@^1.0.0, call-bind@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
- integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
- dependencies:
- function-bind "^1.1.1"
- get-intrinsic "^1.0.2"
-
call-limit@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/call-limit/-/call-limit-1.1.1.tgz#ef15f2670db3f1992557e2d965abc459e6e358d4"
@@ -6416,28 +6387,6 @@ es-abstract@^1.10.0, es-abstract@^1.11.0, es-abstract@^1.12.0, es-abstract@^1.13
string.prototype.trimend "^1.0.1"
string.prototype.trimstart "^1.0.1"
-es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2:
- version "1.18.3"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0"
- integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==
- dependencies:
- call-bind "^1.0.2"
- es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
- get-intrinsic "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.2"
- is-callable "^1.2.3"
- is-negative-zero "^2.0.1"
- is-regex "^1.1.3"
- is-string "^1.0.6"
- object-inspect "^1.10.3"
- object-keys "^1.1.1"
- object.assign "^4.1.2"
- string.prototype.trimend "^1.0.4"
- string.prototype.trimstart "^1.0.4"
- unbox-primitive "^1.0.1"
-
es-cookie@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/es-cookie/-/es-cookie-1.3.2.tgz#80e831597f72a25721701bdcb21d990319acd831"
@@ -6613,24 +6562,6 @@ eslint-plugin-react@^7.12.4:
prop-types "^15.7.2"
resolve "^1.10.1"
-eslint-plugin-react@^7.24.0:
- version "7.24.0"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.24.0.tgz#eadedfa351a6f36b490aa17f4fa9b14e842b9eb4"
- integrity sha512-KJJIx2SYx7PBx3ONe/mEeMz4YE0Lcr7feJTCMyyKb/341NcjuAgim3Acgan89GfPv7nxXK2+0slu0CWXYM4x+Q==
- dependencies:
- array-includes "^3.1.3"
- array.prototype.flatmap "^1.2.4"
- doctrine "^2.1.0"
- has "^1.0.3"
- jsx-ast-utils "^2.4.1 || ^3.0.0"
- minimatch "^3.0.4"
- object.entries "^1.1.4"
- object.fromentries "^2.0.4"
- object.values "^1.1.4"
- prop-types "^15.7.2"
- resolve "^2.0.0-next.3"
- string.prototype.matchall "^4.0.5"
-
eslint-plugin-sort-destructure-keys@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.3.5.tgz#c6f45c3e58d4435564025a6ca5f4a838010800fd"
@@ -7565,15 +7496,6 @@ get-func-name@^2.0.0:
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
-get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
- integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
- dependencies:
- function-bind "^1.1.1"
- has "^1.0.3"
- has-symbols "^1.0.1"
-
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -7873,11 +7795,6 @@ has-ansi@^2.0.0:
dependencies:
ansi-regex "^2.0.0"
-has-bigints@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
- integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
-
has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
@@ -7898,11 +7815,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
-has-symbols@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
- integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
-
has-unicode@^2.0.0, has-unicode@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -8481,15 +8393,6 @@ internal-ip@^3.0.1:
default-gateway "^2.6.0"
ipaddr.js "^1.5.2"
-internal-slot@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
- integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==
- dependencies:
- get-intrinsic "^1.1.0"
- has "^1.0.3"
- side-channel "^1.0.4"
-
interpret@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
@@ -8590,11 +8493,6 @@ is-arrayish@^0.3.1:
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03"
integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==
-is-bigint@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.2.tgz#ffb381442503235ad245ea89e45b3dbff040ee5a"
- integrity sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==
-
is-binary-path@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
@@ -8614,13 +8512,6 @@ is-boolean-object@^1.0.0:
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93"
integrity sha1-mPiygDBoQhmpXzdc+9iM40Bd/5M=
-is-boolean-object@^1.1.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8"
- integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==
- dependencies:
- call-bind "^1.0.2"
-
is-buffer@^1.1.0, is-buffer@^1.1.4, is-buffer@^1.1.5, is-buffer@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -8636,11 +8527,6 @@ is-callable@^1.1.4, is-callable@^1.2.0:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
-is-callable@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
- integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==
-
is-ci@^1.0.10:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
@@ -8681,13 +8567,6 @@ is-core-module@^2.1.0:
dependencies:
has "^1.0.3"
-is-core-module@^2.2.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
- integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
- dependencies:
- has "^1.0.3"
-
is-data-descriptor@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56"
@@ -8837,11 +8716,6 @@ is-negated-glob@^1.0.0:
resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2"
integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=
-is-negative-zero@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
- integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
-
is-npm@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
@@ -8852,11 +8726,6 @@ is-number-object@^1.0.3:
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.3.tgz#f265ab89a9f445034ef6aff15a8f00b00f551799"
integrity sha1-8mWrian0RQNO9q/xWo8AsA9VF5k=
-is-number-object@^1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb"
- integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==
-
is-number@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
@@ -8947,14 +8816,6 @@ is-regex@^1.0.4, is-regex@^1.1.0:
dependencies:
has-symbols "^1.0.1"
-is-regex@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
- integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==
- dependencies:
- call-bind "^1.0.2"
- has-symbols "^1.0.2"
-
is-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069"
@@ -8999,11 +8860,6 @@ is-string@^1.0.4:
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.4.tgz#cc3a9b69857d621e963725a24caeec873b826e64"
integrity sha1-zDqbaYV9Yh6WNyWiTK7shzuCbmQ=
-is-string@^1.0.5, is-string@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f"
- integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==
-
is-subset@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6"
@@ -9030,13 +8886,6 @@ is-symbol@^1.0.2:
dependencies:
has-symbols "^1.0.1"
-is-symbol@^1.0.3:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
- integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
- dependencies:
- has-symbols "^1.0.2"
-
is-text-path@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e"
@@ -9761,14 +9610,6 @@ jsx-ast-utils@^2.1.0, jsx-ast-utils@^2.2.1:
array-includes "^3.0.3"
object.assign "^4.1.0"
-"jsx-ast-utils@^2.4.1 || ^3.0.0":
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82"
- integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==
- dependencies:
- array-includes "^3.1.2"
- object.assign "^4.1.2"
-
keycode@^2.1.7, keycode@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.2.0.tgz#3d0af56dc7b8b8e5cba8d0a97f107204eec22b04"
@@ -11803,11 +11644,6 @@ object-hash@^1.3.1:
resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
-object-inspect@^1.10.3, object-inspect@^1.9.0:
- version "1.10.3"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
- integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==
-
object-inspect@^1.6.0, object-inspect@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
@@ -11850,16 +11686,6 @@ object.assign@^4.0.4, object.assign@^4.1.0:
has-symbols "^1.0.0"
object-keys "^1.0.11"
-object.assign@^4.1.2:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
- integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
- dependencies:
- call-bind "^1.0.0"
- define-properties "^1.1.3"
- has-symbols "^1.0.1"
- object-keys "^1.1.1"
-
object.entries@^1.0.4, object.entries@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519"
@@ -11870,15 +11696,6 @@ object.entries@^1.0.4, object.entries@^1.1.0:
function-bind "^1.1.1"
has "^1.0.3"
-object.entries@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd"
- integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.18.2"
-
object.fromentries@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.0.tgz#49a543d92151f8277b3ac9600f1e930b189d30ab"
@@ -11889,16 +11706,6 @@ object.fromentries@^2.0.0:
function-bind "^1.1.1"
has "^1.0.1"
-object.fromentries@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8"
- integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
- has "^1.0.3"
-
object.getownpropertydescriptors@^2.0.3:
version "2.1.0"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649"
@@ -11932,15 +11739,6 @@ object.values@^1.0.4, object.values@^1.1.0:
function-bind "^1.1.1"
has "^1.0.3"
-object.values@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30"
- integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.18.2"
-
on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -14596,14 +14394,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
-regexp.prototype.flags@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
- integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
-
regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@@ -14975,14 +14765,6 @@ resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0,
is-core-module "^2.1.0"
path-parse "^1.0.6"
-resolve@^2.0.0-next.3:
- version "2.0.0-next.3"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46"
- integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==
- dependencies:
- is-core-module "^2.2.0"
- path-parse "^1.0.6"
-
resp-modifier@^6.0.0:
version "6.0.2"
resolved "https://registry.yarnpkg.com/resp-modifier/-/resp-modifier-6.0.2.tgz#b124de5c4fbafcba541f48ffa73970f4aa456b4f"
@@ -15427,15 +15209,6 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
-side-channel@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
- integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==
- dependencies:
- call-bind "^1.0.0"
- get-intrinsic "^1.0.2"
- object-inspect "^1.9.0"
-
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
@@ -15934,20 +15707,6 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
-string.prototype.matchall@^4.0.5:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da"
- integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.18.2"
- get-intrinsic "^1.1.1"
- has-symbols "^1.0.2"
- internal-slot "^1.0.3"
- regexp.prototype.flags "^1.3.1"
- side-channel "^1.0.4"
-
string.prototype.trim@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.0.tgz#75a729b10cfc1be439543dae442129459ce61e3d"
@@ -15965,14 +15724,6 @@ string.prototype.trimend@^1.0.1:
define-properties "^1.1.3"
es-abstract "^1.17.5"
-string.prototype.trimend@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80"
- integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
-
string.prototype.trimstart@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
@@ -15981,14 +15732,6 @@ string.prototype.trimstart@^1.0.1:
define-properties "^1.1.3"
es-abstract "^1.17.5"
-string.prototype.trimstart@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
- integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
-
string_decoder@0.10, string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
@@ -16808,16 +16551,6 @@ umd@^3.0.0:
resolved "https://registry.yarnpkg.com/umd/-/umd-3.0.3.tgz#aa9fe653c42b9097678489c01000acb69f0b26cf"
integrity sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==
-unbox-primitive@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
- integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==
- dependencies:
- function-bind "^1.1.1"
- has-bigints "^1.0.1"
- has-symbols "^1.0.2"
- which-boxed-primitive "^1.0.2"
-
unc-path-regex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
@@ -17584,17 +17317,6 @@ whet.extend@~0.9.9:
resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1"
integrity sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=
-which-boxed-primitive@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
- integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==
- dependencies:
- is-bigint "^1.0.1"
- is-boolean-object "^1.1.0"
- is-number-object "^1.0.4"
- is-string "^1.0.5"
- is-symbol "^1.0.3"
-
which-module@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f"
From c2c9ee93fba54900be347a6c2b4025d969e81bdd Mon Sep 17 00:00:00 2001
From: Landon Reed
Date: Fri, 4 Jun 2021 08:39:14 -0400
Subject: [PATCH 19/89] refactor(call-taker): increase call history limit
---
lib/actions/call-taker.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/actions/call-taker.js b/lib/actions/call-taker.js
index 5215eb5f4..c46a455ee 100644
--- a/lib/actions/call-taker.js
+++ b/lib/actions/call-taker.js
@@ -156,7 +156,7 @@ export function fetchCalls () {
if (sessionIsInvalid(callTaker.session)) return
const {datastoreUrl} = otp.config
const {sessionId} = callTaker.session
- const limit = 30
+ const limit = 1000
fetch(`${datastoreUrl}/calltaker/call?${qs.stringify({limit, sessionId})}`)
.then(res => res.json())
.then(calls => dispatch(receivedCalls({calls})))
From d44fd2fb90f36e1f317a232a2210d60b964ae205 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 4 Jun 2021 09:26:16 -0400
Subject: [PATCH 20/89] Revert "style(app-menu): Test styles"
This reverts commit fbf45065e5cf175d57c71f52cf63e10a9410cfab.
---
lib/components/app/app-menu.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/components/app/app-menu.js b/lib/components/app/app-menu.js
index 74201463a..703c0752d 100644
--- a/lib/components/app/app-menu.js
+++ b/lib/components/app/app-menu.js
@@ -6,6 +6,7 @@ import { DropdownButton, MenuItem } from 'react-bootstrap'
import { withRouter } from 'react-router'
import Icon from '../narrative/icon'
+
import { MainPanelContent, setMainPanelContent } from '../../actions/ui'
// TODO: make menu items configurable via props/config
@@ -22,7 +23,6 @@ class AppMenu extends Component {
_startOver = () => {
const { location, reactRouterConfig } = this.props
const { search } = location
-
let startOverUrl = '/'
if (reactRouterConfig && reactRouterConfig.basename) {
startOverUrl += reactRouterConfig.basename
@@ -46,10 +46,10 @@ class AppMenu extends Component {
)}
noCaret
- title={(
)}>
+ className='app-menu-button'
+ id='app-menu'>
From e66a45da926abaae948d9460fd49eeee52417e70 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 4 Jun 2021 09:38:45 -0400
Subject: [PATCH 21/89] chore(lint): Use only mastarm eslint settings.
---
eslint-precommit.json | 36 ------------------------------------
package.json | 3 +--
yarn.lock | 12 ------------
3 files changed, 1 insertion(+), 50 deletions(-)
delete mode 100644 eslint-precommit.json
diff --git a/eslint-precommit.json b/eslint-precommit.json
deleted file mode 100644
index 63d59b0b2..000000000
--- a/eslint-precommit.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "extends": [
- "../mastarm/lib/eslintrc.json"
- ],
- "parser": "babel-eslint",
- "plugins": [
- "sort-destructure-keys"
- ],
- "rules": {
- "react/jsx-sort-props": [
- "error",
- {
- "ignoreCase": true
- }
- ],
- "sort-destructure-keys/sort-destructure-keys": [
- "error",
- {
- "caseSensitive": false
- }
- ],
- "sort-keys": [
- "error",
- "asc",
- {
- "caseSensitive": false
- }
- ],
- "sort-vars": [
- "error",
- {
- "ignoreCase": true
- }
- ]
- }
-}
diff --git a/package.json b/package.json
index 4504174e3..4536ce1e0 100644
--- a/package.json
+++ b/package.json
@@ -110,7 +110,6 @@
"enzyme-adapter-react-16": "^1.4.0",
"enzyme-to-json": "^3.4.0",
"es6-math": "^1.0.0",
- "eslint-plugin-sort-destructure-keys": "^1.3.5",
"husky": "^6.0.0",
"leaflet": "^1.6.0",
"lint-staged": "^11.0.0",
@@ -138,7 +137,7 @@
},
"lint-staged": {
"*.{js,jsx}": [
- "eslint --config eslint-precommit.json --fix"
+ "eslint --config node_modules/mastarm/lib/eslintrc.json --fix"
]
}
}
diff --git a/yarn.lock b/yarn.lock
index 71e325cd6..7b959e53f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6562,13 +6562,6 @@ eslint-plugin-react@^7.12.4:
prop-types "^15.7.2"
resolve "^1.10.1"
-eslint-plugin-sort-destructure-keys@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/eslint-plugin-sort-destructure-keys/-/eslint-plugin-sort-destructure-keys-1.3.5.tgz#c6f45c3e58d4435564025a6ca5f4a838010800fd"
- integrity sha512-JmVpidhDsLwZsmRDV7Tf/vZgOAOEQGkLtwToSvX5mD8fuWYS/xkgMRBsalW1fGlc8CgJJwnzropt4oMQ7YCHLg==
- dependencies:
- natural-compare-lite "^1.4.0"
-
eslint-plugin-standard@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz#f845b45109c99cd90e77796940a344546c8f6b5c"
@@ -11098,11 +11091,6 @@ nanomatch@^1.2.9:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-natural-compare-lite@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4"
- integrity sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=
-
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
From 344fc9fb80b4de8724aa55b4bfae5dafd15d0fc9 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Fri, 4 Jun 2021 15:19:48 -0400
Subject: [PATCH 22/89] refactor(util/state): Address PR comments.
---
lib/components/map/default-map.js | 7 ---
.../narrative/narrative-itineraries.js | 4 +-
lib/util/state.js | 45 ++++++-------------
3 files changed, 16 insertions(+), 40 deletions(-)
diff --git a/lib/components/map/default-map.js b/lib/components/map/default-map.js
index dd1d9b479..f3306cbe9 100644
--- a/lib/components/map/default-map.js
+++ b/lib/components/map/default-map.js
@@ -158,13 +158,6 @@ class DefaultMap extends Component {
- {/*
- HACK: Use the key prop to force a remount and full resizing of transitive
- if the map container size changes,
- per https://linguinecode.com/post/4-methods-to-re-render-react-component
- Without it, transitive resolution will not match the map,
- and transitive will appear blurry after e.g. the narrative is expanded.
- */}
diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js
index 301c0d89d..ce7d16a28 100644
--- a/lib/components/narrative/narrative-itineraries.js
+++ b/lib/components/narrative/narrative-itineraries.js
@@ -20,7 +20,7 @@ import {
getActiveSearch,
getRealtimeEffects,
getResponsesWithErrors,
- getVisibleItinerary
+ getVisibleItineraryIndex
} from '../../util/state'
import SaveTripButton from './save-trip-button'
@@ -288,7 +288,7 @@ const mapStateToProps = (state, ownProps) => {
sort,
timeFormat: coreUtils.time.getTimeFormat(state.otp.config),
useRealtime,
- visibleItinerary: getVisibleItinerary(state)
+ visibleItinerary: getVisibleItineraryIndex(state)
}
}
diff --git a/lib/util/state.js b/lib/util/state.js
index 0f3d7b40d..bbde22fa6 100644
--- a/lib/util/state.js
+++ b/lib/util/state.js
@@ -308,45 +308,34 @@ export function getActiveItinerary (otpState) {
* Returns true if the OTP state contains a response within the current active search.
* @param {*} state The entire redux state used to obtain the response.
*/
-function hasResponse (state) {
+function activeSearchHasResponse (state) {
const activeSearch = getActiveSearch(state.otp)
return !!(activeSearch && activeSearch.response)
}
-/**
- * Returns true if the OTP state contains one or more OTP responses for the current active search.
- * @param {*} state The entire redux state used to obtain the responses.
- */
-function hasAtLeastOneResponse (state) {
- const activeSearch = getActiveSearch(state.otp)
- return activeSearch && activeSearch.response && activeSearch.response.length > 0
-}
-
/**
* Returns the raw OTP response for the current active search.
* @param {*} state The entire redux state used to obtain the response.
*/
function getOtpResponse (state) {
- const activeSearch = getActiveSearch(state.otp)
- return activeSearch && activeSearch.response && activeSearch.response.otp
+ return getActiveSearch(state.otp)?.response?.otp
}
/**
- * Returns true if the query routing type specifies 'ITINERARY'.
+ * Returns true if the query routing type specifies 'ITINERARY' and an OTP response is available.
* @param {*} state The entire redux state in which the query is stored.
*/
-function queryIsItineraryRouting (state) {
+function itineraryResponseExists (state) {
const activeSearch = getActiveSearch(state.otp)
- return activeSearch &&
- activeSearch.query &&
- activeSearch.query.routingType === 'ITINERARY'
+ return activeSearch?.response?.length > 0 &&
+ activeSearch?.query?.routingType === 'ITINERARY'
}
/**
- * Returns the visible itinerary to render on the map and in narrative components.
+ * Returns the visible itinerary index to render on the map and in narrative components.
* @param {*} state The entire redux state from which to retrieve the itinerary.
*/
-export function getVisibleItinerary (state) {
+export function getVisibleItineraryIndex (state) {
const activeSearch = getActiveSearch(state.otp)
return activeSearch && activeSearch.visibleItinerary
}
@@ -356,14 +345,10 @@ export function getVisibleItinerary (state) {
* @param {*} state The entire redux state from which to derive the itinerary.
*/
function getItineraryToRender (state) {
- const visibleItinerary = getVisibleItinerary(state)
+ const visibleItineraryIndex = getVisibleItineraryIndex(state)
const activeItinerary = getActiveItinerary(state.otp)
const itins = getActiveItineraries(state.otp)
-
- const visibleIndex = visibleItinerary !== undefined && visibleItinerary !== null
- ? visibleItinerary
- : activeItinerary
- return itins[visibleIndex] || activeItinerary
+ return itins[visibleItineraryIndex] || activeItinerary
}
/**
@@ -371,22 +356,20 @@ function getItineraryToRender (state) {
* using a selector to prevent unnecessary re-renderings of the transitive overlay.
*/
export const getTransitiveData = createSelector(
- hasResponse,
- hasAtLeastOneResponse,
+ activeSearchHasResponse,
getOtpResponse,
- queryIsItineraryRouting,
+ itineraryResponseExists,
getItineraryToRender,
(state, props) => props.getTransitiveRouteLabel,
(
hasResponse,
- hasAtLeastOneResponse,
otpResponse,
- queryIsItineraryRouting,
+ hasItineraryResponse,
itineraryToRender,
getTransitiveRouteLabel
) => {
if (hasResponse) {
- if (queryIsItineraryRouting && hasAtLeastOneResponse) {
+ if (hasItineraryResponse) {
return itineraryToRender
? coreUtils.map.itineraryToTransitive(
itineraryToRender,
From 32d67571bf76c73fa94708a62c1402fe6f5e2892 Mon Sep 17 00:00:00 2001
From: Rob Gregg
Date: Mon, 7 Jun 2021 17:15:09 +0100
Subject: [PATCH 23/89] fix(batch-routing-panel.js): Fixed the code so the
button shows.
For some reason the button was showing on my initial commit but not when I pushed teh changes. I
changed some code and cleared my cache. All seems good now.
#371
---
lib/components/app/batch-routing-panel.js | 30 ++++++++++++-----------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/lib/components/app/batch-routing-panel.js b/lib/components/app/batch-routing-panel.js
index ee6376d6b..d7505ef79 100644
--- a/lib/components/app/batch-routing-panel.js
+++ b/lib/components/app/batch-routing-panel.js
@@ -9,7 +9,7 @@ import LocationField from '../form/connected-location-field'
import NarrativeItineraries from '../narrative/narrative-itineraries'
import { getActiveSearch, getShowUserSettings } from '../../util/state'
import ViewerContainer from '../viewers/viewer-container'
-import switchButton from '../form/switch-button'
+import SwitchButton from '../form/switch-button'
// Style for setting the top of the narrative itineraries based on the width of the window.
// If the window width is less than 1200px (Bootstrap's "large" size), the
@@ -36,19 +36,21 @@ class BatchRoutingPanel extends Component {
const {mobile} = this.props
const actionText = mobile ? 'tap' : 'click'
return (
-
-
-
-
-
} />
+
+
{/* FIXME: Add back user settings (home, work, etc.) once connected to
From 61236f217c33cd0450f64b3210af75f1c3d71c59 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 8 Jun 2021 11:36:57 -0400
Subject: [PATCH 24/89] refactor(transitive-overlay): Remove
componentShouldUpdate
---
.../map/connected-transitive-overlay.js | 25 +------------------
1 file changed, 1 insertion(+), 24 deletions(-)
diff --git a/lib/components/map/connected-transitive-overlay.js b/lib/components/map/connected-transitive-overlay.js
index 8a2658fed..5d7c6da75 100644
--- a/lib/components/map/connected-transitive-overlay.js
+++ b/lib/components/map/connected-transitive-overlay.js
@@ -1,35 +1,12 @@
-import TransitiveOverlay from '@opentripplanner/transitive-overlay'
-import React, { Component } from 'react'
+import TransitiveCanvasOverlay from '@opentripplanner/transitive-overlay'
import { connect } from 'react-redux'
import { getTransitiveData } from '../../util/state'
-/**
- * Wrapper for TransitiveOverlay that avoids rerenders by checking transitive
- * data computed from redux store.
- */
-class TransitiveCanvasOverlay extends Component {
- shouldComponentUpdate (nextProps) {
- return nextProps.transitiveData !== this.props.transitiveData
- }
-
- render () {
- const { labeledModes, styles, transitiveData } = this.props
- return (
-
- )
- }
-}
-
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
const { labeledModes, styles } = state.otp.config.map.transitive || {}
-
return {
labeledModes,
styles,
From da1262751ad1d8e9c18a39b35ddd4a2f1c13b3a3 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Wed, 9 Jun 2021 09:47:11 -0400
Subject: [PATCH 25/89] fix(calltaker): Do not require modules in config.
Fix #382
---
lib/reducers/call-taker.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/reducers/call-taker.js b/lib/reducers/call-taker.js
index 97709ec5e..4fa3849b7 100644
--- a/lib/reducers/call-taker.js
+++ b/lib/reducers/call-taker.js
@@ -5,7 +5,7 @@ import {constructNewCall} from '../util/call-taker'
import {FETCH_STATUS} from '../util/constants'
function createCallTakerReducer (config) {
- const calltakerConfig = config.modules.find(m => m.id === 'call')
+ const calltakerConfig = config.modules?.find(m => m.id === 'call')
const initialState = {
activeCall: null,
callHistory: {
From b9e07a113c0ad15355997560179765d70f4c8f6d Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 10 Jun 2021 08:51:07 -0400
Subject: [PATCH 26/89] fix(SavedTripScreen): Initialize trip monitored days
using itin transit leg svc date.
---
__tests__/util/itinerary.js | 62 +++++++++++++++++--
.../user/monitored-trip/saved-trip-screen.js | 6 +-
lib/util/itinerary.js | 27 ++++++++
lib/util/monitored-trip.js | 3 +-
4 files changed, 91 insertions(+), 7 deletions(-)
diff --git a/__tests__/util/itinerary.js b/__tests__/util/itinerary.js
index c2604a303..8bbc95538 100644
--- a/__tests__/util/itinerary.js
+++ b/__tests__/util/itinerary.js
@@ -1,6 +1,14 @@
/* globals describe, expect, it */
-import { itineraryCanBeMonitored } from '../../lib/util/itinerary'
+import {
+ getTransitItineraryDefaultMonitoredDays,
+ itineraryCanBeMonitored
+} from '../../lib/util/itinerary'
+import { WEEKDAYS, WEEKEND_DAYS } from '../../lib/util/monitored-trip'
+
+const walkLeg = {
+ mode: 'WALK'
+}
describe('util > itinerary', () => {
describe('itineraryCanBeMonitored', () => {
@@ -20,9 +28,6 @@ describe('util > itinerary', () => {
mode: 'MICROMOBILITY_RENT',
rentedVehicle: true
}
- const walkLeg = {
- mode: 'WALK'
- }
const rideHailLeg = {
mode: 'CAR_HAIL',
hailedCar: true
@@ -80,4 +85,53 @@ describe('util > itinerary', () => {
})
})
})
+ describe('getTransitItineraryDefaultMonitoredDays', () => {
+ const transitLegWeekday = {
+ mode: 'BUS',
+ serviceDate: '20210609', // Wendesday
+ transitLeg: true
+ }
+ const transitLegSaturday = {
+ mode: 'BUS',
+ serviceDate: '20210612', // Saturday
+ transitLeg: true
+ }
+ const transitLegSunday = {
+ mode: 'BUS',
+ serviceDate: '20210613', // Sunday
+ transitLeg: true
+ }
+
+ const testCases = [{
+ expected: WEEKDAYS,
+ itinerary: {
+ legs: [walkLeg, transitLegWeekday]
+ },
+ title: 'should be [\'monday\' thru \'friday\'] for an itinerary starting on a weekday.'
+ }, {
+ expected: WEEKEND_DAYS,
+ itinerary: {
+ legs: [walkLeg, transitLegSaturday]
+ },
+ title: 'should be [\'saturday\', \'sunday\'] for an itinerary starting on a Saturday.'
+ }, {
+ expected: WEEKEND_DAYS,
+ itinerary: {
+ legs: [walkLeg, transitLegSunday]
+ },
+ title: 'should be [\'saturday\', \'sunday\'] for an itinerary starting on a Sunday.'
+ }, {
+ expected: null,
+ itinerary: {
+ legs: [walkLeg]
+ },
+ title: 'should be null for an itinerary without transit.'
+ }]
+
+ testCases.forEach(({ expected, itinerary, title }) => {
+ it(title, () => {
+ expect(getTransitItineraryDefaultMonitoredDays(itinerary)).toBe(expected)
+ })
+ })
+ })
})
diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js
index 3b02e59d5..8b17d743d 100644
--- a/lib/components/user/monitored-trip/saved-trip-screen.js
+++ b/lib/components/user/monitored-trip/saved-trip-screen.js
@@ -14,7 +14,8 @@ import TripBasicsPane from './trip-basics-pane'
import TripNotificationsPane from './trip-notifications-pane'
import TripSummaryPane from './trip-summary-pane'
import { TRIPS_PATH } from '../../../util/constants'
-import { ALL_DAYS, arrayToDayFields, WEEKDAYS } from '../../../util/monitored-trip'
+import { getTransitItineraryDefaultMonitoredDays } from '../../../util/itinerary'
+import { ALL_DAYS, arrayToDayFields } from '../../../util/monitored-trip'
import { getActiveItineraries, getActiveSearch } from '../../../util/state'
import { RETURN_TO_CURRENT_ROUTE } from '../../../util/ui'
import withLoggedInUserSupport from '../with-logged-in-user-support'
@@ -60,8 +61,9 @@ class SavedTripScreen extends Component {
*/
_createMonitoredTrip = () => {
const { itinerary, loggedInUser, queryParams } = this.props
+ const monitoredDays = getTransitItineraryDefaultMonitoredDays(itinerary)
return {
- ...arrayToDayFields(WEEKDAYS),
+ ...arrayToDayFields(monitoredDays),
arrivalVarianceMinutesThreshold: 5,
departureVarianceMinutesThreshold: 5,
excludeFederalHolidays: true,
diff --git a/lib/util/itinerary.js b/lib/util/itinerary.js
index e31e70c67..b030afedd 100644
--- a/lib/util/itinerary.js
+++ b/lib/util/itinerary.js
@@ -1,6 +1,7 @@
import { latLngBounds } from 'leaflet'
import moment from 'moment'
import coreUtils from '@opentripplanner/core-utils'
+import { WEEKDAYS, WEEKEND_DAYS } from './monitored-trip'
export function getLeafletItineraryBounds (itinerary) {
return latLngBounds(coreUtils.itinerary.getItineraryBounds(itinerary))
@@ -47,3 +48,29 @@ export function itineraryCanBeMonitored (itinerary) {
export function getMinutesUntilItineraryStart (itinerary) {
return moment(itinerary.startTime).diff(moment(), 'minutes')
}
+
+/**
+ * Gets the first transit leg of the given itinerary, or null if none found.
+ */
+function getFirstTransitLeg (itinerary) {
+ return itinerary?.legs?.find(leg => leg.transitLeg)
+}
+
+/**
+ * Returns the set of monitored days that will be initially shown to the user
+ * for the given transit itinerary (itinerary with transit leg).
+ * @param itinerary The itinerary from which the default monitored days are extracted.
+ * @returns ['monday' thru 'friday'] if itinerary happens on a weekday(*),
+ * ['saturday', 'sunday'] if itinerary happens on a saturday/sunday(*).
+ * (*) The first transit leg will be used to make the determination.
+ */
+export function getTransitItineraryDefaultMonitoredDays (itinerary) {
+ const firstTransitLeg = getFirstTransitLeg(itinerary)
+ // Assume a transit leg exists.
+ if (!firstTransitLeg) return null
+
+ const dayOfWeek = moment(firstTransitLeg.serviceDate, 'YYYYMMDD').day()
+ return (dayOfWeek === 0 || dayOfWeek === 6)
+ ? WEEKEND_DAYS
+ : WEEKDAYS
+}
diff --git a/lib/util/monitored-trip.js b/lib/util/monitored-trip.js
index 4ff62656f..dee229197 100644
--- a/lib/util/monitored-trip.js
+++ b/lib/util/monitored-trip.js
@@ -1,5 +1,6 @@
export const WEEKDAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday']
-export const ALL_DAYS = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday']
+export const WEEKEND_DAYS = ['saturday', 'sunday']
+export const ALL_DAYS = [...WEEKDAYS, ...WEEKEND_DAYS]
/**
* Extracts the day of week fields of an object (e.g. a monitoredTrip) to an array.
From 0e87eb28ec806efb6cf079318a1093e7b66524c5 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 10 Jun 2021 09:05:48 -0400
Subject: [PATCH 27/89] docs(tests/itinerary): Fix comment typo.
---
__tests__/util/itinerary.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/__tests__/util/itinerary.js b/__tests__/util/itinerary.js
index 8bbc95538..44922640a 100644
--- a/__tests__/util/itinerary.js
+++ b/__tests__/util/itinerary.js
@@ -88,7 +88,7 @@ describe('util > itinerary', () => {
describe('getTransitItineraryDefaultMonitoredDays', () => {
const transitLegWeekday = {
mode: 'BUS',
- serviceDate: '20210609', // Wendesday
+ serviceDate: '20210609', // Wednesday
transitLeg: true
}
const transitLegSaturday = {
From 4eaa00046b5dbcda886968309c4452f49cda1237 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Thu, 10 Jun 2021 12:43:16 -0400
Subject: [PATCH 28/89] refactor(util/itinerary): Add monitored days
calculation for non-transit itineraries.
---
__tests__/util/itinerary.js | 27 ++++++++++++++-----
.../user/monitored-trip/saved-trip-screen.js | 4 +--
lib/util/itinerary.js | 14 +++++-----
3 files changed, 31 insertions(+), 14 deletions(-)
diff --git a/__tests__/util/itinerary.js b/__tests__/util/itinerary.js
index 44922640a..caac6ec17 100644
--- a/__tests__/util/itinerary.js
+++ b/__tests__/util/itinerary.js
@@ -1,7 +1,7 @@
/* globals describe, expect, it */
import {
- getTransitItineraryDefaultMonitoredDays,
+ getItineraryDefaultMonitoredDays,
itineraryCanBeMonitored
} from '../../lib/util/itinerary'
import { WEEKDAYS, WEEKEND_DAYS } from '../../lib/util/monitored-trip'
@@ -85,7 +85,7 @@ describe('util > itinerary', () => {
})
})
})
- describe('getTransitItineraryDefaultMonitoredDays', () => {
+ describe('getItineraryDefaultMonitoredDays', () => {
const transitLegWeekday = {
mode: 'BUS',
serviceDate: '20210609', // Wednesday
@@ -121,16 +121,31 @@ describe('util > itinerary', () => {
},
title: 'should be [\'saturday\', \'sunday\'] for an itinerary starting on a Sunday.'
}, {
- expected: null,
+ expected: WEEKDAYS,
+ itinerary: {
+ legs: [walkLeg],
+ startTime: 1623341891000 // Thursday 2021-06-10 12:18 pm EDT
+ },
+ title: 'should be [\'monday\' thru \'friday\'] for an itinerary without transit starting on a weekday (fallback case).'
+ }, {
+ expected: WEEKEND_DAYS,
+ itinerary: {
+ legs: [walkLeg],
+ startTime: 1623514691000 // Saturday 2021-06-12 12:18 pm EDT
+ },
+ title: 'should be [\'saturday\', \'sunday\'] for an itinerary without transit starting on a Saturday (fallback case).'
+ }, {
+ expected: WEEKEND_DAYS,
itinerary: {
- legs: [walkLeg]
+ legs: [walkLeg],
+ startTime: 1623601091000 // Sunday 2021-06-13 12:18 pm EDT
},
- title: 'should be null for an itinerary without transit.'
+ title: 'should be [\'saturday\', \'sunday\'] for an itinerary without transit starting on a Sunday (fallback case).'
}]
testCases.forEach(({ expected, itinerary, title }) => {
it(title, () => {
- expect(getTransitItineraryDefaultMonitoredDays(itinerary)).toBe(expected)
+ expect(getItineraryDefaultMonitoredDays(itinerary)).toBe(expected)
})
})
})
diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js
index 8b17d743d..0a814d9e7 100644
--- a/lib/components/user/monitored-trip/saved-trip-screen.js
+++ b/lib/components/user/monitored-trip/saved-trip-screen.js
@@ -14,7 +14,7 @@ import TripBasicsPane from './trip-basics-pane'
import TripNotificationsPane from './trip-notifications-pane'
import TripSummaryPane from './trip-summary-pane'
import { TRIPS_PATH } from '../../../util/constants'
-import { getTransitItineraryDefaultMonitoredDays } from '../../../util/itinerary'
+import { getItineraryDefaultMonitoredDays } from '../../../util/itinerary'
import { ALL_DAYS, arrayToDayFields } from '../../../util/monitored-trip'
import { getActiveItineraries, getActiveSearch } from '../../../util/state'
import { RETURN_TO_CURRENT_ROUTE } from '../../../util/ui'
@@ -61,7 +61,7 @@ class SavedTripScreen extends Component {
*/
_createMonitoredTrip = () => {
const { itinerary, loggedInUser, queryParams } = this.props
- const monitoredDays = getTransitItineraryDefaultMonitoredDays(itinerary)
+ const monitoredDays = getItineraryDefaultMonitoredDays(itinerary)
return {
...arrayToDayFields(monitoredDays),
arrivalVarianceMinutesThreshold: 5,
diff --git a/lib/util/itinerary.js b/lib/util/itinerary.js
index b030afedd..a8eec1c9c 100644
--- a/lib/util/itinerary.js
+++ b/lib/util/itinerary.js
@@ -58,18 +58,20 @@ function getFirstTransitLeg (itinerary) {
/**
* Returns the set of monitored days that will be initially shown to the user
- * for the given transit itinerary (itinerary with transit leg).
+ * for the given itinerary.
* @param itinerary The itinerary from which the default monitored days are extracted.
* @returns ['monday' thru 'friday'] if itinerary happens on a weekday(*),
* ['saturday', 'sunday'] if itinerary happens on a saturday/sunday(*).
- * (*) The first transit leg will be used to make the determination.
+ * (*) For transit itineraries, the first transit leg is used to make
+ * the determination. Otherwise, the itinerary startTime is used.
*/
-export function getTransitItineraryDefaultMonitoredDays (itinerary) {
+export function getItineraryDefaultMonitoredDays (itinerary) {
const firstTransitLeg = getFirstTransitLeg(itinerary)
- // Assume a transit leg exists.
- if (!firstTransitLeg) return null
+ const startMoment = firstTransitLeg
+ ? moment(firstTransitLeg.serviceDate, 'YYYYMMDD')
+ : moment(itinerary.startTime)
+ const dayOfWeek = startMoment.day()
- const dayOfWeek = moment(firstTransitLeg.serviceDate, 'YYYYMMDD').day()
return (dayOfWeek === 0 || dayOfWeek === 6)
? WEEKEND_DAYS
: WEEKDAYS
From 1616cfa01a08d122c67dff4708e0d28c011e3804 Mon Sep 17 00:00:00 2001
From: Rob Gregg
Date: Fri, 11 Jun 2021 14:25:57 +0100
Subject: [PATCH 29/89] refactor(batch-routing-panel.js): Added the class back
for the ViewerContainer
---
lib/components/app/batch-routing-panel.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/components/app/batch-routing-panel.js b/lib/components/app/batch-routing-panel.js
index d7505ef79..5d7125d67 100644
--- a/lib/components/app/batch-routing-panel.js
+++ b/lib/components/app/batch-routing-panel.js
@@ -36,7 +36,7 @@ class BatchRoutingPanel extends Component {
const {mobile} = this.props
const actionText = mobile ? 'tap' : 'click'
return (
-
+
Date: Mon, 14 Jun 2021 10:46:44 -0400
Subject: [PATCH 30/89] refactor(mailables): update config, add menu item in
navbar
---
lib/components/admin/mailables-window.js | 44 +++++++++++++-----------
lib/components/admin/styled.js | 7 ++++
lib/components/app/app-menu.js | 17 +++++++--
lib/reducers/call-taker.js | 2 +-
lib/util/mailables.js | 37 ++++++++++----------
5 files changed, 64 insertions(+), 43 deletions(-)
diff --git a/lib/components/admin/mailables-window.js b/lib/components/admin/mailables-window.js
index 7766c5aa1..1d5f7af99 100644
--- a/lib/components/admin/mailables-window.js
+++ b/lib/components/admin/mailables-window.js
@@ -1,14 +1,15 @@
import React, { Component } from 'react'
+import { Badge } from 'react-bootstrap'
import { connect } from 'react-redux'
import * as callTakerActions from '../../actions/call-taker'
import DraggableWindow from './draggable-window'
import Icon from '../narrative/icon'
-import {WindowHeader} from './styled'
+import {MailablesList, WindowHeader} from './styled'
import {createLetter, MAILABLE_FIELDS} from '../../util/mailables'
/**
- * A window enabled through the Call Taker module that allows Call Taker users
+ * A window enabled through the Mailables module that allows Call Taker users
* to generate a PDF with an invoice of items to be mailed to transit customers.
*/
class MailablesWindow extends Component {
@@ -20,13 +21,11 @@ class MailablesWindow extends Component {
}
_addMailable = (mailable) => {
- const mailables = [...this.state.mailables]
- if (!mailables.find(m => m.name === mailable.name)) {
+ if (!this.state.mailables.find(m => m.name === mailable.name)) {
+ const mailables = [...this.state.mailables]
mailables.push({...mailable, quantity: 1})
- } else {
- // FIXME: Increase quanity?
+ this.setState({mailables})
}
- this.setState({mailables})
}
_removeMailable = (mailable) => {
@@ -42,18 +41,20 @@ class MailablesWindow extends Component {
this.setState({mailables})
}
- _onClickCreateLetter = () => createLetter(this.state, this.props.callConfig.options)
+ _onClickCreateLetter = () => createLetter(this.state, this.props.mailablesConfig)
_updateField = (evt) => {
this.setState({[evt.target.id]: evt.target.value})
}
render () {
- const {callConfig, callTaker, toggleMailables} = this.props
+ const {mailablesConfig, callTaker, toggleMailables} = this.props
const {mailables: selectedMailables} = this.state
- const {mailables} = callConfig.options
+ const {items} = mailablesConfig
if (!callTaker.mailables.visible) return null
- const selectableMailables = mailables.filter(m => !selectedMailables.find(mailable => mailable.name === m.name))
+ const selectableMailables = items.filter(m =>
+ !selectedMailables.find(mailable => mailable.name === m.name)
+ )
return (
{MAILABLE_FIELDS.map(f => (
@@ -82,25 +83,26 @@ class MailablesWindow extends Component {
key={f.fieldName}
id={f.fieldName}
onChange={this._updateField}
- placeholder={f.fieldName}
+ placeholder={f.placeholder}
+ style={{margin: '5px'}}
value={this.state[f.fieldName]} />
))}
All Mailables
-
+
{selectableMailables.map((mailable, i) => (
))}
-
+
-
Selected Mailables
-
+
Selected Mailables {selectedMailables.length}
+
{selectedMailables.length > 0
? selectedMailables.map((mailable, i) => (
No mailables selected.
}
-
+
@@ -178,10 +180,10 @@ class MailableOption extends Component {
}
const mapStateToProps = (state, ownProps) => {
- const callConfig = state.otp.config.modules.find(m => m.id === 'call')
+ const mailablesConfig = state.otp.config.modules?.find(m => m.id === 'mailables')
return {
- callConfig,
- callTaker: state.callTaker
+ callTaker: state.callTaker,
+ mailablesConfig
}
}
diff --git a/lib/components/admin/styled.js b/lib/components/admin/styled.js
index 888c0cbb6..29d34cec3 100644
--- a/lib/components/admin/styled.js
+++ b/lib/components/admin/styled.js
@@ -154,3 +154,10 @@ export const WindowHeader = styled.h3`
margin-bottom: 10px;
margin-top: 10px;
`
+
+// Mailables components
+
+export const MailablesList = styled.div`
+ max-height: 120px;
+ overflow-y: scroll;
+`
diff --git a/lib/components/app/app-menu.js b/lib/components/app/app-menu.js
index 703c0752d..fae07c9f1 100644
--- a/lib/components/app/app-menu.js
+++ b/lib/components/app/app-menu.js
@@ -7,6 +7,7 @@ import { withRouter } from 'react-router'
import Icon from '../narrative/icon'
+import * as callTakerActions from '../../actions/call-taker'
import { MainPanelContent, setMainPanelContent } from '../../actions/ui'
// TODO: make menu items configurable via props/config
@@ -39,8 +40,10 @@ class AppMenu extends Component {
window.location.href = startOverUrl
}
+ _toggleMailables = () => this.props.toggleMailables()
+
render () {
- const { languageConfig } = this.props
+ const { languageConfig, mailablesEnabled } = this.props
return (
@@ -53,6 +56,11 @@ class AppMenu extends Component {
+ {mailablesEnabled &&
+
+ }
@@ -65,13 +73,16 @@ class AppMenu extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
+ const {language, modules} = state.otp.config
return {
- languageConfig: state.otp.config.language
+ languageConfig: language,
+ mailablesEnabled: Boolean(modules?.find(m => m.id === 'mailables'))
}
}
const mapDispatchToProps = {
- setMainPanelContent
+ setMainPanelContent,
+ toggleMailables: callTakerActions.toggleMailables
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(AppMenu))
diff --git a/lib/reducers/call-taker.js b/lib/reducers/call-taker.js
index 6c0e1cad6..2694017dc 100644
--- a/lib/reducers/call-taker.js
+++ b/lib/reducers/call-taker.js
@@ -28,7 +28,7 @@ function createCallTakerReducer (config) {
visible: false
},
mailables: {
- visible: true
+ visible: false
},
session: null
}
diff --git a/lib/util/mailables.js b/lib/util/mailables.js
index 5094aaefd..59ee14394 100644
--- a/lib/util/mailables.js
+++ b/lib/util/mailables.js
@@ -4,16 +4,16 @@ import moment from 'moment'
import PDFDocument from './PDFDocumentWithTables'
export const MAILABLE_FIELDS = [
- {fieldName: 'firstname'},
- {fieldName: 'lastname'},
- {fieldName: 'address1'},
- {fieldName: 'address2'},
- {fieldName: 'city'},
- {fieldName: 'state'},
- {fieldName: 'zip'}
+ {fieldName: 'firstname', placeholder: 'First name'},
+ {fieldName: 'lastname', placeholder: 'Last name'},
+ {fieldName: 'address1', placeholder: 'Address 1'},
+ {fieldName: 'address2', placeholder: 'Address 2'},
+ {fieldName: 'city', placeholder: 'City'},
+ {fieldName: 'state', placeholder: 'State'},
+ {fieldName: 'zip', placeholder: 'Zip'}
]
-export function createLetter (formData, otpConfig) {
+export function createLetter (formData, mailablesConfig) {
// This is a very goofy approach to convert an image URL to its image data for
// writing to the PDF, but it seems to be a solid approach.
const img = new Image()
@@ -27,9 +27,10 @@ export function createLetter (formData, otpConfig) {
ctx.drawImage(img, 0, 0)
const data = canvas.toDataURL('image/png')
- writePDF(formData, {data, height: img.height, width: img.width}, otpConfig)
+ const imageData = {data, height: img.height, width: img.width}
+ writePDF(formData, imageData, mailablesConfig)
}
- img.src = otpConfig.mailables_header_graphic
+ img.src = mailablesConfig.header_graphic
}
function writePDF (formData, imageData, otpConfig) {
@@ -44,8 +45,8 @@ function writePDF (formData, imageData, otpConfig) {
zip = ''
} = formData
const {
- mailables_horizontal_margin: horizontalMargin,
- mailables_vertical_margin: verticalMargin
+ horizontal_margin: horizontalMargin,
+ vertical_margin: verticalMargin
} = otpConfig
const margins = {
top: verticalMargin,
@@ -76,7 +77,7 @@ function writePDF (formData, imageData, otpConfig) {
// introduction block
doc.moveDown()
.moveDown()
- .text(otpConfig.mailables_introduction)
+ .text(otpConfig.introduction)
// table header
doc.font('Helvetica-Bold')
@@ -106,7 +107,7 @@ function writePDF (formData, imageData, otpConfig) {
doc.moveDown()
.moveDown()
.font('Helvetica')
- .text(otpConfig.mailables_conclusion)
+ .text(otpConfig.conclusion)
doc.end()
stream.on('finish', () => {
@@ -117,10 +118,10 @@ function writePDF (formData, imageData, otpConfig) {
function preparePage (doc, imageData, otpConfig) {
const {
- mailables_footer: footer,
- mailables_header_graphic: headerGraphic,
- mailables_header_graphic_height: headerGraphicHeight,
- mailables_header_graphic_width: headerGraphicWidth
+ footer: footer,
+ header_graphic: headerGraphic,
+ header_graphic_height: headerGraphicHeight,
+ header_graphic_width: headerGraphicWidth
} = otpConfig
// Store true bottom of page while bottom is temporarily moved to 0.
const bottom = doc.page.margins.bottom
From d66db6d84e238eb6d16f1c02944ee3191621e590 Mon Sep 17 00:00:00 2001
From: Landon Reed
Date: Mon, 14 Jun 2021 10:55:14 -0400
Subject: [PATCH 31/89] refactor(mailables): tweak window height
---
lib/components/admin/mailables-window.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/components/admin/mailables-window.js b/lib/components/admin/mailables-window.js
index 1d5f7af99..73674cf03 100644
--- a/lib/components/admin/mailables-window.js
+++ b/lib/components/admin/mailables-window.js
@@ -75,7 +75,7 @@ class MailablesWindow extends Component {
}
onClickClose={toggleMailables}
scroll={false}
- style={{height: '400px', width: '600px'}}
+ style={{height: '340px', width: '600px'}}
>
{MAILABLE_FIELDS.map(f => (
From a0e0384c6689c5f3dd2774e50dc7eba255a02d8c Mon Sep 17 00:00:00 2001
From: Landon Reed
Date: Mon, 14 Jun 2021 13:37:21 -0400
Subject: [PATCH 32/89] refactor(mailables): fix lint
---
lib/util/mailables.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/util/mailables.js b/lib/util/mailables.js
index 59ee14394..d4c30221d 100644
--- a/lib/util/mailables.js
+++ b/lib/util/mailables.js
@@ -118,7 +118,7 @@ function writePDF (formData, imageData, otpConfig) {
function preparePage (doc, imageData, otpConfig) {
const {
- footer: footer,
+ footer,
header_graphic: headerGraphic,
header_graphic_height: headerGraphicHeight,
header_graphic_width: headerGraphicWidth
From 5c4d8f693ad6644619c6352b0461eb597a8973c5 Mon Sep 17 00:00:00 2001
From: binh-dam-ibigroup <56846598+binh-dam-ibigroup@users.noreply.github.com>
Date: Tue, 15 Jun 2021 07:28:13 -0400
Subject: [PATCH 33/89] Update lib/util/state.js per PR suggestion.
Co-authored-by: Evan Siroky
---
lib/util/state.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/util/state.js b/lib/util/state.js
index bbde22fa6..846e2da3f 100644
--- a/lib/util/state.js
+++ b/lib/util/state.js
@@ -336,8 +336,7 @@ function itineraryResponseExists (state) {
* @param {*} state The entire redux state from which to retrieve the itinerary.
*/
export function getVisibleItineraryIndex (state) {
- const activeSearch = getActiveSearch(state.otp)
- return activeSearch && activeSearch.visibleItinerary
+ return getActiveSearch(state.otp)?.visibleItinerary
}
/**
From fa122b9c3aed283fccef701163e6b41e9be9c723 Mon Sep 17 00:00:00 2001
From: Evan Siroky
Date: Wed, 16 Jun 2021 16:45:16 -0700
Subject: [PATCH 34/89] refactor: remove otpState middleman
---
__tests__/util/state.js | 14 ++--
lib/actions/api.js | 68 ++++++++++--------
lib/actions/form.js | 19 ++---
lib/actions/map.js | 4 +-
lib/actions/ui.js | 11 +--
lib/components/app/batch-routing-panel.js | 4 +-
lib/components/app/call-taker-panel.js | 4 +-
lib/components/app/default-main-panel.js | 4 +-
lib/components/app/print-layout.js | 2 +-
lib/components/app/responsive-webapp.js | 7 +-
lib/components/form/batch-preferences.js | 2 +-
lib/components/form/batch-settings.js | 9 +--
lib/components/form/connect-location-field.js | 4 +-
.../form/connected-settings-selector-panel.js | 2 +-
lib/components/form/error-message.js | 4 +-
lib/components/map/bounds-updating-overlay.js | 4 +-
.../map/connected-endpoints-overlay.js | 4 +-
.../map/connected-transitive-overlay.js | 6 +-
lib/components/map/stylized-map.js | 4 +-
lib/components/mobile/batch-results-screen.js | 6 +-
lib/components/mobile/main.js | 10 +--
lib/components/mobile/results-header.js | 6 +-
lib/components/mobile/results-screen.js | 8 +--
.../narrative/itinerary-carousel.js | 9 +--
.../narrative/narrative-itineraries.js | 13 ++--
.../narrative/narrative-routing-results.js | 12 ++--
lib/components/narrative/save-trip-button.js | 2 +-
.../narrative/tabbed-itineraries.js | 4 +-
.../user/monitored-trip/saved-trip-screen.js | 13 ++--
lib/components/viewers/stop-viewer.js | 9 +--
lib/util/state.js | 72 +++++++++----------
31 files changed, 182 insertions(+), 158 deletions(-)
diff --git a/__tests__/util/state.js b/__tests__/util/state.js
index 5385038f9..ae982c5d8 100644
--- a/__tests__/util/state.js
+++ b/__tests__/util/state.js
@@ -15,17 +15,21 @@ describe('util > state', () => {
const testCases = [{
expected: false,
input: {
- currentQuery: {
- from: fakeFromLocation
+ otp: {
+ currentQuery: {
+ from: fakeFromLocation
+ }
}
},
title: 'should not be valid with only from location'
}, {
expected: true,
input: {
- currentQuery: {
- from: fakeFromLocation,
- to: fakeToLocation
+ otp: {
+ currentQuery: {
+ from: fakeFromLocation,
+ to: fakeToLocation
+ }
}
},
title: 'should be valid with from and to locations'
diff --git a/lib/actions/api.js b/lib/actions/api.js
index 0bf3a442c..f712a786b 100644
--- a/lib/actions/api.js
+++ b/lib/actions/api.js
@@ -8,10 +8,11 @@ import queryParams from '@opentripplanner/core-utils/lib/query-params'
import { createAction } from 'redux-actions'
import qs from 'qs'
-import { rememberPlace } from './map'
import { getStopViewerConfig, queryIsValid } from '../util/state'
import { getSecureFetchOptions } from '../util/middleware'
+import { rememberPlace } from './map'
+
if (typeof (fetch) === 'undefined') require('isomorphic-fetch')
const { hasCar } = coreUtils.itinerary
@@ -39,9 +40,9 @@ function formatRecentPlace (place) {
}
}
-function formatRecentSearch (url, otpState) {
+function formatRecentSearch (url, state) {
return {
- query: getTripOptionsFromQuery(otpState.currentQuery, true),
+ query: getTripOptionsFromQuery(state.otp.currentQuery, true),
url,
id: randId(),
timestamp: new Date().getTime()
@@ -57,8 +58,8 @@ function isStoredPlace (place) {
* session (i.e. searches lookup is empty/null) AND an activeItinerary ID
* is specified in URL parameters, use that ID. Otherwise, use null/0.
*/
-function getActiveItinerary (otpState) {
- const {currentQuery, searches} = otpState
+function getActiveItinerary (state) {
+ const {currentQuery, searches} = state.otp
let activeItinerary = currentQuery.routingType === 'ITINERARY' ? 0 : null
// We cannot use window.history.state here to check for the active
// itinerary param because it is unreliable in some states (e.g.,
@@ -84,43 +85,47 @@ export function routingQuery (searchId = null) {
return async function (dispatch, getState) {
// FIXME: batchId is searchId for now.
const state = getState()
- const otpState = state.otp
const isNewSearch = !searchId
if (isNewSearch) searchId = randId()
// Don't permit a routing query if the query is invalid
- if (!queryIsValid(otpState)) {
- console.warn('Query is invalid. Aborting routing query', otpState.currentQuery)
+ if (!queryIsValid(state)) {
+ console.warn(
+ 'Query is invalid. Aborting routing query',
+ state.otp.currentQuery
+ )
return
}
- const activeItinerary = getActiveItinerary(otpState)
- const routingType = otpState.currentQuery.routingType
+ const activeItinerary = getActiveItinerary(state)
+ const routingType = state.otp.currentQuery.routingType
// For multiple mode combinations, gather injected params from config/query.
// Otherwise, inject nothing (rely on what's in current query) and perform
// one iteration.
- const iterations = otpState.currentQuery.combinations
- ? otpState.currentQuery.combinations.map(({mode, params}) => ({mode, ...params}))
+ const iterations = state.otp.currentQuery.combinations
+ ? state.otp.currentQuery.combinations.map(
+ ({mode, params}) => ({mode, ...params})
+ )
: [{}]
dispatch(routingRequest({ activeItinerary, routingType, searchId, pending: iterations.length }))
iterations.forEach((injectedParams, i) => {
const requestId = randId()
// fetch a realtime route
- const query = constructRoutingQuery(otpState, false, injectedParams)
+ const query = constructRoutingQuery(state, false, injectedParams)
fetch(query, getOtpFetchOptions(state))
.then(getJsonAndCheckResponse)
.then(json => {
dispatch(routingResponse({ response: json, requestId, searchId }))
// If tracking is enabled, store locations and search after successful
// search is completed.
- if (otpState.user.trackRecent) {
- const { from, to } = otpState.currentQuery
+ if (state.otp.user.trackRecent) {
+ const { from, to } = state.otp.currentQuery
if (!isStoredPlace(from)) {
dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(from) }))
}
if (!isStoredPlace(to)) {
dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(to) }))
}
- dispatch(rememberSearch(formatRecentSearch(query, otpState)))
+ dispatch(rememberSearch(formatRecentSearch(query, state)))
}
})
.catch(error => {
@@ -135,7 +140,7 @@ export function routingQuery (searchId = null) {
// that the path absolutely accurately reflects the app state.
const params = getUrlParams()
if (isNewSearch || params.ui_activeSearch !== searchId) {
- dispatch(updateOtpUrlParams(otpState, searchId))
+ dispatch(updateOtpUrlParams(state, searchId))
}
// Also fetch a non-realtime route.
@@ -159,7 +164,10 @@ export function routingQuery (searchId = null) {
user.loggedInUser &&
user.loggedInUser.storeTripHistory
- fetch(constructRoutingQuery(otpState, true), getOtpFetchOptions(state, storeTripHistory))
+ fetch(
+ constructRoutingQuery(state, true),
+ getOtpFetchOptions(state, storeTripHistory)
+ )
.then(getJsonAndCheckResponse)
.then(json => {
// FIXME: This is only performed when ignoring realtimeupdates currently, just
@@ -219,8 +227,8 @@ function getOtpFetchOptions (state, includeToken = false) {
}
}
-function constructRoutingQuery (otpState, ignoreRealtimeUpdates, injectedParams = {}) {
- const { config, currentQuery } = otpState
+function constructRoutingQuery (state, ignoreRealtimeUpdates, injectedParams = {}) {
+ const { config, currentQuery } = state.otp
const routingType = currentQuery.routingType
// Check for routingType-specific API config; if none, use default API
const rt = config.routingTypes && config.routingTypes.find(rt => rt.key === routingType)
@@ -549,6 +557,7 @@ const findStopTimesForStopError = createAction('FIND_STOP_TIMES_FOR_STOP_ERROR')
*/
export function findStopTimesForStop (params) {
return function (dispatch, getState) {
+ const state = getState()
dispatch(fetchingStopTimesForStop(params))
const { date, stopId, ...otherParams } = params
let datePath = ''
@@ -559,7 +568,7 @@ export function findStopTimesForStop (params) {
// If other params not provided, fall back on defaults from stop viewer config.
// Note: query params don't apply with the OTP /date endpoint.
- const queryParams = { ...getStopViewerConfig(getState().otp), ...otherParams }
+ const queryParams = { ...getStopViewerConfig(state), ...otherParams }
// If no start time is provided and no date is provided in params,
// pass in the current time. Note: this is not
@@ -936,15 +945,18 @@ window.setInterval(() => {
function createQueryAction (endpoint, responseAction, errorAction, options = {}) {
return async function (dispatch, getState) {
- const otpState = getState().otp
+ const state = getState()
+ const { config } = state.otp
let url
- if (options.serviceId && otpState.config.alternateTransitIndex &&
- otpState.config.alternateTransitIndex.services.includes(options.serviceId)
+ if (
+ options.serviceId &&
+ config.alternateTransitIndex &&
+ config.alternateTransitIndex.services.includes(options.serviceId)
) {
console.log('Using alt service for ' + options.serviceId)
- url = otpState.config.alternateTransitIndex.apiRoot + endpoint
+ url = config.alternateTransitIndex.apiRoot + endpoint
} else {
- const api = otpState.config.api
+ const api = config.api
url = `${api.host}${api.port ? ':' + api.port : ''}${api.path}/${endpoint}`
}
@@ -1023,8 +1035,8 @@ export function setUrlSearch (params, replaceCurrent = false) {
* Update the OTP Query parameters in the URL and ensure that the active search
* is set correctly. Leaves any other existing URL parameters (e.g., UI) unchanged.
*/
-function updateOtpUrlParams (otpState, searchId) {
- const {config, currentQuery} = otpState
+function updateOtpUrlParams (state, searchId) {
+ const {config, currentQuery} = state.otp
// Get updated OTP params from current query.
const otpParams = getRoutingParams(currentQuery, config, true)
return function (dispatch, getState) {
diff --git a/lib/actions/form.js b/lib/actions/form.js
index 077e85ae3..1192b2218 100644
--- a/lib/actions/form.js
+++ b/lib/actions/form.js
@@ -5,6 +5,8 @@ import moment from 'moment'
import qs from 'qs'
import { createAction } from 'redux-actions'
+import { queryIsValid } from '../util/state'
+
import { routingQuery } from './api'
import { setLocation } from './map'
import {
@@ -13,7 +15,6 @@ import {
setMainPanelContent,
setMobileScreen
} from './ui'
-import { queryIsValid } from '../util/state'
const {
getDefaultQuery,
@@ -35,15 +36,15 @@ export const storeDefaultSettings = createAction('STORE_DEFAULT_SETTINGS')
*/
export function resetForm (full = false) {
return function (dispatch, getState) {
- const otpState = getState().otp
- const { transitModes } = otpState.config.modes
- if (otpState.user.defaults) {
- dispatch(settingQueryParam(otpState.user.defaults))
+ const state = getState()
+ const { transitModes } = state.otp.config.modes
+ if (state.otp.user.defaults) {
+ dispatch(settingQueryParam(state.otp.user.defaults))
} else {
// Get user overrides and apply to default query
const userOverrides = coreUtils.storage.getItem('defaultQuery', {})
const defaultQuery = Object.assign(
- getDefaultQuery(otpState.config),
+ getDefaultQuery(state.otp.config),
userOverrides
)
// Filter out non-options (i.e., date, places).
@@ -113,8 +114,8 @@ let lastDebouncePlanTimeMs
*/
export function formChanged (oldQuery, newQuery) {
return function (dispatch, getState) {
- const otpState = getState().otp
- const { config, currentQuery, ui } = otpState
+ const state = getState()
+ const { config, currentQuery, ui } = state.otp
const { autoPlan, debouncePlanTimeMs } = config
const isMobile = coreUtils.ui.isMobile()
const {
@@ -146,7 +147,7 @@ export function formChanged (oldQuery, newQuery) {
dispatch(setMobileScreen(MobileScreens.SEARCH_FORM))
}
}
- } else if (queryIsValid(otpState)) {
+ } else if (queryIsValid(state)) {
// If replanning trip and query is valid,
// check if debouncing function needs to be (re)created.
if (!debouncedPlanTrip || lastDebouncePlanTimeMs !== debouncePlanTimeMs) {
diff --git a/lib/actions/map.js b/lib/actions/map.js
index 26cbcbcef..c139b9da6 100644
--- a/lib/actions/map.js
+++ b/lib/actions/map.js
@@ -51,11 +51,11 @@ export function onLocationSelected ({ locationType, location, resultType }) {
export function setLocation (payload) {
return function (dispatch, getState) {
- const otpState = getState().otp
+ const state = getState()
// reverse geocode point location if requested
if (payload.reverseGeocode) {
- getGeocoder(otpState.config.geocoder)
+ getGeocoder(state.otp.config.geocoder)
.reverse({ point: payload.location })
.then((location) => {
dispatch(settingLocation({
diff --git a/lib/actions/ui.js b/lib/actions/ui.js
index 955515798..bfcd22f90 100644
--- a/lib/actions/ui.js
+++ b/lib/actions/ui.js
@@ -3,6 +3,8 @@ import coreUtils from '@opentripplanner/core-utils'
import { createAction } from 'redux-actions'
import { matchPath } from 'react-router'
+import { getUiUrlParams } from '../util/state'
+
import { findRoute, setUrlSearch } from './api'
import { setMapCenter, setMapZoom, setRouterId } from './config'
import {
@@ -12,7 +14,6 @@ import {
} from './form'
import { clearLocation } from './map'
import { setActiveItinerary } from './narrative'
-import { getUiUrlParams } from '../util/state'
/**
* Wrapper function for history#push (or, if specified, replace, etc.)
@@ -111,15 +112,15 @@ function idToParams (id, delimiter = ',') {
*/
export function handleBackButtonPress (e) {
return function (dispatch, getState) {
- const otpState = getState().otp
- const { activeSearchId } = otpState
- const uiUrlParams = getUiUrlParams(otpState)
+ const state = getState()
+ const { activeSearchId } = state.otp
+ const uiUrlParams = getUiUrlParams(state)
// Get new search ID from URL after back button pressed.
// console.log('back button pressed', e)
const urlParams = coreUtils.query.getUrlParams()
const previousSearchId = urlParams.ui_activeSearch
const previousItinIndex = +urlParams.ui_activeItinerary || 0
- const previousSearch = otpState.searches[previousSearchId]
+ const previousSearch = state.otp.searches[previousSearchId]
if (previousSearch) {
// If back button pressed and active search has changed, set search to
// previous search ID.
diff --git a/lib/components/app/batch-routing-panel.js b/lib/components/app/batch-routing-panel.js
index 0cc9a36a8..c5b5798c5 100644
--- a/lib/components/app/batch-routing-panel.js
+++ b/lib/components/app/batch-routing-panel.js
@@ -71,9 +71,9 @@ class BatchRoutingPanel extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const showUserSettings = getShowUserSettings(state.otp)
+ const showUserSettings = getShowUserSettings(state)
return {
- activeSearch: getActiveSearch(state.otp),
+ activeSearch: getActiveSearch(state),
config: state.otp.config,
currentQuery: state.otp.currentQuery,
expandAdvanced: state.otp.user.expandAdvanced,
diff --git a/lib/components/app/call-taker-panel.js b/lib/components/app/call-taker-panel.js
index b731c07da..f096d27b2 100644
--- a/lib/components/app/call-taker-panel.js
+++ b/lib/components/app/call-taker-panel.js
@@ -275,9 +275,9 @@ class CallTakerPanel extends Component {
const mapStateToProps = (state, ownProps) => {
const {activeId, requests} = state.callTaker.fieldTrip
const request = requests.data.find(req => req.id === activeId)
- const showUserSettings = getShowUserSettings(state.otp)
+ const showUserSettings = getShowUserSettings(state)
return {
- activeSearch: getActiveSearch(state.otp),
+ activeSearch: getActiveSearch(state),
currentQuery: state.otp.currentQuery,
expandAdvanced: state.otp.user.expandAdvanced,
groupSize: state.callTaker.fieldTrip.groupSize,
diff --git a/lib/components/app/default-main-panel.js b/lib/components/app/default-main-panel.js
index 2f708b43a..a98be3451 100644
--- a/lib/components/app/default-main-panel.js
+++ b/lib/components/app/default-main-panel.js
@@ -63,9 +63,9 @@ class DefaultMainPanel extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const showUserSettings = getShowUserSettings(state.otp)
+ const showUserSettings = getShowUserSettings(state)
return {
- activeSearch: getActiveSearch(state.otp),
+ activeSearch: getActiveSearch(state),
currentQuery: state.otp.currentQuery,
mainPanelContent: state.otp.ui.mainPanelContent,
showUserSettings
diff --git a/lib/components/app/print-layout.js b/lib/components/app/print-layout.js
index a67760e13..da1a292f5 100644
--- a/lib/components/app/print-layout.js
+++ b/lib/components/app/print-layout.js
@@ -102,7 +102,7 @@ class PrintLayout extends Component {
const mapStateToProps = (state, ownProps) => {
return {
config: state.otp.config,
- itinerary: getActiveItinerary(state.otp)
+ itinerary: getActiveItinerary(state)
}
}
diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js
index 8dfd7f934..80d5f698e 100644
--- a/lib/components/app/responsive-webapp.js
+++ b/lib/components/app/responsive-webapp.js
@@ -18,11 +18,9 @@ import * as locationActions from '../../actions/location'
import * as mapActions from '../../actions/map'
import * as uiActions from '../../actions/ui'
import { frame } from '../app/app-frame'
-import DesktopNav from './desktop-nav'
import { RedirectWithQuery } from '../form/connected-links'
import Map from '../map/map'
import MobileMain from '../mobile/main'
-import PrintLayout from './print-layout'
import { getAuth0Config } from '../../util/auth'
import {
ACCOUNT_PATH,
@@ -48,6 +46,9 @@ import SavedTripScreen from '../user/monitored-trip/saved-trip-screen'
import UserAccountScreen from '../user/user-account-screen'
import withLoggedInUserSupport from '../user/with-logged-in-user-support'
+import PrintLayout from './print-layout'
+import DesktopNav from './desktop-nav'
+
const { isMobile } = coreUtils.ui
class ResponsiveWebapp extends Component {
@@ -228,7 +229,7 @@ class ResponsiveWebapp extends Component {
const mapStateToProps = (state, ownProps) => {
const title = getTitle(state)
return {
- activeItinerary: getActiveItinerary(state.otp),
+ activeItinerary: getActiveItinerary(state),
activeSearchId: state.otp.activeSearchId,
currentPosition: state.otp.location.currentPosition,
initZoomOnLocate: state.otp.config.map && state.otp.config.map.initZoomOnLocate,
diff --git a/lib/components/form/batch-preferences.js b/lib/components/form/batch-preferences.js
index 29718eac2..fe9bcb470 100644
--- a/lib/components/form/batch-preferences.js
+++ b/lib/components/form/batch-preferences.js
@@ -100,7 +100,7 @@ const mapStateToProps = (state, ownProps) => {
return {
query: currentQuery,
config,
- showUserSettings: getShowUserSettings(state.otp)
+ showUserSettings: getShowUserSettings(state)
}
}
diff --git a/lib/components/form/batch-settings.js b/lib/components/form/batch-settings.js
index 88deaadac..61d124b44 100644
--- a/lib/components/form/batch-settings.js
+++ b/lib/components/form/batch-settings.js
@@ -5,10 +5,12 @@ import styled from 'styled-components'
import * as apiActions from '../../actions/api'
import * as formActions from '../../actions/form'
+import Icon from '../narrative/icon'
+import { hasValidLocation, getActiveSearch, getShowUserSettings } from '../../util/state'
+
import BatchPreferences from './batch-preferences'
import DateTimeModal from './date-time-modal'
import ModeButtons, {MODE_OPTIONS, StyledModeButton} from './mode-buttons'
-import Icon from '../narrative/icon'
import {
BatchPreferencesContainer,
DateTimeModalContainer,
@@ -18,7 +20,6 @@ import {
StyledDateTimePreview
} from './batch-styled'
import { Dot } from './styled'
-import { hasValidLocation, getActiveSearch, getShowUserSettings } from '../../util/state'
/**
* Simple utility to check whether a list of mode strings contains the provided
@@ -182,9 +183,9 @@ class BatchSettings extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const showUserSettings = getShowUserSettings(state.otp)
+ const showUserSettings = getShowUserSettings(state)
return {
- activeSearch: getActiveSearch(state.otp),
+ activeSearch: getActiveSearch(state),
config: state.otp.config,
currentQuery: state.otp.currentQuery,
expandAdvanced: state.otp.user.expandAdvanced,
diff --git a/lib/components/form/connect-location-field.js b/lib/components/form/connect-location-field.js
index b22262f21..ca2c562d1 100644
--- a/lib/components/form/connect-location-field.js
+++ b/lib/components/form/connect-location-field.js
@@ -20,7 +20,7 @@ export default function connectLocationField (StyledLocationField, options = {})
const mapStateToProps = (state, ownProps) => {
const { config, currentQuery, location, transitIndex, user } = state.otp
const { currentPosition, nearbyStops, sessionSearches } = location
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const query = activeSearch ? activeSearch.query : currentQuery
const stateToProps = {
@@ -28,7 +28,7 @@ export default function connectLocationField (StyledLocationField, options = {})
geocoderConfig: config.geocoder,
nearbyStops,
sessionSearches,
- showUserSettings: getShowUserSettings(state.otp),
+ showUserSettings: getShowUserSettings(state),
stopsIndex: transitIndex.stops,
userLocationsAndRecentPlaces: [...user.locations, ...user.recentPlaces]
}
diff --git a/lib/components/form/connected-settings-selector-panel.js b/lib/components/form/connected-settings-selector-panel.js
index 7ca2aa5b9..f918f1e69 100644
--- a/lib/components/form/connected-settings-selector-panel.js
+++ b/lib/components/form/connected-settings-selector-panel.js
@@ -47,7 +47,7 @@ const mapStateToProps = (state, ownProps) => {
return {
query: currentQuery,
config,
- showUserSettings: getShowUserSettings(state.otp)
+ showUserSettings: getShowUserSettings(state)
}
}
diff --git a/lib/components/form/error-message.js b/lib/components/form/error-message.js
index 96a1e6df9..f00285626 100644
--- a/lib/components/form/error-message.js
+++ b/lib/components/form/error-message.js
@@ -1,7 +1,7 @@
import React from 'react'
import { connect } from 'react-redux'
-import TripTools from '../narrative/trip-tools'
+import TripTools from '../narrative/trip-tools'
import { getActiveError, getErrorMessage } from '../../util/state'
const ErrorMessage = ({ message }) => {
@@ -23,7 +23,7 @@ const ErrorMessage = ({ message }) => {
const mapStateToProps = (state, ownProps) => {
return {
message: getErrorMessage(
- getActiveError(state.otp),
+ getActiveError(state),
state.otp.config.errorMessages
)
}
diff --git a/lib/components/map/bounds-updating-overlay.js b/lib/components/map/bounds-updating-overlay.js
index e4ce308e6..1a11659c6 100644
--- a/lib/components/map/bounds-updating-overlay.js
+++ b/lib/components/map/bounds-updating-overlay.js
@@ -169,13 +169,13 @@ class BoundsUpdatingOverlay extends MapLayer {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const urlParams = coreUtils.query.getUrlParams()
return {
activeLeg: activeSearch && activeSearch.activeLeg,
activeStep: activeSearch && activeSearch.activeStep,
- itinerary: getActiveItinerary(state.otp),
+ itinerary: getActiveItinerary(state),
itineraryView: urlParams.ui_itineraryView,
popupLocation: state.otp.ui.mapPopupLocation,
query: state.otp.currentQuery
diff --git a/lib/components/map/connected-endpoints-overlay.js b/lib/components/map/connected-endpoints-overlay.js
index 0e85d3d80..73016b101 100644
--- a/lib/components/map/connected-endpoints-overlay.js
+++ b/lib/components/map/connected-endpoints-overlay.js
@@ -14,9 +14,9 @@ import { getActiveSearch, getShowUserSettings } from '../../util/state'
const mapStateToProps = (state, ownProps) => {
// Use query from active search (if a search has been made) or default to
// current query is no search is available.
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const query = activeSearch ? activeSearch.query : state.otp.currentQuery
- const showUserSettings = getShowUserSettings(state.otp)
+ const showUserSettings = getShowUserSettings(state)
const { from, to } = query
// Intermediate places doesn't trigger a re-plan, so for now default to
// current query. FIXME: Determine with TriMet if this is desired behavior.
diff --git a/lib/components/map/connected-transitive-overlay.js b/lib/components/map/connected-transitive-overlay.js
index 9b2eed104..655e4d146 100644
--- a/lib/components/map/connected-transitive-overlay.js
+++ b/lib/components/map/connected-transitive-overlay.js
@@ -7,7 +7,7 @@ import { getActiveSearch, getActiveItinerary, getActiveItineraries } from '../..
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
let transitiveData = null
if (
activeSearch &&
@@ -16,12 +16,12 @@ const mapStateToProps = (state, ownProps) => {
activeSearch.response.length > 0
) {
// FIXME: This may need some simplification.
- const itins = getActiveItineraries(state.otp)
+ const itins = getActiveItineraries(state)
const visibleIndex = activeSearch.visibleItinerary !== undefined && activeSearch.visibleItinerary !== null
? activeSearch.visibleItinerary
: activeSearch.activeItinerary
// TODO: prevent itineraryToTransitive() from being called more than needed
- const visibleItinerary = itins[visibleIndex] ? itins[visibleIndex] : getActiveItinerary(state.otp)
+ const visibleItinerary = itins[visibleIndex] ? itins[visibleIndex] : getActiveItinerary(state)
if (visibleItinerary) transitiveData = coreUtils.map.itineraryToTransitive(visibleItinerary)
} else if (
activeSearch &&
diff --git a/lib/components/map/stylized-map.js b/lib/components/map/stylized-map.js
index 48a8ee794..1d32f33f1 100644
--- a/lib/components/map/stylized-map.js
+++ b/lib/components/map/stylized-map.js
@@ -107,7 +107,7 @@ class StylizedMap extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
let transitiveData = null
if (
activeSearch &&
@@ -115,7 +115,7 @@ const mapStateToProps = (state, ownProps) => {
activeSearch.response &&
activeSearch.response.plan
) {
- const itins = getActiveItineraries(state.otp)
+ const itins = getActiveItineraries(state)
const visibleItinerary = itins[activeSearch.activeItinerary]
if (visibleItinerary) transitiveData = coreUtils.map.itineraryToTransitive(visibleItinerary)
} else if (
diff --git a/lib/components/mobile/batch-results-screen.js b/lib/components/mobile/batch-results-screen.js
index 51370a897..489fb4fa7 100644
--- a/lib/components/mobile/batch-results-screen.js
+++ b/lib/components/mobile/batch-results-screen.js
@@ -129,12 +129,12 @@ const BatchMobileResultsScreen = ({
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const urlParams = coreUtils.query.getUrlParams()
return {
activeLeg: activeSearch ? activeSearch.activeLeg : null,
- errors: getResponsesWithErrors(state.otp),
- itineraries: getActiveItineraries(state.otp),
+ errors: getResponsesWithErrors(state),
+ itineraries: getActiveItineraries(state),
itineraryView: urlParams.ui_itineraryView || ItineraryView.DEFAULT
}
}
diff --git a/lib/components/mobile/main.js b/lib/components/mobile/main.js
index 4027f295e..58af94275 100644
--- a/lib/components/mobile/main.js
+++ b/lib/components/mobile/main.js
@@ -2,6 +2,10 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
+import * as uiActions from '../../actions/ui'
+import { ComponentContext } from '../../util/contexts'
+import { getActiveSearch } from '../../util/state'
+
import MobileDateTimeScreen from './date-time-screen'
import MobileOptionsScreen from './options-screen'
import MobileLocationSearch from './location-search'
@@ -10,10 +14,6 @@ import MobileStopViewer from './stop-viewer'
import MobileTripViewer from './trip-viewer'
import MobileRouteViewer from './route-viewer'
-import * as uiActions from '../../actions/ui'
-import { ComponentContext } from '../../util/contexts'
-import { getActiveSearch } from '../../util/state'
-
const { MainPanelContent, MobileScreens } = uiActions
class MobileMain extends Component {
@@ -122,7 +122,7 @@ class MobileMain extends Component {
const mapStateToProps = (state, ownProps) => {
const { config, currentQuery, location, ui: uiState } = state.otp
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
return {
activeSearch,
config,
diff --git a/lib/components/mobile/results-header.js b/lib/components/mobile/results-header.js
index d0aa51c4b..39431c201 100644
--- a/lib/components/mobile/results-header.js
+++ b/lib/components/mobile/results-header.js
@@ -93,15 +93,15 @@ class ResultsHeader extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const {useRealtime} = state.otp
const response = !activeSearch
? null
: useRealtime ? activeSearch.response : activeSearch.nonRealtimeResponse
- const itineraries = getActiveItineraries(state.otp)
+ const itineraries = getActiveItineraries(state)
return {
- errors: getResponsesWithErrors(state.otp),
+ errors: getResponsesWithErrors(state),
query: state.otp.currentQuery,
resultCount: response
? itineraries.length
diff --git a/lib/components/mobile/results-screen.js b/lib/components/mobile/results-screen.js
index ece1501bc..170eeeb56 100644
--- a/lib/components/mobile/results-screen.js
+++ b/lib/components/mobile/results-screen.js
@@ -157,18 +157,18 @@ class MobileResultsScreen extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const {useRealtime} = state.otp
const response = !activeSearch
? null
: useRealtime ? activeSearch.response : activeSearch.nonRealtimeResponse
- const realtimeEffects = getRealtimeEffects(state.otp)
- const itineraries = getActiveItineraries(state.otp)
+ const realtimeEffects = getRealtimeEffects(state)
+ const itineraries = getActiveItineraries(state)
return {
activeItineraryIndex: activeSearch ? activeSearch.activeItinerary : null,
activeLeg: activeSearch ? activeSearch.activeLeg : null,
- error: getActiveError(state.otp),
+ error: getActiveError(state),
query: state.otp.currentQuery,
realtimeEffects,
resultCount:
diff --git a/lib/components/narrative/itinerary-carousel.js b/lib/components/narrative/itinerary-carousel.js
index 912126d88..9b08b0cc6 100644
--- a/lib/components/narrative/itinerary-carousel.js
+++ b/lib/components/narrative/itinerary-carousel.js
@@ -6,11 +6,12 @@ import { connect } from 'react-redux'
import SwipeableViews from 'react-swipeable-views'
import { setActiveItinerary, setActiveLeg, setActiveStep } from '../../actions/narrative'
-import Icon from './icon'
-import Loading from './loading'
import { ComponentContext } from '../../util/contexts'
import { getActiveItineraries, getActiveSearch } from '../../util/state'
+import Icon from './icon'
+import Loading from './loading'
+
class ItineraryCarousel extends Component {
state = {}
static propTypes = {
@@ -110,8 +111,8 @@ class ItineraryCarousel extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
- const itineraries = getActiveItineraries(state.otp)
+ const activeSearch = getActiveSearch(state)
+ const itineraries = getActiveItineraries(state)
return {
itineraries,
diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js
index 3f0283811..ba4a145fc 100644
--- a/lib/components/narrative/narrative-itineraries.js
+++ b/lib/components/narrative/narrative-itineraries.js
@@ -13,8 +13,6 @@ import {
updateItineraryFilter
} from '../../actions/narrative'
import * as uiActions from '../../actions/ui'
-import NarrativeItinerariesErrors from './narrative-itineraries-errors'
-import NarrativeItinerariesHeader from './narrative-itineraries-header'
import { ComponentContext } from '../../util/contexts'
import {
getActiveItineraries,
@@ -23,6 +21,9 @@ import {
getResponsesWithErrors
} from '../../util/state'
+import NarrativeItinerariesErrors from './narrative-itineraries-errors'
+import NarrativeItinerariesHeader from './narrative-itineraries-header'
+
const { ItineraryView } = uiActions
class NarrativeItineraries extends Component {
@@ -211,13 +212,13 @@ class NarrativeItineraries extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const activeItinerary = activeSearch && activeSearch.activeItinerary
const { errorMessages, modes } = state.otp.config
const { sort } = state.otp.filter
const pending = activeSearch ? Boolean(activeSearch.pending) : false
- const itineraries = getActiveItineraries(state.otp)
- const realtimeEffects = getRealtimeEffects(state.otp)
+ const itineraries = getActiveItineraries(state)
+ const realtimeEffects = getRealtimeEffects(state)
const useRealtime = state.otp.useRealtime
const urlParams = coreUtils.query.getUrlParams()
const itineraryView = urlParams.ui_itineraryView || ItineraryView.DEFAULT
@@ -234,7 +235,7 @@ const mapStateToProps = (state, ownProps) => {
activeLeg: activeSearch && activeSearch.activeLeg,
activeSearch,
activeStep: activeSearch && activeSearch.activeStep,
- errors: getResponsesWithErrors(state.otp),
+ errors: getResponsesWithErrors(state),
errorMessages,
itineraries,
itineraryIsExpanded,
diff --git a/lib/components/narrative/narrative-routing-results.js b/lib/components/narrative/narrative-routing-results.js
index 5660c7e29..9cd2fdbb9 100644
--- a/lib/components/narrative/narrative-routing-results.js
+++ b/lib/components/narrative/narrative-routing-results.js
@@ -2,10 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
-import Loading from './loading'
-import TabbedItineraries from './tabbed-itineraries'
import ErrorMessage from '../form/error-message'
-
import {
getActiveError,
getActiveItineraries,
@@ -13,6 +10,9 @@ import {
} from '../../util/state'
import { setMainPanelContent } from '../../actions/ui'
+import TabbedItineraries from './tabbed-itineraries'
+import Loading from './loading'
+
class NarrativeRoutingResults extends Component {
static propTypes = {
routingType: PropTypes.string
@@ -46,12 +46,12 @@ class NarrativeRoutingResults extends Component {
}
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const pending = activeSearch ? Boolean(activeSearch.pending) : false
return {
mainPanelContent: state.otp.ui.mainPanelContent,
- error: getActiveError(state.otp),
- itineraries: getActiveItineraries(state.otp),
+ error: getActiveError(state),
+ itineraries: getActiveItineraries(state),
pending,
routingType: activeSearch && activeSearch.query.routingType
}
diff --git a/lib/components/narrative/save-trip-button.js b/lib/components/narrative/save-trip-button.js
index af80a07fa..d5cabe2e7 100644
--- a/lib/components/narrative/save-trip-button.js
+++ b/lib/components/narrative/save-trip-button.js
@@ -79,7 +79,7 @@ const SaveTripButton = ({
const mapStateToProps = (state, ownProps) => {
const { persistence } = state.otp.config
return {
- itinerary: getActiveItinerary(state.otp),
+ itinerary: getActiveItinerary(state),
loggedInUser: state.user.loggedInUser,
persistence
}
diff --git a/lib/components/narrative/tabbed-itineraries.js b/lib/components/narrative/tabbed-itineraries.js
index cfa2af827..d57ff665b 100644
--- a/lib/components/narrative/tabbed-itineraries.js
+++ b/lib/components/narrative/tabbed-itineraries.js
@@ -162,9 +162,9 @@ class TabButton extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const pending = activeSearch ? Boolean(activeSearch.pending) : false
- const realtimeEffects = getRealtimeEffects(state.otp)
+ const realtimeEffects = getRealtimeEffects(state)
const useRealtime = state.otp.useRealtime
return {
// swap out realtime itineraries with non-realtime depending on boolean
diff --git a/lib/components/user/monitored-trip/saved-trip-screen.js b/lib/components/user/monitored-trip/saved-trip-screen.js
index 3b02e59d5..d7fe2534c 100644
--- a/lib/components/user/monitored-trip/saved-trip-screen.js
+++ b/lib/components/user/monitored-trip/saved-trip-screen.js
@@ -9,16 +9,17 @@ import AccountPage from '../account-page'
import * as uiActions from '../../../actions/ui'
import * as userActions from '../../../actions/user'
import AwaitingScreen from '../awaiting-screen'
-import SavedTripEditor from './saved-trip-editor'
-import TripBasicsPane from './trip-basics-pane'
-import TripNotificationsPane from './trip-notifications-pane'
-import TripSummaryPane from './trip-summary-pane'
import { TRIPS_PATH } from '../../../util/constants'
import { ALL_DAYS, arrayToDayFields, WEEKDAYS } from '../../../util/monitored-trip'
import { getActiveItineraries, getActiveSearch } from '../../../util/state'
import { RETURN_TO_CURRENT_ROUTE } from '../../../util/ui'
import withLoggedInUserSupport from '../with-logged-in-user-support'
+import TripSummaryPane from './trip-summary-pane'
+import TripNotificationsPane from './trip-notifications-pane'
+import TripBasicsPane from './trip-basics-pane'
+import SavedTripEditor from './saved-trip-editor'
+
// The validation schema shape for the form fields.
// TODO: add fields here as they are implemented.
const validationSchemaShape = {
@@ -194,9 +195,9 @@ class SavedTripScreen extends Component {
// connect to the redux store
const mapStateToProps = (state, ownProps) => {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
const activeItinerary = activeSearch && activeSearch.activeItinerary
- const itineraries = getActiveItineraries(state.otp) || []
+ const itineraries = getActiveItineraries(state) || []
const tripId = ownProps.match.params.id
return {
activeSearchId: state.otp.activeSearchId,
diff --git a/lib/components/viewers/stop-viewer.js b/lib/components/viewers/stop-viewer.js
index 2cc4ae95c..b4f338a6a 100644
--- a/lib/components/viewers/stop-viewer.js
+++ b/lib/components/viewers/stop-viewer.js
@@ -11,11 +11,12 @@ import styled from 'styled-components'
import * as apiActions from '../../actions/api'
import * as mapActions from '../../actions/map'
import * as uiActions from '../../actions/ui'
-import LiveStopTimes from './live-stop-times'
import Icon from '../narrative/icon'
-import StopScheduleTable from './stop-schedule-table'
import { getShowUserSettings, getStopViewerConfig } from '../../util/state'
+import LiveStopTimes from './live-stop-times'
+import StopScheduleTable from './stop-schedule-table'
+
const {
getTimeFormat,
getUserTimezone,
@@ -290,8 +291,8 @@ class StopViewer extends Component {
// connect to redux store
const mapStateToProps = (state, ownProps) => {
- const showUserSettings = getShowUserSettings(state.otp)
- const stopViewerConfig = getStopViewerConfig(state.otp)
+ const showUserSettings = getShowUserSettings(state)
+ const stopViewerConfig = getStopViewerConfig(state)
return {
autoRefreshStopTimes: state.otp.user.autoRefreshStopTimes,
favoriteStops: state.otp.user.favoriteStops,
diff --git a/lib/util/state.js b/lib/util/state.js
index 89dd207af..0e6c0f6ec 100644
--- a/lib/util/state.js
+++ b/lib/util/state.js
@@ -11,11 +11,11 @@ const { calculateFares } = coreUtils.itinerary
/**
* Get the active search object
- * @param {Object} otpState the OTP state object
+ * @param {Object} state the redux state object
* @returns {Object} an search object, or null if there is no active search
*/
-export function getActiveSearch (otpState) {
- return otpState.searches[otpState.activeSearchId]
+export function getActiveSearch (state) {
+ return state.otp.searches[state.otp.activeSearchId]
}
/**
@@ -74,14 +74,14 @@ function humanReadableMode (modeStr) {
/**
* Generates a list of issues/errors from a list of OTP responses.
*
- * @param {Object} otpState the OTP state object
+ * @param {Object} state the redux state object
* @return {Array} An array of objects describing the errors seen. These will at
* a minimum contain the `msg` object describing the error, but could also
* include an `id` and `modes` key for trip planning errors or `network` for
* errors with vehicle rentals
*/
-export function getResponsesWithErrors (otpState) {
- const search = getActiveSearch(otpState)
+export function getResponsesWithErrors (state) {
+ const search = getActiveSearch(state)
const rentalFeedErrors = []
const networksWithFeedWideErrors = {}
const tripPlanningErrors = []
@@ -126,8 +126,8 @@ export function getResponsesWithErrors (otpState) {
* Gets the active error (either a planning error or a rental feed error). This
* should only be used with itinerary routing, not batch routing.
*/
-export function getActiveError (otpState) {
- const errors = getResponsesWithErrors(otpState)
+export function getActiveError (state) {
+ const errors = getResponsesWithErrors(state)
return errors[errors.length - 1]
}
@@ -162,16 +162,16 @@ export function getErrorMessage (error, errorMessages) {
/**
* Helper to get the active search's non-realtime response
*/
-function getActiveSearchNonRealtimeResponse (otpState) {
- const search = getActiveSearch(otpState)
+function getActiveSearchNonRealtimeResponse (state) {
+ const search = getActiveSearch(state)
return search && search.nonRealtimeResponse
}
/**
* Helper to get the active search's realtime response
*/
-function getActiveSearchRealtimeResponse (otpState) {
- const search = getActiveSearch(otpState)
+function getActiveSearchRealtimeResponse (state) {
+ const search = getActiveSearch(state)
return search && search.response
}
@@ -208,20 +208,20 @@ const hashItinerary = memoize(
/**
* Get the active itineraries for the active search, which is dependent on
* whether realtime or non-realtime results should be displayed
- * @param {Object} otpState the OTP state object
+ * @param {Object} state the redux state object
* @return {Array} array of itinerary objects from the OTP plan response,
* or null if there is no active search
*/
export const getActiveItineraries = createSelector(
- otpState => otpState.config,
+ state => state.otp.config,
getActiveSearchNonRealtimeResponse,
- otpState => otpState.filter,
+ state => state.otp.filter,
getActiveSearchRealtimeResponse,
- otpState => otpState.useRealtime,
+ state => state.otp.useRealtime,
(
config,
nonRealtimeResponse,
- otpStateFilter,
+ itinerarySortSettings,
realtimeResponse,
useRealtime
) => {
@@ -251,7 +251,7 @@ export const getActiveItineraries = createSelector(
}
})
}
- const {sort} = otpStateFilter
+ const {sort} = itinerarySortSettings
const {direction, type} = sort
// If no sort type is provided (e.g., because batch routing is not enabled),
// do not sort itineraries (default sort from API response is used).
@@ -394,13 +394,13 @@ export function getTotalFareAsString (itinerary) {
/**
* Get the active itinerary/profile for the active search object
- * @param {Object} otpState the OTP state object
+ * @param {Object} state the redux state object
* @returns {Object} an itinerary object from the OTP plan response, or null if
* there is no active search or itinerary
*/
-export function getActiveItinerary (otpState) {
- const search = getActiveSearch(otpState)
- const itineraries = getActiveItineraries(otpState)
+export function getActiveItinerary (state) {
+ const search = getActiveSearch(state)
+ const itineraries = getActiveItineraries(state)
if (!itineraries || !search) return null
return itineraries.length > search.activeItinerary && search.activeItinerary >= 0
? itineraries[search.activeItinerary]
@@ -421,19 +421,19 @@ export function hasValidLocation (query, locationKey) {
/**
* Determine if the current query is valid
- * @param {Object} otpState the OTP state object
+ * @param {Object} state the redux state object
* @returns {boolean}
*/
-export function queryIsValid (otpState) {
- const {currentQuery} = otpState
+export function queryIsValid (state) {
+ const {currentQuery} = state.otp
return hasValidLocation(currentQuery, 'from') &&
hasValidLocation(currentQuery, 'to')
// TODO: add mode validation
// TODO: add date/time validation
}
-export function getRealtimeEffects (otpState) {
- const search = getActiveSearch(otpState)
+export function getRealtimeEffects (state) {
+ const search = getActiveSearch(state)
const realtimeItineraries = search &&
search.response &&
@@ -477,7 +477,7 @@ export function getRealtimeEffects (otpState) {
routesDiffer: !isEqual(normalRoutes, realtimeRoutes),
normalDuration,
realtimeDuration,
- exceedsThreshold: Math.abs(normalDuration - realtimeDuration) >= otpState.config.realtimeEffectsDisplayThreshold
+ exceedsThreshold: Math.abs(normalDuration - realtimeDuration) >= state.otp.config.realtimeEffectsDisplayThreshold
}
// // TESTING: Return this instead to simulate a realtime-affected itinerary.
// return {
@@ -494,23 +494,23 @@ export function getRealtimeEffects (otpState) {
/**
* Determine whether user settings panel is enabled.
*/
-export function getShowUserSettings (otpState) {
- return otpState.config.persistence && otpState.config.persistence.enabled
+export function getShowUserSettings (state) {
+ return state.otp.config.persistence?.enabled
}
-export function getStopViewerConfig (otpState) {
- return otpState.config.stopViewer
+export function getStopViewerConfig (state) {
+ return state.otp.config.stopViewer
}
/**
* Assemble any UI-state properties to be tracked via URL into a single object
* TODO: Expand to include additional UI properties
*/
-export function getUiUrlParams (otpState) {
- const activeSearch = getActiveSearch(otpState)
+export function getUiUrlParams (state) {
+ const activeSearch = getActiveSearch(state)
const uiParams = {
ui_activeItinerary: activeSearch ? activeSearch.activeItinerary : 0,
- ui_activeSearch: otpState.activeSearchId
+ ui_activeSearch: state.otp.activeSearchId
}
return uiParams
}
@@ -533,7 +533,7 @@ export function getTitle (state) {
if (viewedStop && viewedStop.stopId) title += ` ${viewedStop.stopId}`
break
default:
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
if (activeSearch) {
title += ` | ${coreUtils.query.summarizeQuery(activeSearch.query, user.locations)}`
}
From 6cc6a0d6f543688b21b8f0a0a918e68b3b3b9d30 Mon Sep 17 00:00:00 2001
From: Evan Siroky
Date: Wed, 16 Jun 2021 16:58:36 -0700
Subject: [PATCH 35/89] refactor: add a few otpState fixes that got forgotten
---
lib/util/state.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/util/state.js b/lib/util/state.js
index 3559387b4..872df2620 100644
--- a/lib/util/state.js
+++ b/lib/util/state.js
@@ -421,7 +421,7 @@ function activeSearchHasResponse (state) {
* @param {*} state The entire redux state used to obtain the response.
*/
function getOtpResponse (state) {
- return getActiveSearch(state.otp)?.response?.otp
+ return getActiveSearch(state)?.response?.otp
}
/**
@@ -429,7 +429,7 @@ function getOtpResponse (state) {
* @param {*} state The entire redux state in which the query is stored.
*/
function itineraryResponseExists (state) {
- const activeSearch = getActiveSearch(state.otp)
+ const activeSearch = getActiveSearch(state)
return activeSearch?.response?.length > 0 &&
activeSearch?.query?.routingType === 'ITINERARY'
}
@@ -439,7 +439,7 @@ function itineraryResponseExists (state) {
* @param {*} state The entire redux state from which to retrieve the itinerary.
*/
export function getVisibleItineraryIndex (state) {
- return getActiveSearch(state.otp)?.visibleItinerary
+ return getActiveSearch(state)?.visibleItinerary
}
/**
@@ -448,8 +448,8 @@ export function getVisibleItineraryIndex (state) {
*/
function getItineraryToRender (state) {
const visibleItineraryIndex = getVisibleItineraryIndex(state)
- const activeItinerary = getActiveItinerary(state.otp)
- const itins = getActiveItineraries(state.otp)
+ const activeItinerary = getActiveItinerary(state)
+ const itins = getActiveItineraries(state)
return itins[visibleItineraryIndex] || activeItinerary
}
From 6c23d7ec0ea5ab18ea6f3ed68e96e6ad0752c0e5 Mon Sep 17 00:00:00 2001
From: Phil Cline
Date: Thu, 17 Jun 2021 11:08:04 -0400
Subject: [PATCH 36/89] fix(routingQuery): Properly revert to list view after
planning trip.
---
lib/actions/api.js | 3 +++
lib/components/form/batch-settings.js | 1 +
2 files changed, 4 insertions(+)
diff --git a/lib/actions/api.js b/lib/actions/api.js
index 0bf3a442c..820ba1564 100644
--- a/lib/actions/api.js
+++ b/lib/actions/api.js
@@ -9,6 +9,7 @@ import { createAction } from 'redux-actions'
import qs from 'qs'
import { rememberPlace } from './map'
+import { ItineraryView, setItineraryView } from './ui'
import { getStopViewerConfig, queryIsValid } from '../util/state'
import { getSecureFetchOptions } from '../util/middleware'
@@ -93,6 +94,8 @@ export function routingQuery (searchId = null) {
console.warn('Query is invalid. Aborting routing query', otpState.currentQuery)
return
}
+ // Reset itinerary view to default (list view).
+ dispatch(setItineraryView(ItineraryView.DEFAULT))
const activeItinerary = getActiveItinerary(otpState)
const routingType = otpState.currentQuery.routingType
// For multiple mode combinations, gather injected params from config/query.
diff --git a/lib/components/form/batch-settings.js b/lib/components/form/batch-settings.js
index 88deaadac..b0e61e957 100644
--- a/lib/components/form/batch-settings.js
+++ b/lib/components/form/batch-settings.js
@@ -114,6 +114,7 @@ class BatchSettings extends Component {
}
// Close any expanded panels.
this.setState({expanded: null})
+
// Plan trip.
routingQuery()
}
From 85f47abf2ff15e290c08c18bd4749f2bed4862c3 Mon Sep 17 00:00:00 2001
From: Phil Cline
Date: Thu, 17 Jun 2021 11:40:19 -0400
Subject: [PATCH 37/89] test(Update snapshots):
---
__tests__/actions/__snapshots__/api.js.snap | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/__tests__/actions/__snapshots__/api.js.snap b/__tests__/actions/__snapshots__/api.js.snap
index 3c1375d6c..1932ad477 100644
--- a/__tests__/actions/__snapshots__/api.js.snap
+++ b/__tests__/actions/__snapshots__/api.js.snap
@@ -2,6 +2,9 @@
exports[`actions > api routingQuery should gracefully handle bad response 1`] = `
Array [
+ Array [
+ [Function],
+ ],
Array [
Object {
"payload": Object {
@@ -16,6 +19,9 @@ Array [
Array [
[Function],
],
+ Array [
+ [Function],
+ ],
Array [
Object {
"payload": Object {
@@ -35,6 +41,9 @@ Array [
exports[`actions > api routingQuery should make a query to OTP 1`] = `
Array [
+ Array [
+ [Function],
+ ],
Array [
Object {
"payload": Object {
From 6e4b2c0b492571f7f0215bf585f24758304d66d7 Mon Sep 17 00:00:00 2001
From: Phil Cline
Date: Thu, 17 Jun 2021 12:19:21 -0400
Subject: [PATCH 38/89] refactor(Add FIXME):
---
lib/actions/ui.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/actions/ui.js b/lib/actions/ui.js
index 955515798..fc6206b9a 100644
--- a/lib/actions/ui.js
+++ b/lib/actions/ui.js
@@ -240,6 +240,7 @@ export const MobileScreens = {
* (currently only used in batch results).
*/
export const ItineraryView = {
+ /** FIXME: Duplicate value for 'list', DEFAULT and LIST */
DEFAULT: 'list',
/** One itinerary is shown. (In mobile view, the map is hidden.) */
FULL: 'full',
From 8ae80cb6da5e63712a54eedcd21a50ab18c5efd5 Mon Sep 17 00:00:00 2001
From: Landon Reed
Date: Tue, 22 Jun 2021 17:56:07 -0400
Subject: [PATCH 39/89] refactor(mailables): address remaining mailables
feedback
---
lib/actions/call-taker.js | 13 +--
lib/components/admin/call-taker-controls.js | 6 +-
lib/components/admin/mailables-window.js | 91 +++++++++++++--------
lib/components/app/app-menu.js | 30 ++++++-
lib/index.css | 6 ++
lib/reducers/call-taker.js | 3 +-
lib/util/mailables.js | 41 +++++-----
7 files changed, 126 insertions(+), 64 deletions(-)
diff --git a/lib/actions/call-taker.js b/lib/actions/call-taker.js
index c46a455ee..b0413bc31 100644
--- a/lib/actions/call-taker.js
+++ b/lib/actions/call-taker.js
@@ -3,12 +3,14 @@ import { serialize } from 'object-to-formdata'
import qs from 'qs'
import { createAction } from 'redux-actions'
-import {toggleFieldTrips} from './field-trip'
-import {resetForm} from './form'
import {searchToQuery, sessionIsInvalid} from '../util/call-taker'
+import {isModuleEnabled, Modules} from '../util/config'
import {URL_ROOT} from '../util/constants'
import {getTimestamp} from '../util/state'
+import {resetForm} from './form'
+import {toggleFieldTrips} from './field-trip'
+
if (typeof (fetch) === 'undefined') require('isomorphic-fetch')
/// PRIVATE ACTIONS
@@ -45,9 +47,10 @@ export function resetAndToggleCallHistory () {
*/
export function beginCallIfNeeded () {
return function (dispatch, getState) {
- const {callTaker, otp} = getState()
- const calltakerConfig = otp.config.modules.find(m => m.id === 'call')
- if (calltakerConfig && !callTaker.activeCall && !callTaker.fieldTrip.visible) {
+ const state = getState()
+ const {activeCall, fieldTrip} = state.callTaker
+ const callTakerEnabled = isModuleEnabled(state, Modules.CALL_TAKER)
+ if (callTakerEnabled && !activeCall && !fieldTrip.visible) {
dispatch(beginCall())
}
}
diff --git a/lib/components/admin/call-taker-controls.js b/lib/components/admin/call-taker-controls.js
index f4391ef63..ee5e1cf1a 100644
--- a/lib/components/admin/call-taker-controls.js
+++ b/lib/components/admin/call-taker-controls.js
@@ -6,6 +6,8 @@ import * as callTakerActions from '../../actions/call-taker'
import * as fieldTripActions from '../../actions/field-trip'
import * as uiActions from '../../actions/ui'
import Icon from '../narrative/icon'
+import { isModuleEnabled, Modules } from '../../util/config'
+
import {
CallHistoryButton,
CallTimeCounter,
@@ -126,8 +128,8 @@ class CallTakerControls extends Component {
const mapStateToProps = (state, ownProps) => {
return {
callTaker: state.callTaker,
- callTakerEnabled: Boolean(state.otp.config.modules.find(m => m.id === 'call')),
- fieldTripEnabled: Boolean(state.otp.config.modules.find(m => m.id === 'ft')),
+ callTakerEnabled: isModuleEnabled(state, Modules.CALL_TAKER),
+ fieldTripEnabled: isModuleEnabled(state, Modules.FIELD_TRIP),
session: state.callTaker.session
}
}
diff --git a/lib/components/admin/mailables-window.js b/lib/components/admin/mailables-window.js
index 73674cf03..a29dbdfbb 100644
--- a/lib/components/admin/mailables-window.js
+++ b/lib/components/admin/mailables-window.js
@@ -1,13 +1,15 @@
import React, { Component } from 'react'
-import { Badge } from 'react-bootstrap'
+import { Badge, Button } from 'react-bootstrap'
import { connect } from 'react-redux'
import * as callTakerActions from '../../actions/call-taker'
-import DraggableWindow from './draggable-window'
import Icon from '../narrative/icon'
-import {MailablesList, WindowHeader} from './styled'
+import {getModuleConfig, Modules} from '../../util/config'
import {createLetter, MAILABLE_FIELDS} from '../../util/mailables'
+import {MailablesList, WindowHeader} from './styled'
+import DraggableWindow from './draggable-window'
+
/**
* A window enabled through the Mailables module that allows Call Taker users
* to generate a PDF with an invoice of items to be mailed to transit customers.
@@ -55,41 +57,52 @@ class MailablesWindow extends Component {
const selectableMailables = items.filter(m =>
!selectedMailables.find(mailable => mailable.name === m.name)
)
+ const MAILABLE_WIDTH = 300
return (
+
+
+
+ >
+ }
header={
<>
- Mailables{' '}
-
-
-
+ Mailables{' '}
>
}
+ height='300px'
onClickClose={toggleMailables}
scroll={false}
- style={{height: '340px', width: '600px'}}
+ style={{width: MAILABLE_WIDTH * 2}}
>
-
+
All Mailables
{selectableMailables.map((mailable, i) => (
@@ -100,7 +113,7 @@ class MailablesWindow extends Component {
))}
-
+
Selected Mailables {selectedMailables.length}
{selectedMailables.length > 0
@@ -140,13 +153,16 @@ class MailableOption extends Component {
render () {
const {mailable, onClear} = this.props
const isSelected = Boolean(onClear)
+ const containerStyle = {display: 'block', maxWidth: '290px'}
+ const label = (
+
+ {mailable.name}
+
+ )
if (isSelected) {
return (
-
- {mailable.name}
-
+
)
}
return (
-