1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2025-06-15 13:36:35 +02:00

Compare commits

...

36 Commits

Author SHA1 Message Date
e2695d49a1 Bump v5.1.6
* NPM audit fix
* Add displayCard function to utils
* Add optional sizes to Modal
* Add information about optional sizes to docs
* Remove redundant merge.py
2020-11-25 23:29:42 +01:00
a87e6858bf Remove redundant merge.py 2020-11-25 23:29:31 +01:00
e864de5a24 Merge branch 'add-optional-sizes-modals' into 'dev'
Add optional sizes to Modals

See merge request turris/reforis/foris-js!138
2020-11-23 22:25:18 +01:00
5469e6ec80 Add displayCard function to utils 2020-11-22 23:45:27 +01:00
4898016388 Update Snapshots 2020-11-20 17:02:10 +01:00
e0fab75c69 NPM audit fix 2020-11-20 17:00:26 +01:00
6480a39cdb Add information about optional sizes to docs 2020-11-20 16:56:25 +01:00
6f05d5d136 Add optional sizes to Modal 2020-11-20 16:56:16 +01:00
0892a1534a Merge branch 'release-v5.1.5' into 'dev'
Release v5.1.5

See merge request turris/reforis/foris-js!136
2020-09-29 10:56:55 +02:00
1bac60e054 Bump v5.1.5 2020-09-25 19:27:58 +02:00
328e568ab3 NPM audit fix 2020-09-25 19:26:57 +02:00
c68389359e Update Snapshots 2020-09-25 18:52:25 +02:00
e03e0f44cc Fix extra empty space in Switch's classes 2020-09-25 18:50:04 +02:00
1e04d34645 Fix DateTime import 2020-09-25 18:50:04 +02:00
ed7cf34e76 Merge branch 'release-v5.1.4' into 'dev'
Release v5.1.4

See merge request turris/reforis/foris-js!133
2020-09-25 17:43:10 +02:00
aaf4087c96 Update Snapshots 2020-09-25 17:32:04 +02:00
240db88661 Bump v5.1.4 2020-09-25 17:27:47 +02:00
913a7d7b75 Add closing bootstrap modal using ESC 2020-09-25 17:27:47 +02:00
bdc8726791 Change reboot modal's heading to "Warning!" 2020-09-25 17:27:46 +02:00
1c986519f6 Fix Alert's dismissible class condition 2020-09-25 17:27:46 +02:00
defc363f01 Add inline option to Wi-Fi's RadioSet 2020-09-14 18:48:30 +02:00
69723f6b0b Merge branch 'new-bump' into 'dev'
Bump v5.1.3

See merge request turris/reforis/foris-js!130
2020-09-11 18:08:32 +02:00
c32137e29a Bump v5.1.3 2020-09-11 18:00:05 +02:00
be7349661f Merge branch 'ssid-validation' into 'dev'
Ssid validation

Closes reforis#218

See merge request turris/reforis/foris-js!128
2020-09-11 17:39:05 +02:00
5186385b9f Update snapshots 2020-09-11 17:32:46 +02:00
002786d073 Add test 2020-09-11 17:32:46 +02:00
4d246540c1 Add SSID validation for bytes count 2020-09-11 17:32:45 +02:00
35b97ec0fe Add validation for SSID with diacritic 2020-09-11 17:32:45 +02:00
e1d75d8328 Merge branch 'release-v5.1.2' into 'dev'
Bump v5.1.2

See merge request turris/reforis/foris-js!126
2020-09-08 18:36:28 +02:00
0f85713483 Bump v5.1.2 2020-09-08 18:26:15 +02:00
c3cdafce13 Merge branch 'fix-ws-loop' into 'dev'
Fix infinity loop caused by WebSockets

Closes #17

