Compare commits
15 Commits
2ba10dd2e8
...
3fd43e0de8
Author | SHA1 | Date |
---|---|---|
Egor Savkin | 3fd43e0de8 | |
Egor Savkin | 4448029757 | |
Egor Savkin | 51c9031f24 | |
Egor Savkin | be50b2a3c3 | |
Egor Savkin | ee6da1b282 | |
Egor Savkin | 5e3a9af749 | |
Egor Savkin | d3fb46956e | |
Egor Savkin | 6bfed3e779 | |
Egor Savkin | dfe1f0ea2d | |
Egor Savkin | 839d7c6612 | |
Egor Savkin | 1cb9c90c65 | |
Egor Savkin | eb196b086e | |
Egor Savkin | 56a44ce4a3 | |
Egor Savkin | aa35348288 | |
Egor Savkin | 4bc6f6a3ee |
|
@ -9,24 +9,24 @@
|
|||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.23.9",
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/preset-env": "^7.24.0",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"@hello-pangea/dnd": "^16.5.0",
|
||||
"@uidotdev/usehooks": "^2.4.1",
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-preset-minify": "^0.5.2",
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"jquery": "^3.7.1",
|
||||
"json-logic-js": "^2.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.10.0",
|
||||
"react-bootstrap": "^2.10.2",
|
||||
"react-dom": "^18.2.0",
|
||||
"uuid": "^9.0.1",
|
||||
"webpack": "^5.90.1",
|
||||
"webpack": "^5.90.3",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-preprocessor-loader": "^1.3.0",
|
||||
"zustand": "^4.5.0"
|
||||
"zustand": "^4.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
|
@ -94,9 +94,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/core": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
|
||||
"integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz",
|
||||
"integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
|
@ -104,11 +104,11 @@
|
|||
"@babel/generator": "^7.23.6",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-module-transforms": "^7.23.3",
|
||||
"@babel/helpers": "^7.23.9",
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@babel/template": "^7.23.9",
|
||||
"@babel/traverse": "^7.23.9",
|
||||
"@babel/types": "^7.23.9",
|
||||
"@babel/helpers": "^7.24.0",
|
||||
"@babel/parser": "^7.24.0",
|
||||
"@babel/template": "^7.24.0",
|
||||
"@babel/traverse": "^7.24.0",
|
||||
"@babel/types": "^7.24.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.2",
|
||||
|
@ -360,9 +360,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
|
||||
"integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
|
||||
"integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -480,14 +480,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
|
||||
"integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz",
|
||||
"integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.23.9",
|
||||
"@babel/traverse": "^7.23.9",
|
||||
"@babel/types": "^7.23.9"
|
||||
"@babel/template": "^7.24.0",
|
||||
"@babel/traverse": "^7.24.0",
|
||||
"@babel/types": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
@ -508,9 +508,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
|
||||
"integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz",
|
||||
"integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
|
@ -1300,14 +1300,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz",
|
||||
"integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.0.tgz",
|
||||
"integrity": "sha512-y/yKMm7buHpFFXfxVFS4Vk1ToRJDilIa6fKRioB9Vjichv58TDGXTvqV0dN7plobAmTW5eSEGXDngE+Mm+uO+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.23.3",
|
||||
"@babel/helper-compilation-targets": "^7.22.15",
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/compat-data": "^7.23.5",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
|
||||
"@babel/plugin-transform-parameters": "^7.23.3"
|
||||
},
|
||||
|
@ -1667,14 +1667,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/preset-env": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz",
|
||||
"integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.0.tgz",
|
||||
"integrity": "sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.23.5",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-plugin-utils": "^7.22.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/helper-validator-option": "^7.23.5",
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.23.3",
|
||||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.23.3",
|
||||
|
@ -1727,7 +1727,7 @@
|
|||
"@babel/plugin-transform-new-target": "^7.23.3",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.23.4",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.23.4",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.23.4",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.24.0",
|
||||
"@babel/plugin-transform-object-super": "^7.23.3",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.23.4",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.23.4",
|
||||
|
@ -1822,23 +1822,23 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
|
||||
"integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
|
||||
"integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.23.5",
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@babel/types": "^7.23.9"
|
||||
"@babel/parser": "^7.24.0",
|
||||
"@babel/types": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
|
||||
"integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz",
|
||||
"integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.23.5",
|
||||
|
@ -1847,8 +1847,8 @@
|
|||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@babel/types": "^7.23.9",
|
||||
"@babel/parser": "^7.24.0",
|
||||
"@babel/types": "^7.24.0",
|
||||
"debug": "^4.3.1",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
|
@ -1857,9 +1857,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.23.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
|
||||
"integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
|
||||
"integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.23.4",
|
||||
|
@ -2025,9 +2025,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@react-aria/ssr": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.7.1.tgz",
|
||||
"integrity": "sha512-ovVPSD1WlRpZHt7GI9DqJrWG3OIYS+NXQ9y5HIewMJpSe+jPQmMQfyRmgX4EnvmxSlp0u04Wg/7oItcoSIb/RA==",
|
||||
"version": "3.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.2.tgz",
|
||||
"integrity": "sha512-0gKkgDYdnq1w+ey8KzG9l+H5Z821qh9vVjztk55rUg71vTk/Eaebeir+WtzcLLwTjw3m/asIjx8Y59y1lJZhBw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
|
@ -2040,9 +2040,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@restart/hooks": {
|
||||
"version": "0.4.11",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.11.tgz",
|
||||
"integrity": "sha512-Ft/ncTULZN6ldGHiF/k5qt72O8JyRMOeg0tApvCni8LkoiEahO+z3TNxfXIVGy890YtWVDvJAl662dVJSJXvMw==",
|
||||
"version": "0.4.16",
|
||||
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
|
||||
"integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
|
@ -2052,9 +2052,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@restart/ui": {
|
||||
"version": "1.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.6.tgz",
|
||||
"integrity": "sha512-eC3puKuWE1SRYbojWHXnvCNHGgf3uzHCb6JOhnF4OXPibOIPEkR1sqDSkL643ydigxwh+ruCa1CmYHlzk7ikKA==",
|
||||
"version": "1.6.8",
|
||||
"resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.6.8.tgz",
|
||||
"integrity": "sha512-6ndCv3oZ7r9vuP1Ok9KH55TM1/UkdBnP/fSraW0DFDMbPMzWKhVKeFAIEUCRCSdzayjZDcFYK6xbMlipN9dmMA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
|
@ -2082,9 +2082,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz",
|
||||
"integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==",
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.7.tgz",
|
||||
"integrity": "sha512-BVvNZhx362+l2tSwSuyEUV4h7+jk9raNdoTSdLfwTshXJSaGmYKluGRJznziCI3KX02Z19DdsQrdfrpXAU3Hfg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
|
@ -2180,9 +2180,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/@types/warning": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
|
||||
"integrity": "sha512-t/Tvs5qR47OLOr+4E9ckN8AmP2Tf16gWq+/qA4iUGS/OOyHVO8wv2vjJuX8SNOUTJyWb+2t7wJm6cXILFnOROA==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
|
||||
"integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@uidotdev/usehooks": {
|
||||
|
@ -2813,9 +2813,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/bootstrap": {
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
|
||||
"integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
|
||||
"integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -4077,14 +4077,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-bootstrap": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.0.tgz",
|
||||
"integrity": "sha512-87gRP69VAfeU2yKgp8RI3HvzhPNrnYIV2QNranYXataz3ef+k7OhvKGGdxQLQfUsQ2RTmlY66tn4pdFrZ94hNg==",
|
||||
"version": "2.10.2",
|
||||
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.2.tgz",
|
||||
"integrity": "sha512-UvB7mRqQjivdZNxJNEA2yOQRB7L9N43nBnKc33K47+cH90/ujmnMwatTCwQLu83gLhrzAl8fsa6Lqig/KLghaA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.22.5",
|
||||
"@restart/hooks": "^0.4.9",
|
||||
"@restart/ui": "^1.6.6",
|
||||
"@restart/ui": "^1.6.8",
|
||||
"@types/react-transition-group": "^4.4.6",
|
||||
"classnames": "^2.3.2",
|
||||
"dom-helpers": "^5.2.1",
|
||||
|
@ -4748,9 +4748,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/webpack": {
|
||||
"version": "5.90.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.1.tgz",
|
||||
"integrity": "sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog==",
|
||||
"version": "5.90.3",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz",
|
||||
"integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.3",
|
||||
|
@ -4974,9 +4974,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/zustand": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.0.tgz",
|
||||
"integrity": "sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==",
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.2.tgz",
|
||||
"integrity": "sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"use-sync-external-store": "1.2.0"
|
||||
|
|
24
package.json
24
package.json
|
@ -14,29 +14,37 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.23.9",
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/preset-env": "^7.23.9",
|
||||
"@babel/core": "^7.24.0",
|
||||
"@babel/preset-env": "^7.24.0",
|
||||
"@babel/preset-react": "^7.23.3",
|
||||
"babel-loader": "^9.1.3",
|
||||
"babel-preset-minify": "^0.5.2",
|
||||
"bootstrap": "^5.3.2",
|
||||
"bootstrap": "^5.3.3",
|
||||
"jquery": "^3.7.1",
|
||||
"react": "^18.2.0",
|
||||
"react-bootstrap": "^2.10.0",
|
||||
"react-bootstrap": "^2.10.2",
|
||||
"@hello-pangea/dnd": "^16.5.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"uuid": "^9.0.1",
|
||||
"webpack": "^5.90.1",
|
||||
"webpack": "^5.90.3",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"json-logic-js": "^2.0.2",
|
||||
"zustand": "^4.5.0",
|
||||
"zustand": "^4.5.2",
|
||||
"@uidotdev/usehooks":"^2.4.1",
|
||||
"webpack-preprocessor-loader": "^1.3.0"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react"
|
||||
"@babel/preset-react",
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"browsers": [
|
||||
">0.25%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
]
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,26 +72,32 @@ button {
|
|||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
position: relative;
|
||||
max-width: max(1/4 * 100%, 310px);
|
||||
scrollbar-width: thin;
|
||||
scrollbar-gutter: stable;
|
||||
scrollbar-color: #6e7e87 transparent;
|
||||
scrollbar-arrow-color: transparent;
|
||||
/*padding-bottom: 4rem!important;*/
|
||||
}
|
||||
|
||||
> aside.aside:after {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
height: 100px;
|
||||
width: calc(2 / 6 * 100%);
|
||||
content: "";
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(13, 53, 71, 1),
|
||||
rgba(13, 53, 71, 0)
|
||||
);
|
||||
pointer-events: none;
|
||||
.gradient-bottom {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
height: 100px;
|
||||
//width: max(1/4 * 100%, 310px);
|
||||
width: inherit;
|
||||
content: "";
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
rgba(13, 53, 71, 1),
|
||||
rgba(13, 53, 71, 0)
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
> section.main {
|
||||
flex: 4;
|
||||
max-width: calc(4 / 6 * 100%);
|
||||
width: calc(3/4 * 100%);
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +106,7 @@ button {
|
|||
|
||||
display: flex;
|
||||
color: white;
|
||||
padding: 3rem 2rem 1rem;
|
||||
padding: 1rem 0rem 1rem 1.5rem;
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
|
@ -119,6 +125,7 @@ button {
|
|||
|
||||
h3 {
|
||||
color: white;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
|
@ -176,8 +183,50 @@ button {
|
|||
}
|
||||
}
|
||||
|
||||
.backlog-container {
|
||||
.catalog-container {
|
||||
padding-bottom: 4rem;
|
||||
|
||||
.catalog-bar {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 13px 0 0.4rem 0;
|
||||
padding: 0 0.5rem;
|
||||
justify-content: space-around;
|
||||
|
||||
.mobileCloseMenu {
|
||||
display: flex;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 10%;
|
||||
align-content: center;
|
||||
}
|
||||
.search-catalog {
|
||||
display: inline-block;
|
||||
border: 0;
|
||||
width: 90%;
|
||||
|
||||
.search-catalog-input {
|
||||
display: inline;
|
||||
border: 0;
|
||||
color: white;
|
||||
border-radius: 2rem;
|
||||
background: rgba(255, 255, 255, 0.15) url("/images/shop/icon-search.svg") no-repeat;
|
||||
background-position: left 2% center;
|
||||
background-size: 20px;
|
||||
padding-right: 1rem;
|
||||
text-indent: 20px;
|
||||
|
||||
&::placeholder {
|
||||
color: white;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rule {
|
||||
|
@ -241,6 +290,9 @@ button {
|
|||
|
||||
.item-card-name {
|
||||
font-weight: 700;
|
||||
&.tabbed {
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
color: white;
|
||||
font-weight: bold;
|
||||
font-size: 1.75rem;
|
||||
padding: .75rem 2rem;
|
||||
padding: .75rem 1.5rem;
|
||||
}
|
||||
|
||||
#accordion_categories .accordion-body {
|
||||
|
@ -73,6 +73,10 @@
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.options-invalid {
|
||||
box-shadow: 0 0 0 .25rem rgba(229, 62, 62, 0.25)!important;
|
||||
--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important;
|
||||
}
|
||||
/*
|
||||
##Device = Tablets, Ipads (portrait)
|
||||
##Screen = B/w 768px to 1024px
|
||||
|
@ -94,6 +98,14 @@
|
|||
height: calc(100vh - 10px - 2.5rem); /* .navbar vertical padding + line height (.navbar-brand.font-size.rem * body.font-size * body.line-height)*/
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside {
|
||||
min-width: max(300px, 30%);
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside .gradient-bottom {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
#root-shop .productItem {
|
||||
padding: 2rem 1rem 1rem;
|
||||
}
|
||||
|
@ -111,7 +123,7 @@
|
|||
}
|
||||
|
||||
#root-shop .productItem .content ul {
|
||||
font-size: .6rem;
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control {
|
||||
|
@ -133,7 +145,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: 1rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form,
|
||||
|
@ -163,7 +175,7 @@
|
|||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
padding: .2em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
@ -192,7 +204,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
|
@ -217,7 +229,7 @@
|
|||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
padding: .2em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
@ -227,7 +239,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form,
|
||||
|
@ -236,7 +248,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
font-size: 1.0rem;
|
||||
}
|
||||
|
||||
/*#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
|
@ -288,7 +300,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
|
@ -308,11 +320,11 @@
|
|||
}
|
||||
|
||||
#root-shop .productItem .content h3 {
|
||||
font-size: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content ul {
|
||||
font-size: .5rem;
|
||||
font-size: .75rem;
|
||||
}
|
||||
|
||||
#root-shop .panel {
|
||||
|
@ -345,7 +357,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form,
|
||||
|
@ -354,7 +366,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/*#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
|
@ -367,7 +379,6 @@
|
|||
border-top-right-radius: 30px;
|
||||
width: 80px;
|
||||
padding: 5px 0 5px 10px;
|
||||
margin-bottom: -25px;
|
||||
margin-left: -1.3rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
@ -386,7 +397,7 @@
|
|||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
padding: .2em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
@ -394,21 +405,22 @@
|
|||
#root-shop .layout>aside.aside.menu-opened {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
width: 310px;
|
||||
width: min(310px, 60vw);
|
||||
max-width: 60%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main {
|
||||
/*transform: translate3d(310px, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 310px;
|
||||
left: min(310px, 60vw);
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
|
@ -422,13 +434,13 @@
|
|||
transition: left .3s;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: -310px;
|
||||
width: 310px;
|
||||
left: max(-310px, -60vw);
|
||||
width: min(310px, 60vw);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside:after {
|
||||
width: 0;
|
||||
#root-shop .layout>aside.aside .gradient-bottom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside + section.main {
|
||||
|
@ -450,7 +462,7 @@
|
|||
overflow: initial;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
|
||||
#root-shop .layout>aside.aside.menu-opened > .catalog-container {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -460,7 +472,7 @@
|
|||
}
|
||||
|
||||
#accordion_categories button {
|
||||
font-size: 1rem;
|
||||
font-size: 1.5rem;
|
||||
padding: .5rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
@ -500,7 +512,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
|
@ -516,20 +528,21 @@
|
|||
}
|
||||
|
||||
#root-shop .productItem .content h3 {
|
||||
font-size: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
width: 310px;
|
||||
width: min(310px, 90vw);
|
||||
max-width: 90%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main {
|
||||
/*transform: translate3d(310px, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 310px;
|
||||
left: min(310px, 90vw);
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
@ -549,13 +562,13 @@
|
|||
transition: left .3s;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: -310px;
|
||||
width: 310px;
|
||||
left: max(-310px, -90vw);
|
||||
width: min(310px, 90vw);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside:after {
|
||||
width: 0;
|
||||
#root-shop .layout>aside.aside .gradient-bottom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside + section.main {
|
||||
|
@ -611,7 +624,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
font-size: .8rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form,
|
||||
|
@ -620,7 +633,7 @@
|
|||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
/*#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
|
@ -633,7 +646,6 @@
|
|||
border-top-right-radius: 30px;
|
||||
width: 80px;
|
||||
padding: 5px 0 5px 10px;
|
||||
margin-bottom: 15px;
|
||||
margin-left: -1.3rem;
|
||||
}
|
||||
|
||||
|
@ -650,7 +662,7 @@
|
|||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
padding: .2em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
@ -659,7 +671,7 @@
|
|||
overflow: initial;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
|
||||
#root-shop .layout>aside.aside.menu-opened > .catalog-container {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
}
|
||||
|
@ -669,7 +681,7 @@
|
|||
}
|
||||
|
||||
#accordion_categories button {
|
||||
font-size: 1rem;
|
||||
font-size: 1.5rem;
|
||||
padding: .5rem 0.5rem;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="512"
|
||||
height="512"
|
||||
version="1.1"
|
||||
viewBox="0 0 512 512"
|
||||
id="svg1"
|
||||
sodipodi:docname="icon-search.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:zoom="1.59375"
|
||||
inkscape:cx="255.68627"
|
||||
inkscape:cy="256"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg1" />
|
||||
<path
|
||||
d="M456.69,421.39,362.6,327.3a173.81,173.81,0,0,0,34.84-104.58C397.44,126.38,319.06,48,222.72,48S48,126.38,48,222.72s78.38,174.72,174.72,174.72A173.81,173.81,0,0,0,327.3,362.6l94.09,94.09a25,25,0,0,0,35.3-35.3ZM97.92,222.72a124.8,124.8,0,1,1,124.8,124.8A124.95,124.95,0,0,1,97.92,222.72Z"
|
||||
fill="#fff"
|
||||
id="path1"
|
||||
style="fill:#ffffff;fill-opacity:0.5" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,68 @@
|
|||
import React from 'react';
|
||||
import {Droppable} from "@hello-pangea/dnd";
|
||||
import {useShopStore} from "./shop_store";
|
||||
// #!render_count
|
||||
import {useRenderCount} from "@uidotdev/usehooks";
|
||||
import {CatalogGroups} from "./CatalogGroups";
|
||||
import {SearchBar} from "./SearchBar";
|
||||
import {CatalogSearchResult} from "./CatalogSearchResult";
|
||||
import {GradientBottom} from "./GradientBottom";
|
||||
|
||||
/**
|
||||
* Component that renders the catalog in the aside
|
||||
*/
|
||||
export function Catalog() {
|
||||
// #!render_count
|
||||
const renderCount = useRenderCount();
|
||||
|
||||
const data = useShopStore((state) => state.groups);
|
||||
const items = useShopStore((state) => state.cards);
|
||||
|
||||
const onClickToggleMobileSideMenu = useShopStore((state) => state.switchSideMenu);
|
||||
const isMobile = useShopStore((state) => state.isMobile);
|
||||
const showSearch = useShopStore((state) => state.listed_cards.length > 0);
|
||||
|
||||
// #!render_count
|
||||
console.log("Catalog renders: ", renderCount)
|
||||
|
||||
return (
|
||||
<Droppable
|
||||
droppableId={data.id}
|
||||
isDropDisabled={false}>
|
||||
|
||||
{(provided) => (
|
||||
<div
|
||||
className="catalog-container"
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}>
|
||||
|
||||
|
||||
|
||||
<div className="catalog-bar">
|
||||
<SearchBar/>
|
||||
|
||||
{isMobile ? (
|
||||
<div className="mobileCloseMenu">
|
||||
<button onClick={onClickToggleMobileSideMenu}>
|
||||
<img src="/images/shop/icon-close-white.svg" alt="add"/>
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
{showSearch ? <CatalogSearchResult/> : <CatalogGroups/>}
|
||||
|
||||
{provided.placeholder && (
|
||||
<div style={{display: 'none'}}>
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<GradientBottom/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</Droppable>
|
||||
);
|
||||
|
||||
}
|
|
@ -1,24 +1,10 @@
|
|||
import React from 'react';
|
||||
import {Droppable} from "@hello-pangea/dnd";
|
||||
import {ProductItem} from "./ProductItem";
|
||||
import React from "react";
|
||||
import {useShopStore} from "./shop_store";
|
||||
// #!render_count
|
||||
import {useRenderCount} from "@uidotdev/usehooks";
|
||||
|
||||
/**
|
||||
* Component that renders the backlog in the aside
|
||||
*/
|
||||
export function Backlog() {
|
||||
// #!render_count
|
||||
const renderCount = useRenderCount();
|
||||
|
||||
export function CatalogGroups() {
|
||||
const data = useShopStore((state) => state.groups);
|
||||
const items = useShopStore((state) => state.cards);
|
||||
const onClickToggleMobileSideMenu = useShopStore((state) => state.switchSideMenu);
|
||||
const isMobile = useShopStore((state) => state.isMobile);
|
||||
|
||||
// #!render_count
|
||||
console.log("Backlog renders: ", renderCount)
|
||||
|
||||
const ordered_groups = data.categories.map(groupItem => ({
|
||||
name: groupItem.name,
|
||||
|
@ -50,39 +36,9 @@ export function Backlog() {
|
|||
);
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<Droppable
|
||||
droppableId={data.id}
|
||||
isDropDisabled={false}>
|
||||
|
||||
{(provided) => (
|
||||
<div
|
||||
className="backlog-container"
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}>
|
||||
|
||||
{isMobile ? (
|
||||
<div className="mobileCloseMenu">
|
||||
<button onClick={onClickToggleMobileSideMenu}>
|
||||
<img src="/images/shop/icon-close-white.svg" alt="add"/>
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="accordion accordion-flush" id="accordion_categories">
|
||||
{groups}
|
||||
</div>
|
||||
|
||||
{provided.placeholder && (
|
||||
<div style={{display: 'none'}}>
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
</Droppable>
|
||||
);
|
||||
|
||||
<div className="accordion accordion-flush" id="accordion_categories">
|
||||
{groups}
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import React from 'react';
|
||||
import {useShopStore} from "./shop_store";
|
||||
import {ProductItem} from "./ProductItem";
|
||||
|
||||
|
||||
export function CatalogSearchResult() {
|
||||
const cards_to_display = useShopStore((state) => state.listed_cards);
|
||||
return ( <>
|
||||
{cards_to_display.map((item, _) => {
|
||||
return (
|
||||
<ProductItem card_index={item} key={"searched_" + item} />
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import React from 'react';
|
||||
|
||||
export function GradientBottom() {
|
||||
return (
|
||||
<div className="gradient-bottom"></div>
|
||||
)
|
||||
}
|
|
@ -27,13 +27,16 @@ const JSONExample = JSON.stringify({
|
|||
"options": null
|
||||
}
|
||||
],
|
||||
"type": "rack"
|
||||
"type": "rack",
|
||||
"options": {}
|
||||
},
|
||||
{
|
||||
"items": [],
|
||||
"type": "no_crate"
|
||||
"type": "no_crate",
|
||||
"options": {}
|
||||
}
|
||||
]
|
||||
],
|
||||
"options": {}
|
||||
});
|
||||
|
||||
export function ImportJSON() {
|
||||
|
|
|
@ -11,6 +11,11 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
|||
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
||||
const options_class = useShopStore((state) => state.crates[crate_index].items[card_index].options_class);
|
||||
const sideMenuIsOpen = useShopStore((state) => state.sideMenuIsOpen);
|
||||
const _notificationTimer = useShopStore((state) => state.notificationTimer);
|
||||
const hideNotification = useShopStore((state) => state.hideNotification);
|
||||
const displayNotification = useShopStore((state) =>
|
||||
state.notificationCrateId === crate_id &&
|
||||
(state.notificationCardIndex === card_index || (state.crates[crate_index].items.length + (state.notificationCardIndex || -1)) === card_index));
|
||||
|
||||
const onOptionsUpdate = useShopStore((state) => state.updateOptions);
|
||||
|
||||
|
@ -25,6 +30,8 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
|||
first={first}
|
||||
last={last}
|
||||
sideMenuIsOpen={sideMenuIsOpen}
|
||||
onHideNotification={hideNotification}
|
||||
displayNotification={displayNotification}
|
||||
target={{
|
||||
construct: ((outvar, value) => {
|
||||
// #!options_log
|
||||
|
|
|
@ -8,7 +8,7 @@ import {useRenderCount} from "@uidotdev/usehooks";
|
|||
|
||||
/**
|
||||
* Component that renders a product.
|
||||
* Used in the aside (e.g backlog of product)
|
||||
* Used in the aside (e.g catalog of product)
|
||||
*/
|
||||
export function ProductItem({card_index}) {
|
||||
// #!render_count
|
||||
|
@ -16,7 +16,7 @@ export function ProductItem({card_index}) {
|
|||
|
||||
const getCardDescription = useShopStore((state) => state.getCardDescription);
|
||||
const currency = useShopStore((state) => state.currency);
|
||||
const onAddCard = useShopStore((state) => state.addCardFromBacklog);
|
||||
const onAddCard = useShopStore((state) => state.addCardFromCatalog);
|
||||
const card = getCardDescription(card_index);
|
||||
|
||||
// #!render_count
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import React from 'react';
|
||||
import {useShopStore} from "./shop_store";
|
||||
|
||||
export function SearchBar() {
|
||||
const search_bar_value = useShopStore((state) => state.search_bar_value);
|
||||
const updateSearchBar = useShopStore((state) => state.updateSearchBar);
|
||||
return (
|
||||
<div className="search-catalog form-outline">
|
||||
<input type="search"
|
||||
id="search_bar"
|
||||
className="search-catalog-input form-control"
|
||||
placeholder="Search"
|
||||
value={search_bar_value}
|
||||
onChange={event => updateSearchBar(event.target.value)}
|
||||
aria-label="Search"/>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -6,7 +6,7 @@ import {useRenderCount} from "@uidotdev/usehooks";
|
|||
|
||||
|
||||
import {Layout} from "./Layout";
|
||||
import {Backlog} from "./Backlog";
|
||||
import {Catalog} from "./Catalog";
|
||||
import {OrderPanel} from "./OrderPanel";
|
||||
import {useShopStore} from "./shop_store";
|
||||
|
||||
|
@ -18,7 +18,7 @@ export function Shop() {
|
|||
// #!render_count
|
||||
const renderCount = useRenderCount();
|
||||
|
||||
const addCardFromBacklog = useShopStore((state) => state.addCardFromBacklog);
|
||||
const addCardFromCatalog = useShopStore((state) => state.addCardFromCatalog);
|
||||
const initExtData = useShopStore((state) => state.initExtData);
|
||||
const moveCard = useShopStore((state) => state.moveCard);
|
||||
const deleteCard = useShopStore((state) => state.deleteCard);
|
||||
|
@ -30,16 +30,16 @@ export function Shop() {
|
|||
console.log(drop_result)
|
||||
return;
|
||||
}
|
||||
if (drop_result.source.droppableId === "backlog")
|
||||
addCardFromBacklog(drop_result.destination.droppableId, drop_result.source.index, drop_result.destination.index);
|
||||
else if (drop_result.destination.droppableId === "backlog")
|
||||
if (drop_result.source.droppableId === "catalog")
|
||||
addCardFromCatalog(drop_result.destination.droppableId, drop_result.source.index, drop_result.destination.index);
|
||||
else if (drop_result.destination.droppableId === "catalog")
|
||||
deleteCard(drop_result.source.droppableId, drop_result.source.index);
|
||||
else
|
||||
moveCard(drop_result.source.droppableId, drop_result.source.index, drop_result.destination.droppableId, drop_result.destination.index)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
addCardFromBacklog(null, [cardIndexById("eem_pwr_mod"), cardIndexById("kasli")], -1, true);
|
||||
addCardFromCatalog(null, [cardIndexById("eem_pwr_mod"), cardIndexById("kasli")], -1, true);
|
||||
initExtData();
|
||||
}, []);
|
||||
|
||||
|
@ -50,7 +50,7 @@ export function Shop() {
|
|||
<DragDropContext onDragEnd={handleOnDragEnd}>
|
||||
<Layout
|
||||
aside={
|
||||
<Backlog/>
|
||||
<Catalog/>
|
||||
}
|
||||
main={(
|
||||
<OrderPanel
|
||||
|
|
|
@ -41,11 +41,7 @@ export function SummaryCrateCard({crate_index, card_index}) {
|
|||
onClick={() => setHighlight(crate_id, card_index)}
|
||||
onMouseEnter={() => setHighlight(crate_id, card_index)}
|
||||
onMouseLeave={() => resetHighlight()}>
|
||||
<td className="item-card-name">
|
||||
<span style={{
|
||||
'display': 'inline-block',
|
||||
'width': '16px',
|
||||
}}> </span>
|
||||
<td className="item-card-name tabbed">
|
||||
<div>{`${card.name_number} ${card.name} ${card.name_codename}`}</div>
|
||||
</td>
|
||||
|
||||
|
|
|
@ -23,10 +23,7 @@ export function SummaryCratePricedOptions({crate_index}) {
|
|||
|
||||
return options.map((option, _i) => (
|
||||
<tr key={"summary_crate_" + crate_id +"option_" + option.id}>
|
||||
<td className="item-card-name">
|
||||
<span style={{
|
||||
'display': 'inline-block', 'width': '16px',
|
||||
}}> </span>
|
||||
<td className="item-card-name tabbed">
|
||||
<div>{option.title}</div>
|
||||
</td>
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ import {useClickAway} from "./useClickAway";
|
|||
import {ProcessOptions} from "./Options";
|
||||
import {Notification} from "./Notification";
|
||||
|
||||
export function DialogPopup({options, data, target, id, big, first, last, options_class, sideMenuIsOpen}) {
|
||||
export function DialogPopup({options, data, target, id, big, first, last, options_class,
|
||||
sideMenuIsOpen, displayNotification, onHideNotification}) {
|
||||
const [show, setShow] = useState(false);
|
||||
const ref = useClickAway((e) => {
|
||||
if (e.type === "mousedown") // ignore touchstart
|
||||
|
@ -22,8 +23,11 @@ export function DialogPopup({options, data, target, id, big, first, last, option
|
|||
id={"processed_options_notification" + id}
|
||||
tip="Customization options available"
|
||||
sideMenuIsOpen={sideMenuIsOpen}
|
||||
show={displayNotification}
|
||||
onHide={onHideNotification}
|
||||
content={
|
||||
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
||||
<img className="alert-info"
|
||||
src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
||||
onClick={handleClick}/>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -1,30 +1,21 @@
|
|||
import {OverlayTrigger, Tooltip} from "react-bootstrap";
|
||||
import React, {useEffect, useState} from "react";
|
||||
|
||||
export function Notification({id, tip, content, sideMenuIsOpen}) {
|
||||
const [show, setShow] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setShow(true)
|
||||
}, 100);
|
||||
|
||||
setTimeout(() => {
|
||||
setShow(false)
|
||||
}, 5000);
|
||||
}, []);
|
||||
import React from "react";
|
||||
|
||||
export function Notification({id, tip, content, sideMenuIsOpen, show, onHide}) {
|
||||
return (
|
||||
<OverlayTrigger
|
||||
placement="top"
|
||||
trigger={["click", "hover"]}
|
||||
style={{display: 'inline'}}
|
||||
show={show}
|
||||
onToggle={() => setShow(false)}
|
||||
overlay={props => <Tooltip id={id} {...props}>{tip}</Tooltip>}
|
||||
rootClose={!sideMenuIsOpen}
|
||||
>
|
||||
{content}
|
||||
</OverlayTrigger>
|
||||
<OverlayTrigger
|
||||
placement="top"
|
||||
trigger={["click", "hover"]}
|
||||
style={{display: 'inline'}}
|
||||
show={show}
|
||||
overlay={props => <Tooltip id={id} {...props}>{tip}</Tooltip>}
|
||||
rootClose={!sideMenuIsOpen}
|
||||
onToggle={onHide}
|
||||
popperConfig={{
|
||||
strategy: 'fixed'
|
||||
}}
|
||||
>
|
||||
{content}
|
||||
</OverlayTrigger>
|
||||
)
|
||||
}
|
|
@ -1,22 +1,25 @@
|
|||
import React, {Component} from "react";
|
||||
import {Tip} from "./Tip";
|
||||
import {Validation} from "../validation";
|
||||
|
||||
class Line extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
// Initialize the state object with the initial values from the props
|
||||
this.state = {
|
||||
text: props.outvar in props.data ? props.data[props.outvar] : (props.fallback ? props.fallback : "")
|
||||
text: props.outvar in props.data ? props.data[props.outvar] : (props.fallback ? props.fallback : ""),
|
||||
valid: true
|
||||
};
|
||||
// Bind the event handler to this
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.props.target.construct(this.props.outvar, this.state.text);
|
||||
}
|
||||
|
||||
handleClick(element) {
|
||||
handleChange(element) {
|
||||
let text = element.target.value;
|
||||
this.setState({
|
||||
text: text
|
||||
text: text,
|
||||
valid: this.props.validator ? this.props.validator(text) : true
|
||||
});
|
||||
this.props.target.update(this.props.outvar, text);
|
||||
}
|
||||
|
@ -39,14 +42,14 @@ class Line extends Component {
|
|||
{this.props.title}:
|
||||
</label>
|
||||
{this.props.tip && <Tip id={this.props.id + "tooltip"} tip={this.props.tip}/>}
|
||||
<input type="text" className="form-control form-control-sm" id={key} onChange={this.handleClick}
|
||||
<input type="text" className={`form-control form-control-sm ${this.state.valid ? "" : "options-invalid"}`} id={key} onChange={this.handleChange}
|
||||
value={this.state.text}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function LineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes}) {
|
||||
export function LineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes, validator}) {
|
||||
return <Line target={target} title={title} fallback={fallback} outvar={outvar} icon={icon} tip={tip} key={id}
|
||||
id={id} data={data} classes={classes}/>;
|
||||
id={id} data={data} classes={classes} validator={validator && Validation[validator.name](validator.params)}/>;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import React, {Component} from "react";
|
||||
import {Tip} from "./Tip";
|
||||
import {Validation} from "../validation";
|
||||
|
||||
class SwitchLine extends Component {
|
||||
constructor(props) {
|
||||
|
@ -7,7 +8,8 @@ class SwitchLine extends Component {
|
|||
// Initialize the state object with the initial values from the props
|
||||
this.state = {
|
||||
text: props.outvar in props.data ? props.data[props.outvar].text : (props.fallback ? props.fallback.text : ""),
|
||||
checked: props.outvar in props.data ? props.data[props.outvar].checked : (props.fallback ? props.fallback.checked : false)
|
||||
checked: props.outvar in props.data ? props.data[props.outvar].checked : (props.fallback ? props.fallback.checked : false),
|
||||
valid: true
|
||||
};
|
||||
// Bind the event handler to this
|
||||
this.handleText = this.handleText.bind(this);
|
||||
|
@ -18,7 +20,8 @@ class SwitchLine extends Component {
|
|||
handleText(element) {
|
||||
let new_state = {
|
||||
...this.state,
|
||||
text: element.target.value
|
||||
text: element.target.value,
|
||||
valid: this.props.validator ? this.props.validator(element.target.value) : true
|
||||
}
|
||||
this.setState(new_state);
|
||||
this.props.target.update(this.props.outvar, new_state);
|
||||
|
@ -39,6 +42,7 @@ class SwitchLine extends Component {
|
|||
return {
|
||||
checked: props.data[props.outvar].checked,
|
||||
text: props.data[props.outvar].text,
|
||||
valid: this.props.validator ? this.props.validator(props.data[props.outvar].text) : true
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
@ -64,14 +68,14 @@ class SwitchLine extends Component {
|
|||
</label>
|
||||
{this.props.tip && <Tip id={this.props.id + "tooltip"} tip={this.props.tip}/>}
|
||||
</div>
|
||||
<input type="text" className="form-control form-control-sm" id={key + "line"} onChange={this.handleText}
|
||||
<input type="text" className={`form-control form-control-sm ${this.state.valid ? "" : "options-invalid"}`} id={key + "line"} onChange={this.handleText}
|
||||
value={this.state.text} disabled={!this.state.checked}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function SwitchLineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes}) {
|
||||
export function SwitchLineWrapper(target, id, data, {title, fallback, outvar, icon, tip, classes, validator}) {
|
||||
return <SwitchLine target={target} title={title} fallback={fallback} outvar={outvar} icon={icon} tip={tip} key={id}
|
||||
id={id} data={data} classes={classes}/>;
|
||||
id={id} data={data} classes={classes} validator={validator && Validation[validator.name](validator.params)}/>;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
|
||||
const ipv4 = (params) => {
|
||||
const ipv4WithMaskPattern = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(0|1[0-9]|2[0-9]|3[0-2]|[0-9])$/;
|
||||
return (text) => {
|
||||
return ipv4WithMaskPattern.test(text);
|
||||
}
|
||||
}
|
||||
|
||||
const ipv6 = (params) => {
|
||||
const ipv6WithMaskPattern = /(^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(\/(\d{1,2}|1[0-1]\d|12[0-8]))(%.+)?\s*$)/;
|
||||
|
||||
|
||||
return (text) => {
|
||||
return ipv6WithMaskPattern.test(text);
|
||||
}
|
||||
}
|
||||
|
||||
const ipv4or6 = (params) => {
|
||||
const ipv4Local = ipv4(params);
|
||||
const ipv6Local = ipv6(params);
|
||||
return (text) => {
|
||||
return ipv4Local(text) || ipv6Local(text);
|
||||
}
|
||||
}
|
||||
|
||||
const frequency = (params) => {
|
||||
const factors = {
|
||||
"mhz": 1e6,
|
||||
"khz": 1e3,
|
||||
"hz": 1e1,
|
||||
"ghz": 1e9,
|
||||
};
|
||||
|
||||
return (text) => {
|
||||
const splited = text.split(/(\s+)/);
|
||||
const numerator = parseFloat(splited[0]);
|
||||
if (splited.length !== 3 || isNaN(numerator)) return false;
|
||||
const factor = factors[splited[2].toLowerCase()];
|
||||
if (!factor) return false;
|
||||
const realFreq = factor * numerator;
|
||||
return realFreq >= (params.min || 10*factors.mhz) && realFreq <= (params.max || 1*factors.ghz);
|
||||
}
|
||||
}
|
||||
|
||||
export const Validation = {
|
||||
ipv4: ipv4,
|
||||
ipv6: ipv6,
|
||||
ipv4or6: ipv4or6,
|
||||
frequency: frequency
|
||||
};
|
|
@ -18,9 +18,9 @@ const cards_to_pn_map = (cards) => {
|
|||
return result;
|
||||
};
|
||||
|
||||
const useBacklog = ((set, get) => ({
|
||||
const useCatalog = ((set, get) => ({
|
||||
cards: shared_data.items,
|
||||
groups: shared_data.columns.backlog,
|
||||
groups: shared_data.columns.catalog,
|
||||
cards_list: itemsUnfoldedList,
|
||||
currency: shared_data.currency,
|
||||
pn_to_cards: cards_to_pn_map(shared_data.items),
|
||||
|
@ -29,6 +29,43 @@ const useBacklog = ((set, get) => ({
|
|||
cardIndexById: card_id => get().cards_list.findIndex((element) => (card_id === element))
|
||||
}));
|
||||
|
||||
const useOptionsNotification = ((set, get) => ({
|
||||
notificationCrateId: null,
|
||||
notificationCardIndex: null,
|
||||
notificationTimer: null,
|
||||
_showNotification: (crate_id, card_index) => set(state => ({
|
||||
notificationCrateId: crate_id,
|
||||
notificationCardIndex: card_index,
|
||||
notificationTimer: setTimeout(() => {
|
||||
state.hideNotification()
|
||||
}, 5000)
|
||||
})),
|
||||
showNotification: (crate_id, card_index) => {
|
||||
get().hideNotification()
|
||||
setTimeout(() => get()._showNotification(crate_id, card_index), 100);
|
||||
},
|
||||
hideNotification: () => set(state => ({
|
||||
notificationCrateId: null,
|
||||
notificationCardIndex: null,
|
||||
notificationTimer: (state.notificationTimer && clearTimeout(state.notificationTimer)) || null,
|
||||
}))
|
||||
}));
|
||||
|
||||
const useSearch = ((set, get) => ({
|
||||
search_index: Array.from(Object.values(shared_data.items)
|
||||
.map((card, _) => (
|
||||
[(card.name + " " + card.name_number + " " + card.name_codename).toLowerCase(), card.id]
|
||||
))),
|
||||
search_bar_value: "",
|
||||
listed_cards: [],
|
||||
updateSearchBar: text => set(state => ({
|
||||
search_bar_value: text,
|
||||
listed_cards: text.length > 0 ? Array.from(get().search_index
|
||||
.filter((card, _) => card[0].includes(text.toLowerCase()))
|
||||
.map(([index, card_id], _) => get().cards_list.findIndex(elem => elem === card_id))) : []
|
||||
}))
|
||||
}));
|
||||
|
||||
const useCrateModes = ((set, get) => ({
|
||||
crate_modes: shared_data.crateModes,
|
||||
modes_order: shared_data.crateModeOrder,
|
||||
|
@ -114,9 +151,15 @@ const useLayout = ((set, get) => ({
|
|||
showNoDestination: false,
|
||||
timerAdded: null,
|
||||
|
||||
switchSideMenu: () => set(state => ({
|
||||
_switchSideMenu: () => set(state => ({
|
||||
sideMenuIsOpen: !state.sideMenuIsOpen
|
||||
})),
|
||||
switchSideMenu: () => {
|
||||
if (!get().sideMenuIsOpen) {
|
||||
get().hideNotification()
|
||||
}
|
||||
get()._switchSideMenu();
|
||||
},
|
||||
cardAdded: () => set(state => ({
|
||||
showCardAddedFeedback: true,
|
||||
showNoDestination: false,
|
||||
|
@ -167,6 +210,7 @@ const useImportJSON = ((set, get) => ({
|
|||
get().fillExtCrateData(crate.id);
|
||||
});
|
||||
get()._updateTotalOrderPrice();
|
||||
get().showNotification(get().active_crate, null);
|
||||
},
|
||||
updateImportDescription: (new_description) => set(state => ({
|
||||
importValue: {
|
||||
|
@ -339,7 +383,7 @@ const useCart = ((set, get) => ({
|
|||
})
|
||||
})),
|
||||
setActiveCrate: (id) => set(state => ({active_crate: id})),
|
||||
_addCardFromBacklog: (crate_to, index_from, index_to) => set(state => {
|
||||
_addCardFromCatalog: (crate_to, index_from, index_to) => set(state => {
|
||||
const take_from = (true_type_of(index_from) === "array" ? index_from : [index_from]).map((item, _i) => (state.cards_list[item]));
|
||||
const dest = crate_to || state.active_crate;
|
||||
if (!dest) return {};
|
||||
|
@ -510,14 +554,15 @@ const useCart = ((set, get) => ({
|
|||
get().fillOrderExtData();
|
||||
},
|
||||
|
||||
addCardFromBacklog: (crate_to, index_from, index_to, just_mounted) => {
|
||||
addCardFromCatalog: (crate_to, index_from, index_to, just_mounted) => {
|
||||
const dest = crate_to || get().active_crate;
|
||||
if (!dest) {
|
||||
console.warn("No destination");
|
||||
get().noDestinationWarning();
|
||||
return {};
|
||||
}
|
||||
get()._addCardFromBacklog(dest, index_from, index_to)
|
||||
get().showNotification(dest, index_to);
|
||||
get()._addCardFromCatalog(dest, index_from, index_to)
|
||||
get().fillExtData(dest);
|
||||
get().fillWarnings(dest);
|
||||
get().setActiveCrate(dest);
|
||||
|
@ -568,7 +613,9 @@ const useCart = ((set, get) => ({
|
|||
|
||||
|
||||
export const useShopStore = createWithEqualityFn((...params) => ({
|
||||
...useBacklog(...params),
|
||||
...useOptionsNotification(...params),
|
||||
...useCatalog(...params),
|
||||
...useSearch(...params),
|
||||
...useCrateModes(...params),
|
||||
...useCart(...params),
|
||||
...useSubmitForm(...params),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
export const data = window.shop_data;
|
||||
export const itemsUnfoldedList = Array.from(data.columns.backlog.categories.map(groupId => groupId.itemIds).flat());
|
||||
export const itemsUnfoldedList = Array.from(data.columns.catalog.categories.map(groupId => groupId.itemIds).flat());
|
||||
|
||||
export const productStyle = (style, snapshot, removeAnim, hovered, selected, cart=false) => {
|
||||
const custom = {
|
||||
|
@ -9,7 +9,7 @@ export const productStyle = (style, snapshot, removeAnim, hovered, selected, car
|
|||
backgroundColor: (hovered || selected) ? '#eae7f7' : 'initial',
|
||||
};
|
||||
|
||||
if (!cart && snapshot.draggingOver == null && // hack for backlog
|
||||
if (!cart && snapshot.draggingOver == null && // hack for catalog
|
||||
((!snapshot.isDragging) // prevent next elements from animation
|
||||
|| (snapshot.isDragging && snapshot.isDropAnimating))) { // prevent dragged element from weird animation
|
||||
style.transform = "none";
|
||||
|
|
|
@ -194,9 +194,14 @@ const shop_data = {
|
|||
]
|
||||
},
|
||||
[
|
||||
{type: "Line", args: {title: "IPv4", outvar: "ipv4", fallback: "192.168.1.75/24", tip: "Set up IPv4 address used by core device"}},
|
||||
{type: "SwitchLine", args: {title: "IPv6", outvar: "ipv6"}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}, tip: "Use external clock reference: 10, 80 (beta), 100 or 125 MHz. Other variants may be provided if needed."}}
|
||||
{type: "Line", args: {title: "IPv4", outvar: "ipv4", fallback: "192.168.1.75/24",
|
||||
tip: "Set up IPv4 address and mask used by core device", validator: {name: "ipv4"}}},
|
||||
{type: "SwitchLine", args: {title: "IPv6", outvar: "ipv6",
|
||||
tip: "Set up IPv6 address and prefix used by core device",
|
||||
validator: {name: "ipv6"}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false},
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
tip: "Use external clock reference: 10, 80 (beta), 100 or 125 MHz. Other variants may be provided if needed."}}
|
||||
],
|
||||
[
|
||||
{type: "Switch", args: {title: "Optical fiber", outvar: "optics", tip: "Use optical fiber instead of direct attach copper cable"}},
|
||||
|
@ -262,9 +267,17 @@ const shop_data = {
|
|||
]
|
||||
},
|
||||
[
|
||||
{type: "Line", args: {title: "IPv4", outvar: "ipv4", fallback: "192.168.1.75/24", tip: "Set up IPv4 address used by core device"}},
|
||||
{type: "SwitchLine", args: {title: "IPv6", outvar: "ipv6"}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}, tip: "Use external clock reference: 10, 80 (beta), 100 or 125 MHz. Other variants may be provided if needed."}}
|
||||
{type: "Line", args: {title: "IPv4", outvar: "ipv4",
|
||||
validator: {name: "ipv4"},
|
||||
fallback: "192.168.1.75/24",
|
||||
tip: "Set up IPv4 address used by core device"}},
|
||||
{type: "SwitchLine", args: {title: "IPv6", outvar: "ipv6",
|
||||
tip: "Set up IPv6 address and prefix used by core device",
|
||||
validator: {name: "ipv6"}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
fallback: {text: "125 MHz", checked: false},
|
||||
tip: "Use external clock reference: 10, 80 (beta), 100 or 125 MHz. Other variants may be provided if needed."}}
|
||||
],
|
||||
[
|
||||
{type: "Switch", args: {title: "Optical fiber", outvar: "optics", tip: "Use optical fiber instead of direct attach copper cable"}},
|
||||
|
@ -658,7 +671,9 @@ const shop_data = {
|
|||
"if": [
|
||||
{"var": "mono_eem"},
|
||||
[
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
fallback: {text: "125 MHz", checked: false}}},
|
||||
],
|
||||
[
|
||||
{type: "Switch", args: {title: "Synchronization", outvar: "sync", tip: "Synchronize phases across Urukuls"}},
|
||||
|
@ -667,7 +682,9 @@ const shop_data = {
|
|||
{"var": "sync"},
|
||||
null,
|
||||
[
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
fallback: {text: "125 MHz", checked: false}}},
|
||||
{
|
||||
"if": [
|
||||
{"var": "ext_data.has_sampler"},
|
||||
|
@ -716,7 +733,9 @@ const shop_data = {
|
|||
datasheet_name: '4410/4412 Urukul datasheet',
|
||||
options: [
|
||||
{type: "Switch", args: {title: "Use 1 EEM", outvar: "mono_eem", tip: "Use one EEM port setup. RF switch and synchronization will be unavailable."}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}}
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
fallback: {text: "125 MHz", checked: false}}}
|
||||
],
|
||||
size: 'small',
|
||||
type: 'urukul',
|
||||
|
@ -747,7 +766,9 @@ const shop_data = {
|
|||
'The upconverter is optional, if you would like the baseband version please leave us a note.'
|
||||
],
|
||||
options: [
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 1e9}},
|
||||
fallback: {text: "125 MHz", checked: false}}},
|
||||
{type: "Radio", args: {title: "Variant", outvar: "variant", variants: ["Baseband", "Upconverter"], fallback: 1}},
|
||||
],
|
||||
size: 'small',
|
||||
|
@ -1025,7 +1046,10 @@ const shop_data = {
|
|||
'Can be controlled by Kasli or work stand-alone with PoE supply.'
|
||||
],
|
||||
options: [
|
||||
{type: "SwitchLine", args: {title: "IP", outvar: "ip", fallback: {text: "DHCP", checked: false}, tip: "Set up IP address used by the device"}},
|
||||
{type: "SwitchLine", args: {title: "IP", outvar: "ip",
|
||||
validator: {name: "ipv4or6"},
|
||||
fallback: {text: "DHCP", checked: false},
|
||||
tip: "Set up IP address used by the device"}},
|
||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||
{type: "Switch", args: {title: "Term #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
||||
{type: "Switch", args: {title: "Term #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
||||
|
@ -1057,7 +1081,9 @@ const shop_data = {
|
|||
'Large frequency changes take several milliseconds.',
|
||||
],
|
||||
options: [
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}}
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 600e6}},
|
||||
fallback: {text: "125 MHz", checked: false}}}
|
||||
],
|
||||
size: 'small',
|
||||
type: null,
|
||||
|
@ -1084,7 +1110,9 @@ const shop_data = {
|
|||
'Each Almazny channel outputs twice the frequency of its corresponding Mirny channel.',
|
||||
],
|
||||
options: [
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}}
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
validator: {name: "frequency", params: {min: 10e6, max: 600e6}},
|
||||
fallback: {text: "125 MHz", checked: false}}}
|
||||
],
|
||||
size: 'big',
|
||||
type: null,
|
||||
|
@ -1166,9 +1194,13 @@ const shop_data = {
|
|||
'AD9959 DDS (500MSPS, 10-bit).'
|
||||
],
|
||||
options: [
|
||||
{type: "SwitchLine", args: {title: "IP", outvar: "ip", fallback: {text: "DHCP", checked: false}, tip: "Set up IP address used by the device"}},
|
||||
{type: "SwitchLine", args: {title: "IP", outvar: "ip",
|
||||
validator: {name: "ipv4or6"},
|
||||
fallback: {text: "DHCP", checked: false},
|
||||
tip: "Set up IP address used by the device"}},
|
||||
{type: "Switch", args: {title: "Ext power", outvar: "ext_pwr", "tip": "Use external power supply in order to reduce number of used EEM connectors"}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk", fallback: {text: "125 MHz", checked: false}}},
|
||||
{type: "SwitchLine", args: {title: "Ext CLK", outvar: "ext_clk",
|
||||
fallback: {text: "125 MHz", checked: false}, validator: {name: "frequency", params: {min: 10e6, max: 1e9}}}},
|
||||
{type: "Switch", args: {title: "Termination #0", outvar: "term_0", tip: "Enable termination on ADC channel #0"}},
|
||||
{type: "Switch", args: {title: "Termination #1", outvar: "term_1", tip: "Enable termination on ADC channel #1"}}
|
||||
],
|
||||
|
@ -1213,12 +1245,12 @@ const shop_data = {
|
|||
|
||||
columns: {
|
||||
/***
|
||||
* backlog is the column containing all items on left aside,
|
||||
* catalog is the column containing all items on left aside,
|
||||
* name should not change
|
||||
*/
|
||||
'backlog': {
|
||||
id: 'backlog',
|
||||
title: 'Backlog',
|
||||
'catalog': {
|
||||
id: 'catalog',
|
||||
title: 'Catalog',
|
||||
/* itemIds define items order - change order to suit your need */
|
||||
categories: [
|
||||
{ name: 'Core',
|
||||
|
|
Loading…
Reference in New Issue