Make maps and curves read only (#346)
* Refactor Table and Curve to be non-editable * Refactor Map component, remove dependency * Update dependencies
This commit is contained in:
parent
8eceff928f
commit
a293e95979
|
@ -22,7 +22,6 @@
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.6",
|
||||||
"react-router-dom": "^5.2.1",
|
"react-router-dom": "^5.2.1",
|
||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
"react-table-drag-select": "^0.3.1",
|
|
||||||
"uplot": "^1.6.18",
|
"uplot": "^1.6.18",
|
||||||
"uplot-react": "^1.1.1"
|
"uplot-react": "^1.1.1"
|
||||||
},
|
},
|
||||||
|
@ -31,10 +30,10 @@
|
||||||
"@speedy-tuner/eslint-config": "^0.1.3",
|
"@speedy-tuner/eslint-config": "^0.1.3",
|
||||||
"@types/d3": "^7.0.0",
|
"@types/d3": "^7.0.0",
|
||||||
"@types/node": "^17.0.4",
|
"@types/node": "^17.0.4",
|
||||||
"@types/pako": "^1.0.2",
|
"@types/pako": "^1.0.3",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "^17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@types/react-redux": "^7.1.20",
|
"@types/react-redux": "^7.1.21",
|
||||||
"@types/react-router-dom": "^5.3.2",
|
"@types/react-router-dom": "^5.3.2",
|
||||||
"eslint-plugin-modules-newline": "^0.0.6",
|
"eslint-plugin-modules-newline": "^0.0.6",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
@ -3767,9 +3766,9 @@
|
||||||
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/pako": {
|
"node_modules/@types/pako": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.3.tgz",
|
||||||
"integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==",
|
"integrity": "sha512-EDxOsHAD5dqjbjEUM1xwa7rpKPFb8ECBE5irONTQU7/OsO3thI5YrNEWSPNMvYmvFM0l/OLQJ6Mgw7PEdXSjhg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/parse-json": {
|
"node_modules/@types/parse-json": {
|
||||||
|
@ -3812,9 +3811,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-redux": {
|
"node_modules/@types/react-redux": {
|
||||||
"version": "7.1.20",
|
"version": "7.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.20.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.21.tgz",
|
||||||
"integrity": "sha512-q42es4c8iIeTgcnB+yJgRTTzftv3eYYvCZOh1Ckn2eX/3o5TdsQYKUWpLoLuGlcY/p+VAhV9IOEZJcWk/vfkXw==",
|
"integrity": "sha512-bLdglUiBSQNzWVVbmNPKGYYjrzp3/YDPwfOH3nLEz99I4awLlaRAPWjo6bZ2POpxztFWtDDXIPxBLVykXqBt+w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/hoist-non-react-statics": "^3.3.0",
|
"@types/hoist-non-react-statics": "^3.3.0",
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
|
@ -6179,6 +6178,7 @@
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
|
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
|
@ -6586,15 +6586,6 @@
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/create-react-class": {
|
|
||||||
"version": "15.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz",
|
|
||||||
"integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
|
|
||||||
"dependencies": {
|
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"object-assign": "^4.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/create-require": {
|
"node_modules/create-require": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
|
@ -7747,14 +7738,6 @@
|
||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/encoding": {
|
|
||||||
"version": "0.1.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
|
||||||
"dependencies": {
|
|
||||||
"iconv-lite": "^0.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/end-of-stream": {
|
"node_modules/end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
|
@ -9263,34 +9246,6 @@
|
||||||
"bser": "2.1.1"
|
"bser": "2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fbjs": {
|
|
||||||
"version": "0.8.18",
|
|
||||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz",
|
|
||||||
"integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": "^1.0.0",
|
|
||||||
"isomorphic-fetch": "^2.1.1",
|
|
||||||
"loose-envify": "^1.0.0",
|
|
||||||
"object-assign": "^4.1.0",
|
|
||||||
"promise": "^7.1.1",
|
|
||||||
"setimmediate": "^1.0.5",
|
|
||||||
"ua-parser-js": "^0.7.30"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fbjs/node_modules/core-js": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
|
||||||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
|
|
||||||
"deprecated": "core-js@<3.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js."
|
|
||||||
},
|
|
||||||
"node_modules/fbjs/node_modules/promise": {
|
|
||||||
"version": "7.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
|
||||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
|
||||||
"dependencies": {
|
|
||||||
"asap": "~2.0.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/figgy-pudding": {
|
"node_modules/figgy-pudding": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
||||||
|
@ -10583,17 +10538,6 @@
|
||||||
"node": ">=8.12.0"
|
"node": ">=8.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/iconv-lite": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
|
||||||
"dependencies": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/icss-utils": {
|
"node_modules/icss-utils": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
|
||||||
|
@ -11372,15 +11316,6 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/isomorphic-fetch": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
|
|
||||||
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
|
|
||||||
"dependencies": {
|
|
||||||
"node-fetch": "^1.0.1",
|
|
||||||
"whatwg-fetch": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/istanbul-lib-coverage": {
|
"node_modules/istanbul-lib-coverage": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
|
||||||
|
@ -14186,23 +14121,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch": {
|
|
||||||
"version": "1.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
|
||||||
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"encoding": "^0.1.11",
|
|
||||||
"is-stream": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-fetch/node_modules/is-stream": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/node-forge": {
|
"node_modules/node-forge": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||||
|
@ -17740,31 +17658,6 @@
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-table-drag-select": {
|
|
||||||
"version": "0.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-table-drag-select/-/react-table-drag-select-0.3.1.tgz",
|
|
||||||
"integrity": "sha512-+aOYkpbQ1YlEpDoMhdD+S+GVY5lG1+YN60YIt6pVRuEkU24G8BgGAy9+R+JXX+Izw3Nv7Jq8+kKoCPhBrKgaiw==",
|
|
||||||
"dependencies": {
|
|
||||||
"clone": "^2.1.1",
|
|
||||||
"deep-is": "^0.1.3",
|
|
||||||
"react": "^15.5.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-table-drag-select/node_modules/react": {
|
|
||||||
"version": "15.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-15.7.0.tgz",
|
|
||||||
"integrity": "sha512-5/MMRYmpmM0sMTHGLossnJCrmXQIiJilD6y3YN3TzAwGFj6zdnMtFv6xmi65PHKRV+pehIHpT7oy67Sr6s9AHA==",
|
|
||||||
"dependencies": {
|
|
||||||
"create-react-class": "^15.6.0",
|
|
||||||
"fbjs": "^0.8.9",
|
|
||||||
"loose-envify": "^1.1.0",
|
|
||||||
"object-assign": "^4.1.0",
|
|
||||||
"prop-types": "^15.5.10"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/read-pkg": {
|
"node_modules/read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
|
@ -20912,24 +20805,6 @@
|
||||||
"node": ">=4.2.0"
|
"node": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ua-parser-js": {
|
|
||||||
"version": "0.7.31",
|
|
||||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
|
|
||||||
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/ua-parser-js"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "paypal",
|
|
||||||
"url": "https://paypal.me/faisalman"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||||
|
@ -26036,9 +25911,9 @@
|
||||||
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
"integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
|
||||||
},
|
},
|
||||||
"@types/pako": {
|
"@types/pako": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.3.tgz",
|
||||||
"integrity": "sha512-8UJl2MjkqqS6ncpLZqRZ5LmGiFBkbYxocD4e4jmBqGvfRG1RS23gKsBQbdtV9O9GvRyjFTiRHRByjSlKCLlmZw==",
|
"integrity": "sha512-EDxOsHAD5dqjbjEUM1xwa7rpKPFb8ECBE5irONTQU7/OsO3thI5YrNEWSPNMvYmvFM0l/OLQJ6Mgw7PEdXSjhg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/parse-json": {
|
"@types/parse-json": {
|
||||||
|
@ -26081,9 +25956,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-redux": {
|
"@types/react-redux": {
|
||||||
"version": "7.1.20",
|
"version": "7.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.20.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.21.tgz",
|
||||||
"integrity": "sha512-q42es4c8iIeTgcnB+yJgRTTzftv3eYYvCZOh1Ckn2eX/3o5TdsQYKUWpLoLuGlcY/p+VAhV9IOEZJcWk/vfkXw==",
|
"integrity": "sha512-bLdglUiBSQNzWVVbmNPKGYYjrzp3/YDPwfOH3nLEz99I4awLlaRAPWjo6bZ2POpxztFWtDDXIPxBLVykXqBt+w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/hoist-non-react-statics": "^3.3.0",
|
"@types/hoist-non-react-statics": "^3.3.0",
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
|
@ -27988,7 +27863,8 @@
|
||||||
"clone": {
|
"clone": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"co": {
|
"co": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
|
@ -28329,15 +28205,6 @@
|
||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"create-react-class": {
|
|
||||||
"version": "15.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz",
|
|
||||||
"integrity": "sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==",
|
|
||||||
"requires": {
|
|
||||||
"loose-envify": "^1.3.1",
|
|
||||||
"object-assign": "^4.1.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"create-require": {
|
"create-require": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||||
|
@ -29234,14 +29101,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
"encoding": {
|
|
||||||
"version": "0.1.13",
|
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
|
||||||
"requires": {
|
|
||||||
"iconv-lite": "^0.6.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"end-of-stream": {
|
"end-of-stream": {
|
||||||
"version": "1.4.4",
|
"version": "1.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||||
|
@ -30356,35 +30215,6 @@
|
||||||
"bser": "2.1.1"
|
"bser": "2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fbjs": {
|
|
||||||
"version": "0.8.18",
|
|
||||||
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz",
|
|
||||||
"integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==",
|
|
||||||
"requires": {
|
|
||||||
"core-js": "^1.0.0",
|
|
||||||
"isomorphic-fetch": "^2.1.1",
|
|
||||||
"loose-envify": "^1.0.0",
|
|
||||||
"object-assign": "^4.1.0",
|
|
||||||
"promise": "^7.1.1",
|
|
||||||
"setimmediate": "^1.0.5",
|
|
||||||
"ua-parser-js": "^0.7.30"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"core-js": {
|
|
||||||
"version": "1.2.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
|
||||||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
|
|
||||||
},
|
|
||||||
"promise": {
|
|
||||||
"version": "7.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
|
||||||
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
|
||||||
"requires": {
|
|
||||||
"asap": "~2.0.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"figgy-pudding": {
|
"figgy-pudding": {
|
||||||
"version": "3.5.2",
|
"version": "3.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
|
||||||
|
@ -31382,14 +31212,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
|
||||||
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
|
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
|
||||||
},
|
},
|
||||||
"iconv-lite": {
|
|
||||||
"version": "0.6.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
|
||||||
"requires": {
|
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"icss-utils": {
|
"icss-utils": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
|
||||||
|
@ -31923,15 +31745,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
|
||||||
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
|
||||||
},
|
},
|
||||||
"isomorphic-fetch": {
|
|
||||||
"version": "2.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
|
|
||||||
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
|
|
||||||
"requires": {
|
|
||||||
"node-fetch": "^1.0.1",
|
|
||||||
"whatwg-fetch": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"istanbul-lib-coverage": {
|
"istanbul-lib-coverage": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
|
||||||
|
@ -34063,22 +33876,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
|
||||||
"version": "1.7.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
|
||||||
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
|
|
||||||
"requires": {
|
|
||||||
"encoding": "^0.1.11",
|
|
||||||
"is-stream": "^1.0.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"is-stream": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
|
||||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||||
|
@ -36826,30 +36623,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"react-table-drag-select": {
|
|
||||||
"version": "0.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-table-drag-select/-/react-table-drag-select-0.3.1.tgz",
|
|
||||||
"integrity": "sha512-+aOYkpbQ1YlEpDoMhdD+S+GVY5lG1+YN60YIt6pVRuEkU24G8BgGAy9+R+JXX+Izw3Nv7Jq8+kKoCPhBrKgaiw==",
|
|
||||||
"requires": {
|
|
||||||
"clone": "^2.1.1",
|
|
||||||
"deep-is": "^0.1.3",
|
|
||||||
"react": "^15.5.4"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"react": {
|
|
||||||
"version": "15.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react/-/react-15.7.0.tgz",
|
|
||||||
"integrity": "sha512-5/MMRYmpmM0sMTHGLossnJCrmXQIiJilD6y3YN3TzAwGFj6zdnMtFv6xmi65PHKRV+pehIHpT7oy67Sr6s9AHA==",
|
|
||||||
"requires": {
|
|
||||||
"create-react-class": "^15.6.0",
|
|
||||||
"fbjs": "^0.8.9",
|
|
||||||
"loose-envify": "^1.1.0",
|
|
||||||
"object-assign": "^4.1.0",
|
|
||||||
"prop-types": "^15.5.10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"read-pkg": {
|
"read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
|
@ -39305,11 +39078,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
||||||
},
|
},
|
||||||
"ua-parser-js": {
|
|
||||||
"version": "0.7.31",
|
|
||||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
|
|
||||||
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ=="
|
|
||||||
},
|
|
||||||
"unbox-primitive": {
|
"unbox-primitive": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"react-redux": "^7.2.6",
|
"react-redux": "^7.2.6",
|
||||||
"react-router-dom": "^5.2.1",
|
"react-router-dom": "^5.2.1",
|
||||||
"react-scripts": "^4.0.3",
|
"react-scripts": "^4.0.3",
|
||||||
"react-table-drag-select": "^0.3.1",
|
|
||||||
"uplot": "^1.6.18",
|
"uplot": "^1.6.18",
|
||||||
"uplot-react": "^1.1.1"
|
"uplot-react": "^1.1.1"
|
||||||
},
|
},
|
||||||
|
@ -52,10 +51,10 @@
|
||||||
"@speedy-tuner/eslint-config": "^0.1.3",
|
"@speedy-tuner/eslint-config": "^0.1.3",
|
||||||
"@types/d3": "^7.0.0",
|
"@types/d3": "^7.0.0",
|
||||||
"@types/node": "^17.0.4",
|
"@types/node": "^17.0.4",
|
||||||
"@types/pako": "^1.0.2",
|
"@types/pako": "^1.0.3",
|
||||||
"@types/react": "^17.0.38",
|
"@types/react": "^17.0.38",
|
||||||
"@types/react-dom": "^17.0.11",
|
"@types/react-dom": "^17.0.11",
|
||||||
"@types/react-redux": "^7.1.20",
|
"@types/react-redux": "^7.1.21",
|
||||||
"@types/react-router-dom": "^5.3.2",
|
"@types/react-router-dom": "^5.3.2",
|
||||||
"eslint-plugin-modules-newline": "^0.0.6",
|
"eslint-plugin-modules-newline": "^0.0.6",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
declare module 'react-table-drag-select';
|
|
|
@ -75,7 +75,6 @@ html, body {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid @main-light;
|
border: 1px solid @main-light;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
user-select: none;
|
|
||||||
// transition: all 0.1s;
|
// transition: all 0.1s;
|
||||||
|
|
||||||
&.value {
|
&.value {
|
||||||
|
|
|
@ -38,10 +38,7 @@ import {
|
||||||
parseZ,
|
parseZ,
|
||||||
} from '../utils/tune/table';
|
} from '../utils/tune/table';
|
||||||
import Map from './Dialog/Map';
|
import Map from './Dialog/Map';
|
||||||
import {
|
import { evaluateExpression } from '../utils/tune/expression';
|
||||||
evaluateExpression,
|
|
||||||
isExpression,
|
|
||||||
} from '../utils/tune/expression';
|
|
||||||
import useStorage from '../hooks/useStorage';
|
import useStorage from '../hooks/useStorage';
|
||||||
import useConfig from '../hooks/useConfig';
|
import useConfig from '../hooks/useConfig';
|
||||||
|
|
||||||
|
@ -153,7 +150,6 @@ const Dialog = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Curve
|
<Curve
|
||||||
name={curve.yBins[0]}
|
|
||||||
width={canvasWidth}
|
width={canvasWidth}
|
||||||
key={curve.yBins[0]}
|
key={curve.yBins[0]}
|
||||||
disabled={false} // TODO: evaluate condition
|
disabled={false} // TODO: evaluate condition
|
||||||
|
@ -162,10 +158,6 @@ const Dialog = ({
|
||||||
yLabel={curve.labels[1]}
|
yLabel={curve.labels[1]}
|
||||||
xUnits={xConstant.units}
|
xUnits={xConstant.units}
|
||||||
yUnits={yConstant.units}
|
yUnits={yConstant.units}
|
||||||
xMin={xConstant.min as number}
|
|
||||||
xMax={xConstant.max as number}
|
|
||||||
yMin={yConstant.min as number}
|
|
||||||
yMax={yConstant.max as number}
|
|
||||||
xData={parseXy(x.value as string)}
|
xData={parseXy(x.value as string)}
|
||||||
yData={parseXy(y.value as string)}
|
yData={parseXy(y.value as string)}
|
||||||
/>
|
/>
|
||||||
|
@ -176,30 +168,15 @@ const Dialog = ({
|
||||||
const x = tune.constants[table.xBins[0]];
|
const x = tune.constants[table.xBins[0]];
|
||||||
const y = tune.constants[table.yBins[0]];
|
const y = tune.constants[table.yBins[0]];
|
||||||
const z = tune.constants[table.zBins[0]];
|
const z = tune.constants[table.zBins[0]];
|
||||||
const zConstant = findConstantOnPage(table.zBins[0]) as ScalarConstantType;
|
|
||||||
|
|
||||||
let max = zConstant.max as number;
|
|
||||||
if (isExpression(zConstant.max)) {
|
|
||||||
max = evaluateExpression(zConstant.max as string, tune.constants, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
let min = zConstant.min as number;
|
|
||||||
if (isExpression(zConstant.min)) {
|
|
||||||
min = evaluateExpression(zConstant.min as string, tune.constants, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{renderHelp(table.help)}
|
{renderHelp(table.help)}
|
||||||
<Map
|
<Map
|
||||||
name={table.map}
|
|
||||||
key={table.map}
|
key={table.map}
|
||||||
xData={parseXy(x.value as string)}
|
xData={parseXy(x.value as string)}
|
||||||
yData={parseXy(y.value as string).reverse()}
|
yData={parseXy(y.value as string).reverse()}
|
||||||
zData={parseZ(z.value as string)}
|
zData={parseZ(z.value as string)}
|
||||||
disabled={false}
|
disabled={false}
|
||||||
zMin={min}
|
|
||||||
zMax={max}
|
|
||||||
digits={zConstant.digits as number}
|
|
||||||
xUnits={x.units as string}
|
xUnits={x.units as string}
|
||||||
yUnits={y.units as string}
|
yUnits={y.units as string}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -10,12 +10,11 @@ import UplotReact from 'uplot-react';
|
||||||
import uPlot from 'uplot';
|
import uPlot from 'uplot';
|
||||||
import { Colors } from '../../utils/colors';
|
import { Colors } from '../../utils/colors';
|
||||||
import LandscapeNotice from './LandscapeNotice';
|
import LandscapeNotice from './LandscapeNotice';
|
||||||
import Table from './Table';
|
import Table from './Curve/Table';
|
||||||
|
|
||||||
const { useBreakpoint } = Grid;
|
const { useBreakpoint } = Grid;
|
||||||
|
|
||||||
const Curve = ({
|
const Curve = ({
|
||||||
name,
|
|
||||||
width,
|
width,
|
||||||
xLabel,
|
xLabel,
|
||||||
yLabel,
|
yLabel,
|
||||||
|
@ -23,14 +22,9 @@ const Curve = ({
|
||||||
yData,
|
yData,
|
||||||
disabled,
|
disabled,
|
||||||
help,
|
help,
|
||||||
xMin,
|
|
||||||
xMax,
|
|
||||||
yMin,
|
|
||||||
yMax,
|
|
||||||
xUnits = '',
|
xUnits = '',
|
||||||
yUnits = '',
|
yUnits = '',
|
||||||
}: {
|
}: {
|
||||||
name: string,
|
|
||||||
width: number,
|
width: number,
|
||||||
xLabel: string,
|
xLabel: string,
|
||||||
yLabel: string,
|
yLabel: string,
|
||||||
|
@ -38,10 +32,6 @@ const Curve = ({
|
||||||
yData: number[],
|
yData: number[],
|
||||||
disabled: boolean,
|
disabled: boolean,
|
||||||
help: string,
|
help: string,
|
||||||
xMin: number,
|
|
||||||
xMax: number,
|
|
||||||
yMin: number,
|
|
||||||
yMax: number,
|
|
||||||
xUnits?: string,
|
xUnits?: string,
|
||||||
yUnits?: string,
|
yUnits?: string,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -99,17 +89,11 @@ const Curve = ({
|
||||||
</Typography.Paragraph>
|
</Typography.Paragraph>
|
||||||
<UplotReact options={options!} data={plotData!} />
|
<UplotReact options={options!} data={plotData!} />
|
||||||
<Table
|
<Table
|
||||||
name={name}
|
|
||||||
key={name}
|
|
||||||
xLabel={xLabel}
|
xLabel={xLabel}
|
||||||
yLabel={yLabel}
|
yLabel={yLabel}
|
||||||
xData={xData}
|
xData={xData}
|
||||||
yData={yData}
|
yData={yData}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
xMin={xMin}
|
|
||||||
xMax={xMax}
|
|
||||||
yMin={yMin}
|
|
||||||
yMax={yMax}
|
|
||||||
xUnits={xUnits}
|
xUnits={xUnits}
|
||||||
yUnits={yUnits}
|
yUnits={yUnits}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/* eslint-disable react/no-array-index-key */
|
||||||
|
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { colorHsl } from '../../../utils/number';
|
||||||
|
|
||||||
|
const titleProps = { disabled: true };
|
||||||
|
|
||||||
|
type AxisType = 'x' | 'y';
|
||||||
|
|
||||||
|
const Table = ({
|
||||||
|
xLabel,
|
||||||
|
yLabel,
|
||||||
|
xData,
|
||||||
|
yData,
|
||||||
|
disabled,
|
||||||
|
xUnits,
|
||||||
|
yUnits,
|
||||||
|
}: {
|
||||||
|
xLabel: string,
|
||||||
|
yLabel: string,
|
||||||
|
xData: number[],
|
||||||
|
yData: number[],
|
||||||
|
disabled: boolean,
|
||||||
|
xUnits: string,
|
||||||
|
yUnits: string,
|
||||||
|
}) => {
|
||||||
|
const renderRow = useCallback((axis: AxisType, input: number[]) => input
|
||||||
|
.map((value, index) => {
|
||||||
|
const [hue, sat, light] = colorHsl(Math.min(...input), Math.max(...input), value);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td
|
||||||
|
className="value"
|
||||||
|
key={`${axis}-${index}-${value}-${hue}${sat}${light}`}
|
||||||
|
style={{ backgroundColor: `hsl(${hue}, ${sat}%, ${light}%)` }}
|
||||||
|
>
|
||||||
|
{`${value}`}
|
||||||
|
</td>
|
||||||
|
);
|
||||||
|
}), []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="table">
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td {...titleProps} className="title-curve" key={yLabel}>{`${yLabel} (${yUnits})`}</td>
|
||||||
|
{renderRow('y', yData)}
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td {...titleProps} className="title-curve" key={xLabel}>{`${xLabel} (${xUnits})`}</td>
|
||||||
|
{renderRow('x', xData)}
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Table;
|
|
@ -1,182 +1,31 @@
|
||||||
/* eslint-disable react/no-array-index-key */
|
/* eslint-disable react/no-array-index-key */
|
||||||
|
|
||||||
import {
|
import { Grid } from 'antd';
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
InputNumber,
|
|
||||||
Modal,
|
|
||||||
Popover,
|
|
||||||
Space,
|
|
||||||
Grid,
|
|
||||||
} from 'antd';
|
|
||||||
import {
|
|
||||||
PlusCircleOutlined,
|
|
||||||
MinusCircleOutlined,
|
|
||||||
EditOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import TableDragSelect from 'react-table-drag-select';
|
|
||||||
import {
|
|
||||||
isDecrement,
|
|
||||||
isEscape,
|
|
||||||
isIncrement,
|
|
||||||
isReplace,
|
|
||||||
} from '../../utils/keyboard/shortcuts';
|
|
||||||
import LandscapeNotice from './LandscapeNotice';
|
import LandscapeNotice from './LandscapeNotice';
|
||||||
import { colorHsl } from '../../utils/number';
|
import { colorHsl } from '../../utils/number';
|
||||||
|
|
||||||
type CellsType = boolean[][];
|
|
||||||
type DataType = number[][];
|
|
||||||
type OnChangeType = (data: DataType) => void;
|
|
||||||
enum Operations {
|
|
||||||
INC,
|
|
||||||
DEC,
|
|
||||||
REPLACE,
|
|
||||||
}
|
|
||||||
|
|
||||||
const { useBreakpoint } = Grid;
|
const { useBreakpoint } = Grid;
|
||||||
|
|
||||||
const Map = ({
|
const Map = ({
|
||||||
name,
|
|
||||||
xData,
|
xData,
|
||||||
yData,
|
yData,
|
||||||
zData,
|
zData,
|
||||||
disabled,
|
disabled,
|
||||||
onChange,
|
|
||||||
zMin,
|
|
||||||
zMax,
|
|
||||||
digits,
|
|
||||||
xUnits,
|
xUnits,
|
||||||
yUnits,
|
yUnits,
|
||||||
}: {
|
}: {
|
||||||
name: string,
|
|
||||||
xData: number[],
|
xData: number[],
|
||||||
yData: number[],
|
yData: number[],
|
||||||
zData: number[][],
|
zData: number[][],
|
||||||
disabled: boolean,
|
disabled: boolean,
|
||||||
onChange?: OnChangeType,
|
|
||||||
zMin: number,
|
|
||||||
zMax: number,
|
|
||||||
digits: number,
|
|
||||||
xUnits: string,
|
xUnits: string,
|
||||||
yUnits: string,
|
yUnits: string,
|
||||||
}) => {
|
}) => {
|
||||||
const { sm } = useBreakpoint();
|
const { sm } = useBreakpoint();
|
||||||
const titleProps = { disabled: true };
|
const titleProps = { disabled: true };
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
||||||
const [modalValue, setModalValue] = useState<number | undefined>();
|
|
||||||
const [data, _setData] = useState<DataType>(zData);
|
|
||||||
const generateCells = () => Array.from(
|
|
||||||
Array(yData.length + 1).fill(false),
|
|
||||||
() => new Array(xData.length + 1).fill(false),
|
|
||||||
);
|
|
||||||
const [cells, _setCells] = useState<CellsType>(generateCells());
|
|
||||||
const cellsRef = useRef(cells);
|
|
||||||
const dataRef = useRef(data);
|
|
||||||
const modalInputRef = useRef<HTMLInputElement | null>(null);
|
|
||||||
const setCells = (currentCells: CellsType) => {
|
|
||||||
cellsRef.current = currentCells;
|
|
||||||
_setCells(currentCells);
|
|
||||||
};
|
|
||||||
const setData = (currentData: DataType) => {
|
|
||||||
dataRef.current = currentData;
|
|
||||||
_setData(currentData);
|
|
||||||
if (onChange) {
|
|
||||||
onChange(currentData);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const modifyData = (operation: Operations, currentCells: CellsType, currentData: DataType, value = 0): DataType => {
|
|
||||||
const newData = [...currentData.map((row) => [...row])];
|
|
||||||
currentCells.forEach((_, rowIndex) => {
|
|
||||||
currentCells[rowIndex].forEach((selected, valueIndex) => {
|
|
||||||
if (!selected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const current = newData[rowIndex][valueIndex - 1];
|
const min = Math.min(...zData.map((row) => Math.min(...row)));
|
||||||
switch (operation) {
|
const max = Math.max(...zData.map((row) => Math.max(...row)));
|
||||||
case Operations.INC:
|
|
||||||
if (current < zMax) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = Number((newData[rowIndex][valueIndex - 1] + 10**-digits).toFixed(digits));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Operations.DEC:
|
|
||||||
if (current > zMin) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = Number((newData[rowIndex][valueIndex - 1] - 10**-digits).toFixed(digits));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Operations.REPLACE:
|
|
||||||
if (value > zMax) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = zMax;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (value < zMin) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = zMin;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newData[rowIndex][valueIndex - 1] = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...newData];
|
|
||||||
};
|
|
||||||
|
|
||||||
const oneModalOk = () => {
|
|
||||||
setData(modifyData(Operations.REPLACE, cellsRef.current, dataRef.current, modalValue));
|
|
||||||
setIsModalVisible(false);
|
|
||||||
setModalValue(undefined);
|
|
||||||
};
|
|
||||||
const onModalCancel = () => {
|
|
||||||
setIsModalVisible(false);
|
|
||||||
setModalValue(undefined);
|
|
||||||
};
|
|
||||||
const resetCells = () => setCells(generateCells());
|
|
||||||
const increment = () => setData(modifyData(Operations.INC, cellsRef.current, dataRef.current));
|
|
||||||
const decrement = () => setData(modifyData(Operations.DEC, cellsRef.current, dataRef.current));
|
|
||||||
const replace = () => {
|
|
||||||
// don't show modal when no cell is selected
|
|
||||||
if (cellsRef.current.flat().find((val) => val === true)) {
|
|
||||||
setModalValue(undefined);
|
|
||||||
setIsModalVisible(true);
|
|
||||||
setInterval(() => modalInputRef.current?.focus(), 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const keyboardListener = (e: KeyboardEvent) => {
|
|
||||||
|
|
||||||
if (isIncrement(e)) {
|
|
||||||
increment();
|
|
||||||
}
|
|
||||||
if (isDecrement(e)) {
|
|
||||||
decrement();
|
|
||||||
}
|
|
||||||
if (isReplace(e)) {
|
|
||||||
e.preventDefault();
|
|
||||||
replace();
|
|
||||||
}
|
|
||||||
if (isEscape(e)) {
|
|
||||||
resetCells();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('keydown', keyboardListener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('keydown', keyboardListener);
|
|
||||||
};
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const min = Math.min(...data.map((row) => Math.min(...row)));
|
|
||||||
const max = Math.max(...data.map((row) => Math.max(...row)));
|
|
||||||
|
|
||||||
const renderRow = (rowIndex: number, input: number[]) => input
|
const renderRow = (rowIndex: number, input: number[]) => input
|
||||||
.map((value, index) => {
|
.map((value, index) => {
|
||||||
|
@ -210,58 +59,27 @@ const Map = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="table">
|
||||||
<div className="table">
|
<table>
|
||||||
<Popover
|
<tbody>
|
||||||
visible={cells.flat().find((val) => val === true) === true}
|
{zData.map((row, i) => (
|
||||||
content={
|
<tr key={`row-${i}`}>
|
||||||
<Space>
|
{renderRow(i, row)}
|
||||||
<Button onClick={decrement} icon={<MinusCircleOutlined />} />
|
|
||||||
<Button onClick={increment} icon={<PlusCircleOutlined />} />
|
|
||||||
<Button onClick={replace} icon={<EditOutlined />} />
|
|
||||||
</Space>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TableDragSelect
|
|
||||||
key={name}
|
|
||||||
value={cells}
|
|
||||||
onChange={setCells}
|
|
||||||
>
|
|
||||||
{data.map((row, i) => (
|
|
||||||
<tr key={`row-${i}`}>
|
|
||||||
{renderRow(i, row)}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
<tr>
|
|
||||||
<td {...titleProps} className="title-map">
|
|
||||||
{yUnits} / {xUnits}
|
|
||||||
</td>
|
|
||||||
{xData.map((xValue) => (
|
|
||||||
<td {...titleProps} key={`x-${xValue}`}>
|
|
||||||
{`${xValue}`}
|
|
||||||
</td>
|
|
||||||
))}
|
|
||||||
</tr>
|
</tr>
|
||||||
</TableDragSelect>
|
))}
|
||||||
</Popover>
|
<tr>
|
||||||
</div>
|
<td {...titleProps} className="title-map">
|
||||||
<Modal
|
{yUnits} / {xUnits}
|
||||||
title="Set cell values"
|
</td>
|
||||||
visible={isModalVisible}
|
{xData.map((xValue, l) => (
|
||||||
onOk={oneModalOk}
|
<td {...titleProps} key={`x-${l}-${xValue}`}>
|
||||||
onCancel={onModalCancel}
|
{`${xValue}`}
|
||||||
centered
|
</td>
|
||||||
forceRender
|
))}
|
||||||
>
|
</tr>
|
||||||
<InputNumber
|
</tbody>
|
||||||
ref={modalInputRef}
|
</table>
|
||||||
value={modalValue}
|
</div>
|
||||||
onChange={(val) => setModalValue(Number(val))}
|
|
||||||
onPressEnter={oneModalOk}
|
|
||||||
style={{ width: '20%' }}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ const SmartSelect = ({
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
defaultValue={values.indexOf(defaultValue)}
|
defaultValue={values.indexOf(defaultValue)}
|
||||||
showSearch
|
|
||||||
optionFilterProp="label"
|
optionFilterProp="label"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
style={{ maxWidth: 250 }}
|
style={{ maxWidth: 250 }}
|
||||||
|
|
|
@ -1,260 +0,0 @@
|
||||||
/* eslint-disable react/no-array-index-key */
|
|
||||||
|
|
||||||
import {
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
InputNumber,
|
|
||||||
Modal,
|
|
||||||
Popover,
|
|
||||||
Space,
|
|
||||||
} from 'antd';
|
|
||||||
import {
|
|
||||||
PlusCircleOutlined,
|
|
||||||
MinusCircleOutlined,
|
|
||||||
EditOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import TableDragSelect from 'react-table-drag-select';
|
|
||||||
import {
|
|
||||||
isDecrement,
|
|
||||||
isEscape,
|
|
||||||
isIncrement,
|
|
||||||
isReplace,
|
|
||||||
} from '../../utils/keyboard/shortcuts';
|
|
||||||
import { colorHsl } from '../../utils/number';
|
|
||||||
|
|
||||||
type AxisType = 'x' | 'y';
|
|
||||||
type CellsType = boolean[][];
|
|
||||||
type DataType = number[][];
|
|
||||||
type OnChangeType = (data: DataType) => void;
|
|
||||||
enum Operations {
|
|
||||||
INC,
|
|
||||||
DEC,
|
|
||||||
REPLACE,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Table = ({
|
|
||||||
name,
|
|
||||||
xLabel,
|
|
||||||
yLabel,
|
|
||||||
xData,
|
|
||||||
yData,
|
|
||||||
disabled,
|
|
||||||
onChange,
|
|
||||||
xMin,
|
|
||||||
xMax,
|
|
||||||
yMin,
|
|
||||||
yMax,
|
|
||||||
xUnits,
|
|
||||||
yUnits,
|
|
||||||
}: {
|
|
||||||
name: string,
|
|
||||||
xLabel: string,
|
|
||||||
yLabel: string,
|
|
||||||
xData: number[],
|
|
||||||
yData: number[],
|
|
||||||
disabled: boolean,
|
|
||||||
onChange?: OnChangeType,
|
|
||||||
xMin: number,
|
|
||||||
xMax: number,
|
|
||||||
yMin: number,
|
|
||||||
yMax: number,
|
|
||||||
xUnits: string,
|
|
||||||
yUnits: string,
|
|
||||||
}) => {
|
|
||||||
const titleProps = { disabled: true };
|
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
|
||||||
const [modalValue, setModalValue] = useState<number | undefined>();
|
|
||||||
const [data, _setData] = useState<DataType>([yData, xData]);
|
|
||||||
// data starts from `1` index, 0 is title / name
|
|
||||||
const rowsCount = data[1].length + 1;
|
|
||||||
const generateCells = () => [
|
|
||||||
Array(rowsCount).fill(false),
|
|
||||||
Array(rowsCount).fill(false),
|
|
||||||
];
|
|
||||||
const [cells, _setCells] = useState<CellsType>(generateCells());
|
|
||||||
const cellsRef = useRef(cells);
|
|
||||||
const dataRef = useRef(data);
|
|
||||||
const modalInputRef = useRef<HTMLInputElement | null>(null);
|
|
||||||
const setCells = (currentCells: CellsType) => {
|
|
||||||
cellsRef.current = currentCells;
|
|
||||||
_setCells(currentCells);
|
|
||||||
};
|
|
||||||
const setData = (currentData: DataType) => {
|
|
||||||
dataRef.current = currentData;
|
|
||||||
_setData(currentData);
|
|
||||||
if (onChange) {
|
|
||||||
onChange(currentData);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const modifyData = useCallback((operation: Operations, currentCells: CellsType, currentData: DataType, value = 0): DataType => {
|
|
||||||
const newData = [...currentData.map((row) => [...row])];
|
|
||||||
// rowIndex: [0 => Y, 1 => X]
|
|
||||||
const isY = (row: number) => row === 0;
|
|
||||||
const isX = (row: number) => row === 1;
|
|
||||||
const isNotGreater = (row: number, val: number) => (isY(row) && val < yMax) || (isX(row) && val < xMax);
|
|
||||||
const isNotLess = (row: number, val: number) => (isY(row) && val > yMin) || (isX(row) && val > xMin);
|
|
||||||
|
|
||||||
currentCells.forEach((_, rowIndex) => {
|
|
||||||
currentCells[rowIndex].forEach((selected, valueIndex) => {
|
|
||||||
if (!selected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const current = newData[rowIndex][valueIndex - 1];
|
|
||||||
switch (operation) {
|
|
||||||
case Operations.INC:
|
|
||||||
if (isNotGreater(rowIndex, current)) {
|
|
||||||
newData[rowIndex][valueIndex - 1] += 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Operations.DEC:
|
|
||||||
if (isNotLess(rowIndex, current)) {
|
|
||||||
newData[rowIndex][valueIndex - 1] -= 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Operations.REPLACE:
|
|
||||||
if (isX(rowIndex) && value > xMax) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = xMax;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isX(rowIndex) && value < xMin) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = xMin;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isY(rowIndex) && value < yMin) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = yMin;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (isY(rowIndex) && value > yMax) {
|
|
||||||
newData[rowIndex][valueIndex - 1] = yMax;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
newData[rowIndex][valueIndex - 1] = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...newData];
|
|
||||||
}, [xMax, xMin, yMax, yMin]);
|
|
||||||
|
|
||||||
const oneModalOk = () => {
|
|
||||||
setData(modifyData(Operations.REPLACE, cellsRef.current, dataRef.current, modalValue));
|
|
||||||
setIsModalVisible(false);
|
|
||||||
setModalValue(undefined);
|
|
||||||
};
|
|
||||||
const onModalCancel = () => {
|
|
||||||
setIsModalVisible(false);
|
|
||||||
setModalValue(undefined);
|
|
||||||
};
|
|
||||||
const resetCells = () => setCells(generateCells());
|
|
||||||
const increment = () => setData(modifyData(Operations.INC, cellsRef.current, dataRef.current));
|
|
||||||
const decrement = () => setData(modifyData(Operations.DEC, cellsRef.current, dataRef.current));
|
|
||||||
const replace = () => {
|
|
||||||
// don't show modal when no cell is selected
|
|
||||||
if (cellsRef.current.flat().find((val) => val === true)) {
|
|
||||||
setModalValue(undefined);
|
|
||||||
setIsModalVisible(true);
|
|
||||||
setInterval(() => modalInputRef.current?.focus(), 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const keyboardListener = (e: KeyboardEvent) => {
|
|
||||||
|
|
||||||
if (isIncrement(e)) {
|
|
||||||
increment();
|
|
||||||
}
|
|
||||||
if (isDecrement(e)) {
|
|
||||||
decrement();
|
|
||||||
}
|
|
||||||
if (isReplace(e)) {
|
|
||||||
e.preventDefault();
|
|
||||||
replace();
|
|
||||||
}
|
|
||||||
if (isEscape(e)) {
|
|
||||||
resetCells();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener('keydown', keyboardListener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('keydown', keyboardListener);
|
|
||||||
};
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const renderRow = (axis: AxisType, input: number[]) => input
|
|
||||||
.map((value, index) => {
|
|
||||||
const [hue, sat, light] = colorHsl(Math.min(...input), Math.max(...input), value);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<td
|
|
||||||
className="value"
|
|
||||||
key={`${axis}-${index}-${value}-${hue}${sat}${light}`}
|
|
||||||
style={{ backgroundColor: `hsl(${hue}, ${sat}%, ${light}%)` }}
|
|
||||||
>
|
|
||||||
{`${value}`}
|
|
||||||
</td>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="table table-2d">
|
|
||||||
<Popover
|
|
||||||
visible={cells.flat().find((val) => val === true) === true}
|
|
||||||
content={
|
|
||||||
<Space>
|
|
||||||
<Button onClick={decrement} icon={<MinusCircleOutlined />} />
|
|
||||||
<Button onClick={increment} icon={<PlusCircleOutlined />} />
|
|
||||||
<Button onClick={replace} icon={<EditOutlined />} />
|
|
||||||
</Space>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<TableDragSelect
|
|
||||||
key={name}
|
|
||||||
value={cells}
|
|
||||||
onChange={setCells}
|
|
||||||
>
|
|
||||||
<tr>
|
|
||||||
<td {...titleProps} className="title-curve" key={yLabel}>{`${yLabel} (${yUnits})`}</td>
|
|
||||||
{renderRow('y', data[0])}
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td {...titleProps} className="title-curve" key={xLabel}>{`${xLabel} (${xUnits})`}</td>
|
|
||||||
{renderRow('x', data[1])}
|
|
||||||
</tr>
|
|
||||||
</TableDragSelect>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
<Modal
|
|
||||||
title="Set cell values"
|
|
||||||
visible={isModalVisible}
|
|
||||||
onOk={oneModalOk}
|
|
||||||
onCancel={onModalCancel}
|
|
||||||
centered
|
|
||||||
forceRender
|
|
||||||
>
|
|
||||||
<InputNumber
|
|
||||||
ref={modalInputRef}
|
|
||||||
value={modalValue}
|
|
||||||
onChange={(val) => setModalValue(Number(val))}
|
|
||||||
onPressEnter={oneModalOk}
|
|
||||||
style={{ width: '20%' }}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Table;
|
|
|
@ -5,10 +5,7 @@ import {
|
||||||
Row,
|
Row,
|
||||||
Col,
|
Col,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||||
CarOutlined,
|
|
||||||
InfoCircleOutlined,
|
|
||||||
} from '@ant-design/icons';
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import {
|
import {
|
||||||
AppState,
|
AppState,
|
||||||
|
@ -32,12 +29,7 @@ const firmware = (signature: string) => (
|
||||||
const StatusBar = ({ status, config }: { status: StatusState, config: ConfigState }) => (
|
const StatusBar = ({ status, config }: { status: StatusState, config: ConfigState }) => (
|
||||||
<Footer className="app-status-bar">
|
<Footer className="app-status-bar">
|
||||||
<Row>
|
<Row>
|
||||||
<Col span={8}>
|
<Col span={8} />
|
||||||
<Space>
|
|
||||||
<CarOutlined />
|
|
||||||
default
|
|
||||||
</Space>
|
|
||||||
</Col>
|
|
||||||
<Col span={8} style={{ textAlign: 'center' }}>
|
<Col span={8} style={{ textAlign: 'center' }}>
|
||||||
{config.megaTune && firmware(config.megaTune.signature)}
|
{config.megaTune && firmware(config.megaTune.signature)}
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -3,28 +3,11 @@ import React from 'react';
|
||||||
type KeyEvent = KeyboardEvent | React.KeyboardEvent<HTMLInputElement>;
|
type KeyEvent = KeyboardEvent | React.KeyboardEvent<HTMLInputElement>;
|
||||||
|
|
||||||
enum Keys {
|
enum Keys {
|
||||||
INCREMENT = '.',
|
|
||||||
DECREMENT = ',',
|
|
||||||
COMMAND = 'p',
|
COMMAND = 'p',
|
||||||
SIDEBAR = '\\',
|
SIDEBAR = '\\',
|
||||||
ESCAPE = 'Escape',
|
ESCAPE = 'Escape',
|
||||||
REPLACE = '=',
|
|
||||||
UP = 'ArrowUp',
|
|
||||||
DOWN = 'ArrowDown',
|
|
||||||
LEFT = 'ArrowLeft',
|
|
||||||
RIGHT = 'ArrowRight',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
||||||
|
|
||||||
export const isCommand = (e: KeyEvent) => (e.metaKey || e.ctrlKey) && e.key === Keys.COMMAND;
|
export const isCommand = (e: KeyEvent) => (e.metaKey || e.ctrlKey) && e.key === Keys.COMMAND;
|
||||||
export const isToggleSidebar = (e: KeyEvent) => (e.metaKey || e.ctrlKey) && e.key === Keys.SIDEBAR;
|
export const isToggleSidebar = (e: KeyEvent) => (e.metaKey || e.ctrlKey) && e.key === Keys.SIDEBAR;
|
||||||
export const isIncrement = (e: KeyEvent) => e.key === Keys.INCREMENT;
|
|
||||||
export const isDecrement = (e: KeyEvent) => e.key === Keys.DECREMENT;
|
|
||||||
export const isReplace = (e: KeyEvent) => e.key === Keys.REPLACE;
|
|
||||||
export const isEscape = (e: KeyEvent) => e.key === Keys.ESCAPE;
|
export const isEscape = (e: KeyEvent) => e.key === Keys.ESCAPE;
|
||||||
export const isUp = (e: KeyEvent) => e.key === Keys.UP;
|
|
||||||
export const isDown = (e: KeyEvent) => e.key === Keys.DOWN;
|
|
||||||
export const isLeft = (e: KeyEvent) => e.key === Keys.LEFT;
|
|
||||||
export const isRight = (e: KeyEvent) => e.key === Keys.RIGHT;
|
|
||||||
export const useDigits = (e: KeyEvent): [boolean, number] => [digits.includes(Number(e.key)), Number(e.key)];
|
|
||||||
|
|
Loading…
Reference in New Issue