See merge request turris/reforis/foris-js!125
2020-09-08 18:11:05 +02:00
b96b434a3e Update Snapshots 2020-09-02 17:55:53 +02:00
0ea5f7de84 Decrease Switch's margin-bottom with headings 2020-09-02 17:55:44 +02:00
0c7997f6c0 Fix Reboot page URL in respective dropdown 2020-09-02 17:55:44 +02:00
90ce866869 Fix infinity loop caused by WebSockets 2020-09-02 17:55:25 +02:00
4ff814f0fd Merge branch 'small-fixes' into 'dev'
Add "inline" option to RadioSet

See merge request turris/reforis/foris-js!123
2020-08-31 18:19:12 +02:00
21 changed files with 154 additions and 149 deletions

133
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "foris", "name": "foris",
"version": "5.1.1", "version": "5.1.6",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -4500,11 +4500,6 @@
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
"dev": true "dev": true
}, },
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asn1": { "asn1": {
"version": "0.2.4", "version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
@ -5450,9 +5445,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001037", "version": "1.0.30001159",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001037.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz",
"integrity": "sha512-qQP40FzWQ1i9RTjxppOUnpM8OwTBFL5DQbjoR9Az32EtM7YUZOw9orFO6rj1C+xWAGzz+X3bUe09Jf5Ep+zpuA==", "integrity": "sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA==",
"dev": true "dev": true
}, },
"capture-exit": { "capture-exit": {
@ -5979,11 +5974,6 @@
} }
} }
}, },
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
},
"core-js-compat": { "core-js-compat": {
"version": "3.6.4", "version": "3.6.4",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz",
@ -6053,16 +6043,6 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"create-react-class": {
"version": "15.6.3",
"resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
"integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
"requires": {
"fbjs": "^0.8.9",
"loose-envify": "^1.3.1",
"object-assign": "^4.1.1"
}
},
"cross-spawn": { "cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@ -6596,14 +6576,6 @@
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
"dev": true "dev": true
}, },
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "~0.4.13"
}
},
"end-of-stream": { "end-of-stream": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
@ -7681,20 +7653,6 @@
"bser": "2.1.1" "bser": "2.1.1"
} }
}, },
"fbjs": {
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
"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.18"
}
},
"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",
@ -9066,6 +9024,7 @@
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": { "requires": {
"safer-buffer": ">= 2.1.2 < 3" "safer-buffer": ">= 2.1.2 < 3"
} }
@ -9663,7 +9622,8 @@
"is-stream": { "is-stream": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
}, },
"is-symbol": { "is-symbol": {
"version": "1.0.2", "version": "1.0.2",
@ -9723,15 +9683,6 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
"dev": true "dev": true
}, },
"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"
}
},
"isstream": { "isstream": {
"version": "0.1.2", "version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
@ -13267,19 +13218,10 @@
"minimatch": "^3.0.2" "minimatch": "^3.0.2"
} }
}, },
"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"
}
},
"node-forge": { "node-forge": {
"version": "0.9.0", "version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
"dev": true "dev": true
}, },
"node-int64": { "node-int64": {
@ -14253,14 +14195,6 @@
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true "dev": true
}, },
"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"
}
},
"promise-inflight": { "promise-inflight": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
@ -14482,21 +14416,11 @@
} }
}, },
"react-datetime": { "react-datetime": {
"version": "2.16.3", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-2.16.3.tgz", "resolved": "https://registry.npmjs.org/react-datetime/-/react-datetime-3.0.4.tgz",
"integrity": "sha512-amWfb5iGEiyqjLmqCLlPpu2oN415jK8wX1qoTq7qn6EYiU7qQgbNHglww014PT4O/3G5eo/3kbJu/M/IxxTyGw==", "integrity": "sha512-v6MVwCve+DRaLN2f22LTO5TlrPpkUXumPkp1zfrbhaFtSYGl2grZ2JtwJfLxRj/T4ACyePAV4srCR6cMSiQ/Iw==",
"requires": { "requires": {
"create-react-class": "^15.5.2", "prop-types": "^15.5.7"
"object-assign": "^3.0.0",
"prop-types": "^15.5.7",
"react-onclickoutside": "^6.5.0"
},
"dependencies": {
"object-assign": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
"integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I="
}
} }
}, },
"react-dev-utils": { "react-dev-utils": {
@ -14891,11 +14815,6 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
"integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==" "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw=="
}, },
"react-onclickoutside": {
"version": "6.9.0",
"resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.9.0.tgz",
"integrity": "sha512-8ltIY3bC7oGhj2nPAvWOGi+xGFybPNhJM0V1H8hY/whNcXgmDeaeoCMPPd8VatrpTsUWjb/vGzrmu6SrXVty3A=="
},
"react-router": { "react-router": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz",
@ -15576,7 +15495,8 @@
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"dev": true
}, },
"sane": { "sane": {
"version": "4.1.0", "version": "4.1.0",
@ -15666,12 +15586,12 @@
"dev": true "dev": true
}, },
"selfsigned": { "selfsigned": {
"version": "1.10.7", "version": "1.10.8",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
"integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
"dev": true, "dev": true,
"requires": { "requires": {
"node-forge": "0.9.0" "node-forge": "^0.10.0"
} }
}, },
"semver": { "semver": {
@ -15820,7 +15740,8 @@
"setimmediate": { "setimmediate": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
"dev": true
}, },
"setprototypeof": { "setprototypeof": {
"version": "1.1.1", "version": "1.1.1",
@ -17408,11 +17329,6 @@
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"ua-parser-js": {
"version": "0.7.20",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
"integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
},
"unherit": { "unherit": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz",
@ -18455,11 +18371,6 @@
"iconv-lite": "0.4.24" "iconv-lite": "0.4.24"
} }
}, },
"whatwg-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
},
"whatwg-mimetype": { "whatwg-mimetype": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "foris", "name": "foris",
"version": "5.1.1", "version": "5.1.6",
"description": "Set of components and utils for Foris and its plugins.", "description": "Set of components and utils for Foris and its plugins.",
"author": "CZ.NIC, z.s.p.o.", "author": "CZ.NIC, z.s.p.o.",
"repository": { "repository": {
@ -18,7 +18,7 @@
"immutability-helper": "3.0.1", "immutability-helper": "3.0.1",
"moment": "^2.24.0", "moment": "^2.24.0",
"qrcode.react": "^0.9.3", "qrcode.react": "^0.9.3",
"react-datetime": "^2.16.3", "react-datetime": "^3.0.4",
"react-uid": "^2.2.0" "react-uid": "^2.2.0"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -37,7 +37,11 @@ Alert.defaultProps = {
export function Alert({ type, onDismiss, children }) { export function Alert({ type, onDismiss, children }) {
return ( return (
<div className={`alert alert-dismissible alert-${type}`}> <div
className={`alert ${
onDismiss ? "alert-dismissible" : ""
} alert-${type}`}
>
{onDismiss ? ( {onDismiss ? (
<button type="button" className="close" onClick={onDismiss}> <button type="button" className="close" onClick={onDismiss}>
&times; &times;

View File

@ -7,7 +7,7 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import Datetime from "react-datetime/DateTime"; import Datetime from "react-datetime";
import moment from "moment/moment"; import moment from "moment/moment";
import "react-datetime/css/react-datetime.css"; import "react-datetime/css/react-datetime.css";
import "./DataTimeInput.css"; import "./DataTimeInput.css";

View File

@ -1,11 +1,11 @@
/* /*
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/) * Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
* *
* This is free software, licensed under the GNU General Public License v3. * This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information. * See /LICENSE for more information.
*/ */
import React, { useRef } from "react"; import React, { useRef, useEffect } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Portal } from "../utils/Portal"; import { Portal } from "../utils/Portal";
@ -18,6 +18,7 @@ Modal.propTypes = {
/** Callback to manage modal visibility */ /** Callback to manage modal visibility */
setShown: PropTypes.func.isRequired, setShown: PropTypes.func.isRequired,
scrollable: PropTypes.bool, scrollable: PropTypes.bool,
size: PropTypes.string,
/** Modal content use following: `ModalHeader`, `ModalBody`, `ModalFooter` */ /** Modal content use following: `ModalHeader`, `ModalBody`, `ModalFooter` */
children: PropTypes.oneOfType([ children: PropTypes.oneOfType([
@ -26,19 +27,51 @@ Modal.propTypes = {
]).isRequired, ]).isRequired,
}; };
export function Modal({ shown, setShown, scrollable, children }) { export function Modal({ shown, setShown, scrollable, size, children }) {
const dialogRef = useRef(); const dialogRef = useRef();
let modalSize = "modal-";
useClickOutside(dialogRef, () => setShown(false)); useClickOutside(dialogRef, () => setShown(false));
useEffect(() => {
const handleEsc = (event) => {
if (event.keyCode === 27) {
setShown(false);
}
};
window.addEventListener("keydown", handleEsc);
return () => {
window.removeEventListener("keydown", handleEsc);
};
}, [setShown]);
switch (size) {
case "sm":
modalSize += "sm";
break;
case "lg":
modalSize += "lg";
break;
case "xl":
modalSize += "xl";
break;
default:
modalSize = "";
break;
}
return ( return (
<Portal containerId="modal-container"> <Portal containerId="modal-container">
<div className={`modal fade ${shown ? "show" : ""}`} role="dialog"> <div
className={`modal fade ${shown ? "show" : ""}`.trim()}
role="dialog"
>
<div <div
ref={dialogRef} ref={dialogRef}
className={`modal-dialog modal-dialog-centered${ className={`modal-dialog ${modalSize} modal-dialog-centered ${
scrollable ? " modal-dialog-scrollable" : "" scrollable ? "modal-dialog-scrollable" : ""
}`} }`.trim()}
role="document" role="document"
> >
<div className="modal-content">{children}</div> <div className="modal-content">{children}</div>

View File

@ -1,8 +1,19 @@
Bootstrap modal component. Bootstrap modal component.
it's required to have an element `<div id={"modal-container"}/>` somewhere on It's required to have an element `<div id={"modal-container"}/>` somewhere on
the page since modals are rendered in portals. the page since modals are rendered in portals.
Modals also have three optional sizes, which can be defined through the `size`
prop:
- small - `sm`
- large - `lg`
- extra-large - `xl`
For more details please visit Bootstrap
<a href="https://getbootstrap.com/docs/4.5/components/modal/#optional-sizes" target="_blank">
documentation</a>.
```js ```js
<div id="modal-container" /> <div id="modal-container" />
``` ```
@ -14,7 +25,7 @@ import { useState } from "react";
const [shown, setShown] = useState(false); const [shown, setShown] = useState(false);
<> <>
<Modal setShown={setShown} shown={shown}> <Modal setShown={setShown} shown={shown} size="sm">
<ModalHeader setShown={setShown} title="Warning!" /> <ModalHeader setShown={setShown} title="Warning!" />
<ModalBody> <ModalBody>
<p>Bla bla bla...</p> <p>Bla bla bla...</p>

View File

@ -23,7 +23,7 @@ Switch.propTypes = {
export function Switch({ label, helpText, switchHeading, ...props }) { export function Switch({ label, helpText, switchHeading, ...props }) {
const uid = useUID(); const uid = useUID();
return ( return (
<div className="form-group switch"> <div className={`form-group ${switchHeading ? "switch" : ""}`.trim()}>
<div <div
className={`custom-control custom-switch ${ className={`custom-control custom-switch ${
!helpText ? "custom-control-inline" : "" !helpText ? "custom-control-inline" : ""

View File

@ -2,7 +2,7 @@
exports[`<Switch/> Render switch 1`] = ` exports[`<Switch/> Render switch 1`] = `
<div <div
class="form-group switch" class="form-group"
> >
<div <div
class="custom-control custom-switch" class="custom-control custom-switch"
@ -30,7 +30,7 @@ exports[`<Switch/> Render switch 1`] = `
exports[`<Switch/> Render uncheked switch 1`] = ` exports[`<Switch/> Render uncheked switch 1`] = `
<div <div
class="form-group switch" class="form-group"
> >
<div <div
class="custom-control custom-switch" class="custom-control custom-switch"

View File

@ -63,7 +63,7 @@ RebootModal.propTypes = {
function RebootModal({ shown, setShown, onReboot }) { function RebootModal({ shown, setShown, onReboot }) {
return ( return (
<Modal shown={shown} setShown={setShown}> <Modal shown={shown} setShown={setShown}>
<ModalHeader setShown={setShown} title={_("Reboot confirmation")} /> <ModalHeader setShown={setShown} title={_("Warning!")} />
<ModalBody> <ModalBody>
<p>{_("Are you sure you want to restart the router?")}</p> <p>{_("Are you sure you want to restart the router?")}</p>
</ModalBody> </ModalBody>

View File

@ -105,6 +105,7 @@ function DeviceForm({
label="SSID" label="SSID"
value={formData.SSID} value={formData.SSID}
error={formErrors.SSID || null} error={formErrors.SSID || null}
helpText={HELP_TEXTS.ssid}
required required
onChange={setFormValue((value) => ({ onChange={setFormValue((value) => ({
devices: { devices: {
@ -156,6 +157,7 @@ function DeviceForm({
choices={getHwmodeChoices(formData)} choices={getHwmodeChoices(formData)}
value={formData.hwmode} value={formData.hwmode}
helpText={HELP_TEXTS.hwmode} helpText={HELP_TEXTS.hwmode}
inline
onChange={setFormValue((value) => ({ onChange={setFormValue((value) => ({
devices: { devices: {
[deviceIndex]: { [deviceIndex]: {

View File

@ -57,6 +57,7 @@ export default function WifiGuestForm({
label="SSID" label="SSID"
value={formData.SSID} value={formData.SSID}
error={formErrors.SSID} error={formErrors.SSID}
helpText={HELP_TEXTS.ssid}
onChange={setFormValue((value) => ({ onChange={setFormValue((value) => ({
devices: { devices: {
[formData.id]: { [formData.id]: {

View File

@ -63,6 +63,12 @@ function prepDataToSubmit(formData) {
return formData; return formData;
} }
export function byteCount(string) {
const buffer = Buffer.from(string, "utf-8");
const count = buffer.byteLength;
return count;
}
export function validator(formData) { export function validator(formData) {
const formErrors = formData.devices.map((device) => { const formErrors = formData.devices.map((device) => {
if (!device.enabled) return {}; if (!device.enabled) return {};
@ -71,6 +77,8 @@ export function validator(formData) {
if (device.SSID.length > 32) if (device.SSID.length > 32)
errors.SSID = _("SSID can't be longer than 32 symbols"); errors.SSID = _("SSID can't be longer than 32 symbols");
if (device.SSID.length === 0) errors.SSID = _("SSID can't be empty"); if (device.SSID.length === 0) errors.SSID = _("SSID can't be empty");
if (byteCount(device.SSID) > 32)
errors.SSID = _("SSID can't be longer than 32 bytes");
if (device.password.length < 8) if (device.password.length < 8)
errors.password = _("Password must contain at least 8 symbols"); errors.password = _("Password must contain at least 8 symbols");
@ -82,6 +90,8 @@ export function validator(formData) {
guest_wifi_errors.SSID = _("SSID can't be longer than 32 symbols"); guest_wifi_errors.SSID = _("SSID can't be longer than 32 symbols");
if (device.guest_wifi.SSID.length === 0) if (device.guest_wifi.SSID.length === 0)
guest_wifi_errors.SSID = _("SSID can't be empty"); guest_wifi_errors.SSID = _("SSID can't be empty");
if (byteCount(device.guest_wifi.SSID) > 32)
guest_wifi_errors.SSID = _("SSID can't be longer than 32 bytes");
if (device.guest_wifi.password.length < 8) if (device.guest_wifi.password.length < 8)
guest_wifi_errors.password = _( guest_wifi_errors.password = _(

View File

@ -19,7 +19,7 @@ import {
twoDevices, twoDevices,
threeDevices, threeDevices,
} from "./__fixtures__/wifiSettings"; } from "./__fixtures__/wifiSettings";
import { WiFiSettings, validator } from "../WiFiSettings"; import { WiFiSettings, validator, byteCount } from "../WiFiSettings";
describe("<WiFiSettings/>", () => { describe("<WiFiSettings/>", () => {
let firstRender; let firstRender;
@ -213,4 +213,8 @@ describe("<WiFiSettings/>", () => {
]; ];
expect(validator(threeDevices)).toEqual(threeDevicesFormErrors); expect(validator(threeDevices)).toEqual(threeDevicesFormErrors);
}); });
it("ByteCount function", () => {
expect(byteCount("abc")).toEqual(3);
});
}); });

View File

@ -5,7 +5,7 @@ exports[`<WiFiSettings/> Snapshot 2.4 GHz 1`] = `
- First value - First value
+ Second value + Second value
@@ -245,207 +245,95 @@ @@ -250,207 +250,95 @@
value=\\"0\\" value=\\"0\\"
> >
auto auto
@ -336,7 +336,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
- First value - First value
+ Second value + Second value
@@ -474,10 +474,89 @@ @@ -479,10 +479,94 @@
Parameters of the guest network can be set in the Guest network tab. Parameters of the guest network can be set in the Guest network tab.
</small> </small>
@ -375,6 +375,11 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
+ </button> + </button>
+ </div> + </div>
+ </div> + </div>
+ <small
+ class=\\"form-text text-muted\\"
+ >
+ SSID which contains non-standard characters could cause problems on some devices.
+ </small>
+ </div> + </div>
+ <div + <div
+ class=\\"form-group\\" + class=\\"form-group\\"
@ -426,7 +431,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
class=\\"form-group switch\\" class=\\"form-group switch\\"
> >
<div <div
@@ -501,10 +580,11 @@ @@ -506,10 +590,11 @@
<div <div
class=\\"text-right\\" class=\\"text-right\\"
> >
@ -445,7 +450,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
- First value - First value
+ Second value + Second value
@@ -22,10 +22,462 @@ @@ -22,10 +22,467 @@
Wi-Fi 1 Wi-Fi 1
</h2> </h2>
</label> </label>
@ -485,6 +490,11 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </button> + </button>
+ </div> + </div>
+ </div> + </div>
+ <small
+ class=\\"form-text text-muted\\"
+ >
+ SSID which contains non-standard characters could cause problems on some devices.
+ </small>
+ </div> + </div>
+ <div + <div
+ class=\\"form-group\\" + class=\\"form-group\\"
@ -560,7 +570,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ GHz + GHz
+ </label> + </label>
+ <div + <div
+ class=\\"custom-control custom-radio\\" + class=\\"custom-control custom-radio custom-control-inline\\"
+ > + >
+ <input + <input
+ class=\\"custom-control-input\\" + class=\\"custom-control-input\\"
@ -577,7 +587,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </label> + </label>
+ </div> + </div>
+ <div + <div
+ class=\\"custom-control custom-radio\\" + class=\\"custom-control custom-radio custom-control-inline\\"
+ > + >
+ <input + <input
+ checked=\\"\\" + checked=\\"\\"
@ -876,7 +886,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
+ </select> + </select>
+ </div> + </div>
+ <div + <div
+ class=\\"form-group switch\\" + class=\\"form-group\\"
+ > + >
+ <div + <div
+ class=\\"custom-control custom-switch\\" + class=\\"custom-control custom-switch\\"

View File

@ -19,6 +19,9 @@ export const HWMODES = {
"11a": "5", "11a": "5",
}; };
export const HELP_TEXTS = { export const HELP_TEXTS = {
ssid: _(
`SSID which contains non-standard characters could cause problems on some devices.`
),
password: _(` password: _(`
WPA2 pre-shared key, that is required to connect to the network. WPA2 pre-shared key, that is required to connect to the network.
`), `),

View File

@ -10,7 +10,7 @@ exports[`<RebootButton/> Render modal. 1`] = `
role="dialog" role="dialog"
> >
<div <div
class="modal-dialog modal-dialog-centered" class="modal-dialog modal-dialog-centered"
role="document" role="document"
> >
<div <div
@ -22,7 +22,7 @@ exports[`<RebootButton/> Render modal. 1`] = `
<h5 <h5
class="modal-title" class="modal-title"
> >
Reboot confirmation Warning!
</h5> </h5>
<button <button
class="close" class="close"

View File

@ -39,7 +39,6 @@ export { Modal, ModalBody, ModalFooter, ModalHeader } from "./bootstrap/Modal";
// Common // Common
export { RebootButton } from "./common/RebootButton"; export { RebootButton } from "./common/RebootButton";
export { WiFiSettings } from "./common/WiFiSettings/WiFiSettings"; export { WiFiSettings } from "./common/WiFiSettings/WiFiSettings";
// Form // Form
export { ForisForm } from "./form/components/ForisForm"; export { ForisForm } from "./form/components/ForisForm";
export { export {
@ -70,6 +69,7 @@ export {
export { ErrorMessage } from "./utils/ErrorMessage"; export { ErrorMessage } from "./utils/ErrorMessage";
export { useClickOutside } from "./utils/hooks"; export { useClickOutside } from "./utils/hooks";
export { toLocaleDateString } from "./utils/datetime"; export { toLocaleDateString } from "./utils/datetime";
export { displayCard } from "./utils/displayCard";
// Foris URL // Foris URL
export { ForisURLs, REFORIS_URL_PREFIX } from "./utils/forisUrls"; export { ForisURLs, REFORIS_URL_PREFIX } from "./utils/forisUrls";

23
src/utils/displayCard.js Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
*
* This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information.
*/
export function displayCard({ package_lists: packages }, cardName) {
const enabledPackagesNames = [];
packages
.filter((item) => item.enabled)
.map((item) => {
enabledPackagesNames.push(item.name);
item.options
.filter((option) => option.enabled)
.map((option) => {
enabledPackagesNames.push(option.name);
return null;
});
return null;
});
return enabledPackagesNames.includes(cardName);
}

View File

@ -27,7 +27,7 @@ export const ForisURLs = {
approveUpdates: "/package-management/updates", approveUpdates: "/package-management/updates",
languages: "/package-management/languages", languages: "/package-management/languages",
rebootPage: "/reforis/administration/reboot", rebootPage: "/administration/reboot",
luci: "/cgi-bin/luci", luci: "/cgi-bin/luci",
// API // API

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/) * Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
* *
* This is free software, licensed under the GNU General Public License v3. * This is free software, licensed under the GNU General Public License v3.
* See /LICENSE for more information. * See /LICENSE for more information.
@ -12,7 +12,7 @@ import { ForisURLs } from "../utils/forisUrls";
const PROTOCOL = window.location.protocol === "http:" ? "ws" : "wss"; const PROTOCOL = window.location.protocol === "http:" ? "ws" : "wss";
const URL = process.env.LIGHTTPD const URL = process.env.LIGHTTPD
? `${PROTOCOL}://${window.location.hostname}/foris-ws` ? `${PROTOCOL}://${window.location.host}/foris-ws`
: `${PROTOCOL}://${window.location.hostname}:${9081}`; : `${PROTOCOL}://${window.location.hostname}:${9081}`;
const WAITING_FOR_CONNECTION_TIMEOUT = 500; const WAITING_FOR_CONNECTION_TIMEOUT = 500;

View File

@ -1,7 +0,0 @@
import os
for entry in os.scandir("."):
if entry.is_dir():
print(entry.name)
os.system(f"msgmerge /home/mcjlnrtwcz/Repositories/reforis/reforis/translations/{entry.name}/LC_MESSAGES/messages.po forisjs.pot -o {entry.name}/LC_MESSAGES/forisjs.po")