Compare commits
435 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f727d6f71 | ||
|
|
99acc4921c | ||
|
|
db7dcba1b9 | ||
|
|
8f76d3fa58 | ||
|
|
0930b1ada8 | ||
|
|
35df7c6429 | ||
|
|
e679e8c5f4 | ||
|
|
d43a655116 | ||
|
|
56a4ca0e21 | ||
|
|
f17b126dd4 | ||
|
|
1ac144e3a7 | ||
|
|
13402a5aa5 | ||
|
|
92a0cc245f | ||
|
|
8b9a2c5f7e | ||
|
|
bc10e4304f | ||
|
|
d40de785b7 | ||
|
|
9ff02eefb8 | ||
|
|
e8837e69a0 | ||
|
|
9d02f2687d | ||
|
|
9f2ecd619f | ||
|
|
6b899b2ce0 | ||
|
|
d5cb66079b | ||
|
|
5690599241 | ||
|
|
3ee2bae78d | ||
|
|
21041fc6da | ||
|
|
2b40db285e | ||
|
|
c3a6cc133f | ||
|
|
10f6bb9cc6 | ||
|
|
5589c61423 | ||
|
|
158c34d091 | ||
|
|
99f182599a | ||
|
|
216bd4e7b4 | ||
|
|
ecfc7c84c3 | ||
|
|
d4819bcd0a | ||
|
|
b067a4723b | ||
|
|
9217ebf75e | ||
|
|
305a8f74b0 | ||
|
|
a3666b3d44 | ||
|
|
182bca9361 | ||
|
|
f0868f383b | ||
|
|
001c4818a0 | ||
|
|
0d47a1a1c2 | ||
|
|
75f4d8e09c | ||
|
|
2e5d8b330b | ||
|
|
42e0200956 | ||
|
|
780bc55a96 | ||
|
|
bc6ea34f14 | ||
|
|
ae237f1ad3 | ||
|
|
7451a0bcc4 | ||
|
|
ffed1dbc90 | ||
|
|
3ffe5559e7 | ||
|
|
2c93e2f783 | ||
|
|
7ef5919ba1 | ||
|
|
4c19a7d598 | ||
|
|
feb782270b | ||
|
|
29c6109ea3 | ||
|
|
ffe4796f2c | ||
|
|
5762cea9bd | ||
|
|
7b0a1c4266 | ||
|
|
d2086b1661 | ||
|
|
c50cbc9750 | ||
|
|
24ee395b73 | ||
|
|
48bd772171 | ||
|
|
928ace5ba6 | ||
|
|
0791d196d4 | ||
|
|
9223044967 | ||
|
|
998a925fd1 | ||
|
|
f49bfb4d74 | ||
|
|
b20cb040b0 | ||
|
|
82096f3a1e | ||
|
|
fcc6f5aa76 | ||
|
|
4c82ef89fb | ||
|
|
9b7141b1f4 | ||
|
|
965133d6e2 | ||
|
|
498b3f80bf | ||
|
|
6cf9044db6 | ||
|
|
acc80cff74 | ||
|
|
9e2407b7f1 | ||
|
|
6da9beb273 | ||
|
|
1104f22f19 | ||
|
|
cd272ab0c8 | ||
|
|
34dbec4a5c | ||
|
|
3f0608fd9c | ||
|
|
17a6b03d00 | ||
|
|
5efb921a6b | ||
|
|
01d4443a4f | ||
|
|
1591205f46 | ||
|
|
ad005d99d2 | ||
|
|
27e1541a6d | ||
|
|
9fb966f705 | ||
|
|
096b981247 | ||
|
|
cea9ac3965 | ||
|
|
f446c9acc1 | ||
|
|
870521c004 | ||
|
|
05114b6dfc | ||
|
|
945a83625d | ||
|
|
e2d7c0225e | ||
|
|
55e5444a71 | ||
|
|
a3e8a4a41f | ||
|
|
b91798e8b8 | ||
|
|
d284002803 | ||
|
|
74e6bf50b1 | ||
|
|
60ba539104 | ||
|
|
979909ad57 | ||
|
|
c4bd471516 | ||
|
|
cd8b4d0dd1 | ||
|
|
d018ebda7e | ||
|
|
5b9aeb70d9 | ||
|
|
35d551f05e | ||
|
|
a32eb24f8c | ||
|
|
5c7f3c282b | ||
|
|
c19c399508 | ||
|
|
4d24d49a0b | ||
|
|
cbe214113c | ||
|
|
fdc2d2cb17 | ||
|
|
eae1d22a2f | ||
|
|
3d66a7deb9 | ||
|
|
a4022dc70c | ||
|
|
f82c0cdb4f | ||
|
|
6e208c3766 | ||
|
|
777fe9b42a | ||
|
|
afbf21c47f | ||
|
|
461c30580f | ||
|
|
82cdcc1cce | ||
|
|
3efcaf4921 | ||
|
|
2be4b672d5 | ||
|
|
2b4d743d79 | ||
|
|
c80634b026 | ||
|
|
0028d03e1b | ||
|
|
d687c9f36d | ||
|
|
5fbf4879ae | ||
|
|
a719dff1f7 | ||
|
|
d99170f0d9 | ||
|
|
7d5a8499c3 | ||
|
|
1cfaf0bd57 | ||
|
|
bc3c608277 | ||
|
|
2f09995306 | ||
|
|
72acdeaab9 | ||
|
|
0bfc0256a6 | ||
|
|
c1a733af53 | ||
|
|
c3544076ba | ||
|
|
ae528f6302 | ||
|
|
6a63325f10 | ||
|
|
395d244e04 | ||
|
|
d9f0e61375 | ||
|
|
b3751ec4bf | ||
|
|
a11a24bfe2 | ||
|
|
b31de72ccc | ||
|
|
fa4c08dcc5 | ||
|
|
d0aa75c792 | ||
|
|
492a5bd5e9 | ||
|
|
772fdd5e87 | ||
|
|
c4116d6819 | ||
|
|
050a53af0d | ||
|
|
a42136c419 | ||
|
|
c5d5c15b11 | ||
|
|
2360803e44 | ||
|
|
3f5752247b | ||
|
|
1e85a649db | ||
|
|
84eed2aab2 | ||
|
|
32f5e784e8 | ||
|
|
53e391982f | ||
|
|
0f8adf13ae | ||
|
|
a91e265097 | ||
|
|
b7fc72004f | ||
|
|
9927239ec9 | ||
|
|
cff94a1672 | ||
|
|
a0191bafe7 | ||
|
|
f2262c0e19 | ||
|
|
068d251b64 | ||
|
|
1872dacb5e | ||
|
|
ef162dd963 | ||
|
|
2a19285d3c | ||
|
|
38a9a75b2d | ||
|
|
6959a4510e | ||
|
|
fe383d32a7 | ||
|
|
560bdb139a | ||
|
|
fe14286bc8 | ||
|
|
7584b489ac | ||
|
|
84461ffa35 | ||
|
|
d89c652622 | ||
|
|
9d19d26d8e | ||
|
|
e307d51f24 | ||
|
|
4632e281a6 | ||
|
|
ab4f961795 | ||
|
|
9859a34e90 | ||
|
|
b10a209daf | ||
|
|
2a81c2611b | ||
|
|
8d98c8ad16 | ||
|
|
1c12c66b31 | ||
|
|
cb79567942 | ||
|
|
c35a9c64f6 | ||
|
|
95832eb657 | ||
|
|
ee53c12c35 | ||
|
|
c3d2d928b3 | ||
|
|
87e598b5f0 | ||
|
|
f61cbba8cb | ||
|
|
a4089efe85 | ||
|
|
781d8e3b68 | ||
|
|
cf81a970cc | ||
|
|
367d73ef23 | ||
|
|
314084d092 | ||
|
|
e4441d129c | ||
|
|
292550f6b5 | ||
|
|
93364afc98 | ||
|
|
558b961afa | ||
|
|
d99b5cf525 | ||
|
|
c75e4a52eb | ||
|
|
0ac01fe8e5 | ||
|
|
13615e06e9 | ||
|
|
623b177eb0 | ||
|
|
a74522c465 | ||
|
|
4f5788fe31 | ||
|
|
d739af3d4b | ||
|
|
3a2284cf99 | ||
|
|
9019babf6d | ||
|
|
5382cd8d5f | ||
|
|
37c41086d2 | ||
|
|
2697cce6dd | ||
|
|
294b26787b | ||
|
|
b67de81616 | ||
|
|
36568d5720 | ||
|
|
dcf1966719 | ||
|
|
33cbc9b525 | ||
|
|
d2115ab004 | ||
|
|
9cbd6ea7b7 | ||
|
|
ded69f979e | ||
|
|
7fab6f4732 | ||
|
|
9ad822577b | ||
|
|
bdaac40435 | ||
|
|
19b43e152a | ||
|
|
c4c320da83 | ||
|
|
43cd6504b6 | ||
|
|
cb8734bba7 | ||
|
|
57860c17d9 | ||
|
|
c56c162045 | ||
|
|
249407403d | ||
|
|
1aa5ec6aa4 | ||
|
|
f129ead9a0 | ||
|
|
321a45615a | ||
|
|
dd280732d1 | ||
|
|
8966e6fd55 | ||
|
|
3523b5f2c7 | ||
|
|
2f727b1a1e | ||
|
|
6e537eed58 | ||
|
|
ffb8fd0172 | ||
|
|
ba1410c7f4 | ||
|
|
61f8e36383 | ||
|
|
20a7094d33 | ||
|
|
06d7534462 | ||
|
|
b3680224cc | ||
|
|
113bf14718 | ||
|
|
937df4486e | ||
|
|
5f79ca2872 | ||
|
|
e999d7428a | ||
|
|
146df237f2 | ||
|
|
d802945ec7 | ||
|
|
122782f244 | ||
|
|
ff006a254a | ||
|
|
c1d11e7489 | ||
|
|
7d78d34de0 | ||
|
|
5f97f49f28 | ||
|
|
f63bb11cc3 | ||
|
|
b23f0a9c16 | ||
|
|
e609300533 | ||
|
|
f623b31220 | ||
|
|
a17239ca31 | ||
|
|
f2a35a7716 | ||
|
|
0383403cce | ||
|
|
57b71ce4ea | ||
|
|
f6752e9743 | ||
|
|
45fa84d5ae | ||
|
|
873b97b052 | ||
|
|
7a25f4c13c | ||
|
|
48e9171153 | ||
|
|
1dbea4d39a | ||
|
|
edba562a99 | ||
|
|
60368341ed | ||
|
|
ab24faaa55 | ||
|
|
e79b113907 | ||
|
|
fb69fcee3c | ||
|
|
41ff83821b | ||
|
|
463ef82255 | ||
|
|
5d011b09ae | ||
|
|
638f3f1a05 | ||
|
|
879fc58d9c | ||
|
|
2c139c2a65 | ||
|
|
4c9c9a2240 | ||
|
|
354ad3983f | ||
|
|
8d99d4aa99 | ||
|
|
1ab2de9c69 | ||
|
|
6a938cdcca | ||
|
|
0c705bfa6d | ||
|
|
6169f1c150 | ||
|
|
3639ed8f70 | ||
|
|
2083e02698 | ||
|
|
a7d483ea1b | ||
|
|
a0dd02ec07 | ||
|
|
929d955237 | ||
|
|
f61eeebc8f | ||
|
|
f8c3d1e6db | ||
|
|
38513d3eed | ||
|
|
051259419c | ||
|
|
fad28ee40b | ||
|
|
1d9778226c | ||
|
|
f1dab84571 | ||
|
|
c413317970 | ||
|
|
631c8b625b | ||
|
|
2dd9683eb1 | ||
|
|
f7faac1afc | ||
|
|
91d0422f53 | ||
|
|
a22090e3df | ||
|
|
62f52a0be1 | ||
|
|
eca1dc8e66 | ||
|
|
8e3542863a | ||
|
|
34be6ce795 | ||
|
|
2d995b87b1 | ||
|
|
edbb81d089 | ||
|
|
6c4fbb501c | ||
|
|
5f3ca632cb | ||
|
|
3db28e4f22 | ||
|
|
79a7b3c985 | ||
|
|
109d57b4b4 | ||
|
|
71779d560a | ||
|
|
967bf49db0 | ||
|
|
3cedd48503 | ||
|
|
0c303b63bd | ||
|
|
ef070dbad7 | ||
|
|
d88e777f80 | ||
|
|
cffdd56522 | ||
|
|
d44b821a04 | ||
|
|
0c6a59282e | ||
|
|
3ba2aa922f | ||
|
|
ce8e2c6684 | ||
|
|
d3aa8e03a2 | ||
|
|
3ae9c49029 | ||
|
|
bac0db10a6 | ||
|
|
a40d67138b | ||
|
|
a8f6df16a8 | ||
|
|
63f23118b6 | ||
|
|
71de9cfec5 | ||
|
|
5f8729536c | ||
|
|
461dd21806 | ||
|
|
d5a44fdec4 | ||
|
|
0fd96aa92e | ||
|
|
3ba6de6f34 | ||
|
|
d214be027d | ||
|
|
af7273e7eb | ||
|
|
69971198af | ||
|
|
23a681f214 | ||
|
|
7516524d38 | ||
|
|
474711431e | ||
|
|
3cea9de8fe | ||
|
|
9235b0ffb6 | ||
|
|
a159275dba | ||
|
|
105005aa07 | ||
|
|
40a8d45ab0 | ||
|
|
009eae83a6 | ||
|
|
c146879fd3 | ||
|
|
00c6e22861 | ||
|
|
939a74b7be | ||
|
|
a53db858e3 | ||
|
|
38da938ec1 | ||
|
|
8cf1a37633 | ||
|
|
9de8c4cf04 | ||
|
|
40be148c9b | ||
|
|
dfbb563b6f | ||
|
|
ab76afb322 | ||
|
|
4b3593d081 | ||
|
|
210e182d7e | ||
|
|
6f1154a1f8 | ||
|
|
d935ff4b3e | ||
|
|
cd92d87c5d | ||
|
|
e8ac8ac0ab | ||
|
|
7ae7bdd670 | ||
|
|
1dbb89df34 | ||
|
|
b9908f68f9 | ||
|
|
b839e8183f | ||
|
|
51b370efa6 | ||
|
|
f65e67d86a | ||
|
|
653e42c2b9 | ||
|
|
3b6c8247c5 | ||
|
|
f457cc5107 | ||
|
|
f9e62f3237 | ||
|
|
4ca78a2fe5 | ||
|
|
179010ddbf | ||
|
|
4cca931d9d | ||
|
|
3c2743510b | ||
|
|
716434d59e | ||
|
|
4accbda497 | ||
|
|
9f0512e81e | ||
|
|
10b699a6f7 | ||
|
|
1a9b4cdbf5 | ||
|
|
ee8f133ebb | ||
|
|
b193625fb6 | ||
|
|
ca3abed605 | ||
|
|
3b2fd26bd9 | ||
|
|
1b21187397 | ||
|
|
c2519bdb7d | ||
|
|
797edc50f4 | ||
|
|
6ffbd88d92 | ||
|
|
377cd2ba1f | ||
|
|
14a67fa698 | ||
|
|
efe1c7ba45 | ||
|
|
96cf5f43d2 | ||
|
|
4ed461bc69 | ||
|
|
78fd2d5399 | ||
|
|
cf1d07e7a6 | ||
|
|
f71b940197 | ||
|
|
aae182a9f8 | ||
|
|
2162f52e00 | ||
|
|
7a88d2d08c | ||
|
|
896c4e7561 | ||
|
|
c537477d3a | ||
|
|
2a9adfd180 | ||
|
|
7a60cc25e9 | ||
|
|
73255c9c75 | ||
|
|
840af00d6d | ||
|
|
c3a58eec8d | ||
|
|
e18b8f6bb6 | ||
|
|
48d4e69fc8 | ||
|
|
c388eddc67 | ||
|
|
dcf5c2a0d6 | ||
|
|
7d070810d5 | ||
|
|
5923c88a94 | ||
|
|
a45770119c | ||
|
|
d3d3cda758 | ||
|
|
8ae157a272 | ||
|
|
8398db90ef | ||
|
|
177585c998 | ||
|
|
7ac9c34820 | ||
|
|
5e424bb64d | ||
|
|
d290b25f8a | ||
|
|
90c3ca47b9 | ||
|
|
924a931568 |
@@ -52,15 +52,6 @@
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "terranblake",
|
||||
"name": "Terran Blake",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/8795767?v=4",
|
||||
"profile": "https://www.lumahealth.io/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AndrewBastin",
|
||||
"name": "Andrew Bastin",
|
||||
|
||||
3
.github/FUNDING.yml
vendored
@@ -1,4 +1,3 @@
|
||||
ko_fi: liyasthomas
|
||||
open_collective: liyasthomas
|
||||
open_collective: postwoman
|
||||
patreon: liyasthomas
|
||||
custom: https://www.paypal.me/liyascthomas
|
||||
|
||||
158
CHANGELOG.md
@@ -1,3 +1,159 @@
|
||||
# Changelog
|
||||
|
||||
* [v0.1.0](https://github.com/liyasthomas/postwoman/releases/tag/v0.1.0) - Initial 🎉 Initial public release
|
||||
## [v1.0.0](https://github.com/liyasthomas/postwoman/tree/v1.0.0) (2019-11-04)
|
||||
|
||||
[Full Changelog](https://github.com/liyasthomas/postwoman/compare/v0.1.0...v1.0.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- On Save Updated existing API [\#204](https://github.com/liyasthomas/postwoman/issues/204)
|
||||
- Chain requests. Execute a bunch of requests one by one and produce results [\#196](https://github.com/liyasthomas/postwoman/issues/196)
|
||||
- Allow User to Choose Whether to Include Authentication in Permalink [\#178](https://github.com/liyasthomas/postwoman/issues/178)
|
||||
- Allow HTTP \(not HTTPS\) on postwoman.io [\#175](https://github.com/liyasthomas/postwoman/issues/175)
|
||||
- Docker-compose in development [\#168](https://github.com/liyasthomas/postwoman/issues/168)
|
||||
- Add Docker [\#164](https://github.com/liyasthomas/postwoman/issues/164)
|
||||
- Clear Input [\#155](https://github.com/liyasthomas/postwoman/issues/155)
|
||||
- introduce some script language to parse the response and pass environment variable as request parameter [\#139](https://github.com/liyasthomas/postwoman/issues/139)
|
||||
- Add links to the footer version and commit sha [\#134](https://github.com/liyasthomas/postwoman/issues/134)
|
||||
- Please add a label for each request. It will be helpful. [\#133](https://github.com/liyasthomas/postwoman/issues/133)
|
||||
- Use 'icon buttons' instead of 'text buttons' [\#130](https://github.com/liyasthomas/postwoman/issues/130)
|
||||
- Change .editorconfig [\#115](https://github.com/liyasthomas/postwoman/issues/115)
|
||||
- \[UX\] Provide Focus State for Buttons, etc. [\#112](https://github.com/liyasthomas/postwoman/issues/112)
|
||||
- Add linter semistandard [\#98](https://github.com/liyasthomas/postwoman/issues/98)
|
||||
- Show "Send" button all over the page or enable hotkeys [\#94](https://github.com/liyasthomas/postwoman/issues/94)
|
||||
- Import request from cURL [\#93](https://github.com/liyasthomas/postwoman/issues/93)
|
||||
- Search on History [\#92](https://github.com/liyasthomas/postwoman/issues/92)
|
||||
- Add support for "application/hal+json" Content-Type [\#88](https://github.com/liyasthomas/postwoman/issues/88)
|
||||
- The query string is built incorrectly when the path contains a parameter [\#87](https://github.com/liyasthomas/postwoman/issues/87)
|
||||
- Option to Copy request as Fetch or XHR Or CURL [\#76](https://github.com/liyasthomas/postwoman/issues/76)
|
||||
- Add Tests [\#65](https://github.com/liyasthomas/postwoman/issues/65)
|
||||
- Request Headers [\#57](https://github.com/liyasthomas/postwoman/issues/57)
|
||||
- Colored response codes based on status code [\#46](https://github.com/liyasthomas/postwoman/issues/46)
|
||||
- Improve SEO [\#45](https://github.com/liyasthomas/postwoman/issues/45)
|
||||
- Add html preview to response section [\#41](https://github.com/liyasthomas/postwoman/issues/41)
|
||||
- websocket support [\#40](https://github.com/liyasthomas/postwoman/issues/40)
|
||||
- Raw request body for POST requests and Authorization key/value in Header [\#36](https://github.com/liyasthomas/postwoman/issues/36)
|
||||
- Code highlight on response body [\#33](https://github.com/liyasthomas/postwoman/issues/33)
|
||||
- Template selector [\#32](https://github.com/liyasthomas/postwoman/issues/32)
|
||||
- Vue template [\#31](https://github.com/liyasthomas/postwoman/issues/31)
|
||||
- Add copy response to clipboard button [\#30](https://github.com/liyasthomas/postwoman/issues/30)
|
||||
- Ability to store/share/create collections [\#29](https://github.com/liyasthomas/postwoman/issues/29)
|
||||
- Send request on Enter Key press [\#17](https://github.com/liyasthomas/postwoman/issues/17)
|
||||
- Readable [\#5](https://github.com/liyasthomas/postwoman/issues/5)
|
||||
- Serialize a request into JSON? [\#4](https://github.com/liyasthomas/postwoman/issues/4)
|
||||
- Add brand new logo to the project [\#244](https://github.com/liyasthomas/postwoman/pull/244) ([caneco](https://github.com/caneco))
|
||||
- Feature/pre request script [\#231](https://github.com/liyasthomas/postwoman/pull/231) ([nickpalenchar](https://github.com/nickpalenchar))
|
||||
- Add the ApolloTV proxy server [\#217](https://github.com/liyasthomas/postwoman/pull/217) ([NBTX](https://github.com/NBTX))
|
||||
- bug: keeping information on page change [\#211](https://github.com/liyasthomas/postwoman/pull/211) ([breno-pereira](https://github.com/breno-pereira))
|
||||
- Work in Progress: feature/allow-collections-importing [\#209](https://github.com/liyasthomas/postwoman/pull/209) ([vlad0337187](https://github.com/vlad0337187))
|
||||
- Feature/log errors [\#207](https://github.com/liyasthomas/postwoman/pull/207) ([nickpalenchar](https://github.com/nickpalenchar))
|
||||
- Use returned value from toggle component on change event [\#205](https://github.com/liyasthomas/postwoman/pull/205) ([hosseinnedaee](https://github.com/hosseinnedaee))
|
||||
- Fix CORS and mixed content issue [\#199](https://github.com/liyasthomas/postwoman/pull/199) ([hosseinnedaee](https://github.com/hosseinnedaee))
|
||||
- Added Tooltips [\#197](https://github.com/liyasthomas/postwoman/pull/197) ([AndrewBastin](https://github.com/AndrewBastin))
|
||||
- Added auto theme [\#185](https://github.com/liyasthomas/postwoman/pull/185) ([AndrewBastin](https://github.com/AndrewBastin))
|
||||
- Add Request name label for every requests [\#184](https://github.com/liyasthomas/postwoman/pull/184) ([sharath2106](https://github.com/sharath2106))
|
||||
- Collections [\#176](https://github.com/liyasthomas/postwoman/pull/176) ([TheHollidayInn](https://github.com/TheHollidayInn))
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Bearer Token value still left even after being cleared [\#212](https://github.com/liyasthomas/postwoman/issues/212)
|
||||
- All changes in input fields lost when you switch to another page [\#203](https://github.com/liyasthomas/postwoman/issues/203)
|
||||
- POST request json bodies aren't sent [\#180](https://github.com/liyasthomas/postwoman/issues/180)
|
||||
- Headers turn into 0 : \[Object object\] [\#166](https://github.com/liyasthomas/postwoman/issues/166)
|
||||
- Send Again Button Constantly Flickering [\#157](https://github.com/liyasthomas/postwoman/issues/157)
|
||||
- There are cross-domain problems [\#128](https://github.com/liyasthomas/postwoman/issues/128)
|
||||
- Raw requests are not being sent [\#124](https://github.com/liyasthomas/postwoman/issues/124)
|
||||
- Request Body Is Not Sent [\#113](https://github.com/liyasthomas/postwoman/issues/113)
|
||||
- default menu option - 'Http' is not highlighted when launched from installed pwa app \(UI bug\) [\#100](https://github.com/liyasthomas/postwoman/issues/100)
|
||||
- App is broken with old history in localStorage [\#74](https://github.com/liyasthomas/postwoman/issues/74)
|
||||
- Last added history entry is removed automatically after refresh [\#66](https://github.com/liyasthomas/postwoman/issues/66)
|
||||
- Cannot use localhost as base url [\#56](https://github.com/liyasthomas/postwoman/issues/56)
|
||||
- \[CORS\] No 'Access-Control-Allow-Origin' header is present on the requested resource [\#2](https://github.com/liyasthomas/postwoman/issues/2)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- Section labels don't display properly in Firefox [\#237](https://github.com/liyasthomas/postwoman/issues/237)
|
||||
- Unsupported URLs \[BUG\]? [\#229](https://github.com/liyasthomas/postwoman/issues/229)
|
||||
- Credentials are still being included in Permalink even when "Include in URL" is turned off [\#227](https://github.com/liyasthomas/postwoman/issues/227)
|
||||
- Display sendRequest runtime errors in the console [\#206](https://github.com/liyasthomas/postwoman/issues/206)
|
||||
- Missing "Landing/start page" [\#162](https://github.com/liyasthomas/postwoman/issues/162)
|
||||
- Response with content-type "application/hal+json" shows as \[Object object\] [\#158](https://github.com/liyasthomas/postwoman/issues/158)
|
||||
- A place to discuss [\#149](https://github.com/liyasthomas/postwoman/issues/149)
|
||||
- Inconsistent version name [\#141](https://github.com/liyasthomas/postwoman/issues/141)
|
||||
- Autoresize the textarea [\#102](https://github.com/liyasthomas/postwoman/issues/102)
|
||||
- Content-Type revamping [\#99](https://github.com/liyasthomas/postwoman/issues/99)
|
||||
- Add version number in footer [\#97](https://github.com/liyasthomas/postwoman/issues/97)
|
||||
- The history doesn't show a date with the timestamp. [\#81](https://github.com/liyasthomas/postwoman/issues/81)
|
||||
- Not working on Brave Browser anymore [\#71](https://github.com/liyasthomas/postwoman/issues/71)
|
||||
- Why da fuq is your name plastered all over the README? [\#70](https://github.com/liyasthomas/postwoman/issues/70)
|
||||
- Comparison with Postman is missing [\#69](https://github.com/liyasthomas/postwoman/issues/69)
|
||||
- HTTP request with different library [\#61](https://github.com/liyasthomas/postwoman/issues/61)
|
||||
- Editorconfig file [\#60](https://github.com/liyasthomas/postwoman/issues/60)
|
||||
- 500 this.isValidURL is not a function [\#58](https://github.com/liyasthomas/postwoman/issues/58)
|
||||
- Styling with Tailwindcss [\#38](https://github.com/liyasthomas/postwoman/issues/38)
|
||||
- Not Working in IE 11 [\#37](https://github.com/liyasthomas/postwoman/issues/37)
|
||||
- PWA not installable [\#19](https://github.com/liyasthomas/postwoman/issues/19)
|
||||
- Simple Misspelling [\#8](https://github.com/liyasthomas/postwoman/issues/8)
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
- docs: add liyasthomas as a contributor [\#264](https://github.com/liyasthomas/postwoman/pull/264) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add jamesgeorge007 as a contributor [\#263](https://github.com/liyasthomas/postwoman/pull/263) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add NBTX as a contributor [\#262](https://github.com/liyasthomas/postwoman/pull/262) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- Fix .all-contributorsrc badge template. [\#260](https://github.com/liyasthomas/postwoman/pull/260) ([NBTX](https://github.com/NBTX))
|
||||
- docs: add hosseinnedaee as a contributor [\#259](https://github.com/liyasthomas/postwoman/pull/259) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add nityanandagohain as a contributor [\#257](https://github.com/liyasthomas/postwoman/pull/257) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add JacobAnavisca as a contributor [\#256](https://github.com/liyasthomas/postwoman/pull/256) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add izerozlu as a contributor [\#255](https://github.com/liyasthomas/postwoman/pull/255) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add vlad0337187 as a contributor [\#254](https://github.com/liyasthomas/postwoman/pull/254) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add AndrewBastin as a contributor [\#253](https://github.com/liyasthomas/postwoman/pull/253) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add terranblake as a contributor [\#252](https://github.com/liyasthomas/postwoman/pull/252) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add nickpalenchar as a contributor [\#251](https://github.com/liyasthomas/postwoman/pull/251) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add yubathom as a contributor [\#250](https://github.com/liyasthomas/postwoman/pull/250) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add larouxn as a contributor [\#249](https://github.com/liyasthomas/postwoman/pull/249) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add NBTX as a contributor [\#248](https://github.com/liyasthomas/postwoman/pull/248) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- docs: add liyasthomas as a contributor [\#247](https://github.com/liyasthomas/postwoman/pull/247) ([allcontributors[bot]](https://github.com/apps/allcontributors))
|
||||
- Make page changes more fluid [\#246](https://github.com/liyasthomas/postwoman/pull/246) ([NBTX](https://github.com/NBTX))
|
||||
- Minor tweaks [\#245](https://github.com/liyasthomas/postwoman/pull/245) ([liyasthomas](https://github.com/liyasthomas))
|
||||
- ⬆️ Bump @nuxtjs/google-tag-manager from 2.3.0 to 2.3.1 [\#243](https://github.com/liyasthomas/postwoman/pull/243) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump yargs-parser from 15.0.0 to 16.1.0 [\#242](https://github.com/liyasthomas/postwoman/pull/242) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump @nuxtjs/toast from 3.2.1 to 3.3.0 [\#241](https://github.com/liyasthomas/postwoman/pull/241) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump highlight.js from 9.15.10 to 9.16.2 [\#240](https://github.com/liyasthomas/postwoman/pull/240) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump cypress from 3.5.0 to 3.6.0 [\#239](https://github.com/liyasthomas/postwoman/pull/239) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- Fix legend labels in Firefox, fix colored labels slider [\#238](https://github.com/liyasthomas/postwoman/pull/238) ([NBTX](https://github.com/NBTX))
|
||||
- Documentation Cleanup [\#230](https://github.com/liyasthomas/postwoman/pull/230) ([amitdash291](https://github.com/amitdash291))
|
||||
- Fix \#227 Exclude credentials from permalink [\#228](https://github.com/liyasthomas/postwoman/pull/228) ([reefqi037](https://github.com/reefqi037))
|
||||
- ⬆️ Bump cypress from 3.4.1 to 3.5.0 [\#224](https://github.com/liyasthomas/postwoman/pull/224) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump @nuxtjs/axios from 5.6.0 to 5.8.0 [\#223](https://github.com/liyasthomas/postwoman/pull/223) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump node-sass from 4.12.0 to 4.13.0 [\#222](https://github.com/liyasthomas/postwoman/pull/222) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump nuxt from 2.10.1 to 2.10.2 [\#221](https://github.com/liyasthomas/postwoman/pull/221) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump @nuxtjs/google-analytics from 2.2.0 to 2.2.1 [\#220](https://github.com/liyasthomas/postwoman/pull/220) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump vuex-persist from 2.1.0 to 2.1.1 [\#219](https://github.com/liyasthomas/postwoman/pull/219) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- Fixed frame colors toggle [\#216](https://github.com/liyasthomas/postwoman/pull/216) ([mateusppereira](https://github.com/mateusppereira))
|
||||
- Re-order sections and add toggle for including authentication in URL [\#215](https://github.com/liyasthomas/postwoman/pull/215) ([NBTX](https://github.com/NBTX))
|
||||
- chore: minor code refactor [\#214](https://github.com/liyasthomas/postwoman/pull/214) ([jamesgeorge007](https://github.com/jamesgeorge007))
|
||||
- Fix \#212 Clear bearer token value [\#213](https://github.com/liyasthomas/postwoman/pull/213) ([reefqi037](https://github.com/reefqi037))
|
||||
- fix: don't display 'Collection is empty' label if collection has any … [\#208](https://github.com/liyasthomas/postwoman/pull/208) ([vlad0337187](https://github.com/vlad0337187))
|
||||
- Fix proxy URL [\#201](https://github.com/liyasthomas/postwoman/pull/201) ([NBTX](https://github.com/NBTX))
|
||||
- Fix CORS and Mixed-Content issue & Bug Fixes [\#200](https://github.com/liyasthomas/postwoman/pull/200) ([NBTX](https://github.com/NBTX))
|
||||
- ⬆️ Bump start-server-and-test from 1.10.5 to 1.10.6 [\#198](https://github.com/liyasthomas/postwoman/pull/198) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump start-server-and-test from 1.10.3 to 1.10.5 [\#194](https://github.com/liyasthomas/postwoman/pull/194) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump @nuxtjs/google-tag-manager from 2.2.1 to 2.3.0 [\#193](https://github.com/liyasthomas/postwoman/pull/193) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump nuxt from 2.10.0 to 2.10.1 [\#192](https://github.com/liyasthomas/postwoman/pull/192) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- ⬆️ Bump yargs-parser from 14.0.0 to 15.0.0 [\#191](https://github.com/liyasthomas/postwoman/pull/191) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- Add quotation marks for generated code [\#187](https://github.com/liyasthomas/postwoman/pull/187) ([johnhenry](https://github.com/johnhenry))
|
||||
- updated threshold and rootMargin for IntersectionObserver [\#182](https://github.com/liyasthomas/postwoman/pull/182) ([edisonaugusthy](https://github.com/edisonaugusthy))
|
||||
- Add basic e2e tests [\#181](https://github.com/liyasthomas/postwoman/pull/181) ([yubathom](https://github.com/yubathom))
|
||||
- ⬆️ Bump nuxt from 2.9.2 to 2.10.0 [\#179](https://github.com/liyasthomas/postwoman/pull/179) ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
|
||||
- 🐛 Fixed sitemap configuration [\#177](https://github.com/liyasthomas/postwoman/pull/177) ([NicoPennec](https://github.com/NicoPennec))
|
||||
- Code Refactoring [\#173](https://github.com/liyasthomas/postwoman/pull/173) ([edisonaugusthy](https://github.com/edisonaugusthy))
|
||||
- Added Black Theme [\#172](https://github.com/liyasthomas/postwoman/pull/172) ([AndrewBastin](https://github.com/AndrewBastin))
|
||||
- Update PWA configuration [\#171](https://github.com/liyasthomas/postwoman/pull/171) ([NBTX](https://github.com/NBTX))
|
||||
|
||||
## [v0.1.0](https://github.com/liyasthomas/postwoman/tree/v0.1.0) (2019-08-22)
|
||||
|
||||
[Full Changelog](https://github.com/liyasthomas/postwoman/compare/91c08a5e6305cc95a0df46a33fdd0013bf7339b4...v0.1.0)
|
||||
|
||||
|
||||
|
||||
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
|
||||
|
||||
@@ -34,12 +34,12 @@ Examples of unacceptable behavior by participants include:
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
behavior. Maintainers are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
that are not aligned with our Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
When contributing to this repository, please first discuss the change you wish to make via issue,
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
email, or any other method with the owners of this repository before making a change.
|
||||
|
||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
|
||||
1. Ensure any install or build dependencies are removed before the end of the layer when doing a
|
||||
build.
|
||||
2. Update the README.md with details of changes to the interface, this includes new environment
|
||||
2. Update the README.md with details of changes to the interface, this includes new environment
|
||||
variables, exposed ports, useful file locations and container parameters.
|
||||
3. Increase the version numbers in any examples files and the README.md to the new version that this
|
||||
Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
|
||||
4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
|
||||
do not have permission to do that, you may request the second reviewer to merge it for you.
|
||||
4. You may merge the Pull Request once you have the sign-off of two other developers, or if you
|
||||
do not have permission to do that, you may request the second reviewer merge it for you.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
@@ -52,12 +52,12 @@ advances
|
||||
### Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
behavior. Maintainers are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
that are not aligned with our Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
|
||||
11
Dockerfile
@@ -1,12 +1,19 @@
|
||||
FROM node:12.10.0-buster
|
||||
FROM node:12.10.0-alpine
|
||||
|
||||
LABEL maintainer="Liyas Thomas (liyascthomas@gmail.com)"
|
||||
|
||||
# Add git as the prebuild target requires it to parse version information
|
||||
RUN apk add --update --no-cache \
|
||||
git
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN npm install
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
192
README.md
@@ -10,7 +10,7 @@
|
||||
</p>
|
||||
<p>
|
||||
|
||||
[](https://travis-ci.com/liyasthomas/postwoman) [](https://github.com/liyasthomas/postwoman/releases/latest) [](https://postwoman.io) [](CONTRIBUTING.md) [](#contributors) [](https://opencollective.com/postwoman) [](https://www.paypal.me/liyascthomas) [](https://t.me/postwoman_app) [](https://discord.gg/GAMWxmR) [](https://twitter.com/intent/tweet?url=https%3A%2F%2Fpostwoman.io&text=%F0%9F%91%BD%20Postwoman%20%E2%80%A2%20API%20request%20builder%20-%20Helps%20you%20create%20your%20requests%20faster%2C%20saving%20you%20precious%20time%20on%20your%20development&original_referer=https%3A%2F%2Ftwitter.com%2Fshare%3Ftext%3D%25F0%259F%2591%25BD%2520Postwoman%2520%25E2%2580%25A2%2520API%2520request%2520builder%2520-%2520Helps%2520you%2520create%2520your%2520requests%2520faster%2C%2520saving%2520you%2520precious%2520time%2520on%2520your%2520development%26url%3Dhttps%3A%2F%2Fpostwoman.io%26hashtags%3Dpostwoman%26via%3Dliyasthomas&via=liyasthomas&hashtags=postwoman)
|
||||
[](https://travis-ci.com/liyasthomas/postwoman) [](https://github.com/liyasthomas/postwoman/releases/latest) [](https://postwoman.io) [](CONTRIBUTING.md) [](https://opencollective.com/postwoman) [](https://www.paypal.me/liyascthomas) [](https://t.me/postwoman_app) [](https://discord.gg/GAMWxmR) [](https://twitter.com/intent/tweet?url=https%3A%2F%2Fpostwoman.io&text=%F0%9F%91%BD%20Postwoman%20%E2%80%A2%20API%20request%20builder%20-%20Helps%20you%20create%20your%20requests%20faster%2C%20saving%20you%20precious%20time%20on%20your%20development&original_referer=https%3A%2F%2Ftwitter.com%2Fshare%3Ftext%3D%25F0%259F%2591%25BD%2520Postwoman%2520%25E2%2580%25A2%2520API%2520request%2520builder%2520-%2520Helps%2520you%2520create%2520your%2520requests%2520faster%2C%2520saving%2520you%2520precious%2520time%2520on%2520your%2520development%26url%3Dhttps%3A%2F%2Fpostwoman.io%26hashtags%3Dpostwoman%26via%3Dliyasthomas&via=liyasthomas&hashtags=postwoman)
|
||||
|
||||
</p>
|
||||
<p>
|
||||
@@ -23,11 +23,11 @@
|
||||
|
||||
---
|
||||
|
||||
**Start here: _[Story behind Postwoman](https://dev.to/liyasthomas/i-created-postwoman-an-online-open-source-api-request-builder-41md)_**
|
||||
**Read: _[Story behind Postwoman](https://dev.to/liyasthomas/i-created-postwoman-an-online-open-source-api-request-builder-41md), [Postwoman v1.0](https://dev.to/liyasthomas/postwoman-v1-0-a-free-fast-beautiful-alternative-to-postman-mn0)_**
|
||||
|
||||
**Chat here: _[Telegram](https://t.me/postwoman_app), [Discord](https://discord.gg/GAMWxmR)_**
|
||||
**Chat: _[Telegram](https://t.me/postwoman_app), [Discord](https://discord.gg/GAMWxmR)_**
|
||||
|
||||
**Donate here: _[PayPal](https://www.paypal.me/liyascthomas), [Open Collective](https://opencollective.com/postwoman), [Patreon](https://www.patreon.com/liyasthomas)_**
|
||||
**Donate: _[PayPal](https://www.paypal.me/liyascthomas), [Open Collective](https://opencollective.com/postwoman), [Patreon](https://www.patreon.com/liyasthomas)_**
|
||||
|
||||
<div align="center">
|
||||
<br>
|
||||
@@ -38,11 +38,9 @@
|
||||
|
||||
### Features ✨
|
||||
|
||||
❤️ **Lightweight**: Crafted with minimalistic UI design. Simple design is the best design.
|
||||
❤️ **Lightweight**: Crafted with minimalistic UI design - simple design is the best design.
|
||||
|
||||
- Faster, lighter, cleaner, minimal & responsive
|
||||
|
||||
⚡️ **Fast**: Send requests and get/copy responses in real-time! Fast software is the best software.
|
||||
⚡️ **Fast**: Send requests and get/copy responses in real-time - fast software is the best software.
|
||||
|
||||
**Methods:**
|
||||
- `GET` - Retrieve information about the REST API resource
|
||||
@@ -50,19 +48,20 @@
|
||||
- `POST` - Create a REST API resource
|
||||
- `PUT` - Update a REST API resource
|
||||
- `DELETE` - Delete a REST API resource or related component
|
||||
- `CONNECT` - Establishes a tunnel to the server identified by the target resource
|
||||
- `OPTIONS` - Describe the communication options for the target resource
|
||||
- `TRACE` - Performs a message loop-back test along the path to the target resource
|
||||
- `PATCH` - Apply partial modifications to a REST API resource
|
||||
- `<custom>` - Some APIs use custom request methods such as `LIST`. Type in your custom methods.
|
||||
|
||||
_History entries are synced with local session storage_
|
||||
|
||||
🌈 **Make it yours**: Customizable combinations for background, foreground and accent colors: because customization === freedom. [Customize now ✨](https://postwoman.io/settings).
|
||||
🌈 **Make it yours**: Customizable combinations for background, foreground and accent colors: because customization is freedom. [Customize now ✨](https://postwoman.io/settings).
|
||||
|
||||
**Customizations:**
|
||||
- Choose theme: Kinda Dark (default), Clearly White, Just Black and System theme
|
||||
- Choose accent color: Green (default), Yellow, Pink, Red, Purple, Orange, Cyan and Blue
|
||||
- Toggle multi-colored frames
|
||||
- Toggle multi-colored headings
|
||||
|
||||
_Customized themes are also synced with local session storage_
|
||||
_Customized themes are synced with local session storage_
|
||||
|
||||
🔥 **PWA**: Install as a [PWA](https://developers.google.com/web/progressive-web-apps) on your device.
|
||||
|
||||
@@ -74,24 +73,36 @@ _Customized themes are also synced with local session storage_
|
||||
- [Desktop PWA](https://developers.google.com/web/progressive-web-apps/desktop) support (button in footer)
|
||||
- ([full features](https://developers.google.com/web/progressive-web-apps))
|
||||
|
||||
🚀 **Request**: Retrieve data from a URL without having to do a full page refresh.
|
||||
🚀 **Request**: Retrieve response from endpoint instantly.
|
||||
|
||||
- Choose `method`
|
||||
- Enter `URL`
|
||||
- Enter `Path`
|
||||
- Enter `URL` and `Path`
|
||||
- Send
|
||||
|
||||
**Features:**
|
||||
- Copy/share public "Share URL"
|
||||
- Generate request code for JavaScript XHR, Fetch and cURL
|
||||
- Generate request code for `JavaScript XHR`, `Fetch` and `cURL`
|
||||
- Copy generated request code to clipboard
|
||||
- Import cURL
|
||||
- Import `cURL`
|
||||
- Label requests
|
||||
|
||||
🔌 **Web Socket**: Establish full-duplex communication channels over a single TCP connection.
|
||||
🔌 **WebSocket**: Establish full-duplex communication channels over a single TCP connection.
|
||||
|
||||
- Send and receive data
|
||||
- Send and receive data
|
||||
- Basic authentication using username and password
|
||||
- Token based authentication
|
||||
|
||||
🔐 **Authentication**: Allows to identity the end user.
|
||||
📡 **Server Sent Events**: Receive a stream of updates from a server over a HTTP connection without resorting to polling.
|
||||
|
||||
🔮 **GraphQL**: GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.
|
||||
|
||||
- Set endpoint and get schemas
|
||||
- Multi-column docs
|
||||
- Set custom request headers
|
||||
- Query schema
|
||||
- Get query response
|
||||
|
||||
🔐 **Authentication**: Allows to identify the end user.
|
||||
|
||||
**Types:**
|
||||
- None
|
||||
@@ -107,30 +118,32 @@ _Customized themes are also synced with local session storage_
|
||||
📃 **Request Body**: Used to send and receive data via the REST API.
|
||||
|
||||
**Options:**
|
||||
- Set Content Type
|
||||
- Set `Content Type`
|
||||
- Add or remove Parameter list
|
||||
- Toggle between key-value and RAW input Parameter list
|
||||
|
||||
👋 **Responses**: Contains the status line, headers and the message/response body.
|
||||
|
||||
- Copy response to clipboard
|
||||
- View preview for HTML responses
|
||||
|
||||
_HTML responses have "Preview HTML" feature_
|
||||
- Download response to as a file
|
||||
- View preview of HTML responses
|
||||
|
||||
⏰ **History**: Request entries are synced with local session storage to reuse with a single click.
|
||||
|
||||
**Fields:**
|
||||
- Star
|
||||
- Label
|
||||
- Timestamp
|
||||
- Method
|
||||
- Status code
|
||||
- URL
|
||||
- Path
|
||||
- Timestamp
|
||||
- Duration
|
||||
- Pre-request script
|
||||
|
||||
_History entries can be sorted by any fields_
|
||||
|
||||
_Histories can deleted one-by-one or all together_
|
||||
_Histories can be deleted one-by-one or all together_
|
||||
|
||||
📁 **Collections**: Keep your API requests organized with collections and folders. Reuse them with a single click.
|
||||
|
||||
@@ -138,8 +151,6 @@ _Histories can deleted one-by-one or all together_
|
||||
- Create infinite collections, folders and requests
|
||||
- Edit, delete, move, export, import and replace
|
||||
|
||||
_Export, import and replace collections with JSON files_
|
||||
|
||||
_Collections are synced with local session storage_
|
||||
|
||||
🌐 **Proxy**: Enable Proxy Mode from Settings to access blocked APIs.
|
||||
@@ -147,33 +158,86 @@ _Collections are synced with local session storage_
|
||||
**Features:**
|
||||
- Hide your IP address
|
||||
- Fixes [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) (Cross Origin Resource Sharing) issues
|
||||
- Access APIs served in non-HTTPS (`http://`, `localhost`, etc.)
|
||||
- Access APIs served in non-HTTPS (`http://`)
|
||||
- Use custom Proxy URL
|
||||
|
||||
_Proxy is hosted by ApolloTV - [Privacy policy](https://apollotv.xyz/legal)_
|
||||
_Official Postwoman Proxy is hosted by ApolloTV - **[Privacy policy](https://apollotv.xyz/legal)**_
|
||||
|
||||
📜 **Pre-Request Scripts β**: Snippets of code associated with a request that are executed before the request is sent.
|
||||
|
||||
**Use-cases:**
|
||||
- Including the timestamp in the request headers
|
||||
- Sending a random alphanumeric string in the URL parameters
|
||||
|
||||
_Pre-Request Scripts is an experimental feature and is in Public Beta testing_
|
||||
- Include timestamp in the request headers
|
||||
- Send a random alphanumeric string in the URL parameters
|
||||
|
||||
_Requests with Pre-Request Scripts are indicated in History entries_
|
||||
|
||||
📄 **API Documentation**: Create and share dynamic API documentation easily, quickly.
|
||||
|
||||
**Usage:**
|
||||
1. Add your requests to Collections and Folders
|
||||
2. Export Collections and easily share your APIs with the rest of your team
|
||||
3. Import Collections and Generate Documentation on-the-go
|
||||
|
||||
⌨️ **Keyboard Shortcuts**: Optimized for efficiency.
|
||||
|
||||
**Shortcuts:**
|
||||
- Send Request <kbd>Ctrl</kbd> + <kbd>G</kbd>
|
||||
- Save to Collections <kbd>Ctrl</kbd> + <kbd>S</kbd>
|
||||
- Copy Request Link <kbd>Ctrl</kbd> + <kbd>K</kbd>
|
||||
- Reset Request <kbd>Ctrl</kbd> + <kbd>L</kbd>
|
||||
|
||||
🌎 **i18n β**: Experience the app in your own language.
|
||||
|
||||
1. Scroll down to the footer
|
||||
2. Click "Choose Language" button
|
||||
3. Select your language from the menu
|
||||
|
||||
_Keep in mind translations aren't available for all source and target language combinations_
|
||||
|
||||
**To provide a localized experience for users around the world, you can add you own translations.**
|
||||
|
||||
- Add a new locale in `lang/`
|
||||
|
||||
Example: `lang/es-ES.js`
|
||||
- Mention `code`, `name`, `iso` and `file` in `nuxt.config.js`
|
||||
|
||||
Example:
|
||||
```
|
||||
i18n: {
|
||||
locales: [{
|
||||
code: 'es',
|
||||
name: 'Español',
|
||||
iso: 'es-ES',
|
||||
file: 'es-ES.js'
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
_**All `i18n` contributions are welcome to `i18n` [branch](https://github.com/liyasthomas/postwoman/tree/i18n) only!**_
|
||||
|
||||
📦 **Add-ons**: Official add-ons for Postwoman.
|
||||
|
||||
- **[Postwoman Proxy β](https://github.com/postwoman-io/postwoman-proxy)** - A simple proxy server created for Postwoman
|
||||
- **[Postwoman CLI β](https://github.com/postwoman-io/postwoman-cli)** - A CLI solution for Postwoman
|
||||
|
||||
_Add-ons are developed and maintained under **[Official Postwoman Organization](https://github.com/postwoman-io)**_
|
||||
|
||||
**To find out more, please check out [Postwoman Wiki](https://github.com/liyasthomas/postwoman/wiki).**
|
||||
|
||||
## Demo 🚀 [](https://postwoman.io)
|
||||
## Demo 🚀 [](https://postwoman.io)
|
||||
|
||||
[https://postwoman.io](https://postwoman.io)
|
||||
[postwoman.io](https://postwoman.io)
|
||||
|
||||
<a href="https://www.netlify.com">
|
||||
<img src="https://www.netlify.com/img/global/badges/netlify-light.svg"/>
|
||||
</a>
|
||||
|
||||
## Usage 💡
|
||||
|
||||
1. Specify your request method
|
||||
2. Type in your API URL
|
||||
3. Add API path
|
||||
4. Send request
|
||||
5. Get response!
|
||||
1. Specify your request `method`
|
||||
2. Type in your API `URL` and `path`
|
||||
3. Send request
|
||||
4. Get response
|
||||
|
||||
You're done!
|
||||
|
||||
@@ -188,6 +252,12 @@ You're done!
|
||||
|
||||
## Developing 👷
|
||||
|
||||
#### Use a browser based development environment:
|
||||
|
||||
[](https://gitpod.io/#https://github.com/liyasthomas/postwoman)
|
||||
|
||||
#### Or, with local development environment:
|
||||
|
||||
1. [Clone this repo](https://help.github.com/en/articles/cloning-a-repository) with git.
|
||||
2. Install dependencies by running `npm install` within the directory that you cloned (probably `postwoman`).
|
||||
3. Start the development server with `npm run dev`.
|
||||
@@ -258,11 +328,10 @@ See the [CHANGELOG](CHANGELOG.md) file for details.
|
||||
<td align="center"><a href="https://nicholaslaroux.com"><img src="https://avatars0.githubusercontent.com/u/1557529?v=4" width="100px;" alt="Nicholas La Roux"/><br /><sub><b>Nicholas La Roux</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=larouxn" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/yubathom"><img src="https://avatars3.githubusercontent.com/u/4117768?v=4" width="100px;" alt="Thomas Yuba"/><br /><sub><b>Thomas Yuba</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=yubathom" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://www.linkedin.com/in/nickpalenchar"><img src="https://avatars1.githubusercontent.com/u/7539781?v=4" width="100px;" alt="Nick Palenchar"/><br /><sub><b>Nick Palenchar</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=nickpalenchar" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://www.lumahealth.io/"><img src="https://avatars3.githubusercontent.com/u/8795767?v=4" width="100px;" alt="Terran Blake"/><br /><sub><b>Terran Blake</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=terranblake" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/AndrewBastin"><img src="https://avatars2.githubusercontent.com/u/9131943?v=4" width="100px;" alt="Andrew Bastin"/><br /><sub><b>Andrew Bastin</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=AndrewBastin" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/vlad0337187"><img src="https://avatars1.githubusercontent.com/u/12682937?v=4" width="100px;" alt="Vladislav"/><br /><sub><b>Vladislav</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=vlad0337187" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/vlad0337187"><img src="https://avatars1.githubusercontent.com/u/12682937?v=4" width="100px;" alt="Vladislav"/><br /><sub><b>Vladislav</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=vlad0337187" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/izerozlu"><img src="https://avatars3.githubusercontent.com/u/17386157?v=4" width="100px;" alt="izerozlu"/><br /><sub><b>izerozlu</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=izerozlu" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/JacobAnavisca"><img src="https://avatars2.githubusercontent.com/u/21232366?v=4" width="100px;" alt="Jacob Anavisca"/><br /><sub><b>Jacob Anavisca</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=JacobAnavisca" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://nityanandagohain.github.io"><img src="https://avatars3.githubusercontent.com/u/26831659?v=4" width="100px;" alt="Nityananda Gohain"/><br /><sub><b>Nityananda Gohain</b></sub></a><br /><a href="https://github.com/liyasthomas/postwoman/commits?author=nityanandagohain" title="Code">💻</a></td>
|
||||
@@ -320,13 +389,34 @@ This project is licensed under the [MIT License](https://opensource.org/licenses
|
||||
|
||||
## Badges
|
||||
|
||||
| Status | Preview | Markdown Code (copy & paste into `readme.md`) |
|
||||
| ----------- | ----------- | ----------- |
|
||||
| **Default** | [](https://postwoman.io) | `[](https://postwoman.io)` |
|
||||
| **Success** | [](https://postwoman.io) | `[](https://postwoman.io)` |
|
||||
| **Critical** | [](https://postwoman.io) | `[](https://postwoman.io)` |
|
||||
| **Custom** | [](https://postwoman.io) | `[](https://postwoman.io)` |
|
||||
| Make your own badge! | [](https://postwoman.io) | `[](https://postwoman.io)` |
|
||||
<table>
|
||||
<tr>
|
||||
<th>Preview</th>
|
||||
<th>Markdown code</th>
|
||||
</tr>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" width="200px"><a href="https://postwoman.io"><br/><img src="https://img.shields.io/badge/Tested_on-Postwoman-202124?logo=Postwoman"/></a><br/><sub>Default<sub></td>
|
||||
<td><code>[](https://postwoman.io)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" width="200px"><a href="https://postwoman.io"><br/><img src="https://img.shields.io/badge/Tested_on-Postwoman-success?logo=Postwoman"/></a><br/><sub>Success<sub></td>
|
||||
<td><code>[](https://postwoman.io)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" width="200px"><a href="https://postwoman.io"><br/><img src="https://img.shields.io/badge/Tested_on-Postwoman-critical?logo=Postwoman"/></a><br/><sub>Critical<sub></td>
|
||||
<td><code>[](https://postwoman.io)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" width="200px"><a href="https://postwoman.io"><br/><img src="https://img.shields.io/badge/Tested_on-Postwoman-blueviolet?logo=Postwoman"/></a><br/><sub>Custom<sub></td>
|
||||
<td><code>[](https://postwoman.io)</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" width="200px"><a href="https://postwoman.io"><br/><img src="https://img.shields.io/badge/your_text-Postwoman-hex_color_code?logo=Postwoman"/></a><br/><sub>Customize<sub></td>
|
||||
<td><code>[](https://postwoman.io)</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div align="center">
|
||||
<br>
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
// @import url("https://fonts.googleapis.com/css?family=Poppins:500,700|Roboto+Mono:400&display=swap");
|
||||
// @import url("https://fonts.googleapis.com/icon?family=Material+Icons&display=swap");
|
||||
|
||||
/* Material Design Icons */
|
||||
@font-face {
|
||||
font-family: "Material Icons";
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(~@/assets/fonts/material-icons-v48.woff2) format("woff2");
|
||||
font-display: swap;
|
||||
src: url("~static/fonts/material-icons-v48.woff2") format("woff2");
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-family: "Material Icons";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
@@ -21,43 +26,44 @@
|
||||
direction: ltr;
|
||||
-webkit-font-feature-settings: "liga";
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-feature-settings: "liga";
|
||||
}
|
||||
|
||||
/* Roboto Mono 400 */
|
||||
@font-face {
|
||||
font-family: "Roboto Mono";
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Roboto Mono"), local("RobotoMono-Regular"),
|
||||
url("~@/assets/fonts/roboto-mono-v7-latin-regular.woff2") format("woff2"),
|
||||
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url("~@/assets/fonts/roboto-mono-v7-latin-regular.woff") format("woff");
|
||||
/* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
||||
|
||||
/* Poppins 500 */
|
||||
/* poppins-500 - latin */
|
||||
@font-face {
|
||||
font-family: "Poppins";
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: local("Poppins Medium"), local("Poppins-Medium"),
|
||||
url("~@/assets/fonts/poppins-v9-latin-500.woff2") format("woff2"),
|
||||
url("~static/fonts/poppins-v9-latin-500.woff2") format("woff2"),
|
||||
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url("~@/assets/fonts/poppins-v9-latin-500.woff") format("woff");
|
||||
url("~static/fonts/poppins-v9-latin-500.woff") format("woff");
|
||||
/* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
||||
|
||||
/* poppins-700 - latin */
|
||||
@font-face {
|
||||
font-family: "Poppins";
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: local("Poppins Bold"), local("Poppins-Bold"),
|
||||
url("~@/assets/fonts/poppins-v9-latin-700.woff2") format("woff2"),
|
||||
url("~static/fonts/poppins-v9-latin-700.woff2") format("woff2"),
|
||||
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url("~@/assets/fonts/poppins-v9-latin-700.woff") format("woff");
|
||||
url("~static/fonts/poppins-v9-latin-700.woff") format("woff");
|
||||
/* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
||||
|
||||
/* roboto-mono-regular - latin */
|
||||
@font-face {
|
||||
font-family: "Roboto Mono";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local("Roboto Mono"), local("RobotoMono-Regular"),
|
||||
url("~static/fonts/roboto-mono-v7-latin-regular.woff2") format("woff2"),
|
||||
/* Chrome 26+, Opera 23+, Firefox 39+ */
|
||||
url("~static/fonts/roboto-mono-v7-latin-regular.woff") format("woff");
|
||||
/* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
|
||||
}
|
||||
|
||||
@@ -1,27 +1,38 @@
|
||||
$responsiveWidth: 720px;
|
||||
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
.page-enter-active,
|
||||
.page-leave-active,
|
||||
.layout-enter-active,
|
||||
.layout-leave-active {
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.page-enter,
|
||||
.page-leave-active,
|
||||
.layout-enter,
|
||||
.layout-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
$responsiveWidth: 768px;
|
||||
|
||||
::selection {
|
||||
background-color: var(--ac-sel-color);
|
||||
background-color: var(--ac-color);
|
||||
color: var(--act-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 4px;
|
||||
background-color: var(--bg-light-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--fg-light-color);
|
||||
border-radius: 8px;
|
||||
border: 2px solid var(--bg-color);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--fg-color);
|
||||
&:hover {
|
||||
background-color: var(--fg-color);
|
||||
}
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
@@ -35,11 +46,12 @@ html {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--fg-color);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
font-size: 14px;
|
||||
font-family: "Poppins", "Roboto", "Noto", sans-serif;
|
||||
line-height: 1.5;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
@@ -47,15 +59,12 @@ body {
|
||||
user-select: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
// Make theme transition smoother.
|
||||
body.afterLoad {
|
||||
|
||||
&,
|
||||
& * {
|
||||
transition: background-color 0.2s ease-in-out, border 0.2s ease-in-out;
|
||||
}
|
||||
transition: background-color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
body.sticky-footer footer {
|
||||
@@ -66,14 +75,14 @@ a {
|
||||
display: inline-flex;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
header,
|
||||
footer {
|
||||
& > div {
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
padding: 16px 8px;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -86,8 +95,8 @@ footer {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.wrapper .content {
|
||||
min-height: 100vh;
|
||||
.wrapper .page {
|
||||
min-height: calc(100vh - 153px);
|
||||
}
|
||||
|
||||
.header,
|
||||
@@ -117,42 +126,50 @@ footer {
|
||||
|
||||
.logo {
|
||||
font-size: 22px;
|
||||
color: var(--ac-color);
|
||||
|
||||
&:hover {
|
||||
color: var(--ac-color);
|
||||
}
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.nav-first {
|
||||
.nav-first,
|
||||
.sticky-inner {
|
||||
display: flex;
|
||||
order: 1;
|
||||
flex-flow: column;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.nav-first {
|
||||
z-index: 1;
|
||||
height: 100vh;
|
||||
padding: 0 8px;
|
||||
background-color: var(--bg-light-color);
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
flex: 1;
|
||||
order: 2;
|
||||
position: relative;
|
||||
padding: 0 16px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.nav-second {
|
||||
display: flex;
|
||||
width: 10%;
|
||||
order: 3;
|
||||
// comment this to display
|
||||
// comment below this to display
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav.primary-nav {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
border-bottom: 1px solid var(--brd-color);
|
||||
|
||||
svg {
|
||||
fill: var(--fg-light-color);
|
||||
@@ -163,15 +180,17 @@ nav.primary-nav {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
padding: 16px;
|
||||
padding: 14px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--brd-color);
|
||||
background-color: var(--bg-light-color);
|
||||
color: var(--fg-light-color);
|
||||
margin: 8px;
|
||||
fill: var(--fg-light-color);
|
||||
margin: 8px 0;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
color: var(--fg-color);
|
||||
fill: var(--fg-color);
|
||||
|
||||
svg {
|
||||
fill: var(--fg-color);
|
||||
@@ -181,6 +200,7 @@ nav.primary-nav {
|
||||
&.nuxt-link-exact-active {
|
||||
background-color: var(--ac-color);
|
||||
color: var(--act-color);
|
||||
fill: var(--act-color);
|
||||
border-radius: 16px;
|
||||
|
||||
svg {
|
||||
@@ -192,6 +212,7 @@ nav.primary-nav {
|
||||
|
||||
nav.secondary-nav {
|
||||
display: flex;
|
||||
border-top: 1px dashed var(--brd-color);
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
@@ -205,11 +226,11 @@ nav.secondary-nav {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
padding: 16px;
|
||||
padding: 14px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--bg-dark-color);
|
||||
color: var(--fg-light-color);
|
||||
margin: 8px;
|
||||
margin: 8px 0;
|
||||
|
||||
&:hover {
|
||||
color: var(--fg-color);
|
||||
@@ -228,48 +249,30 @@ nav.secondary-nav {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
$responsiveWidth: 720px;
|
||||
|
||||
@media (max-width: $responsiveWidth) {
|
||||
.columns {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.nav-first {
|
||||
width: 100%;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
nav.primary-nav {
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
nav.secondary-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
h3,
|
||||
h4 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
$bgcolor: var(--tt-color);
|
||||
$fgcolor: var(--fg-color);
|
||||
display: block !important;
|
||||
z-index: 10000;
|
||||
|
||||
.tooltip-inner {
|
||||
background: black;
|
||||
color: white;
|
||||
background: $bgcolor;
|
||||
color: $fgcolor;
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
font-size: 14px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4px 24px rgba(black, 0.1);
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
@@ -278,7 +281,7 @@ h3 {
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
border-color: black;
|
||||
border-color: $bgcolor;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
@@ -343,18 +346,22 @@ h3 {
|
||||
}
|
||||
|
||||
&.popover {
|
||||
$color: #f9f9f9;
|
||||
.wrapper {
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.popover-inner {
|
||||
background: $color;
|
||||
color: black;
|
||||
padding: 24px;
|
||||
border-radius: 5px;
|
||||
background: $bgcolor;
|
||||
color: $fgcolor;
|
||||
padding: 4px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 5px 30px rgba(black, 0.1);
|
||||
max-height: 256px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
border-color: $color;
|
||||
border-color: $bgcolor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,21 +382,25 @@ h3.title {
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.info {
|
||||
margin-left: 4px;
|
||||
color: var(--fg-light-color);
|
||||
}
|
||||
|
||||
button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 4px;
|
||||
padding: 0 16px;
|
||||
padding: 6px 16px;
|
||||
border-radius: 20px;
|
||||
background-color: var(--ac-color);
|
||||
color: var(--act-color);
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
font-family: "Poppins", "Roboto", "Noto", sans-serif;
|
||||
font-weight: 700;
|
||||
transition: all 0.2s ease-in-out;
|
||||
fill: var(--act-color);
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
|
||||
span {
|
||||
@@ -397,28 +408,64 @@ button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&:not([disabled]):hover,
|
||||
&:not([disabled]):active,
|
||||
&:not([disabled]):focus {
|
||||
color: var(--act-color);
|
||||
fill: var(--act-color);
|
||||
box-shadow: inset 0 0 0 2px var(--fg-color);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&.icon {
|
||||
background-color: var(--bg-color);
|
||||
background-color: transparent;
|
||||
color: var(--fg-light-color);
|
||||
fill: var(--fg-light-color);
|
||||
border-radius: 8px;
|
||||
|
||||
&:not([disabled]):hover {
|
||||
&:not([disabled]):hover,
|
||||
&:not([disabled]):active,
|
||||
&:not([disabled]):focus {
|
||||
color: var(--fg-color);
|
||||
fill: var(--fg-color);
|
||||
box-shadow: none;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&:not([disabled]):hover {
|
||||
color: var(--act-color);
|
||||
fill: var(--act-color);
|
||||
&.primary {
|
||||
color: var(--ac-color);
|
||||
|
||||
&:not([disabled]):hover,
|
||||
&:not([disabled]):active,
|
||||
&:not([disabled]):focus {
|
||||
background-color: var(--ac-color);
|
||||
color: var(--act-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes beat {
|
||||
30% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.material-icons:active {
|
||||
animation: beat 0.5s forwards 1;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
margin: 16px 0;
|
||||
border: 1px solid var(--brd-color);
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 16px;
|
||||
transition: all 0.2s ease-in-out;
|
||||
background-color: var(--bg-dark-color);
|
||||
}
|
||||
|
||||
legend {
|
||||
@@ -474,31 +521,42 @@ fieldset.yellow legend {
|
||||
color: #f1fa8c;
|
||||
}
|
||||
|
||||
input[type="file"],
|
||||
input[type="radio"],
|
||||
.tab,
|
||||
.hide-on-large-screen,
|
||||
#installPWA,
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
kbd,
|
||||
select,
|
||||
input,
|
||||
option,
|
||||
textarea,
|
||||
pre {
|
||||
pre,
|
||||
code {
|
||||
display: inline-flex;
|
||||
margin: 4px;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-dark-color);
|
||||
color: var(--fg-color);
|
||||
font-size: 16px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
transition: all 0.2s ease-in-out;
|
||||
user-select: text;
|
||||
width: calc(100% - 8px);
|
||||
min-height: 40px;
|
||||
resize: vertical;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
&:not([readonly]):hover {
|
||||
background-color: var(--bg-dark-color);
|
||||
&:not([readonly]):not(.ace_editor):hover,
|
||||
&:not([readonly]):not(.ace_editor):active,
|
||||
&:not([readonly]):not(.ace_editor):focus {
|
||||
box-shadow: inset 0 0 0 2px var(--fg-light-color);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,22 +564,47 @@ pre {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
code {
|
||||
height: 336px;
|
||||
border-radius: 8px;
|
||||
pre.ace_editor {
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-weight: 400;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.hljs,
|
||||
.hljs-subst {
|
||||
background-color: var(--bg-dark-color) !important;
|
||||
color: var(--fg-color) !important;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
kbd,
|
||||
code,
|
||||
pre {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.select-wrapper {
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
content: "\e313";
|
||||
font-family: "Material Icons";
|
||||
top: 14px;
|
||||
right: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
height: 37px;
|
||||
background-color: var(--bg-dark-color);
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
select,
|
||||
input,
|
||||
option {
|
||||
height: 40px;
|
||||
background-color: var(--bg-color);
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
@@ -554,17 +637,17 @@ input[type="checkbox"] {
|
||||
}
|
||||
}
|
||||
|
||||
.error,
|
||||
.disabled,
|
||||
.error:not(input),
|
||||
.disabled:not(input),
|
||||
[disabled] {
|
||||
background-color: var(--err-color);
|
||||
color: var(--fg-light-color);
|
||||
fill: var(--fg-light-color);
|
||||
cursor: default;
|
||||
cursor: not-allowed;
|
||||
|
||||
&.icon {
|
||||
color: var(--bg-color);
|
||||
fill: var(--bg-color);
|
||||
color: var(--err-color);
|
||||
fill: var(--err-color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +662,11 @@ ol {
|
||||
margin: 4px 0 4px;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul li,
|
||||
@@ -586,41 +674,30 @@ ol li {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-grow: 1;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
display: inline-flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.show-on-small-screen {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media (max-width: $responsiveWidth) {
|
||||
|
||||
ul,
|
||||
ol {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
ul li,
|
||||
ol li {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.hide-on-small-screen {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.show-on-small-screen {
|
||||
display: inline-flex;
|
||||
}
|
||||
}
|
||||
|
||||
#installPWA {
|
||||
display: none;
|
||||
.show-on-large-screen {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.info-response {
|
||||
@@ -647,23 +724,6 @@ ol li {
|
||||
background-color: var(--err-color);
|
||||
}
|
||||
|
||||
.virtual-list::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
fieldset#history {
|
||||
.method-list-item {
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
font-family: 'Roboto Mono', monospace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
@@ -676,6 +736,11 @@ fieldset#history {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mono {
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
#response-details-wrapper {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
@@ -684,6 +749,7 @@ fieldset#history {
|
||||
textarea {
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.covers-response {
|
||||
@@ -699,21 +765,21 @@ fieldset#history {
|
||||
}
|
||||
|
||||
#send {
|
||||
#hidden-message {
|
||||
display: none;
|
||||
}
|
||||
// #hidden-message {
|
||||
// display: none;
|
||||
// }
|
||||
|
||||
&.show {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
z-index: 1;
|
||||
z-index: 2;
|
||||
|
||||
#hidden-message {
|
||||
display: block;
|
||||
margin-left: 4px;
|
||||
}
|
||||
// #hidden-message {
|
||||
// display: block;
|
||||
// margin-left: 4px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -722,44 +788,152 @@ section {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
div.tab {
|
||||
.tab {
|
||||
width: 100%;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
div.tab {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type="radio"] + label {
|
||||
padding: 8px 16px;
|
||||
border-bottom: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
&:hover {
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
border-color: var(--brd-color);
|
||||
}
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label {
|
||||
border-color: var(--fg-color);
|
||||
color: var(--fg-color);
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label + div.tab {
|
||||
input[type="radio"]:checked + label + .tab {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.toasted-container .toasted {
|
||||
justify-content: start !important;
|
||||
justify-content: flex-start !important;
|
||||
}
|
||||
|
||||
.toasted.info {
|
||||
background-color: var(--ac-color) !important;
|
||||
color: var(--act-color) !important;
|
||||
font-weight: 700 !important;
|
||||
}
|
||||
|
||||
.toasted.bubble .action {
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.toasted .action {
|
||||
margin-left: auto !important;
|
||||
}
|
||||
|
||||
.page-columns {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.inner-left {
|
||||
display: flex;
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.inner-right {
|
||||
display: flex;
|
||||
width: 30%;
|
||||
order: 2;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: $responsiveWidth) {
|
||||
.content {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.columns {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.nav-first {
|
||||
position: fixed;
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
background-color: var(--bg-color);
|
||||
transition: all 0.2s ease-in-out;
|
||||
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
nav.primary-nav {
|
||||
flex-flow: row nowrap;
|
||||
overflow: auto;
|
||||
justify-content: space-around;
|
||||
|
||||
a {
|
||||
background-color: transparent;
|
||||
margin: 8px;
|
||||
|
||||
&.nuxt-link-exact-active {
|
||||
background-color: transparent;
|
||||
color: var(--ac-color);
|
||||
fill: var(--ac-color);
|
||||
|
||||
svg {
|
||||
fill: var(--ac-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav.secondary-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 0 8px 68px;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
ul li,
|
||||
ol li {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.hide-on-small-screen {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hide-on-large-screen,
|
||||
.show-on-small-screen {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.sticky-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.inner-left {
|
||||
order: 0;
|
||||
}
|
||||
|
||||
.inner-right {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.toasted-container {
|
||||
margin-bottom: 68px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,91 +8,100 @@
|
||||
|
||||
// Dark is the default theme variant.
|
||||
@mixin darkTheme {
|
||||
// Dark Background color
|
||||
--bg-dark-color: rgb(41, 42, 45);
|
||||
// Background color
|
||||
--bg-color: rgb(37, 38, 40);
|
||||
// Auto-complete color
|
||||
--atc-color: rgb(49, 49, 55);
|
||||
--bg-color: rgba(32, 33, 36, 1);
|
||||
// Light Background color
|
||||
--bg-light-color: rgba(255, 255, 255, 0.02);
|
||||
// Dark Background color
|
||||
--bg-dark-color: rgba(0, 0, 0, 0.1);
|
||||
// Text color
|
||||
--fg-color: rgb(247, 248, 248);
|
||||
--fg-color: rgba(255, 255, 255, 0.9);
|
||||
// Light Text color
|
||||
--fg-light-color: rgb(150, 155, 160);
|
||||
--fg-light-color: rgba(255, 255, 255, 0.5);
|
||||
// Border color
|
||||
--brd-color: rgb(48, 47, 55);
|
||||
--brd-color: rgba(255, 255, 255, 0.05);
|
||||
// Error color
|
||||
--err-color: rgb(41, 42, 45);
|
||||
--err-color: rgba(255, 255, 255, 0.05);
|
||||
// Acent color
|
||||
--ac-color: #50fa7b;
|
||||
--ac-sel-color: rgb(80, 250, 123, 0.8);
|
||||
--ac-color: rgba(80, 250, 123, 1);
|
||||
// Active text color
|
||||
--act-color: rgb(37, 38, 40);
|
||||
--act-color: rgba(32, 33, 36, 1);
|
||||
// Auto-complete color
|
||||
--atc-color: rgba(32, 33, 36, 1);
|
||||
// Tooltip color
|
||||
--tt-color: rgba(53, 53, 53, 1);
|
||||
}
|
||||
|
||||
@mixin lightTheme {
|
||||
// Background color
|
||||
--bg-color: rgba(255, 255, 255, 1);
|
||||
// Light Background color
|
||||
--bg-light-color: rgba(0, 0, 0, 0.02);
|
||||
// Dark Background color
|
||||
--bg-dark-color: rgba(0, 0, 0, 0.02);
|
||||
// Text color
|
||||
--fg-color: rgba(0, 0, 0, 0.9);
|
||||
// Light Text color
|
||||
--fg-light-color: rgba(0, 0, 0, 0.6);
|
||||
// Border color
|
||||
--brd-color: rgba(0, 0, 0, 0.1);
|
||||
// Error color
|
||||
--err-color: rgba(0, 0, 0, 0.1);
|
||||
// Acent color
|
||||
--ac-color: rgba(80, 250, 123, 1);
|
||||
// Active text color
|
||||
--act-color: rgba(255, 255, 255, 1);
|
||||
// Auto-complete color
|
||||
--atc-color: rgba(255, 255, 255, 1);
|
||||
// Tooltip color
|
||||
--tt-color: rgba(220, 220, 220, 1);
|
||||
}
|
||||
|
||||
@mixin blackTheme {
|
||||
// Background color
|
||||
--bg-color: rgba(0, 0, 0, 1);
|
||||
// Light Background color
|
||||
--bg-light-color: rgba(255, 255, 255, 0.02);
|
||||
// Dark Background color
|
||||
--bg-dark-color: rgba(255, 255, 255, 0.02);
|
||||
// Text color
|
||||
--fg-color: rgba(255, 255, 255, 0.9);
|
||||
// Light Text color
|
||||
--fg-light-color: rgba(255, 255, 255, 0.5);
|
||||
// Border color
|
||||
--brd-color: rgba(255, 255, 255, 0.05);
|
||||
// Error color
|
||||
--err-color: rgba(255, 255, 255, 0.05);
|
||||
// Acent color
|
||||
--ac-color: rgba(80, 250, 123, 1);
|
||||
// Active text color
|
||||
--act-color: rgba(0, 0, 0, 1);
|
||||
// Auto-complete color
|
||||
--atc-color: rgba(0, 0, 0, 1);
|
||||
// Tooltip color
|
||||
--tt-color: rgba(18, 18, 18, 1);
|
||||
}
|
||||
|
||||
:root {
|
||||
@include darkTheme;
|
||||
}
|
||||
|
||||
@media(prefers-color-scheme: dark) {
|
||||
:root.auto {
|
||||
@include darkTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin lightTheme {
|
||||
// Dark Background color
|
||||
--bg-dark-color: #f6f6f6;
|
||||
// Background color
|
||||
--bg-color: #ffffff;
|
||||
// Auto-complete color
|
||||
--atc-color: #ebebeb;
|
||||
// Text color
|
||||
--fg-color: #525252;
|
||||
// Light Text color
|
||||
--fg-light-color: rgb(150, 155, 160);
|
||||
// Border color
|
||||
--brd-color: #eeeeed;
|
||||
// Error color
|
||||
--err-color: #f6f6f6;
|
||||
// Acent color
|
||||
--ac-color: #57b5f9;
|
||||
--ac-sel-color: #57b5f9;
|
||||
// Active text color
|
||||
--act-color: #ffffff;
|
||||
}
|
||||
|
||||
:root.light {
|
||||
@include lightTheme;
|
||||
}
|
||||
|
||||
@media(prefers-color-scheme: light) {
|
||||
:root.auto {
|
||||
@include lightTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin blackTheme {
|
||||
// Dark Background color
|
||||
--bg-dark-color: rgb(8, 8, 8);
|
||||
// Background color
|
||||
--bg-color: #000000;
|
||||
// Auto-complete color
|
||||
--atc-color: rgb(18, 18, 18);
|
||||
// Text color
|
||||
--fg-color: rgb(250, 250, 250);
|
||||
// Light Text color
|
||||
--fg-light-color: rgb(100, 100, 100);
|
||||
// Border color
|
||||
--brd-color: rgb(16, 16, 16);
|
||||
// Error color
|
||||
--err-color: rgb(8, 8, 8);
|
||||
// Acent color
|
||||
--ac-color: #50fa7b;
|
||||
--ac-sel-color: rgb(80, 250, 123, 0.8);
|
||||
// Active text color
|
||||
--act-color: #000000;
|
||||
}
|
||||
|
||||
:root.black {
|
||||
@include blackTheme;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root.auto {
|
||||
@include darkTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root.auto {
|
||||
@include lightTheme;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@ import * as querystring from "querystring";
|
||||
* output this: 'msg1=value1&msg2=value2'
|
||||
* @param dataArguments
|
||||
*/
|
||||
function joinDataArguments(dataArguments) {
|
||||
const joinDataArguments = dataArguments => {
|
||||
let data = "";
|
||||
dataArguments.forEach(function (argument, i) {
|
||||
dataArguments.forEach((argument, i) => {
|
||||
if (i === 0) {
|
||||
data += argument;
|
||||
} else {
|
||||
data += "&" + argument;
|
||||
data += `&${argument}`;
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
function parseCurlCommand(curlCommand) {
|
||||
const parseCurlCommand = curlCommand => {
|
||||
let newlineFound = /\r|\n/.exec(curlCommand);
|
||||
if (newlineFound) {
|
||||
// remove newlines
|
||||
@@ -47,7 +47,7 @@ function parseCurlCommand(curlCommand) {
|
||||
}
|
||||
let headers;
|
||||
|
||||
let parseHeaders = function (headerFieldName) {
|
||||
const parseHeaders = headerFieldName => {
|
||||
if (parsedArguments[headerFieldName]) {
|
||||
if (!headers) {
|
||||
headers = {};
|
||||
@@ -55,7 +55,7 @@ function parseCurlCommand(curlCommand) {
|
||||
if (!Array.isArray(parsedArguments[headerFieldName])) {
|
||||
parsedArguments[headerFieldName] = [parsedArguments[headerFieldName]];
|
||||
}
|
||||
parsedArguments[headerFieldName].forEach(function (header) {
|
||||
parsedArguments[headerFieldName].forEach(header => {
|
||||
if (header.includes("Cookie")) {
|
||||
// stupid javascript tricks: closure
|
||||
cookieString = header;
|
||||
@@ -95,17 +95,15 @@ function parseCurlCommand(curlCommand) {
|
||||
if (!Array.isArray(parsedArguments.F)) {
|
||||
parsedArguments.F = [parsedArguments.F];
|
||||
}
|
||||
parsedArguments.F.forEach(function (multipartArgument) {
|
||||
parsedArguments.F.forEach(multipartArgument => {
|
||||
// input looks like key=value. value could be json or a file path prepended with an @
|
||||
const [key, value] = multipartArgument.split("=", 2);
|
||||
multipartUploads[key] = value;
|
||||
});
|
||||
}
|
||||
if (cookieString) {
|
||||
let cookieParseOptions = {
|
||||
decode: function (s) {
|
||||
return s;
|
||||
}
|
||||
const cookieParseOptions = {
|
||||
decode: s => s
|
||||
};
|
||||
// separate out cookie headers into separate data structure
|
||||
// note: cookie is case insensitive
|
||||
@@ -174,8 +172,8 @@ function parseCurlCommand(curlCommand) {
|
||||
});
|
||||
|
||||
urlObject.search = null; // Clean out the search/query portion.
|
||||
let request = {
|
||||
url: url,
|
||||
const request = {
|
||||
url,
|
||||
urlWithoutQuery: URL.format(urlObject)
|
||||
};
|
||||
if (compressed) {
|
||||
@@ -223,6 +221,6 @@ function parseCurlCommand(curlCommand) {
|
||||
request.insecure = true;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
};
|
||||
|
||||
export default parseCurlCommand;
|
||||
|
||||
@@ -2,36 +2,39 @@ export default () => {
|
||||
//*** Determine whether or not the PWA has been installed. ***//
|
||||
|
||||
// Step 1: Check local storage
|
||||
let pwaInstalled = localStorage.getItem('pwaInstalled') === 'yes';
|
||||
let pwaInstalled = localStorage.getItem("pwaInstalled") === "yes";
|
||||
|
||||
// Step 2: Check if the display-mode is standalone. (Only permitted for PWAs.)
|
||||
if (!pwaInstalled && window.matchMedia('(display-mode: standalone)').matches) {
|
||||
localStorage.setItem('pwaInstalled', 'yes');
|
||||
if (
|
||||
!pwaInstalled &&
|
||||
window.matchMedia("(display-mode: standalone)").matches
|
||||
) {
|
||||
localStorage.setItem("pwaInstalled", "yes");
|
||||
pwaInstalled = true;
|
||||
}
|
||||
|
||||
// Step 3: Check if the navigator is in standalone mode. (Again, only permitted for PWAs.)
|
||||
if (!pwaInstalled && window.navigator.standalone === true) {
|
||||
localStorage.setItem('pwaInstalled', 'yes');
|
||||
localStorage.setItem("pwaInstalled", "yes");
|
||||
pwaInstalled = true;
|
||||
}
|
||||
|
||||
//*** If the PWA has not been installed, show the install PWA prompt.. ***//
|
||||
let deferredPrompt = null;
|
||||
window.addEventListener('beforeinstallprompt', (event) => {
|
||||
window.addEventListener("beforeinstallprompt", event => {
|
||||
deferredPrompt = event;
|
||||
|
||||
// Show the install button if the prompt appeared.
|
||||
if (!pwaInstalled) {
|
||||
document.querySelector('#installPWA').style.display = 'inline-flex';
|
||||
document.querySelector("#installPWA").style.display = "inline-flex";
|
||||
}
|
||||
});
|
||||
|
||||
// When the app is installed, remove install prompts.
|
||||
window.addEventListener('appinstalled', (event) => {
|
||||
localStorage.setItem('pwaInstalled', 'yes');
|
||||
window.addEventListener("appinstalled", event => {
|
||||
localStorage.setItem("pwaInstalled", "yes");
|
||||
pwaInstalled = true;
|
||||
document.getElementById('installPWA').style.display = 'none';
|
||||
document.getElementById("installPWA").style.display = "none";
|
||||
});
|
||||
|
||||
// When the app is uninstalled, add the prompts back
|
||||
@@ -40,13 +43,14 @@ export default () => {
|
||||
deferredPrompt.prompt();
|
||||
let outcome = await deferredPrompt.userChoice;
|
||||
|
||||
if (outcome === 'accepted') {
|
||||
console.log('Postwoman was installed successfully.')
|
||||
if (outcome === "accepted") {
|
||||
console.log("Postwoman was installed successfully.");
|
||||
} else {
|
||||
console.log('Postwoman could not be installed. (Installation rejected by user.)')
|
||||
console.log(
|
||||
"Postwoman could not be installed. (Installation rejected by user.)"
|
||||
);
|
||||
}
|
||||
deferredPrompt = null;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
39
build.js
@@ -1,12 +1,10 @@
|
||||
const axios = require("axios");
|
||||
const fs = require("fs");
|
||||
const {
|
||||
spawnSync
|
||||
} = require("child_process");
|
||||
const { spawnSync } = require("child_process");
|
||||
const runCommand = (command, args) =>
|
||||
spawnSync(command, args)
|
||||
.stdout.toString()
|
||||
.replace(/\n/g, "");
|
||||
.stdout.toString()
|
||||
.replace(/\n/g, "");
|
||||
|
||||
const FAIL_ON_ERROR = false;
|
||||
const PW_BUILD_DATA_DIR = "./.postwoman";
|
||||
@@ -21,18 +19,24 @@ try {
|
||||
|
||||
let version = {};
|
||||
// Get the current version name as the tag from Git.
|
||||
version.name = process.env.TRAVIS_TAG || runCommand("git", ["tag"]);
|
||||
version.name =
|
||||
process.env.TRAVIS_TAG ||
|
||||
runCommand("git", ["tag --sort=committerdate | tail -1"]);
|
||||
|
||||
// FALLBACK: If version.name was unset, let's grab it from GitHub.
|
||||
if (!version.name) {
|
||||
version.name = (await axios
|
||||
.get("https://api.github.com/repos/liyasthomas/postwoman/releases")
|
||||
// If we can't get it from GitHub, we'll resort to getting it from package.json
|
||||
.catch(ex => ({
|
||||
data: [{
|
||||
tag_name: require("./package.json").version
|
||||
}]
|
||||
}))).data[0]["tag_name"];
|
||||
version.name = (
|
||||
await axios
|
||||
.get("https://api.github.com/repos/liyasthomas/postwoman/releases")
|
||||
// If we can't get it from GitHub, we'll resort to getting it from package.json
|
||||
.catch(ex => ({
|
||||
data: [
|
||||
{
|
||||
tag_name: require("./package.json").version
|
||||
}
|
||||
]
|
||||
}))
|
||||
).data[0]["tag_name"];
|
||||
}
|
||||
|
||||
// Get the current version hash as the short hash from Git.
|
||||
@@ -41,10 +45,11 @@ try {
|
||||
version.variant =
|
||||
process.env.TRAVIS_BRANCH ||
|
||||
runCommand("git", ["branch"])
|
||||
.split("* ")[1]
|
||||
.split(" ")[0] + (IS_DEV_MODE ? " - DEV MODE" : "");
|
||||
if (["", "master"].includes(version.variant))
|
||||
.split("* ")[1]
|
||||
.split(" ")[0] + (IS_DEV_MODE ? " - DEV MODE" : "");
|
||||
if (["", "master"].includes(version.variant)) {
|
||||
delete version.variant;
|
||||
}
|
||||
|
||||
// Write version data into a file
|
||||
fs.writeFileSync(
|
||||
|
||||
92
components/ace-editor.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<pre ref="editor"></pre>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const DEFAULT_THEME = "twilight";
|
||||
|
||||
import ace from "ace-builds";
|
||||
import "ace-builds/webpack-resolver";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false
|
||||
},
|
||||
lang: {
|
||||
type: String,
|
||||
default: "json"
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
cacheValue: ""
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
value(value) {
|
||||
if (value !== this.cacheValue) {
|
||||
this.editor.session.setValue(value, 1);
|
||||
this.cacheValue = value;
|
||||
}
|
||||
},
|
||||
theme() {
|
||||
this.editor.setTheme("ace/theme/" + this.defineTheme());
|
||||
},
|
||||
lang(value) {
|
||||
this.editor.getSession().setMode("ace/mode/" + value);
|
||||
},
|
||||
options(value) {
|
||||
this.editor.setOptions(value);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
const editor = ace.edit(this.$refs.editor, {
|
||||
theme: "ace/theme/" + this.defineTheme(),
|
||||
mode: "ace/mode/" + this.lang,
|
||||
...this.options
|
||||
});
|
||||
|
||||
if (this.value) editor.setValue(this.value, 1);
|
||||
|
||||
this.editor = editor;
|
||||
this.cacheValue = this.value;
|
||||
|
||||
editor.on("change", () => {
|
||||
const content = editor.getValue();
|
||||
this.$emit("input", content);
|
||||
this.cacheValue = content;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
defineTheme() {
|
||||
if (this.theme) {
|
||||
return this.theme;
|
||||
} else {
|
||||
return (
|
||||
this.$store.state.postwoman.settings.THEME_ACE_EDITOR || DEFAULT_THEME
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy();
|
||||
this.editor.container.remove();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -3,7 +3,7 @@
|
||||
<input
|
||||
type="text"
|
||||
:placeholder="placeholder"
|
||||
v-model="value"
|
||||
v-model="text"
|
||||
@input="updateSuggestions"
|
||||
@keyup="updateSuggestions"
|
||||
@click="updateSuggestions"
|
||||
@@ -23,12 +23,14 @@
|
||||
@click.prevent="forceSuggestion(suggestion)"
|
||||
:class="{ active: currentSuggestionIndex === index }"
|
||||
:key="index"
|
||||
>{{ suggestion }}</li>
|
||||
>
|
||||
{{ suggestion }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.autocomplete-wrapper {
|
||||
position: relative;
|
||||
|
||||
@@ -45,20 +47,20 @@
|
||||
margin: 0 4px;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 8px 8px;
|
||||
z-index: 9999;
|
||||
transition: transform 200ms ease-out;
|
||||
transition: transform 0.2s ease-out;
|
||||
box-shadow: 0 5px 30px rgba(black, 0.1);
|
||||
|
||||
li {
|
||||
width: 100%;
|
||||
display: block;
|
||||
padding: 8px 16px;
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
white-space: pre-wrap;
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 8px 8px;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
@@ -89,25 +91,31 @@ export default {
|
||||
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: "Start typing...",
|
||||
default: "",
|
||||
required: false
|
||||
},
|
||||
|
||||
source: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
|
||||
value: {
|
||||
type: String,
|
||||
default: "",
|
||||
required: false
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
value() {
|
||||
this.$emit("input", this.value);
|
||||
text() {
|
||||
this.$emit("input", this.text);
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
value: "application/json",
|
||||
text: this.value,
|
||||
selectionStart: 0,
|
||||
suggestionsOffsetLeft: 0,
|
||||
currentSuggestionIndex: -1,
|
||||
@@ -133,10 +141,10 @@ export default {
|
||||
},
|
||||
|
||||
forceSuggestion(text) {
|
||||
let input = this.value.substring(0, this.selectionStart);
|
||||
this.value = input + text;
|
||||
let input = this.text.substring(0, this.selectionStart);
|
||||
this.text = input + text;
|
||||
|
||||
this.selectionStart = this.value.length;
|
||||
this.selectionStart = this.text.length;
|
||||
this.suggestionsVisible = true;
|
||||
this.currentSuggestionIndex = -1;
|
||||
},
|
||||
@@ -165,8 +173,8 @@ export default {
|
||||
this.currentSuggestionIndex >= 0 ? this.currentSuggestionIndex : 0
|
||||
];
|
||||
if (activeSuggestion) {
|
||||
let input = this.value.substring(0, this.selectionStart);
|
||||
this.value = input + activeSuggestion;
|
||||
let input = this.text.substring(0, this.selectionStart);
|
||||
this.text = input + activeSuggestion;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -183,7 +191,7 @@ export default {
|
||||
* @returns {default.props.source|{type, required}}
|
||||
*/
|
||||
suggestions() {
|
||||
let input = this.value.substring(0, this.selectionStart);
|
||||
let input = this.text.substring(0, this.selectionStart);
|
||||
|
||||
return (
|
||||
this.source
|
||||
@@ -195,8 +203,8 @@ export default {
|
||||
})
|
||||
// Cut off the part that's already been typed.
|
||||
.map(entry => entry.substring(this.selectionStart))
|
||||
// We only want the top 3 suggestions.
|
||||
.slice(0, 3)
|
||||
// We only want the top 6 suggestions.
|
||||
.slice(0, 6)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -22,27 +22,28 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="addNewCollection">
|
||||
<i class="material-icons">add</i>
|
||||
<span>Create</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="addNewCollection">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -22,21 +22,22 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="addNewFolder">
|
||||
<i class="material-icons">add</i>
|
||||
<span>Create</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="addNewFolder">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
@@ -44,7 +45,7 @@ export default {
|
||||
collectionIndex: Number
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -6,53 +6,82 @@
|
||||
<i class="material-icons" v-show="!showChildren">arrow_right</i>
|
||||
<i class="material-icons" v-show="showChildren">arrow_drop_down</i>
|
||||
<i class="material-icons">folder</i>
|
||||
<span>{{collection.name}}</span>
|
||||
<span>{{ collection.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeCollection" v-tooltip="'Delete collection'">
|
||||
<i class="material-icons">delete</i>
|
||||
<v-popover>
|
||||
<button class="tooltip-target icon" v-tooltip="'More'">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<button class="icon" @click="$emit('edit-collection')" v-tooltip="'Edit collection'">
|
||||
<i class="material-icons">create</i>
|
||||
</button>
|
||||
<button class="icon" @click="$emit('add-folder')" v-tooltip="'New Folder'">
|
||||
<i class="material-icons">create_new_folder</i>
|
||||
</button>
|
||||
</div>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button class="icon" @click="$emit('add-folder')" v-close-popover>
|
||||
<i class="material-icons">create_new_folder</i>
|
||||
<span>New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="$emit('edit-collection')"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">create</i>
|
||||
<span>Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeCollection" v-close-popover>
|
||||
<i class="material-icons">delete</i>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</div>
|
||||
|
||||
<div v-show="showChildren">
|
||||
<ul>
|
||||
<li v-for="(folder, index) in collection.folders" :key="folder.name">
|
||||
<folder
|
||||
v-bind:folder="folder"
|
||||
v-bind:folderIndex="index"
|
||||
v-bind:collection-index="collectionIndex"
|
||||
v-on:edit-folder="editFolder(collectionIndex, folder, index)"
|
||||
v-on:edit-request="$emit('edit-request', $event)"
|
||||
:folder="folder"
|
||||
:folderIndex="index"
|
||||
:collection-index="collectionIndex"
|
||||
@edit-folder="editFolder(collectionIndex, folder, index)"
|
||||
@edit-request="$emit('edit-request', $event)"
|
||||
/>
|
||||
</li>
|
||||
<li v-if="(collection.folders.length === 0) && (collection.requests.length === 0)">
|
||||
<li
|
||||
v-if="
|
||||
collection.folders.length === 0 && collection.requests.length === 0
|
||||
"
|
||||
>
|
||||
<label>Collection is empty</label>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li v-for="(request, index) in collection.requests" :key="index">
|
||||
<request
|
||||
v-bind:request="request"
|
||||
v-bind:collection-index="collectionIndex"
|
||||
v-bind:folder-index="-1"
|
||||
v-bind:request-index="index"
|
||||
v-on:edit-request="$emit('edit-request', { request, collectionIndex, folderIndex: undefined, requestIndex: index })"
|
||||
></request>
|
||||
:request="request"
|
||||
:collection-index="collectionIndex"
|
||||
:folder-index="-1"
|
||||
:request-index="index"
|
||||
@edit-request="
|
||||
$emit('edit-request', {
|
||||
request,
|
||||
collectionIndex,
|
||||
folderIndex: undefined,
|
||||
requestIndex: index
|
||||
})
|
||||
"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -66,13 +95,10 @@ ul li {
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import folder from "./folder";
|
||||
import request from "./request";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
folder,
|
||||
request
|
||||
folder: () => import("./folder"),
|
||||
request: () => import("./request")
|
||||
},
|
||||
props: {
|
||||
collectionIndex: Number,
|
||||
@@ -89,7 +115,7 @@ export default {
|
||||
this.showChildren = !this.showChildren;
|
||||
},
|
||||
removeCollection() {
|
||||
if (!confirm("Are you sure you want to remove this collection?")) return;
|
||||
if (!confirm("Are you sure you want to remove this Collection?")) return;
|
||||
this.$store.commit("postwoman/removeCollection", {
|
||||
collectionIndex: this.collectionIndex
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<modal v-if="show" @close="hideModel">
|
||||
<modal v-if="show" @close="hideModal">
|
||||
<div slot="header">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<h3 class="title">Edit Collection</h3>
|
||||
<div>
|
||||
<button class="icon" @click="hideModel">
|
||||
<button class="icon" @click="hideModal">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -17,26 +17,32 @@
|
||||
<div slot="body">
|
||||
<ul>
|
||||
<li>
|
||||
<input type="text" v-model="name" v-bind:placeholder="editingCollection.name" />
|
||||
<input
|
||||
type="text"
|
||||
v-model="name"
|
||||
:placeholder="editingCollection.name"
|
||||
@keyup.enter="saveCollection"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="saveCollection">
|
||||
<i class="material-icons">save</i>
|
||||
<span>Save</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="saveCollection">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
@@ -44,7 +50,7 @@ export default {
|
||||
editingCollectionIndex: Number
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -63,7 +69,7 @@ export default {
|
||||
});
|
||||
this.$emit("hide-modal");
|
||||
},
|
||||
hideModel() {
|
||||
hideModal() {
|
||||
this.$emit("hide-modal");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,26 +17,32 @@
|
||||
<div slot="body">
|
||||
<ul>
|
||||
<li>
|
||||
<input type="text" v-model="name" v-bind:placeholder="folder.name" />
|
||||
<input
|
||||
type="text"
|
||||
v-model="name"
|
||||
:placeholder="folder.name"
|
||||
@keyup.enter="editFolder"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="editFolder">
|
||||
<i class="material-icons">add</i>
|
||||
<span>Save</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="editFolder">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
@@ -46,7 +52,7 @@ export default {
|
||||
folderIndex: Number
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -18,40 +18,75 @@
|
||||
<ul>
|
||||
<li>
|
||||
<label for="selectLabel">Label</label>
|
||||
<input type="text" id="selectLabel" v-model="requestUpdateData.name" :placeholder="request.name" />
|
||||
<input
|
||||
type="text"
|
||||
id="selectLabel"
|
||||
v-model="requestUpdateData.name"
|
||||
@keyup.enter="saveRequest"
|
||||
:placeholder="request.name"
|
||||
/>
|
||||
<label for="selectCollection">Collection</label>
|
||||
<select type="text" id="selectCollection" v-model="requestUpdateData.collectionIndex">
|
||||
<option :key="undefined" :value="undefined" hidden disabled selected>Current Collection</option>
|
||||
<option
|
||||
v-for="(collection, index) in $store.state.postwoman.collections"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>{{ collection.name }}</option>
|
||||
</select>
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
type="text"
|
||||
id="selectCollection"
|
||||
v-model="requestUpdateData.collectionIndex"
|
||||
>
|
||||
<option
|
||||
:key="undefined"
|
||||
:value="undefined"
|
||||
hidden
|
||||
disabled
|
||||
selected
|
||||
>Current Collection</option
|
||||
>
|
||||
<option
|
||||
v-for="(collection, index) in $store.state.postwoman
|
||||
.collections"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
{{ collection.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<label for="selectFolder">Folder</label>
|
||||
<select type="text" id="selectFolder" v-model="requestUpdateData.folderIndex">
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option v-for="(folder, index) in folders" :key="index" :value="index">{{ folder.name }}</option>
|
||||
</select>
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
type="text"
|
||||
id="selectFolder"
|
||||
v-model="requestUpdateData.folderIndex"
|
||||
>
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option
|
||||
v-for="(folder, index) in folders"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
{{ folder.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="saveRequest">
|
||||
<i class="material-icons">save</i>
|
||||
<span>Save</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="saveRequest">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
@@ -61,7 +96,7 @@ export default {
|
||||
requestIndex: Number
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -107,7 +142,6 @@ export default {
|
||||
// pass data separately to don't depend on request's collection, folder fields
|
||||
// probably, they should be deprecated because they don't describe request itself
|
||||
this.$store.commit("postwoman/editRequest", {
|
||||
requestOld: this.$props.request,
|
||||
requestOldCollectionIndex: this.$props.collectionIndex,
|
||||
requestOldFolderIndex: this.$props.folderIndex,
|
||||
requestOldIndex: this.$props.requestIndex,
|
||||
|
||||
@@ -6,29 +6,47 @@
|
||||
<i class="material-icons" v-show="!showChildren">arrow_right</i>
|
||||
<i class="material-icons" v-show="showChildren">arrow_drop_down</i>
|
||||
<i class="material-icons">folder_open</i>
|
||||
<span>{{folder.name}}</span>
|
||||
<span>{{ folder.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeFolder" v-tooltip="'Delete folder'">
|
||||
<i class="material-icons">delete</i>
|
||||
<v-popover>
|
||||
<button class="tooltip-target icon" v-tooltip="'More'">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<button class="icon" @click="editFolder" v-tooltip="'Edit folder'">
|
||||
<i class="material-icons">edit</i>
|
||||
</button>
|
||||
</div>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button class="icon" @click="editFolder" v-close-popover>
|
||||
<i class="material-icons">edit</i>
|
||||
<span>Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeFolder" v-close-popover>
|
||||
<i class="material-icons">delete</i>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</div>
|
||||
|
||||
<div v-show="showChildren">
|
||||
<ul>
|
||||
<li v-for="(request, index) in folder.requests" :key="index">
|
||||
<request
|
||||
v-bind:request="request"
|
||||
v-bind:collection-index="collectionIndex"
|
||||
v-bind:folder-index="folderIndex"
|
||||
v-bind:request-index="index"
|
||||
v-on:edit-request="$emit('edit-request', { request, collectionIndex, folderIndex, requestIndex: index })"
|
||||
></request>
|
||||
:request="request"
|
||||
:collection-index="collectionIndex"
|
||||
:folder-index="folderIndex"
|
||||
:request-index="index"
|
||||
@edit-request="
|
||||
$emit('edit-request', {
|
||||
request,
|
||||
collectionIndex,
|
||||
folderIndex,
|
||||
requestIndex: index
|
||||
})
|
||||
"
|
||||
/>
|
||||
</li>
|
||||
<li v-if="folder.requests.length === 0">
|
||||
<label>Folder is empty</label>
|
||||
@@ -38,7 +56,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -52,8 +70,6 @@ ul li {
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import request from "./request";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
folder: Object,
|
||||
@@ -61,7 +77,7 @@ export default {
|
||||
folderIndex: Number
|
||||
},
|
||||
components: {
|
||||
request
|
||||
request: () => import("./request")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<modal v-if="show" @close="hideModel">
|
||||
<modal v-if="show" @close="hideModal">
|
||||
<div slot="header">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<h3 class="title">Import / Export Collections</h3>
|
||||
<div>
|
||||
<button class="icon" @click="hideModel">
|
||||
<button class="icon" @click="hideModal">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -18,8 +18,8 @@
|
||||
<textarea v-model="collectionJson" rows="8"></textarea>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<span>
|
||||
<button
|
||||
class="icon"
|
||||
@click="openDialogChooseFileToReplaceWith"
|
||||
@@ -34,8 +34,6 @@
|
||||
ref="inputChooseFileToReplaceWith"
|
||||
/>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class="icon"
|
||||
@click="openDialogChooseFileToImportFrom"
|
||||
@@ -50,27 +48,35 @@
|
||||
ref="inputChooseFileToImportFrom"
|
||||
/>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="icon" @click="exportJSON" v-tooltip="'Download file'">
|
||||
<i class="material-icons">get_app</i>
|
||||
<span>Export to JSON</span>
|
||||
</span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
class="icon primary"
|
||||
@click="exportJSON"
|
||||
v-tooltip="'Download file'"
|
||||
>
|
||||
Export
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
computed: {
|
||||
collectionJson() {
|
||||
@@ -78,7 +84,7 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideModel() {
|
||||
hideModal() {
|
||||
this.$emit("hide-modal");
|
||||
},
|
||||
openDialogChooseFileToReplaceWith() {
|
||||
|
||||
@@ -5,39 +5,39 @@ TODO:
|
||||
|
||||
<template>
|
||||
<div class="collections-wrapper">
|
||||
<addCollection v-bind:show="showModalAdd" v-on:hide-modal="displayModalAdd(false)"></addCollection>
|
||||
<addCollection :show="showModalAdd" @hide-modal="displayModalAdd(false)" />
|
||||
<editCollection
|
||||
v-bind:show="showModalEdit"
|
||||
v-bind:editingCollection="editingCollection"
|
||||
v-bind:editingCollectionIndex="editingCollectionIndex"
|
||||
v-on:hide-modal="displayModalEdit(false)"
|
||||
></editCollection>
|
||||
:show="showModalEdit"
|
||||
:editingCollection="editingCollection"
|
||||
:editingCollectionIndex="editingCollectionIndex"
|
||||
@hide-modal="displayModalEdit(false)"
|
||||
/>
|
||||
<addFolder
|
||||
v-bind:show="showModalAddFolder"
|
||||
v-bind:collection="editingCollection"
|
||||
v-bind:collectionIndex="editingCollectionIndex"
|
||||
v-on:hide-modal="displayModalAddFolder(false)"
|
||||
></addFolder>
|
||||
:show="showModalAddFolder"
|
||||
:collection="editingCollection"
|
||||
:collectionIndex="editingCollectionIndex"
|
||||
@hide-modal="displayModalAddFolder(false)"
|
||||
/>
|
||||
<editFolder
|
||||
v-bind:show="showModalEditFolder"
|
||||
v-bind:collection="editingCollection"
|
||||
v-bind:collectionIndex="editingCollectionIndex"
|
||||
v-bind:folder="editingFolder"
|
||||
v-bind:folderIndex="editingFolderIndex"
|
||||
v-on:hide-modal="displayModalEditFolder(false)"
|
||||
></editFolder>
|
||||
:show="showModalEditFolder"
|
||||
:collection="editingCollection"
|
||||
:collectionIndex="editingCollectionIndex"
|
||||
:folder="editingFolder"
|
||||
:folderIndex="editingFolderIndex"
|
||||
@hide-modal="displayModalEditFolder(false)"
|
||||
/>
|
||||
<editRequest
|
||||
v-bind:show="showModalEditRequest"
|
||||
v-bind:collectionIndex="editingCollectionIndex"
|
||||
v-bind:folderIndex="editingFolderIndex"
|
||||
v-bind:request="editingRequest"
|
||||
v-bind:requestIndex="editingRequestIndex"
|
||||
v-on:hide-modal="displayModalEditRequest(false)"
|
||||
></editRequest>
|
||||
:show="showModalEditRequest"
|
||||
:collectionIndex="editingCollectionIndex"
|
||||
:folderIndex="editingFolderIndex"
|
||||
:request="editingRequest"
|
||||
:requestIndex="editingRequestIndex"
|
||||
@hide-modal="displayModalEditRequest(false)"
|
||||
/>
|
||||
<importExportCollections
|
||||
v-bind:show="showModalImportExport"
|
||||
v-on:hide-modal="displayModalImportExport(false)"
|
||||
></importExportCollections>
|
||||
:show="showModalImportExport"
|
||||
@hide-modal="displayModalImportExport(false)"
|
||||
/>
|
||||
|
||||
<div class="flex-wrap">
|
||||
<div>
|
||||
@@ -47,32 +47,57 @@ TODO:
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="displayModalImportExport(true)">
|
||||
<button
|
||||
class="icon"
|
||||
@click="displayModalImportExport(true)"
|
||||
v-tooltip="'Import / Export'"
|
||||
>
|
||||
<i class="material-icons">import_export</i>
|
||||
<span>Import / Export</span>
|
||||
</button>
|
||||
<!-- <a
|
||||
href="https://github.com/liyasthomas/postwoman/wiki/Collections"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon" v-tooltip="'Wiki'">
|
||||
<i class="material-icons">help</i>
|
||||
</button>
|
||||
</a> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li v-for="(collection, index) in collections" :key="collection.name">
|
||||
<collection
|
||||
v-bind:collection-index="index"
|
||||
v-bind:collection="collection"
|
||||
v-on:edit-collection="editCollection(collection, index)"
|
||||
v-on:add-folder="addFolder(collection, index)"
|
||||
v-on:edit-folder="editFolder($event)"
|
||||
v-on:edit-request="editRequest($event)"
|
||||
></collection>
|
||||
</li>
|
||||
<li v-if="collections.length === 0">
|
||||
<label>Collections are empty</label>
|
||||
</li>
|
||||
</ul>
|
||||
<p v-if="collections.length === 0" class="info">
|
||||
Create new collection
|
||||
</p>
|
||||
<virtual-list
|
||||
class="virtual-list"
|
||||
:class="{ filled: collections.length }"
|
||||
:size="152"
|
||||
:remain="Math.min(5, collections.length)"
|
||||
>
|
||||
<ul>
|
||||
<li v-for="(collection, index) in collections" :key="collection.name">
|
||||
<collection
|
||||
:collection-index="index"
|
||||
:collection="collection"
|
||||
@edit-collection="editCollection(collection, index)"
|
||||
@add-folder="addFolder(collection, index)"
|
||||
@edit-folder="editFolder($event)"
|
||||
@edit-request="editRequest($event)"
|
||||
/>
|
||||
</li>
|
||||
<li v-if="collections.length === 0">
|
||||
<label>Collections are empty</label>
|
||||
</li>
|
||||
</ul>
|
||||
</virtual-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
.virtual-list {
|
||||
max-height: calc(100vh - 232px);
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -80,23 +105,18 @@ ul {
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import addCollection from "./addCollection";
|
||||
import addFolder from "./addFolder";
|
||||
import collection from "./collection";
|
||||
import editCollection from "./editCollection";
|
||||
import editFolder from "./editFolder";
|
||||
import editRequest from "./editRequest";
|
||||
import importExportCollections from "./importExportCollections";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
addCollection,
|
||||
addFolder,
|
||||
collection,
|
||||
editCollection,
|
||||
editFolder,
|
||||
editRequest,
|
||||
importExportCollections
|
||||
addCollection: () => import("./addCollection"),
|
||||
addFolder: () => import("./addFolder"),
|
||||
editCollection: () => import("./editCollection"),
|
||||
editFolder: () => import("./editFolder"),
|
||||
editRequest: () => import("./editRequest"),
|
||||
importExportCollections: () => import("./importExportCollections"),
|
||||
VirtualList: () => import("vue-virtual-scroll-list")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -3,21 +3,32 @@
|
||||
<div>
|
||||
<button class="icon" @click="selectRequest()" v-tooltip="'Use request'">
|
||||
<i class="material-icons">insert_drive_file</i>
|
||||
<span>{{request.name}}</span>
|
||||
<span>{{ request.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeRequest" v-tooltip="'Delete request'">
|
||||
<i class="material-icons">delete</i>
|
||||
<v-popover>
|
||||
<button class="tooltip-target icon" v-tooltip="'More'">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<button class="icon" @click="$emit('edit-request')" v-tooltip="'Edit request'">
|
||||
<i class="material-icons">edit</i>
|
||||
</button>
|
||||
</div>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button class="icon" @click="$emit('edit-request')" v-close-popover>
|
||||
<i class="material-icons">edit</i>
|
||||
<span>Edit</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="removeRequest" v-close-popover>
|
||||
<i class="material-icons">delete</i>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -22,61 +22,99 @@
|
||||
type="text"
|
||||
id="selectLabel"
|
||||
v-model="requestData.name"
|
||||
v-bind:placeholder="defaultRequestName"
|
||||
:placeholder="defaultRequestName"
|
||||
@keyup.enter="saveRequestAs"
|
||||
/>
|
||||
<label for="selectCollection">Collection</label>
|
||||
<select type="text" id="selectCollection" v-model="requestData.collectionIndex">
|
||||
<option :key="undefined" :value="undefined" hidden disabled selected>Select a Collection</option>
|
||||
<option
|
||||
v-for="(collection, index) in $store.state.postwoman.collections"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>{{ collection.name }}</option>
|
||||
</select>
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
type="text"
|
||||
id="selectCollection"
|
||||
v-model="requestData.collectionIndex"
|
||||
>
|
||||
<option
|
||||
:key="undefined"
|
||||
:value="undefined"
|
||||
hidden
|
||||
disabled
|
||||
selected
|
||||
>Select a Collection</option
|
||||
>
|
||||
<option
|
||||
v-for="(collection, index) in $store.state.postwoman
|
||||
.collections"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
{{ collection.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<label for="selectFolder">Folder</label>
|
||||
<select type="text" id="selectFolder" v-model="requestData.folderIndex">
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option v-for="(folder, index) in folders" :key="index" :value="index">{{ folder.name }}</option>
|
||||
</select>
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
type="text"
|
||||
id="selectFolder"
|
||||
v-model="requestData.folderIndex"
|
||||
>
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option
|
||||
v-for="(folder, index) in folders"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
{{ folder.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
<label for="selectRequest">Request</label>
|
||||
<select type="text" id="selectRequest" v-model="requestData.requestIndex">
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option
|
||||
v-for="(folder, index) in requests"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>{{ folder.name }}</option>
|
||||
</select>
|
||||
<span class="select-wrapper">
|
||||
<select
|
||||
type="text"
|
||||
id="selectRequest"
|
||||
v-model="requestData.requestIndex"
|
||||
>
|
||||
<option :key="undefined" :value="undefined">/</option>
|
||||
<option
|
||||
v-for="(folder, index) in requests"
|
||||
:key="index"
|
||||
:value="index"
|
||||
>
|
||||
{{ folder.name }}
|
||||
</option>
|
||||
</select>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="saveRequestAs">
|
||||
<i class="material-icons">save</i>
|
||||
<span>Save</span>
|
||||
<div class="flex-wrap">
|
||||
<span></span>
|
||||
<span>
|
||||
<button class="icon" @click="hideModal">
|
||||
Cancel
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<button class="icon primary" @click="saveRequestAs">
|
||||
Save
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</modal>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import modal from "../../components/modal";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
show: Boolean,
|
||||
editingRequest: Object
|
||||
},
|
||||
components: {
|
||||
modal
|
||||
modal: () => import("../../components/modal")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
defaultRequestName: "My New Request",
|
||||
defaultRequestName: "My Request",
|
||||
requestData: {
|
||||
name: undefined,
|
||||
collectionIndex: undefined,
|
||||
@@ -102,6 +140,12 @@ export default {
|
||||
this.$data.requestData.collectionIndex !== undefined;
|
||||
if (!userSelectedAnyCollection) return [];
|
||||
|
||||
const noCollectionAvailable =
|
||||
this.$store.state.postwoman.collections[
|
||||
this.$data.requestData.collectionIndex
|
||||
] !== undefined;
|
||||
if (!noCollectionAvailable) return [];
|
||||
|
||||
return this.$store.state.postwoman.collections[
|
||||
this.$data.requestData.collectionIndex
|
||||
].folders;
|
||||
@@ -124,6 +168,12 @@ export default {
|
||||
const collection = this.$store.state.postwoman.collections[
|
||||
this.$data.requestData.collectionIndex
|
||||
];
|
||||
const noCollectionAvailable =
|
||||
this.$store.state.postwoman.collections[
|
||||
this.$data.requestData.collectionIndex
|
||||
] !== undefined;
|
||||
if (!noCollectionAvailable) return [];
|
||||
|
||||
const requests = collection.requests;
|
||||
return requests;
|
||||
}
|
||||
|
||||
62
components/graphql/field.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="field-box">
|
||||
<div class="field-title">{{ fieldString }}</div>
|
||||
<div class="field-desc" v-if="gqlField.description">
|
||||
{{ gqlField.description }}
|
||||
</div>
|
||||
|
||||
<div class="field-deprecated" v-if="gqlField.isDeprecated">
|
||||
DEPRECATED
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.field-box {
|
||||
padding: 16px;
|
||||
margin: 4px;
|
||||
border-bottom: 1px dashed var(--brd-color);
|
||||
}
|
||||
|
||||
.field-deprecated {
|
||||
background-color: yellow;
|
||||
color: black;
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
margin: 4px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.field-desc {
|
||||
color: var(--fg-light-color);
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
gqlField: Object
|
||||
},
|
||||
|
||||
computed: {
|
||||
fieldString() {
|
||||
const args = (this.gqlField.args || []).reduce((acc, arg, index) => {
|
||||
return (
|
||||
acc +
|
||||
`${arg.name}: ${arg.type.toString()}${
|
||||
index !== this.gqlField.args.length - 1 ? ", " : ""
|
||||
}`
|
||||
);
|
||||
}, "");
|
||||
const argsString = args.length > 0 ? `(${args})` : "";
|
||||
|
||||
return `${
|
||||
this.gqlField.name
|
||||
}${argsString}: ${this.gqlField.type.toString()}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
42
components/graphql/type.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="type-box">
|
||||
<div class="type-title">{{ gqlType.name }}</div>
|
||||
<div class="type-desc" v-if="gqlType.description">
|
||||
{{ gqlType.description }}
|
||||
</div>
|
||||
|
||||
<div v-if="gqlType.getFields">
|
||||
<h5>FIELDS</h5>
|
||||
<div v-for="field in gqlType.getFields()" :key="field.name">
|
||||
<gql-field :gqlField="field" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.type-box {
|
||||
padding: 16px;
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.type-desc {
|
||||
color: var(--fg-light-color);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.type-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
"gql-field": () => import("./field")
|
||||
},
|
||||
props: {
|
||||
gqlType: {}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -6,132 +6,167 @@
|
||||
aria-label="Search"
|
||||
type="text"
|
||||
placeholder="search history"
|
||||
:readonly="history.length === 0"
|
||||
v-model="filterText"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li @click="sort_by_label()">
|
||||
<label>
|
||||
Label
|
||||
</label>
|
||||
</li>
|
||||
<li @click="sort_by_time()">
|
||||
<label>
|
||||
Time
|
||||
</label>
|
||||
</li>
|
||||
<li @click="sort_by_status_code()">
|
||||
<label>
|
||||
Status
|
||||
</label>
|
||||
</li>
|
||||
<li @click="sort_by_url()">
|
||||
<label>
|
||||
URL
|
||||
</label>
|
||||
</li>
|
||||
<li @click="sort_by_path()">
|
||||
<label>
|
||||
Path
|
||||
</label>
|
||||
</li>
|
||||
<li></li>
|
||||
</ul>
|
||||
<virtual-list
|
||||
class="virtual-list"
|
||||
:class="{filled: filteredHistory.length}"
|
||||
:size="54"
|
||||
:class="{ filled: filteredHistory.length }"
|
||||
:size="185"
|
||||
:remain="Math.min(5, filteredHistory.length)"
|
||||
>
|
||||
<ul v-for="(entry, index) in filteredHistory" :key="index" class="entry">
|
||||
<li>
|
||||
<button v-if="entry.usesScripts"
|
||||
v-tooltip="'This entry used pre-request scripts'"
|
||||
<div class="show-on-large-screen">
|
||||
<button
|
||||
class="icon"
|
||||
:class="{ stared: entry.star }"
|
||||
@click="toggleStar(index)"
|
||||
v-tooltip="{ content: !entry.star ? 'Add star' : 'Remove star' }"
|
||||
>
|
||||
<i class="material-icons">code</i>
|
||||
<i class="material-icons">
|
||||
{{ entry.star ? "star" : "star_border" }}
|
||||
</i>
|
||||
</button>
|
||||
<button v-else
|
||||
v-tooltip="'No pre-request scripts'"
|
||||
class="icon"
|
||||
>
|
||||
<i class="material-icons">http</i>
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
aria-label="Label"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.label"
|
||||
placeholder="No label"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input aria-label="Time" type="text" readonly :value="entry.time" v-tooltip="entry.date" />
|
||||
</li>
|
||||
<li class="method-list-item">
|
||||
<input
|
||||
aria-label="Method"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.method"
|
||||
:class="findEntryStatus(entry).className"
|
||||
:style="{'--status-code': entry.status}"
|
||||
/>
|
||||
<span
|
||||
class="entry-status-code"
|
||||
:class="findEntryStatus(entry).className"
|
||||
:style="{'--status-code': entry.status}"
|
||||
>{{entry.status}}</span>
|
||||
</li>
|
||||
<li>
|
||||
<input aria-label="URL" type="text" readonly :value="entry.url" />
|
||||
</li>
|
||||
<li>
|
||||
<input aria-label="Path" type="text" readonly :value="entry.path" placeholder="No path" />
|
||||
</li>
|
||||
<div class="show-on-small-screen">
|
||||
<li>
|
||||
<button
|
||||
v-tooltip="'Delete entry'"
|
||||
class="icon"
|
||||
:id="'delete-button#'+index"
|
||||
@click="deleteHistory(entry)"
|
||||
aria-label="Delete"
|
||||
>
|
||||
<i class="material-icons">delete</i>
|
||||
</button>
|
||||
<input
|
||||
aria-label="Label"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.label"
|
||||
placeholder="No label"
|
||||
class="bg-color"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<!-- <li>
|
||||
<button
|
||||
v-tooltip="'Edit entry'"
|
||||
class="icon"
|
||||
:id="'use-button#'+index"
|
||||
@click="useHistory(entry)"
|
||||
aria-label="Edit"
|
||||
v-tooltip="{
|
||||
content: !entry.usesScripts
|
||||
? 'No pre-request script'
|
||||
: 'Used pre-request script'
|
||||
}"
|
||||
>
|
||||
<i class="material-icons">edit</i>
|
||||
<i class="material-icons">
|
||||
{{ !entry.usesScripts ? "http" : "code" }}
|
||||
</i>
|
||||
</button>
|
||||
</li> -->
|
||||
<v-popover>
|
||||
<button class="tooltip-target icon" v-tooltip="'Options'">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
:id="'use-button#' + index"
|
||||
@click="useHistory(entry)"
|
||||
aria-label="Edit"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">restore</i>
|
||||
<span>Restore</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
:id="'delete-button#' + index"
|
||||
@click="deleteHistory(entry)"
|
||||
aria-label="Delete"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">delete</i>
|
||||
<span>Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</div>
|
||||
<div class="show-on-large-screen">
|
||||
<li class="method-list-item">
|
||||
<input
|
||||
aria-label="Method"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.method"
|
||||
:class="findEntryStatus(entry).className"
|
||||
:style="{ '--status-code': entry.status }"
|
||||
/>
|
||||
<span
|
||||
class="entry-status-code"
|
||||
:class="findEntryStatus(entry).className"
|
||||
:style="{ '--status-code': entry.status }"
|
||||
>{{ entry.status }}</span
|
||||
>
|
||||
</li>
|
||||
</div>
|
||||
<div class="show-on-large-screen">
|
||||
<li>
|
||||
<input
|
||||
aria-label="URL"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.url"
|
||||
placeholder="No URL"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
aria-label="Path"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.path"
|
||||
placeholder="No path"
|
||||
/>
|
||||
</li>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div v-if="showMore" class="show-on-large-screen">
|
||||
<li>
|
||||
<input
|
||||
aria-label="Time"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.time"
|
||||
v-tooltip="entry.date"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
aria-label="Duration"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.duration"
|
||||
placeholder="No duration"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
aria-label="Pre Request Script"
|
||||
type="text"
|
||||
readonly
|
||||
:value="entry.preRequestScript"
|
||||
placeholder="No pre request script"
|
||||
/>
|
||||
</li>
|
||||
</div>
|
||||
</transition>
|
||||
</ul>
|
||||
</virtual-list>
|
||||
<ul :class="{hidden: filteredHistory.length != 0 || history.length === 0 }">
|
||||
<ul
|
||||
:class="{ hidden: filteredHistory.length != 0 || history.length === 0 }"
|
||||
>
|
||||
<li>
|
||||
<label>Nothing found "{{filterText}}"</label>
|
||||
<label>Nothing found "{{ filterText }}"</label>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="history.length === 0">
|
||||
<li>
|
||||
<label>History is empty</label>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-if="history.length !== 0">
|
||||
<li v-if="!isClearingHistory">
|
||||
<p v-if="history.length === 0" class="info">
|
||||
History is empty
|
||||
</p>
|
||||
<div v-if="history.length !== 0">
|
||||
<div class="flex-wrap" v-if="!isClearingHistory">
|
||||
<button
|
||||
class="icon"
|
||||
id="clear-history-button"
|
||||
@@ -141,192 +176,326 @@
|
||||
<i class="material-icons">clear_all</i>
|
||||
<span>Clear All</span>
|
||||
</button>
|
||||
</li>
|
||||
<li v-else>
|
||||
<div class="flex-wrap">
|
||||
<label for="clear-history-button">Are you sure?</label>
|
||||
<div>
|
||||
<button class="icon" id="confirm-clear-history-button" @click="clearHistory">Yes</button>
|
||||
<button class="icon" id="reject-clear-history-button" @click="disableHistoryClearing">No</button>
|
||||
</div>
|
||||
<v-popover>
|
||||
<button class="tooltip-target icon" v-tooltip="'Sort'">
|
||||
<i class="material-icons">sort</i>
|
||||
</button>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button class="icon" @click="sort_by_label()" v-close-popover>
|
||||
<i class="material-icons">sort_by_alpha</i>
|
||||
<span>Label</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="sort_by_time()" v-close-popover>
|
||||
<i class="material-icons">access_time</i>
|
||||
<span>Time</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="sort_by_status_code()"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">assistant</i>
|
||||
<span>Status</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="sort_by_url()" v-close-popover>
|
||||
<i class="material-icons">language</i>
|
||||
<span>URL</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="sort_by_path()" v-close-popover>
|
||||
<i class="material-icons">timeline</i>
|
||||
<span>Path</span>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="showMore">
|
||||
<button class="icon" @click="sort_by_duration()" v-close-popover>
|
||||
<i class="material-icons">timer</i>
|
||||
<span>Duration</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="icon" @click="toggleCollapse()">
|
||||
<i class="material-icons">
|
||||
{{ !showMore ? "first_page" : "last_page" }}
|
||||
</i>
|
||||
<span>{{ !showMore ? "Show more" : "Hide more" }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</div>
|
||||
<div class="flex-wrap" v-else>
|
||||
<label for="clear-history-button" class="info">Are you sure?</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
id="confirm-clear-history-button"
|
||||
@click="clearHistory"
|
||||
v-tooltip="'Yes'"
|
||||
>
|
||||
<i class="material-icons">done</i>
|
||||
</button>
|
||||
<button
|
||||
class="icon"
|
||||
id="reject-clear-history-button"
|
||||
@click="disableHistoryClearing"
|
||||
v-tooltip="'No'"
|
||||
>
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</pw-section>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.virtual-list {
|
||||
[readonly] {
|
||||
cursor: default;
|
||||
}
|
||||
.virtual-list {
|
||||
max-height: calc(100vh - 284px);
|
||||
|
||||
[readonly] {
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.fade-enter,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.stared {
|
||||
color: #f8e81c !important;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
ul li,
|
||||
ol li {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.method-list-item {
|
||||
position: relative;
|
||||
|
||||
span {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
background-color: transparent;
|
||||
padding: 2px 6px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.entry {
|
||||
border-bottom: 1px dashed var(--brd-color);
|
||||
padding: 0 0 8px;
|
||||
}
|
||||
|
||||
.bg-color {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.virtual-list.filled {
|
||||
min-height: 320px;
|
||||
}
|
||||
|
||||
label {
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
color: var(--fg-color);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.virtual-list.filled {
|
||||
min-height: 200px;
|
||||
}
|
||||
.labels {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import VirtualList from "vue-virtual-scroll-list";
|
||||
import section from "./section";
|
||||
import { findStatusGroup } from "../pages/index";
|
||||
import { findStatusGroup } from "../pages/index";
|
||||
|
||||
const updateOnLocalStorage = (propertyName, property) =>
|
||||
window.localStorage.setItem(propertyName, JSON.stringify(property));
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": section,
|
||||
VirtualList
|
||||
},
|
||||
data() {
|
||||
const localStorageHistory = JSON.parse(
|
||||
window.localStorage.getItem("history")
|
||||
);
|
||||
return {
|
||||
history: localStorageHistory || [],
|
||||
filterText: "",
|
||||
showFilter: false,
|
||||
isClearingHistory: false,
|
||||
reverse_sort_label: false,
|
||||
reverse_sort_time: false,
|
||||
reverse_sort_status_code: false,
|
||||
reverse_sort_url: false,
|
||||
reverse_sort_path: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredHistory() {
|
||||
return this.history.filter(entry => {
|
||||
const filterText = this.filterText.toLowerCase();
|
||||
return Object.keys(entry).some(key => {
|
||||
let value = entry[key];
|
||||
value = typeof value !== "string" ? value.toString() : value;
|
||||
return value.toLowerCase().includes(filterText);
|
||||
});
|
||||
const updateOnLocalStorage = (propertyName, property) =>
|
||||
window.localStorage.setItem(propertyName, JSON.stringify(property));
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": () => import("./section"),
|
||||
VirtualList: () => import("vue-virtual-scroll-list")
|
||||
},
|
||||
data() {
|
||||
const localStorageHistory = JSON.parse(
|
||||
window.localStorage.getItem("history")
|
||||
);
|
||||
return {
|
||||
history: localStorageHistory || [],
|
||||
filterText: "",
|
||||
showFilter: false,
|
||||
isClearingHistory: false,
|
||||
reverse_sort_label: false,
|
||||
reverse_sort_time: false,
|
||||
reverse_sort_status_code: false,
|
||||
reverse_sort_url: false,
|
||||
reverse_sort_path: false,
|
||||
showMore: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
filteredHistory() {
|
||||
return this.history.filter(entry => {
|
||||
const filterText = this.filterText.toLowerCase();
|
||||
return Object.keys(entry).some(key => {
|
||||
let value = entry[key];
|
||||
value = typeof value !== "string" ? value.toString() : value;
|
||||
return value.toLowerCase().includes(filterText);
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearHistory() {
|
||||
this.history = [];
|
||||
this.filterText = "";
|
||||
this.disableHistoryClearing();
|
||||
updateOnLocalStorage("history", this.history);
|
||||
this.$toast.error("History Deleted", {
|
||||
icon: "delete"
|
||||
});
|
||||
},
|
||||
useHistory(entry) {
|
||||
this.$emit("useHistory", entry);
|
||||
},
|
||||
findEntryStatus(entry) {
|
||||
const foundStatusGroup = findStatusGroup(entry.status);
|
||||
return (
|
||||
foundStatusGroup || {
|
||||
className: ""
|
||||
}
|
||||
);
|
||||
},
|
||||
deleteHistory(entry) {
|
||||
this.history.splice(this.history.indexOf(entry), 1);
|
||||
if (this.history.length === 0) {
|
||||
this.filterText = "";
|
||||
}
|
||||
updateOnLocalStorage("history", this.history);
|
||||
this.$toast.error("Deleted", {
|
||||
icon: "delete"
|
||||
});
|
||||
},
|
||||
addEntry(entry) {
|
||||
this.history.push(entry);
|
||||
updateOnLocalStorage("history", this.history);
|
||||
},
|
||||
enableHistoryClearing() {
|
||||
if (!this.history || !this.history.length) return;
|
||||
this.isClearingHistory = true;
|
||||
},
|
||||
disableHistoryClearing() {
|
||||
this.isClearingHistory = false;
|
||||
},
|
||||
sort_by_time() {
|
||||
let byDate = this.history.slice(0);
|
||||
byDate.sort((a, b) => {
|
||||
let date_a = a.date.split("/");
|
||||
let date_b = b.date.split("/");
|
||||
let time_a = a.time.split(":");
|
||||
let time_b = b.time.split(":");
|
||||
let final_a = new Date(
|
||||
date_a[2],
|
||||
date_a[1],
|
||||
date_a[0],
|
||||
time_a[0],
|
||||
time_a[1],
|
||||
time_a[2]
|
||||
);
|
||||
let final_b = new Date(
|
||||
date_b[2],
|
||||
date_b[1],
|
||||
date_b[0],
|
||||
time_b[0],
|
||||
time_b[1],
|
||||
time_b[2]
|
||||
);
|
||||
if (this.reverse_sort_time) return final_b - final_a;
|
||||
else return final_a - final_b;
|
||||
});
|
||||
this.history = byDate;
|
||||
this.reverse_sort_time = !this.reverse_sort_time;
|
||||
},
|
||||
sort_by_status_code() {
|
||||
let byCode = this.history.slice(0);
|
||||
byCode.sort((a, b) => {
|
||||
if (this.reverse_sort_status_code) return b.status - a.status;
|
||||
else return a.status - b.status;
|
||||
});
|
||||
this.history = byCode;
|
||||
this.reverse_sort_status_code = !this.reverse_sort_status_code;
|
||||
},
|
||||
sort_by_url() {
|
||||
let byUrl = this.history.slice(0);
|
||||
byUrl.sort((a, b) => {
|
||||
if (this.reverse_sort_url)
|
||||
return a.url == b.url ? 0 : +(a.url < b.url) || -1;
|
||||
else return a.url == b.url ? 0 : +(a.url > b.url) || -1;
|
||||
});
|
||||
this.history = byUrl;
|
||||
this.reverse_sort_url = !this.reverse_sort_url;
|
||||
},
|
||||
sort_by_label() {
|
||||
let byLabel = this.history.slice(0);
|
||||
byLabel.sort((a, b) => {
|
||||
if (this.reverse_sort_label)
|
||||
return a.label == b.label ? 0 : +(a.label < b.label) || -1;
|
||||
else return a.label == b.label ? 0 : +(a.label > b.label) || -1;
|
||||
});
|
||||
this.history = byLabel;
|
||||
this.reverse_sort_label = !this.reverse_sort_label;
|
||||
},
|
||||
sort_by_path() {
|
||||
let byPath = this.history.slice(0);
|
||||
byPath.sort((a, b) => {
|
||||
if (this.reverse_sort_path)
|
||||
return a.path == b.path ? 0 : +(a.path < b.path) || -1;
|
||||
else return a.path == b.path ? 0 : +(a.path > b.path) || -1;
|
||||
});
|
||||
this.history = byPath;
|
||||
this.reverse_sort_path = !this.reverse_sort_path;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
clearHistory() {
|
||||
this.history = [];
|
||||
this.filterText = "";
|
||||
this.disableHistoryClearing();
|
||||
updateOnLocalStorage("history", this.history);
|
||||
this.$toast.error("History Deleted", {
|
||||
icon: "delete"
|
||||
});
|
||||
},
|
||||
useHistory(entry) {
|
||||
this.$emit("useHistory", entry);
|
||||
},
|
||||
findEntryStatus(entry) {
|
||||
const foundStatusGroup = findStatusGroup(entry.status);
|
||||
return (
|
||||
foundStatusGroup || {
|
||||
className: ""
|
||||
}
|
||||
);
|
||||
},
|
||||
deleteHistory(entry) {
|
||||
this.history.splice(this.history.indexOf(entry), 1);
|
||||
if (this.history.length === 0) {
|
||||
this.filterText = "";
|
||||
}
|
||||
updateOnLocalStorage("history", this.history);
|
||||
this.$toast.error("Deleted", {
|
||||
icon: "delete"
|
||||
});
|
||||
},
|
||||
addEntry(entry) {
|
||||
this.history.push(entry);
|
||||
updateOnLocalStorage("history", this.history);
|
||||
},
|
||||
enableHistoryClearing() {
|
||||
if (!this.history || !this.history.length) return;
|
||||
this.isClearingHistory = true;
|
||||
},
|
||||
disableHistoryClearing() {
|
||||
this.isClearingHistory = false;
|
||||
},
|
||||
sort_by_time() {
|
||||
let byDate = this.history.slice(0);
|
||||
byDate.sort((a, b) => {
|
||||
let date_a = a.date.split("/");
|
||||
let date_b = b.date.split("/");
|
||||
let time_a = a.time.split(":");
|
||||
let time_b = b.time.split(":");
|
||||
let final_a = new Date(
|
||||
date_a[2],
|
||||
date_a[1],
|
||||
date_a[0],
|
||||
time_a[0],
|
||||
time_a[1],
|
||||
time_a[2]
|
||||
);
|
||||
let final_b = new Date(
|
||||
date_b[2],
|
||||
date_b[1],
|
||||
date_b[0],
|
||||
time_b[0],
|
||||
time_b[1],
|
||||
time_b[2]
|
||||
);
|
||||
if (this.reverse_sort_time) return final_b - final_a;
|
||||
else return final_a - final_b;
|
||||
});
|
||||
this.history = byDate;
|
||||
this.reverse_sort_time = !this.reverse_sort_time;
|
||||
},
|
||||
sort_by_status_code() {
|
||||
let byCode = this.history.slice(0);
|
||||
byCode.sort((a, b) => {
|
||||
if (this.reverse_sort_status_code) return b.status - a.status;
|
||||
else return a.status - b.status;
|
||||
});
|
||||
this.history = byCode;
|
||||
this.reverse_sort_status_code = !this.reverse_sort_status_code;
|
||||
},
|
||||
sort_by_url() {
|
||||
let byUrl = this.history.slice(0);
|
||||
byUrl.sort((a, b) => {
|
||||
if (this.reverse_sort_url)
|
||||
return a.url === b.url ? 0 : +(a.url < b.url) || -1;
|
||||
else return a.url === b.url ? 0 : +(a.url > b.url) || -1;
|
||||
});
|
||||
this.history = byUrl;
|
||||
this.reverse_sort_url = !this.reverse_sort_url;
|
||||
},
|
||||
sort_by_label() {
|
||||
let byLabel = this.history.slice(0);
|
||||
byLabel.sort((a, b) => {
|
||||
if (this.reverse_sort_label)
|
||||
return a.label === b.label ? 0 : +(a.label < b.label) || -1;
|
||||
else return a.label === b.label ? 0 : +(a.label > b.label) || -1;
|
||||
});
|
||||
this.history = byLabel;
|
||||
this.reverse_sort_label = !this.reverse_sort_label;
|
||||
},
|
||||
sort_by_path() {
|
||||
let byPath = this.history.slice(0);
|
||||
byPath.sort((a, b) => {
|
||||
if (this.reverse_sort_path)
|
||||
return a.path === b.path ? 0 : +(a.path < b.path) || -1;
|
||||
else return a.path === b.path ? 0 : +(a.path > b.path) || -1;
|
||||
});
|
||||
this.history = byPath;
|
||||
this.reverse_sort_path = !this.reverse_sort_path;
|
||||
},
|
||||
sort_by_duration() {
|
||||
let byDuration = this.history.slice(0);
|
||||
byDuration.sort((a, b) => {
|
||||
if (this.reverse_sort_duration)
|
||||
return a.duration === b.duration
|
||||
? 0
|
||||
: +(a.duration < b.duration) || -1;
|
||||
else
|
||||
return a.duration === b.duration
|
||||
? 0
|
||||
: +(a.duration > b.duration) || -1;
|
||||
});
|
||||
this.history = byDuration;
|
||||
this.reverse_sort_duration = !this.reverse_sort_duration;
|
||||
},
|
||||
toggleCollapse() {
|
||||
this.showMore = !this.showMore;
|
||||
},
|
||||
toggleStar(index) {
|
||||
this.history[index]["star"] = !this.history[index]["star"];
|
||||
updateOnLocalStorage("history", this.history);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
<path
|
||||
:fill="color"
|
||||
id="path3816"
|
||||
data-old_color="#121212"
|
||||
data-old_color="#202124"
|
||||
class="active-path"
|
||||
data-original="#121212"
|
||||
data-original="#202124"
|
||||
d="M 64.601,236.822 C 64.601,394.256 192.786,612 306.001,612 412.582,612 547.4,394.256 547.4,236.822 547.4,79.388 439.322,0 306,0 172.678,0 64.601,79.388 64.601,236.822 Z m 304.12,116.415 c 29.475,-29.475 70.598,-40.195 108.552,-32.173 8.021,37.954 -2.698,79.077 -32.173,108.552 -29.475,29.475 -70.598,40.195 -108.552,32.173 -8.022,-37.955 2.698,-79.078 32.173,-108.552 z M 134.727,321.063 c 37.954,-8.021 79.077,2.698 108.552,32.173 29.475,29.475 40.195,70.598 32.173,108.552 -37.954,8.021 -79.077,-2.698 -108.552,-32.173 -29.475,-29.476 -40.194,-70.598 -32.173,-108.552 z"
|
||||
/>
|
||||
</g>
|
||||
@@ -35,7 +35,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
<style scoped lang="scss">
|
||||
#circle3814 {
|
||||
/* fill: var(--fg-color); */
|
||||
fill: transparent;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<transition name="modal-fade">
|
||||
<transition name="modal" appear>
|
||||
<div class="modal-backdrop">
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container">
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
<style scoped>
|
||||
<style scoped lang="scss">
|
||||
.modal-backdrop {
|
||||
position: fixed;
|
||||
z-index: 998;
|
||||
@@ -25,7 +25,7 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgba(0, 0, 0, 0.87);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -37,7 +37,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-grow: 1;
|
||||
max-width: 800px;
|
||||
max-width: 720px;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
@@ -45,11 +45,11 @@
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
margin: 8px;
|
||||
padding: 12px;
|
||||
padding: 16px;
|
||||
transition: all 0.2s ease;
|
||||
background-color: var(--bg-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: rgba(0, 0, 0, 0.5) 0px 16px 70px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0px 16px 70px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -61,13 +61,13 @@
|
||||
* these styles.
|
||||
*/
|
||||
|
||||
.modal-fade-enter,
|
||||
.modal-fade-leave-active {
|
||||
.modal-enter,
|
||||
.modal-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.modal-fade-enter .modal-container,
|
||||
.modal-fade-leave-active .modal-container {
|
||||
.modal-enter .modal-container,
|
||||
.modal-leave-active .modal-container {
|
||||
transform: scale(0.8);
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<template>
|
||||
<fieldset :id="label.toLowerCase()" :class="{ 'no-colored-frames': !frameColorsEnabled }">
|
||||
<fieldset
|
||||
:id="label.toLowerCase()"
|
||||
:class="{ 'no-colored-frames': !frameColorsEnabled }"
|
||||
>
|
||||
<legend @click.prevent="collapse">
|
||||
<span>{{ label }}</span>
|
||||
<i class="material-icons" v-if="isCollapsed">expand_more</i>
|
||||
<i class="material-icons" v-if="!isCollapsed">expand_less</i>
|
||||
<i class="material-icons">
|
||||
{{ isCollapsed ? "expand_more" : "expand_less" }}
|
||||
</i>
|
||||
</legend>
|
||||
<div class="collapsible" :class="{ hidden: collapsed }">
|
||||
<slot />
|
||||
|
||||
@@ -1,34 +1,42 @@
|
||||
<template>
|
||||
<div class="color" :data-color="color">
|
||||
<span :style="{backgroundColor: color}" class="preview">
|
||||
<div
|
||||
class="color"
|
||||
:data-color="color"
|
||||
:class="{ active: active }"
|
||||
v-tooltip="{ content: name || color }"
|
||||
>
|
||||
<span :style="{ backgroundColor: color }" class="preview">
|
||||
<i v-if="active" class="material-icons activeTick">done</i>
|
||||
</span>
|
||||
{{ name || color }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
<style scoped lang="scss">
|
||||
.color {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 16px 0 4px;
|
||||
margin: 4px;
|
||||
background-color: var(--bg-dark-color);
|
||||
color: var(--fg-color);
|
||||
border-radius: 20px;
|
||||
margin: 8px;
|
||||
border-radius: 100%;
|
||||
border: 3px solid var(--bg-dark-color);
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
|
||||
&.fg {
|
||||
color: var(--act-color);
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: var(--bg-dark-color);
|
||||
border: 3px solid var(--ac-color);
|
||||
}
|
||||
|
||||
&.fg.active {
|
||||
border: 3px solid var(--fg-color);
|
||||
}
|
||||
|
||||
.preview {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
border-radius: 100%;
|
||||
margin-right: 8px;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
|
||||
@@ -37,16 +45,9 @@
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.color.vibrant {
|
||||
.preview .activeTick {
|
||||
color: var(--act-color);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div @click="toggle()">
|
||||
<label class="toggle" :class="{on: on}" ref="toggle">
|
||||
<label class="toggle" :class="{ on: on }" ref="toggle">
|
||||
<span class="handle"></span>
|
||||
</label>
|
||||
<label class="caption">
|
||||
@@ -9,7 +9,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped lang="scss">
|
||||
$useBorder: false;
|
||||
$borderColor: var(--fg-light-color);
|
||||
$activeColor: var(--ac-color);
|
||||
|
||||
14
cypress.json
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"integrationFolder": "tests/e2e/integration",
|
||||
"screenshotsFolder": "tests/e2e/screenshots",
|
||||
"fixturesFolder": "tests/e2e/fixtures",
|
||||
"supportFile": "tests/e2e/support",
|
||||
"pluginsFile": false,
|
||||
"video": false
|
||||
"baseUrl": "http://localhost:3000",
|
||||
"integrationFolder": "tests/e2e/integration",
|
||||
"screenshotsFolder": "tests/e2e/screenshots",
|
||||
"fixturesFolder": "tests/e2e/fixtures",
|
||||
"supportFile": "tests/e2e/support",
|
||||
"pluginsFile": false,
|
||||
"video": false
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
/* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */
|
||||
"rules": {
|
||||
".read": false,
|
||||
".write": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
export default {
|
||||
name: "textareaAutoHeight",
|
||||
update(element) {
|
||||
if (element.scrollHeight !== element.clientHeight) {
|
||||
element.style.minHeight = `${element.scrollHeight}px`;
|
||||
update({ scrollHeight, clientHeight, style }) {
|
||||
if (scrollHeight !== clientHeight) {
|
||||
style.minHeight = `${scrollHeight}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ services:
|
||||
- "./plugins:/app/plugins"
|
||||
- "./static:/app/static"
|
||||
- "./store:/app/store"
|
||||
- "./components:/app/components"
|
||||
ports:
|
||||
- "3000:3000"
|
||||
command: "npm run dev"
|
||||
|
||||
15
docs/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
||||
<title>Postwoman</title>
|
||||
<meta http-equiv="refresh" content="0; url=https://postwoman.io" />
|
||||
<link rel="canonical" href="https://postwoman.io" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
Redirecting to postwoman.io
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,4 @@
|
||||
const functions = require('firebase-functions');
|
||||
// const functions = require('firebase-functions');
|
||||
|
||||
// // Create and Deploy Your First Cloud Functions
|
||||
// // https://firebase.google.com/docs/functions/write-firebase-functions
|
||||
|
||||
@@ -5,13 +5,16 @@ export default function getEnvironmentVariablesFromScript(script) {
|
||||
// for security and control purposes, this is the only way a pre-request script should modify variables.
|
||||
let pw = {
|
||||
environment: {
|
||||
set: (key, value) => _variables[key] = value,
|
||||
set: (key, value) => (_variables[key] = value)
|
||||
},
|
||||
env: {
|
||||
set: (key, value) => (_variables[key] = value)
|
||||
}
|
||||
// globals that the script is allowed to have access to.
|
||||
};
|
||||
|
||||
// run pre-request script within this function so that it has access to the pw object.
|
||||
(new Function('pw', script))(pw);
|
||||
new Function("pw", script)(pw);
|
||||
|
||||
return _variables;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export default function parseTemplateString(string, variables) {
|
||||
if(!variables || !string) {
|
||||
return string;
|
||||
}
|
||||
const searchTerm = /<<([^>]*)>>/g; // "<<myVariable>>"
|
||||
return string.replace(searchTerm, (match, p1) => variables[p1] || '');
|
||||
if (!variables || !string) {
|
||||
return string;
|
||||
}
|
||||
const searchTerm = /<<([^>]*)>>/g; // "<<myVariable>>"
|
||||
return string.replace(searchTerm, (match, p1) => variables[p1] || "");
|
||||
}
|
||||
|
||||
90
lang/de-DE.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Startseite",
|
||||
realtime: "Echtzeit",
|
||||
graphql: "GraphQL",
|
||||
settings: "Einstellungen",
|
||||
request: "Anfrage",
|
||||
install_pwa: "PWA installieren",
|
||||
support_us: "Unterstütze uns",
|
||||
tweet: "Twittern",
|
||||
options: "Optionen",
|
||||
communication: "Kommunikation",
|
||||
endpoint: "Endpunkt",
|
||||
schema: "Schema",
|
||||
theme: "Design",
|
||||
subscribe: "Abonnieren",
|
||||
choose_language: "Sprache auswählen",
|
||||
shortcuts: "Tastenkombinationen",
|
||||
send_request: "Anfrage senden",
|
||||
save_to_collections: "In Sammlungen speichern",
|
||||
copy_request_link: "Anfragelink kopieren",
|
||||
reset_request: "Anfrage zurücksetzen",
|
||||
support_us_on: "Unterstütze uns auf",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "JavaScript-Code",
|
||||
method: "Methode",
|
||||
path: "Pfad",
|
||||
label: "Beschriftung",
|
||||
again: "Wiederholen",
|
||||
content_type: "Content-Typ",
|
||||
raw_input: "Rohdaten-Eingabe",
|
||||
parameter_list: "Parameterliste",
|
||||
raw_request_body: "Rohdaten der Anfrage",
|
||||
show_code: "Code zeigen",
|
||||
hide_code: "Code ausblenden",
|
||||
show_prerequest_script: "Preanfrageskript anzeigen",
|
||||
hide_prerequest_script: "Preanfrageskript ausblenden",
|
||||
authentication: "Authentifizierung",
|
||||
authentication_type: "Authentifizierungs-Typ",
|
||||
include_in_url: "In URL einfügen",
|
||||
parameters: "Parameter",
|
||||
expand_response: "Antwort ausklappen",
|
||||
collapse_response: "Antwort einklappen",
|
||||
hide_preview: "Vorschau verstecken",
|
||||
preview_html: "HTML-Vorschau",
|
||||
history: "Verlauf",
|
||||
collections: "Kollektionen",
|
||||
import_curl: "cURL importieren",
|
||||
import: "Importieren",
|
||||
generate_code: "Code generieren",
|
||||
request_type: "Anfrage-Typ",
|
||||
generated_code: "Generierter Code",
|
||||
status: "Status",
|
||||
headers: "Headers",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(warte auf Verbindung)",
|
||||
message: "Nachricht",
|
||||
sse: "SSE",
|
||||
server: "Server",
|
||||
events: "Ereignisse",
|
||||
url: "URL",
|
||||
get_schema: "Schema abrufen",
|
||||
header_list: "Headerliste",
|
||||
add_new: "Neu hinzufügen",
|
||||
response: "Antwort",
|
||||
query: "Abfrage",
|
||||
queries: "Abfragen",
|
||||
query_variables: "Variablen",
|
||||
mutations: "Mutationen",
|
||||
subscriptions: "Abonnements",
|
||||
types: "Typen",
|
||||
send: "Senden",
|
||||
background: "Hintergrund",
|
||||
color: "Farbe",
|
||||
labels: "Bezeichner",
|
||||
multi_color: "Mehrfarbig",
|
||||
enabled: "Aktiviert",
|
||||
disabled: "Deaktiviert",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Postwomans offizieller Proxy wird durch ApolloTV bereitgestellt.",
|
||||
read_the: "Lies die",
|
||||
apollotv_privacy_policy: "ApolloTV Datenschutzerklärung",
|
||||
contact_us: "Kontaktiere uns",
|
||||
connect: "Verbinden",
|
||||
disconnect: "Trennen",
|
||||
start: "Start",
|
||||
stop: "Stopp"
|
||||
};
|
||||
90
lang/en-US.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Home",
|
||||
realtime: "Realtime",
|
||||
graphql: "GraphQL",
|
||||
settings: "Settings",
|
||||
request: "Request",
|
||||
install_pwa: "Install PWA",
|
||||
support_us: "Support us",
|
||||
tweet: "Tweet",
|
||||
options: "Options",
|
||||
communication: "Communication",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Schema",
|
||||
theme: "Theme",
|
||||
subscribe: "Subscribe",
|
||||
choose_language: "Choose Language",
|
||||
shortcuts: "Shortcuts",
|
||||
send_request: "Send Request",
|
||||
save_to_collections: "Save to Collections",
|
||||
copy_request_link: "Copy Request Link",
|
||||
reset_request: "Reset Request",
|
||||
support_us_on: "Support us on",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "JavaScript Code",
|
||||
method: "Method",
|
||||
path: "Path",
|
||||
label: "Label",
|
||||
again: "Again",
|
||||
content_type: "Content Type",
|
||||
raw_input: "Raw input",
|
||||
parameter_list: "Parameter List",
|
||||
raw_request_body: "Raw Request Body",
|
||||
show_code: "Show Code",
|
||||
hide_code: "Hide Code",
|
||||
show_prerequest_script: "Show Pre-Request Script",
|
||||
hide_prerequest_script: "Hide Pre-Request Script",
|
||||
authentication: "Authentication",
|
||||
authentication_type: "Authentication type",
|
||||
include_in_url: "Include in URL",
|
||||
parameters: "Parameters",
|
||||
expand_response: "Expand response",
|
||||
collapse_response: "Collapse response",
|
||||
hide_preview: "Hide Preview",
|
||||
preview_html: "Preview HTML",
|
||||
history: "History",
|
||||
collections: "Collections",
|
||||
import_curl: "Import cURL",
|
||||
import: "Import",
|
||||
generate_code: "Generate code",
|
||||
request_type: "Request type",
|
||||
generated_code: "Generated code",
|
||||
status: "Status",
|
||||
headers: "Headers",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(waiting for connection)",
|
||||
message: "Message",
|
||||
sse: "SSE",
|
||||
server: "Server",
|
||||
events: "Events",
|
||||
url: "URL",
|
||||
get_schema: "Get schema",
|
||||
header_list: "Header list",
|
||||
add_new: "Add new",
|
||||
response: "Response",
|
||||
query: "Query",
|
||||
queries: "Queries",
|
||||
query_variables: "Variables",
|
||||
mutations: "Mutations",
|
||||
subscriptions: "Subscriptions",
|
||||
types: "Types",
|
||||
send: "Send",
|
||||
background: "Background",
|
||||
color: "Color",
|
||||
labels: "Labels",
|
||||
multi_color: "Multi-color",
|
||||
enabled: "Enabled",
|
||||
disabled: "Disabled",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Postwoman's Official Proxy is hosted by ApolloTV.",
|
||||
read_the: "Read the",
|
||||
apollotv_privacy_policy: "ApolloTV privacy policy",
|
||||
contact_us: "Contact us",
|
||||
connect: "Connect",
|
||||
disconnect: "Disconnect",
|
||||
start: "Start",
|
||||
stop: "Stop"
|
||||
};
|
||||
90
lang/es-ES.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Inicio",
|
||||
realtime: "Tiempo real",
|
||||
graphql: "GraphQL",
|
||||
settings: "Ajustes",
|
||||
request: "Petición",
|
||||
install_pwa: "Instalar PWA",
|
||||
support_us: "Ayúdanos",
|
||||
tweet: "Tweet",
|
||||
options: "Opciones",
|
||||
communication: "Comunicación",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Esquema",
|
||||
theme: "Tema",
|
||||
subscribe: "Subscribirse",
|
||||
choose_language: "Seleccione un idioma",
|
||||
shortcuts: "Atajos",
|
||||
send_request: "Enviar petición",
|
||||
save_to_collections: "Guardar en las Colecciones",
|
||||
copy_request_link: "Copiar enlace de la petición",
|
||||
reset_request: "Reiniciar Petición",
|
||||
support_us_on: "Ayúdanos en",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "Código JavaScript",
|
||||
method: "Método",
|
||||
path: "Ruta",
|
||||
label: "Etiqueta",
|
||||
again: "De nuevo",
|
||||
content_type: "Tipo de Contenido",
|
||||
raw_input: "Datos sin Procesar",
|
||||
parameter_list: "Lista de Parámetros",
|
||||
raw_request_body: "Cuerpo de la Solicitud sin Procesar",
|
||||
show_code: "Mostrar el código",
|
||||
hide_code: "Ocultar el código",
|
||||
show_prerequest_script: "Mostrar Script pre solicitud",
|
||||
hide_prerequest_script: "Ocultar Script pre solicitud",
|
||||
authentication: "Autenticación",
|
||||
authentication_type: "Tipo de autenticación",
|
||||
include_in_url: "Incluir en el URL",
|
||||
parameters: "Parámetros",
|
||||
expand_response: "Ampliar Respuesta",
|
||||
collapse_response: "Contraer Respuesta",
|
||||
hide_preview: "Ocultar la vista previa",
|
||||
preview_html: "Vista Previa del HTML",
|
||||
history: "Historial",
|
||||
collections: "Colecciones",
|
||||
import_curl: "Importar cURL",
|
||||
import: "Importar",
|
||||
generate_code: "Generar código",
|
||||
request_type: "Tipo de Petición",
|
||||
generated_code: "Código Generado",
|
||||
status: "Estado",
|
||||
headers: "Cabeceras",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(esperando por conexión)",
|
||||
message: "Mensaje",
|
||||
sse: "SSE",
|
||||
server: "Servidor",
|
||||
events: "Eventos",
|
||||
url: "URL",
|
||||
get_schema: "Obtener esquema",
|
||||
header_list: "Lista de Cabeceras",
|
||||
add_new: "Agregar nuevo",
|
||||
response: "Respuesta",
|
||||
query: "Consulta",
|
||||
queries: "Consultas",
|
||||
query_variables: "Variables",
|
||||
mutations: "Mutaciones",
|
||||
subscriptions: "Subscripciones",
|
||||
types: "Tipos",
|
||||
send: "Enviar",
|
||||
background: "Fondo",
|
||||
color: "Color",
|
||||
labels: "Etiquetas",
|
||||
multi_color: "Multicolor",
|
||||
enabled: "Habilitado",
|
||||
disabled: "Deshabilitado",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Proxy Oficial de Postwoman está hospedado en ApolloTV.",
|
||||
read_the: "Leer la",
|
||||
apollotv_privacy_policy: "Política de Privacidad de ApolloTV",
|
||||
contact_us: "Contáctenos",
|
||||
connect: "Conectar",
|
||||
disconnect: "Desconectar",
|
||||
start: "Comienzo",
|
||||
stop: "Detener"
|
||||
};
|
||||
90
lang/fa-IR.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "خانه",
|
||||
realtime: "بلادرنگ",
|
||||
graphql: "GraphQL",
|
||||
settings: "تنظیمات",
|
||||
request: "درخواست",
|
||||
install_pwa: "نصب PWA",
|
||||
support_us: "از ما حمایت کنید",
|
||||
tweet: "Tweet",
|
||||
options: "گزینهها",
|
||||
communication: "ارتباط",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Schema",
|
||||
theme: "پوسته",
|
||||
subscribe: "اشتراک",
|
||||
choose_language: "تغییر زبان",
|
||||
shortcuts: "میانبرها",
|
||||
send_request: "ارسال درخواست",
|
||||
save_to_collections: "ذخیره در کلکسیون",
|
||||
copy_request_link: "کپی لینک درخواست",
|
||||
reset_request: "بازنشانی درخواست",
|
||||
support_us_on: "حمایت از ما از طریق",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "کد JavaScript",
|
||||
method: "متد",
|
||||
path: "مسیر",
|
||||
label: "برچسب",
|
||||
again: "دوباره",
|
||||
content_type: "Content Type",
|
||||
raw_input: "ورودی raw",
|
||||
parameter_list: "لیست پارامترها",
|
||||
raw_request_body: "Raw Request Body",
|
||||
show_code: "نمایش کد",
|
||||
hide_code: "عدم نمایش کد",
|
||||
show_prerequest_script: "Show Pre-Request Script",
|
||||
hide_prerequest_script: "Hide Pre-Request Script",
|
||||
authentication: "Authentication",
|
||||
authentication_type: "Authentication type",
|
||||
include_in_url: "در URL گنجانده شود",
|
||||
parameters: "پارامترها",
|
||||
expand_response: "نمایش کامل پاسخ",
|
||||
collapse_response: "نمایش مختصر پاسخ",
|
||||
hide_preview: "مخفی کردن نمایش",
|
||||
preview_html: "نمایش HTML",
|
||||
history: "تاریخچه",
|
||||
collections: "کلکسیون",
|
||||
import_curl: "وارد کردن cURL",
|
||||
import: "وارد کردن",
|
||||
generate_code: "تولید کد",
|
||||
request_type: "Request type",
|
||||
generated_code: "کد تولید شده",
|
||||
status: "Status",
|
||||
headers: "Headers",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(منتظر برقراری اتصال)",
|
||||
message: "پیام",
|
||||
sse: "SSE",
|
||||
server: "سرور",
|
||||
events: "رویداد",
|
||||
url: "URL",
|
||||
get_schema: "دریافت Schema",
|
||||
header_list: "لیست Header",
|
||||
add_new: "افزودن",
|
||||
response: "Response",
|
||||
query: "Query",
|
||||
queries: "Queries",
|
||||
query_variables: "Variables",
|
||||
mutations: "Mutations",
|
||||
subscriptions: "Subscriptions",
|
||||
types: "Types",
|
||||
send: "ارسال",
|
||||
background: "پس زمینه",
|
||||
color: "رنگ",
|
||||
labels: "برچسبها",
|
||||
multi_color: "چند رنگی",
|
||||
enabled: "فعال",
|
||||
disabled: "غیر فعال",
|
||||
proxy: "پراکسی",
|
||||
postwoman_official_proxy_hosting:
|
||||
"پراکسی Postwoman برروی هاست ApolloTV قرار دارد.",
|
||||
read_the: "بخوانید",
|
||||
apollotv_privacy_policy: "خط مشی رازداری ApolloTV",
|
||||
contact_us: "Contact us",
|
||||
connect: "Connect",
|
||||
disconnect: "Disconnect",
|
||||
start: "Start",
|
||||
stop: "Stop"
|
||||
};
|
||||
90
lang/fr-FR.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Accueil",
|
||||
realtime: "Temps réel",
|
||||
graphql: "GraphQL",
|
||||
settings: "Paramètres",
|
||||
request: "Request",
|
||||
install_pwa: "Installer la PWA",
|
||||
support_us: "Nous supporter",
|
||||
tweet: "Tweeter",
|
||||
options: "Options",
|
||||
communication: "Communication",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Schéma",
|
||||
theme: "Thème",
|
||||
subscribe: "S'inscrire",
|
||||
choose_language: "Sélectionner une langue",
|
||||
shortcuts: "Raccourcis",
|
||||
send_request: "Envoyer la requête",
|
||||
save_to_collections: "Sauvegarder dans les collections",
|
||||
copy_request_link: "Copier le lien de la requête",
|
||||
reset_request: "Réinitialiser la requête",
|
||||
support_us_on: "Supportez-nous sur",
|
||||
open_collective: "Ouvrir Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "Code JavaScript",
|
||||
method: "Méthode",
|
||||
path: "Chemin d'accès",
|
||||
label: "Libellé",
|
||||
again: "Réessayer",
|
||||
content_type: "Type de contenu",
|
||||
raw_input: "Texte brut",
|
||||
parameter_list: "Liste des paramètres",
|
||||
raw_request_body: "Corps de la requête en texte brut",
|
||||
show_code: "Afficher le code",
|
||||
hide_code: "Masquer le code",
|
||||
show_prerequest_script: "Afficher le script de pré-requête",
|
||||
hide_prerequest_script: "Masquer le script de pré-requête",
|
||||
authentication: "Authentification",
|
||||
authentication_type: "Type d'authentification",
|
||||
include_in_url: "Inclure dans l'URL",
|
||||
parameters: "Paramètres",
|
||||
expand_response: "Agrandir la réponse",
|
||||
collapse_response: "Réduire la réponse",
|
||||
hide_preview: "Masquer la prévisualisation",
|
||||
preview_html: "Prévisualiser le HTML",
|
||||
history: "Historique",
|
||||
collections: "Collections",
|
||||
import_curl: "Importer en cURL",
|
||||
importer: "Importer",
|
||||
generate_code: "Générer le code",
|
||||
request_type: "Type de requête",
|
||||
generated_code: "Code généré",
|
||||
status: "Statut",
|
||||
headers: "En-têtes",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(en attente de connexion)",
|
||||
message: "Message",
|
||||
sse: "SSE",
|
||||
server: "Serveur",
|
||||
events: "Évènements",
|
||||
url: "URL",
|
||||
get_schema: "Récuperer le schéma",
|
||||
header_list: "Liste d'en-têtes",
|
||||
add_new: "Ajouter",
|
||||
response: "Réponse",
|
||||
query: "Requête",
|
||||
queries: "Requêtes",
|
||||
query_variables: "Variables",
|
||||
mutations: "Mutations",
|
||||
subscriptions: "Abonnements",
|
||||
types: "Types",
|
||||
send: "Envoyer",
|
||||
background: "Arrière-plan",
|
||||
color: "Couleur",
|
||||
labels: "Libellés",
|
||||
multi_color: "Multi-couleurs",
|
||||
enabled: "Activé",
|
||||
disabled: "Désactivé",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Le proxy officiel de Postwoman est hébergé par ApolloTV.",
|
||||
read_the: "Lire la",
|
||||
apollotv_privacy_policy: "politique de confidentialité ApolloTV",
|
||||
contact_us: "Contactez nous",
|
||||
connect: "Relier",
|
||||
disconnect: "Déconnecter",
|
||||
start: "Début",
|
||||
stop: "Arrêtez"
|
||||
};
|
||||
90
lang/id-ID.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Beranda",
|
||||
realtime: "Waktu Nyata",
|
||||
graphql: "GraphQL",
|
||||
settings: "Pengaturan",
|
||||
request: "Permintaan",
|
||||
install_pwa: "Pasang PWA",
|
||||
support_us: "Dukung kami",
|
||||
tweet: "Cuitkan",
|
||||
options: "Opsi",
|
||||
communication: "Komunikasi",
|
||||
endpoint: "Titik Akhir",
|
||||
schema: "Skema",
|
||||
theme: "Tema",
|
||||
subscribe: "Berlangganan",
|
||||
choose_language: "Pilih Bahasa",
|
||||
shortcuts: "Pintasan",
|
||||
send_request: "Kirim Permintaan",
|
||||
save_to_collections: "Simpan ke Koleksi",
|
||||
copy_request_link: "Salin Tautan Permintaan",
|
||||
reset_request: "Atur Ulang Permintaan",
|
||||
support_us_on: "Dukung kami di",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "Paypal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "Kode Javascript",
|
||||
method: "Metode",
|
||||
path: "Lintasan",
|
||||
label: "Label",
|
||||
again: "Lagi",
|
||||
content_type: "Jenis Konten",
|
||||
raw_input: "Masukan mentah",
|
||||
parameter_list: "Daftar parameter",
|
||||
raw_request_body: "Badan Permintaan Mentah",
|
||||
show_code: "Tampilkan Kode",
|
||||
hide_code: "Sembunyikan Kode",
|
||||
show_prerequest_script: "Tampilkan Skrip Pra-Permintaan",
|
||||
hide_prerequest_script: "Sembunyikan Skrip Pra-Permintaan",
|
||||
authentication: "Autentikasi",
|
||||
authentication_type: "Jenis Autentikasi",
|
||||
include_in_url: "Sertakan di URL",
|
||||
parameters: "Parameter",
|
||||
expand_response: "Bentangkan Balasan",
|
||||
collapse_response: "Ciutkan Balasan",
|
||||
hide_preview: "Sembunyikan Pratinjau",
|
||||
preview_html: "Pratinjau HTML",
|
||||
history: "Riwayat",
|
||||
collections: "Koleksi",
|
||||
import_curl: "Impor cURL",
|
||||
import: "Impor",
|
||||
generate_code: "Hasilkan kode",
|
||||
request_type: "Jenis permintaan",
|
||||
generated_code: "Kode yang dihasilkan",
|
||||
status: "Status",
|
||||
headers: "Header",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(Menunggu sambungan)",
|
||||
message: "Pesan",
|
||||
sse: "SSE",
|
||||
server: "Peladen",
|
||||
events: "Kejadian",
|
||||
url: "URL",
|
||||
get_schema: "Ambil skema",
|
||||
header_list: "Daftar header",
|
||||
add_new: "Tambah baru",
|
||||
response: "Balasan",
|
||||
query: "Kueri",
|
||||
queries: "Kueri",
|
||||
query_variables: "Variables",
|
||||
mutations: "Mutasi",
|
||||
subscriptions: "Langganan",
|
||||
types: "Jenis",
|
||||
send: "Kirim",
|
||||
background: "Latar belakang",
|
||||
color: "Warna",
|
||||
labels: "Label",
|
||||
multi_color: "Warna beragam",
|
||||
enabled: "diaktifkan",
|
||||
disabled: "dinonaktifkan",
|
||||
proxy: "Proksi",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Proksi Resmi Postwoman dalam penginangan ApolloTV.",
|
||||
read_the: "Bacalah",
|
||||
apollotv_privacy_policy: "kebijakan privasi ApolloTV",
|
||||
contact_us: "Hubungi kami",
|
||||
connect: "Menghubungkan",
|
||||
disconnect: "Memutuskan",
|
||||
start: "Mulai",
|
||||
stop: "Berhenti"
|
||||
};
|
||||
90
lang/ja-JP.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "ホーム",
|
||||
realtime: "リアルタイム",
|
||||
graphql: "GraphQL",
|
||||
settings: "設定",
|
||||
request: "リクエスト",
|
||||
install_pwa: "PWAをインストール",
|
||||
support_us: "寄付",
|
||||
tweet: "ツイート",
|
||||
options: "オプション",
|
||||
communication: "通信",
|
||||
endpoint: "エンドポイント",
|
||||
schema: "スキーマ",
|
||||
theme: "テーマ",
|
||||
subscribe: "登録",
|
||||
choose_language: "言語の選択",
|
||||
shortcuts: "ショートカット",
|
||||
send_request: "リクエストを送信",
|
||||
save_to_collections: "コレクションに保存",
|
||||
copy_request_link: "リクエストURLをコピー",
|
||||
reset_request: "リクエストをリセット",
|
||||
support_us_on: "以下より寄付",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "JavaScriptコード",
|
||||
method: "メソッド",
|
||||
path: "パス",
|
||||
label: "ラベル",
|
||||
again: "",
|
||||
content_type: "Content Type",
|
||||
raw_input: "Raw入力",
|
||||
parameter_list: "パラメータリスト",
|
||||
raw_request_body: "Rawリクエストボディー",
|
||||
show_code: "コードを表示",
|
||||
hide_code: "コードを非表示",
|
||||
show_prerequest_script: "プレリクエストスクリプトを表示",
|
||||
hide_prerequest_script: "プレリクエストスクリプトを非表示",
|
||||
authentication: "認証",
|
||||
authentication_type: "認証タイプ",
|
||||
include_in_url: "URLに含む",
|
||||
parameters: "パラメータ",
|
||||
expand_response: "レスポンスを広げる",
|
||||
collapse_response: "レスポンスを狭める",
|
||||
hide_preview: "プレビューしない",
|
||||
preview_html: "HTMLプレビュー表示",
|
||||
history: "履歴",
|
||||
collections: "コレクション",
|
||||
import_curl: "cURLをインポート",
|
||||
import: "インポート",
|
||||
generate_code: "コード生成",
|
||||
request_type: "リクエストタイプ",
|
||||
generated_code: "生成されたコード",
|
||||
status: "ステータス",
|
||||
headers: "ヘッダー",
|
||||
websocket: "ウェブソケット",
|
||||
waiting_for_connection: "(接続待ち)",
|
||||
message: "メッセージ",
|
||||
sse: "SSE",
|
||||
server: "サーバ",
|
||||
events: "イベント",
|
||||
url: "URL",
|
||||
get_schema: "スキーマを取得",
|
||||
header_list: "ヘッダーリスト",
|
||||
add_new: "追加",
|
||||
response: "レスポンス",
|
||||
query: "クエリ",
|
||||
queries: "クエリ",
|
||||
query_variables: "変数 (へんすう)",
|
||||
mutations: "ミューテーション",
|
||||
subscriptions: "サブスクリプション",
|
||||
types: "タイプ",
|
||||
send: "送信",
|
||||
background: "背景",
|
||||
color: "色",
|
||||
labels: "ラベル",
|
||||
multi_color: "マルチカラー",
|
||||
enabled: "有効",
|
||||
disabled: "無効",
|
||||
proxy: "プロキシ",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Postwomanの公式プロキシは、Apollo TVがホストしています。",
|
||||
read_the: "プライバシーポリシー",
|
||||
apollotv_privacy_policy: "を読む",
|
||||
contact_us: "お問い合わせ",
|
||||
connect: "つなぐ",
|
||||
disconnect: "切断する",
|
||||
start: "開始",
|
||||
stop: "やめる"
|
||||
};
|
||||
89
lang/pt-BR.js
Normal file
@@ -0,0 +1,89 @@
|
||||
export default {
|
||||
home: "Home",
|
||||
realtime: "Tempo real",
|
||||
graphql: "GraphQL",
|
||||
settings: "Configurações",
|
||||
request: "Request",
|
||||
install_pwa: "Instalar PWA",
|
||||
support_us: "Nos ajude",
|
||||
tweet: "Tweet",
|
||||
options: "Opções",
|
||||
communication: "Comunicação",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Schema",
|
||||
theme: "Tema",
|
||||
subscribe: "Subscribe",
|
||||
choose_language: "Escolher idioma",
|
||||
shortcuts: "Atalhos",
|
||||
send_request: "Enviar request",
|
||||
save_to_collections: "Salvar nas coleções",
|
||||
copy_request_link: "Copiar link da request",
|
||||
reset_request: "Reiniciar request",
|
||||
support_us_on: "Nos ajude no",
|
||||
open_collective: "Abrir coletivamente",
|
||||
paypal: "Paypal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "Codigo JavaScript",
|
||||
method: "Método",
|
||||
path: "Caminho",
|
||||
label: "Label",
|
||||
again: "Novamente",
|
||||
content_type: "Content Type",
|
||||
raw_input: "Raw input",
|
||||
parameter_list: "Lista de parâmetros",
|
||||
raw_request_body: "Raw request body",
|
||||
show_code: "Mostrar código",
|
||||
hide_code: "Esconder código",
|
||||
show_prerequest_script: "Mostrar script de pré-request",
|
||||
hide_prerequest_script: "Esconder script de pré-request",
|
||||
authentication: "Autenticação",
|
||||
authentication_type: "Tipo de autenticação",
|
||||
include_in_url: "Incluir na url",
|
||||
parameters: "Parâmetros",
|
||||
expand_response: "Expandir response",
|
||||
collapse_response: "Esconder response",
|
||||
hide_preview: "Esconder preview",
|
||||
preview_html: "Preview html",
|
||||
history: "Histórico",
|
||||
collections: "Coleções",
|
||||
import_curl: "Importar curl",
|
||||
import: "Importar",
|
||||
generate_code: "Gerar código",
|
||||
request_type: "Tipo de request",
|
||||
generated_code: "Código gerado",
|
||||
status: "Status",
|
||||
headers: "Headers",
|
||||
websocket: "Websocket",
|
||||
waiting_for_connection: "(aguardando conexão)",
|
||||
message: "Mensagem",
|
||||
sse: "SSE",
|
||||
server: "Servidor",
|
||||
events: "Eventos",
|
||||
url: "URL",
|
||||
get_schema: "Get schema",
|
||||
header_list: "Lista de headers",
|
||||
add_new: "Adicionar novo",
|
||||
response: "Response",
|
||||
query: "Query",
|
||||
queries: "Queries",
|
||||
query_variables: "Variáveis",
|
||||
mutations: "Mutações",
|
||||
subscriptions: "Assinaturas",
|
||||
types: "Tipos",
|
||||
send: "Enviar",
|
||||
background: "Fundo",
|
||||
color: "Cor",
|
||||
labels: "Labels",
|
||||
multi_color: "Multi cor",
|
||||
enabled: "Ativado",
|
||||
disabled: "Desativado",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting: "Postwoman's alojamento proxy oficial",
|
||||
read_the: "Leia o",
|
||||
apollotv_privacy_policy: "ApolloTV Política de Privacidade",
|
||||
contact_us: "Contate-Nos",
|
||||
connect: "Conectar",
|
||||
disconnect: "Desconectar",
|
||||
start: "Começar",
|
||||
stop: "Pare"
|
||||
};
|
||||
90
lang/tr-TR.js
Normal file
@@ -0,0 +1,90 @@
|
||||
export default {
|
||||
home: "Ana Sayfa",
|
||||
realtime: "Realtime",
|
||||
graphql: "GraphQL",
|
||||
settings: "Ayarlar",
|
||||
request: "İstek",
|
||||
install_pwa: "PWA yükle",
|
||||
support_us: "Bize destek ol",
|
||||
tweet: "Tweet",
|
||||
options: "Options",
|
||||
communication: "İletişim",
|
||||
endpoint: "Endpoint",
|
||||
schema: "Taslak",
|
||||
theme: "Tema",
|
||||
subscribe: "Abonelik",
|
||||
choose_language: "Dil seç",
|
||||
shortcuts: "Kısayollar",
|
||||
send_request: "İstek gönder",
|
||||
save_to_collections: "Koleksiyonları kaydet",
|
||||
copy_request_link: "İstek adresini kopyala",
|
||||
reset_request: "İstekleri resetle",
|
||||
support_us_on: "Bizi destekle",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "PayPal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "JavaScript code",
|
||||
method: "Metot",
|
||||
path: "Yol",
|
||||
label: "Etiket",
|
||||
again: "Yeniden",
|
||||
content_type: "İçerik tipi",
|
||||
raw_input: "Raw giriş",
|
||||
parameter_list: "Parametre listesi",
|
||||
raw_request_body: "Raw istek içeriği",
|
||||
show_code: "Kodu göster",
|
||||
hide_code: "Kodu gizle",
|
||||
show_prerequest_script: "Pre-Request scriptini göster",
|
||||
hide_prerequest_script: "Pre-Request scriptini gizle",
|
||||
authentication: "Authentication",
|
||||
authentication_type: "Authentication tipi",
|
||||
include_in_url: "URL'den içeri aktar",
|
||||
parameters: "Parametre",
|
||||
expand_response: "Cevabı genişlet",
|
||||
collapse_response: "Cevap daralt",
|
||||
hide_preview: "Görüntülemeyi gizle",
|
||||
preview_html: "HTML formatında görüntüle",
|
||||
history: "Geçmiş",
|
||||
collections: "Koleksiyonlar",
|
||||
import_curl: "cURL içeri aktar",
|
||||
import: "İçeri Aktar",
|
||||
generate_code: "Kod Üret",
|
||||
request_type: "Request tipi",
|
||||
generated_code: "Üretilen Kod",
|
||||
status: "Durum",
|
||||
headers: "Headers",
|
||||
websocket: "WebSocket",
|
||||
waiting_for_connection: "(esperando por conexión)",
|
||||
message: "Mesaj",
|
||||
sse: "SSE",
|
||||
server: "Server",
|
||||
events: "Events",
|
||||
url: "URL",
|
||||
get_schema: "Taslak",
|
||||
header_list: "Header listesi",
|
||||
add_new: "Yeni Ekle",
|
||||
response: "Cevap",
|
||||
query: "Sorgu",
|
||||
queries: "Sorgular",
|
||||
query_variables: "Değişkenler",
|
||||
mutations: "Değişimler",
|
||||
subscriptions: "Aboneler",
|
||||
types: "Tipler",
|
||||
send: "Gönder",
|
||||
background: "Arka Plan",
|
||||
color: "Renk",
|
||||
labels: "Etiketler",
|
||||
multi_color: "Çoklu renk",
|
||||
enabled: "Aktif",
|
||||
disabled: "Aktif değil",
|
||||
proxy: "Proxy",
|
||||
postwoman_official_proxy_hosting:
|
||||
"Proxy Oficial de Postwoman está hospedado en ApolloTV.",
|
||||
read_the: "Leer la",
|
||||
apollotv_privacy_policy: "ApolloTV gizlilik politikaları",
|
||||
contact_us: "Bizimle iletişime geçin",
|
||||
connect: "Bağlan",
|
||||
disconnect: "Kesmek",
|
||||
start: "Başla",
|
||||
stop: "Durdurmak"
|
||||
};
|
||||
89
lang/zh-CN.js
Normal file
@@ -0,0 +1,89 @@
|
||||
export default {
|
||||
home: "主页",
|
||||
realtime: "长连接",
|
||||
graphql: "GraphQL",
|
||||
settings: "设置",
|
||||
request: "请求",
|
||||
install_pwa: "安装PWA应用",
|
||||
support_us: "支持我们",
|
||||
tweet: "推特",
|
||||
options: "选项",
|
||||
communication: "联系我们",
|
||||
endpoint: "服务端点",
|
||||
schema: "模式",
|
||||
theme: "主题",
|
||||
subscribe: "订阅",
|
||||
choose_language: "选择语言",
|
||||
shortcuts: "快捷键",
|
||||
send_request: "发送请求",
|
||||
save_to_collections: "保存到收藏夹",
|
||||
copy_request_link: "复制请求链接",
|
||||
reset_request: "重置请求",
|
||||
support_us_on: "支持我们",
|
||||
open_collective: "Open Collective",
|
||||
paypal: "Paypal",
|
||||
patreon: "Patreon",
|
||||
javascript_code: "JavaScript代码",
|
||||
method: "方法",
|
||||
path: "路径",
|
||||
label: "标签",
|
||||
again: "重试",
|
||||
content_type: "内容类型",
|
||||
raw_input: "raw数据",
|
||||
parameter_list: "参数列表",
|
||||
raw_request_body: "raw请求主体",
|
||||
show_code: "显示代码",
|
||||
hide_code: "隐藏代码",
|
||||
show_prerequest_script: "显示预请求脚本",
|
||||
hide_prerequest_script: "隐藏预请求脚本",
|
||||
authentication: "认证方式",
|
||||
authentication_type: "认证类型",
|
||||
include_in_url: "包含在URL中",
|
||||
parameters: "参数",
|
||||
expand_response: "展开显示响应内容",
|
||||
collapse_response: "折叠显示响应内容",
|
||||
hide_preview: "隐藏预览",
|
||||
preview_html: "预览HTML",
|
||||
history: "历史记录",
|
||||
collections: "收藏夹",
|
||||
import_curl: "批量导入",
|
||||
import: "导入",
|
||||
generate_code: "生成代码",
|
||||
request_type: "请求类型",
|
||||
generated_code: "生成的代码",
|
||||
status: "状态码",
|
||||
headers: "请求头",
|
||||
websocket: "Websocket",
|
||||
waiting_for_connection: "(等待连接)",
|
||||
message: "消息内容",
|
||||
sse: "SSE",
|
||||
server: "Server",
|
||||
events: "事件",
|
||||
url: "地址",
|
||||
get_schema: "获取模式",
|
||||
header_list: "请求头列表",
|
||||
add_new: "添加",
|
||||
response: "响应",
|
||||
query: "查询",
|
||||
queries: "查询",
|
||||
query_variables: "变数",
|
||||
mutations: "Mutations",
|
||||
subscriptions: "订阅",
|
||||
types: "种类",
|
||||
send: "发送",
|
||||
background: "背景",
|
||||
color: "颜色",
|
||||
labels: "标签",
|
||||
multi_color: "彩色",
|
||||
enabled: "已启用",
|
||||
disabled: "已禁用",
|
||||
proxy: "代理",
|
||||
postwoman_official_proxy_hosting: "Postwoman的官方代理由ApolloTV托管",
|
||||
read_the: "阅读",
|
||||
apollotv_privacy_policy: "ApolloTV隐私政策",
|
||||
contact_us: "联系我们",
|
||||
connect: "连接",
|
||||
disconnect: "断开",
|
||||
start: "开始",
|
||||
stop: "停止"
|
||||
};
|
||||
@@ -1,21 +1,5 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<header class="header">
|
||||
<div>
|
||||
<div class="slide-in">
|
||||
<nuxt-link to="/">
|
||||
<h1 class="logo">Postwoman</h1>
|
||||
</nuxt-link>
|
||||
<h3 class="tagline">API request builder</h3>
|
||||
</div>
|
||||
<a href="https://github.com/liyasthomas/postwoman" target="_blank" rel="noopener">
|
||||
<button class="icon">
|
||||
<img id="imgGitHub" src="~static/icons/github.svg" alt="GitHub" :style="logoStyle()" />
|
||||
<span>GitHub</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<div class="content">
|
||||
<div class="columns">
|
||||
<aside class="nav-first">
|
||||
@@ -24,82 +8,242 @@
|
||||
We're using manual checks for linkActive because the query string
|
||||
seems to mess up the nuxt-link active class.
|
||||
-->
|
||||
<nuxt-link to="/" :class="linkActive('/')" v-tooltip.right="'Home'" aria-label="Home">
|
||||
<logo alt style="height: 24px;"></logo>
|
||||
</nuxt-link>
|
||||
<nuxt-link
|
||||
to="/websocket"
|
||||
:class="linkActive('/websocket')"
|
||||
v-tooltip.right="'WebSocket'"
|
||||
:to="localePath('index')"
|
||||
:class="linkActive('/')"
|
||||
v-tooltip.right="$t('home')"
|
||||
aria-label="Home"
|
||||
>
|
||||
<i class="material-icons">cloud</i>
|
||||
<logo alt class="material-icons" style="height: 24px;"></logo>
|
||||
</nuxt-link>
|
||||
<nuxt-link
|
||||
to="/settings"
|
||||
:to="localePath('realtime')"
|
||||
:class="linkActive('/realtime')"
|
||||
v-tooltip.right="$t('realtime')"
|
||||
>
|
||||
<i class="material-icons">settings_input_hdmi</i>
|
||||
</nuxt-link>
|
||||
<nuxt-link
|
||||
:to="localePath('graphql')"
|
||||
:class="linkActive('/graphql')"
|
||||
v-tooltip.right="$t('graphql')"
|
||||
aria-label="GraphQL"
|
||||
>
|
||||
<svg
|
||||
class="material-icons"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 400 400"
|
||||
>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="122"
|
||||
y="-0.4"
|
||||
transform="matrix(-0.866 -0.5 0.5 -0.866 163.3196 363.3136)"
|
||||
width="16.6"
|
||||
height="320.3"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="39.8" y="272.2" width="320.3" height="16.6" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="37.9"
|
||||
y="312.2"
|
||||
transform="matrix(-0.866 -0.5 0.5 -0.866 83.0693 663.3409)"
|
||||
width="185"
|
||||
height="16.6"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="177.1"
|
||||
y="71.1"
|
||||
transform="matrix(-0.866 -0.5 0.5 -0.866 463.3409 283.0693)"
|
||||
width="185"
|
||||
height="16.6"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="122.1"
|
||||
y="-13"
|
||||
transform="matrix(-0.5 -0.866 0.866 -0.5 126.7903 232.1221)"
|
||||
width="16.6"
|
||||
height="185"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="109.6"
|
||||
y="151.6"
|
||||
transform="matrix(-0.5 -0.866 0.866 -0.5 266.0828 473.3766)"
|
||||
width="320.3"
|
||||
height="16.6"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g><rect x="52.5" y="107.5" width="16.6" height="185" /></g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="330.9" y="107.5" width="16.6" height="185" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect
|
||||
x="262.4"
|
||||
y="240.1"
|
||||
transform="matrix(-0.5 -0.866 0.866 -0.5 126.7953 714.2875)"
|
||||
width="14.5"
|
||||
height="160.9"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<path
|
||||
d="M369.5,297.9c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8C373.5,259.9,379.2,281.2,369.5,297.9"
|
||||
/>
|
||||
<path
|
||||
d="M90.9,137c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8C94.8,99,100.5,120.3,90.9,137"
|
||||
/>
|
||||
<path
|
||||
d="M30.5,297.9c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6,16.7,3.9,38-12.8,47.7C61.4,320.3,40.1,314.6,30.5,297.9"
|
||||
/>
|
||||
<path
|
||||
d="M309.1,137c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6,16.7,3.9,38-12.8,47.7C340.1,159.4,318.7,153.7,309.1,137"
|
||||
/>
|
||||
<path
|
||||
d="M200,395.8c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9C234.9,380.1,219.3,395.8,200,395.8"
|
||||
/>
|
||||
<path
|
||||
d="M200,74c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9C234.9,58.4,219.3,74,200,74"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</nuxt-link>
|
||||
<nuxt-link
|
||||
:to="localePath('doc')"
|
||||
:class="linkActive('/doc')"
|
||||
v-tooltip.right="'Documentation'"
|
||||
aria-label="Documentation"
|
||||
>
|
||||
<i class="material-icons">books</i>
|
||||
</nuxt-link>
|
||||
<nuxt-link
|
||||
:to="localePath('settings')"
|
||||
:class="linkActive('/settings')"
|
||||
v-tooltip.right="'Settings'"
|
||||
v-tooltip.right="$t('settings')"
|
||||
aria-label="Settings"
|
||||
>
|
||||
<i class="material-icons">settings</i>
|
||||
</nuxt-link>
|
||||
</nav>
|
||||
<div v-if="['/'].includes($route.path)">
|
||||
<div v-if="$route.path === '/'">
|
||||
<nav class="secondary-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#request" v-tooltip.right="'Request'">
|
||||
<a href="#request" v-tooltip.right="$t('request')">
|
||||
<i class="material-icons">cloud_upload</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#options" v-tooltip.right="'Options'">
|
||||
<a href="#options" v-tooltip.right="$t('options')">
|
||||
<i class="material-icons">toc</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#response" v-tooltip.right="'Response'">
|
||||
<a href="#response" v-tooltip.right="$t('response')">
|
||||
<i class="material-icons">cloud_download</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#collections" v-tooltip.right="'Collections'">
|
||||
<i class="material-icons">folder_special</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#history" v-tooltip.right="'History'">
|
||||
<i class="material-icons">watch_later</i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div v-else-if="['/websocket'].includes($route.path)">
|
||||
<div v-else-if="$route.path === '/realtime'">
|
||||
<nav class="secondary-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#request" v-tooltip.right="'Request'">
|
||||
<a href="#request" v-tooltip.right="$t('request')">
|
||||
<i class="material-icons">cloud_upload</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#response" v-tooltip.right="'Response'">
|
||||
<a href="#response" v-tooltip.right="$t('communication')">
|
||||
<i class="material-icons">cloud_download</i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div v-else-if="['/settings'].includes($route.path)">
|
||||
<div v-else-if="$route.path === '/graphql'">
|
||||
<nav class="secondary-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#theme" v-tooltip.right="'Theme'">
|
||||
<a href="#endpoint" v-tooltip.right="$t('endpoint')">
|
||||
<i class="material-icons">cloud</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#schema" v-tooltip.right="$t('schema')">
|
||||
<i class="material-icons">assignment_returned</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#query" v-tooltip.right="$t('query')">
|
||||
<i class="material-icons">cloud_upload</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#response" v-tooltip.right="$t('response')">
|
||||
<i class="material-icons">cloud_download</i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div v-else-if="$route.path === '/doc'">
|
||||
<nav class="secondary-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#collections" v-tooltip.right="$t('collections')">
|
||||
<i class="material-icons">folder</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#documentation" v-tooltip.right="'Documentation'">
|
||||
<i class="material-icons">insert_drive_file</i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
<div v-else-if="$route.path === '/settings'">
|
||||
<nav class="secondary-nav">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#theme" v-tooltip.right="$t('theme')">
|
||||
<i class="material-icons">brush</i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#proxy" v-tooltip.right="'Proxy'">
|
||||
<a href="#proxy" v-tooltip.right="$t('proxy')">
|
||||
<i class="material-icons">public</i>
|
||||
</a>
|
||||
</li>
|
||||
@@ -107,173 +251,376 @@
|
||||
</nav>
|
||||
</div>
|
||||
</aside>
|
||||
<nuxt id="main" class="main" />
|
||||
<div class="main" id="main">
|
||||
<header class="header">
|
||||
<div class="flex-wrap">
|
||||
<span class="slide-in">
|
||||
<nuxt-link :to="localePath('index')">
|
||||
<h1 class="logo">Postwoman</h1>
|
||||
</nuxt-link>
|
||||
</span>
|
||||
<span>
|
||||
<a
|
||||
href="https://github.com/liyasthomas/postwoman"
|
||||
target="_blank"
|
||||
aria-label="GitHub"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon" aria-label="GitHub" v-tooltip="'GitHub'">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
class="material-icons"
|
||||
>
|
||||
<path
|
||||
d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</a>
|
||||
<button
|
||||
class="icon"
|
||||
id="installPWA"
|
||||
@click.prevent="showInstallPrompt()"
|
||||
v-tooltip="$t('install_pwa')"
|
||||
>
|
||||
<i class="material-icons">offline_bolt</i>
|
||||
</button>
|
||||
<v-popover>
|
||||
<button class="icon" v-tooltip="'More'">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
<template slot="popover">
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="showShortcuts = true"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">keyboard</i>
|
||||
<span>{{ $t("shortcuts") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="showSupport = true"
|
||||
v-close-popover
|
||||
>
|
||||
<i class="material-icons">favorite</i>
|
||||
<span>{{ $t("support_us") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
onClick="window.open('https://twitter.com/share?text=👽 Postwoman • API request builder - Helps you create your requests faster, saving you precious time on your development&url=https://postwoman.io&hashtags=postwoman&via=liyasthomas');"
|
||||
v-close-popover
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"
|
||||
/>
|
||||
</svg>
|
||||
<span>{{ $t("tweet") }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
<nuxt />
|
||||
<footer class="footer">
|
||||
<div class="flex-wrap">
|
||||
<span v-if="version.name" class="mono">
|
||||
<a
|
||||
href="https://liyasthomas.web.app"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon" v-tooltip="'Liyas Thomas'">
|
||||
🦄
|
||||
</button>
|
||||
</a>
|
||||
<a
|
||||
:href="
|
||||
'https://github.com/liyasthomas/postwoman/releases/tag/' +
|
||||
version.name
|
||||
"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
v-tooltip="'GitHub'"
|
||||
>
|
||||
{{ version.name }}
|
||||
</a>
|
||||
<!-- <span v-if="version.hash">
|
||||
-
|
||||
<a
|
||||
:href="'https://github.com/liyasthomas/postwoman/commit/' + version.hash"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>{{version.hash}}</a>
|
||||
</span> -->
|
||||
<!-- <span v-if="version.variant">({{version.variant}})</span> -->
|
||||
</span>
|
||||
<span>
|
||||
<a
|
||||
href="mailto:liyascthomas@gmail.com"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon" v-tooltip="$t('contact_us')">
|
||||
<i class="material-icons">email</i>
|
||||
</button>
|
||||
</a>
|
||||
<v-popover>
|
||||
<button class="icon" v-tooltip="$t('choose_language')">
|
||||
<i class="material-icons">translate</i>
|
||||
</button>
|
||||
<template slot="popover">
|
||||
<div v-for="locale in availableLocales" :key="locale.code">
|
||||
<nuxt-link :to="switchLocalePath(locale.code)">
|
||||
<button class="icon" v-close-popover>
|
||||
{{ locale.name }}
|
||||
</button>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</template>
|
||||
</v-popover>
|
||||
</span>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<aside class="nav-second"></aside>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<!-- Top section of footer: GitHub/install links -->
|
||||
<div class="flex-wrap">
|
||||
<button class="icon" id="installPWA" @click.prevent="showInstallPrompt()">
|
||||
<i class="material-icons">add_to_home_screen</i>
|
||||
<span>Install PWA</span>
|
||||
</button>
|
||||
<button
|
||||
class="icon"
|
||||
onClick="window.open('https://twitter.com/share?text=👽 Postwoman • API request builder - Helps you create your requests faster, saving you precious time on your development&url=https://postwoman.io&hashtags=postwoman&via=liyasthomas');"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"
|
||||
/>
|
||||
</svg>
|
||||
<span>Tweet</span>
|
||||
</button>
|
||||
<modal v-if="showShortcuts" @close="showShortcuts = false">
|
||||
<div slot="header">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<h3 class="title">{{ $t("shortcuts") }}</h3>
|
||||
<div>
|
||||
<button class="icon" @click="showShortcuts = false">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- Bottom section of footer: version/author information -->
|
||||
<p class="align-center">
|
||||
<span v-if="version.name">
|
||||
<div slot="body">
|
||||
<br />
|
||||
<div>
|
||||
<label>{{ $t("send_request") }}</label>
|
||||
<kbd>⌘ G</kbd>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<label>{{ $t("save_to_collections") }}</label>
|
||||
<kbd>⌘ S</kbd>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<label>{{ $t("copy_request_link") }}</label>
|
||||
<kbd>⌘ K</kbd>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<label>{{ $t("reset_request") }}</label>
|
||||
<kbd>⌘ L</kbd>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
<div slot="footer"></div>
|
||||
</modal>
|
||||
<modal v-if="showSupport" @close="showSupport = false">
|
||||
<div slot="header">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<h3 class="title">{{ $t("support_us_on") }}</h3>
|
||||
<div>
|
||||
<button class="icon" @click="showSupport = false">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div slot="body">
|
||||
<div>
|
||||
<a
|
||||
v-bind:href="'https://github.com/liyasthomas/postwoman/releases/tag/' + version.name"
|
||||
href="https://opencollective.com/postwoman"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>{{version.name}}</a>
|
||||
<span v-if="version.hash">
|
||||
-
|
||||
<a
|
||||
v-bind:href="'https://github.com/liyasthomas/postwoman/commit/' + version.hash"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>{{version.hash}}</a>
|
||||
</span>
|
||||
<span v-if="version.variant">({{version.variant}})</span>
|
||||
•
|
||||
</span> by
|
||||
<a href="https://liyasthomas.web.app" target="_blank" rel="noopener">Liyas Thomas 🦄</a> •
|
||||
<a href="https://postwoman.launchaco.com" target="_blank" rel="noopener">Subscribe</a>
|
||||
</p>
|
||||
</footer>
|
||||
>
|
||||
<button class="icon">
|
||||
<i class="material-icons">donut_large</i>
|
||||
<span>{{ $t("open_collective") }}</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://www.paypal.me/liyascthomas"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon">
|
||||
<i class="material-icons">payment</i>
|
||||
<span>{{ $t("paypal") }}</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
href="https://www.patreon.com/liyasthomas"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon">
|
||||
<i class="material-icons">local_parking</i>
|
||||
<span>{{ $t("patreon") }}</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer"></div>
|
||||
</modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
<script>
|
||||
import intializePwa from "../assets/js/pwa";
|
||||
import logo from "../components/logo";
|
||||
import * as version from "../.postwoman/version.json";
|
||||
import intializePwa from "../assets/js/pwa";
|
||||
import * as version from "../.postwoman/version.json";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
logo
|
||||
},
|
||||
export default {
|
||||
components: {
|
||||
logo: () => import("../components/logo"),
|
||||
modal: () => import("../components/modal")
|
||||
},
|
||||
|
||||
methods: {
|
||||
linkActive(path) {
|
||||
return {
|
||||
"nuxt-link-exact-active": this.$route.path === path,
|
||||
"nuxt-link-active": this.$route.path === path
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
methods: {
|
||||
linkActive(path) {
|
||||
return {
|
||||
// Once the PWA code is initialized, this holds a method
|
||||
// that can be called to show the user the installation
|
||||
// prompt.
|
||||
showInstallPrompt: null,
|
||||
logoStyle() {
|
||||
return (
|
||||
this.$store.state.postwoman.settings.THEME_CLASS || ""
|
||||
).includes("light")
|
||||
? " filter: invert(100%); -webkit-filter: invert(100%);"
|
||||
: "";
|
||||
},
|
||||
|
||||
version: {}
|
||||
"nuxt-link-exact-active": this.$route.path === path,
|
||||
"nuxt-link-active": this.$route.path === path
|
||||
};
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
// Set version data
|
||||
this.version = version.default;
|
||||
|
||||
// Load theme settings
|
||||
(() => {
|
||||
// Apply theme from settings.
|
||||
document.documentElement.className =
|
||||
this.$store.state.postwoman.settings.THEME_CLASS || "";
|
||||
// Load theme color data from settings, or use default color.
|
||||
let color = this.$store.state.postwoman.settings.THEME_COLOR || "#50fa7b";
|
||||
let vibrant = this.$store.state.postwoman.settings.THEME_COLOR_VIBRANT;
|
||||
if (vibrant == null) vibrant = true;
|
||||
document.documentElement.style.setProperty("--ac-color", color);
|
||||
document.documentElement.style.setProperty(
|
||||
"--act-color",
|
||||
vibrant ? "rgb(37, 38, 40)" : "#ffffff"
|
||||
);
|
||||
})();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (process.client) {
|
||||
document.body.classList.add("afterLoad");
|
||||
}
|
||||
|
||||
document
|
||||
.querySelector("meta[name=theme-color]")
|
||||
.setAttribute(
|
||||
"content",
|
||||
this.$store.state.postwoman.settings.THEME_TAB_COLOR || "#252628"
|
||||
);
|
||||
|
||||
// Initializes the PWA code - checks if the app is installed,
|
||||
// etc.
|
||||
(async () => {
|
||||
this.showInstallPrompt = await intializePwa();
|
||||
let cookiesAllowed = localStorage.getItem("cookiesAllowed") === "yes";
|
||||
if (!cookiesAllowed) {
|
||||
this.$toast.show("We use cookies", {
|
||||
icon: "info",
|
||||
duration: 5000,
|
||||
theme: "toasted-primary",
|
||||
action: [
|
||||
{
|
||||
text: "Dismiss",
|
||||
onClick: (e, toastObject) => {
|
||||
localStorage.setItem("cookiesAllowed", "yes");
|
||||
toastObject.goAway(0);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
window.addEventListener("scroll", event => {
|
||||
let mainNavLinks = document.querySelectorAll("nav ul li a");
|
||||
let fromTop = window.scrollY;
|
||||
mainNavLinks.forEach(link => {
|
||||
let section = document.querySelector(link.hash);
|
||||
|
||||
if (
|
||||
section.offsetTop <= fromTop &&
|
||||
section.offsetTop + section.offsetHeight > fromTop
|
||||
) {
|
||||
link.classList.add("current");
|
||||
} else {
|
||||
link.classList.remove("current");
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route() {
|
||||
this.$toast.clear();
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
// Once the PWA code is initialized, this holds a method
|
||||
// that can be called to show the user the installation
|
||||
// prompt.
|
||||
showInstallPrompt: null,
|
||||
version: {},
|
||||
showShortcuts: false,
|
||||
showSupport: false
|
||||
};
|
||||
},
|
||||
|
||||
beforeMount() {
|
||||
// Set version data
|
||||
this.version = version.default;
|
||||
|
||||
// Load theme settings
|
||||
(() => {
|
||||
// Apply theme from settings.
|
||||
document.documentElement.className =
|
||||
this.$store.state.postwoman.settings.THEME_CLASS || "";
|
||||
// Load theme color data from settings, or use default color.
|
||||
let color = this.$store.state.postwoman.settings.THEME_COLOR || "#50fa7b";
|
||||
let vibrant = this.$store.state.postwoman.settings.THEME_COLOR_VIBRANT;
|
||||
if (vibrant == null) vibrant = true;
|
||||
document.documentElement.style.setProperty("--ac-color", color);
|
||||
document.documentElement.style.setProperty(
|
||||
"--act-color",
|
||||
vibrant ? "rgba(32, 33, 36, 1)" : "rgba(255, 255, 255, 1)"
|
||||
);
|
||||
})();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (process.client) {
|
||||
document.body.classList.add("afterLoad");
|
||||
}
|
||||
|
||||
document
|
||||
.querySelector("meta[name=theme-color]")
|
||||
.setAttribute(
|
||||
"content",
|
||||
this.$store.state.postwoman.settings.THEME_TAB_COLOR || "#202124"
|
||||
);
|
||||
|
||||
// Initializes the PWA code - checks if the app is installed,
|
||||
// etc.
|
||||
(async () => {
|
||||
this.showInstallPrompt = await intializePwa();
|
||||
let cookiesAllowed = localStorage.getItem("cookiesAllowed") === "yes";
|
||||
if (!cookiesAllowed) {
|
||||
this.$toast.show("We use cookies", {
|
||||
icon: "info",
|
||||
duration: 5000,
|
||||
theme: "toasted-primary",
|
||||
action: [
|
||||
{
|
||||
text: "Dismiss",
|
||||
onClick: (e, toastObject) => {
|
||||
localStorage.setItem("cookiesAllowed", "yes");
|
||||
toastObject.goAway(0);
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
window.addEventListener("scroll", event => {
|
||||
let mainNavLinks = document.querySelectorAll("nav ul li a");
|
||||
let fromTop = window.scrollY;
|
||||
mainNavLinks.forEach(link => {
|
||||
let section = document.querySelector(link.hash);
|
||||
|
||||
if (
|
||||
section &&
|
||||
section.offsetTop <= fromTop &&
|
||||
section.offsetTop + section.offsetHeight > fromTop
|
||||
) {
|
||||
link.classList.add("current");
|
||||
} else {
|
||||
link.classList.remove("current");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
console.log("%cWe ❤︎ open source!", "background-color:white;padding:8px 16px;border-radius:8px;font-size:32px;color:red;")
|
||||
console.log("%cContribute: https://github.com/liyasthomas/postwoman", "background-color:black;padding:4px 8px;border-radius:8px;font-size:16px;color:white;")
|
||||
},
|
||||
|
||||
watch: {
|
||||
$route() {
|
||||
this.$toast.clear();
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
availableLocales() {
|
||||
return this.$i18n.locales.filter(i => i.code !== this.$i18n.locale);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
<style scoped lang="scss">
|
||||
// Center the error page in the viewport.
|
||||
.page-error {
|
||||
display: flex;
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
export default function ({
|
||||
route,
|
||||
redirect
|
||||
}) {
|
||||
if (route.fullPath !== '/') {
|
||||
return redirect('/');
|
||||
export default function({ route, redirect }) {
|
||||
if (route.fullPath !== "/") {
|
||||
return redirect("/");
|
||||
}
|
||||
}
|
||||
|
||||
335
nuxt.config.js
@@ -3,50 +3,64 @@
|
||||
export const meta = {
|
||||
name: "Postwoman",
|
||||
shortDescription: "API request builder",
|
||||
description: "The Postwoman API request builder helps you create your requests faster, saving you precious time on your development."
|
||||
description:
|
||||
"The Postwoman API request builder helps you create your requests faster, saving you precious time on your development."
|
||||
};
|
||||
// Sets the base path for the router.
|
||||
// Important for deploying to GitHub pages.
|
||||
// -- Travis includes the author in the repo slug,
|
||||
// so if there's a /, we need to get everything after it.
|
||||
let repoName = (process.env.TRAVIS_REPO_SLUG || '').split('/').pop();
|
||||
export const routerBase = process.env.DEPLOY_ENV === 'GH_PAGES' ? {
|
||||
router: {
|
||||
base: `/${repoName}/`
|
||||
}
|
||||
} : {
|
||||
router: {
|
||||
base: '/'
|
||||
}
|
||||
};
|
||||
let repoName = (process.env.TRAVIS_REPO_SLUG || "").split("/").pop();
|
||||
export const routerBase =
|
||||
process.env.DEPLOY_ENV === "GH_PAGES"
|
||||
? {
|
||||
router: {
|
||||
base: `/${repoName}/`
|
||||
}
|
||||
}
|
||||
: {
|
||||
router: {
|
||||
base: "/"
|
||||
}
|
||||
};
|
||||
export default {
|
||||
mode: 'spa',
|
||||
mode: "spa",
|
||||
/*
|
||||
** Headers of the page
|
||||
*/
|
||||
server: {
|
||||
host: '0.0.0.0', // default: localhost
|
||||
host: "0.0.0.0" // default: localhost
|
||||
},
|
||||
render: {
|
||||
bundleRenderer: {
|
||||
shouldPreload: (file, type) => {
|
||||
return ["script", "style", "font"].includes(type);
|
||||
}
|
||||
}
|
||||
},
|
||||
head: {
|
||||
title: `${meta.name} \u2022 ${meta.shortDescription}`,
|
||||
meta: [{
|
||||
charset: 'utf-8'
|
||||
meta: [
|
||||
{
|
||||
charset: "utf-8"
|
||||
},
|
||||
{
|
||||
name: 'viewport',
|
||||
content: 'width=device-width, initial-scale=1, minimum-scale=1, shrink-to-fit=no, minimal-ui'
|
||||
name: "viewport",
|
||||
content:
|
||||
"width=device-width, initial-scale=1, minimum-scale=1, viewport-fit=cover, minimal-ui"
|
||||
},
|
||||
{
|
||||
hid: 'description',
|
||||
name: 'description',
|
||||
content: meta.description || ''
|
||||
hid: "description",
|
||||
name: "description",
|
||||
content: meta.description || ""
|
||||
},
|
||||
{
|
||||
name: 'keywords',
|
||||
content: 'postwoman, postwoman chrome, postwoman online, postwoman for mac, postwoman app, postwoman for windows, postwoman google chrome, postwoman chrome app, get postwoman, postwoman web, postwoman android, postwoman app for chrome, postwoman mobile app, postwoman web app, api, request, testing, tool, rest, websocket'
|
||||
name: "keywords",
|
||||
content:
|
||||
"postwoman, postwoman chrome, postwoman online, postwoman for mac, postwoman app, postwoman for windows, postwoman google chrome, postwoman chrome app, get postwoman, postwoman web, postwoman android, postwoman app for chrome, postwoman mobile app, postwoman web app, api, request, testing, tool, rest, websocket, sse, graphql"
|
||||
},
|
||||
{
|
||||
name: 'X-UA-Compatible',
|
||||
name: "X-UA-Compatible",
|
||||
content: "IE=edge, chrome=1"
|
||||
},
|
||||
{
|
||||
@@ -59,156 +73,158 @@ export default {
|
||||
},
|
||||
{
|
||||
itemprop: "image",
|
||||
content: `${routerBase.router.base}icons/icon-192x192.png`
|
||||
content: `${routerBase.router.base}logo.jpg`
|
||||
},
|
||||
// Add to homescreen for Chrome on Android. Fallback for PWA (handled by nuxt)
|
||||
{
|
||||
name: 'application-name',
|
||||
name: "application-name",
|
||||
content: meta.name
|
||||
},
|
||||
// Add to homescreen for Safari on iOS
|
||||
{
|
||||
name: 'apple-mobile-web-app-capable',
|
||||
content: 'yes'
|
||||
name: "apple-mobile-web-app-capable",
|
||||
content: "yes"
|
||||
},
|
||||
{
|
||||
name: 'apple-mobile-web-app-status-bar-style',
|
||||
content: 'black-translucent'
|
||||
name: "apple-mobile-web-app-status-bar-style",
|
||||
content: "black-translucent"
|
||||
},
|
||||
{
|
||||
name: 'apple-mobile-web-app-title',
|
||||
name: "apple-mobile-web-app-title",
|
||||
content: meta.name
|
||||
},
|
||||
// Windows phone tile icon
|
||||
{
|
||||
name: 'msapplication-TileImage',
|
||||
name: "msapplication-TileImage",
|
||||
content: `${routerBase.router.base}icons/icon-144x144.png`
|
||||
},
|
||||
{
|
||||
name: 'msapplication-TileColor',
|
||||
content: '#252628'
|
||||
name: "msapplication-TileColor",
|
||||
content: "#202124"
|
||||
},
|
||||
{
|
||||
name: 'msapplication-tap-highlight',
|
||||
content: 'no'
|
||||
name: "msapplication-tap-highlight",
|
||||
content: "no"
|
||||
},
|
||||
// OpenGraph
|
||||
{
|
||||
property: 'og:site_name',
|
||||
property: "og:site_name",
|
||||
content: meta.name
|
||||
},
|
||||
{
|
||||
property: 'og:url',
|
||||
content: 'https://postwoman.io'
|
||||
},
|
||||
{
|
||||
property: 'og:type',
|
||||
content: 'website'
|
||||
},
|
||||
{
|
||||
property: 'og:title',
|
||||
content: `${meta.name} \u2022 ${meta.shortDescription}`
|
||||
},
|
||||
{
|
||||
property: 'og:description',
|
||||
content: meta.description
|
||||
},
|
||||
{
|
||||
property: 'og:image',
|
||||
content: `${routerBase.router.base}icons/icon-144x144.png`
|
||||
},
|
||||
// Twitter
|
||||
{
|
||||
name: 'twitter:card',
|
||||
content: "summary"
|
||||
},
|
||||
{
|
||||
name: 'twitter:site',
|
||||
content: "@liyasthomas"
|
||||
},
|
||||
{
|
||||
name: 'twitter:creator',
|
||||
content: "@liyasthomas"
|
||||
},
|
||||
{
|
||||
name: 'twitter:url',
|
||||
property: "og:url",
|
||||
content: "https://postwoman.io"
|
||||
},
|
||||
{
|
||||
name: 'twitter:title',
|
||||
content: meta.name
|
||||
property: "og:type",
|
||||
content: "website"
|
||||
},
|
||||
{
|
||||
name: 'twitter:description',
|
||||
content: meta.shortDescription
|
||||
property: "og:title",
|
||||
content: `${meta.name} \u2022 ${meta.shortDescription}`
|
||||
},
|
||||
{
|
||||
name: 'twitter:image',
|
||||
content: `${routerBase.router.base}icons/icon-144x144.png`
|
||||
property: "og:description",
|
||||
content: meta.description
|
||||
},
|
||||
{
|
||||
property: "og:image",
|
||||
content: `${routerBase.router.base}logo.jpg`
|
||||
},
|
||||
// Twitter
|
||||
{
|
||||
name: "twitter:card",
|
||||
content: "summary_large_image"
|
||||
},
|
||||
{
|
||||
name: "twitter:site",
|
||||
content: "@liyasthomas"
|
||||
},
|
||||
{
|
||||
name: "twitter:creator",
|
||||
content: "@liyasthomas"
|
||||
},
|
||||
{
|
||||
name: "twitter:url",
|
||||
content: "https://postwoman.io"
|
||||
},
|
||||
{
|
||||
name: "twitter:title",
|
||||
content: `${meta.name} \u2022 ${meta.shortDescription}`
|
||||
},
|
||||
{
|
||||
name: "twitter:description",
|
||||
content: meta.description
|
||||
},
|
||||
{
|
||||
name: "twitter:image",
|
||||
content: "https://postwoman.io/logo.jpg"
|
||||
}
|
||||
],
|
||||
link: [{
|
||||
rel: 'icon',
|
||||
type: 'image/x-icon',
|
||||
link: [
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/x-icon",
|
||||
href: `${routerBase.router.base}favicon.ico`
|
||||
},
|
||||
// Home-screen icons (iOS)
|
||||
{
|
||||
rel: 'apple-touch-icon',
|
||||
rel: "apple-touch-icon",
|
||||
href: `${routerBase.router.base}icons/icon-48x48.png`
|
||||
},
|
||||
{
|
||||
rel: 'apple-touch-icon',
|
||||
sizes: '72x72',
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "72x72",
|
||||
href: `${routerBase.router.base}icons/icon-72x72.png`
|
||||
},
|
||||
{
|
||||
rel: 'apple-touch-icon',
|
||||
sizes: '96x96',
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "96x96",
|
||||
href: `${routerBase.router.base}icons/icon-96x96.png`
|
||||
},
|
||||
{
|
||||
rel: 'apple-touch-icon',
|
||||
sizes: '144x144',
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "144x144",
|
||||
href: `${routerBase.router.base}icons/icon-144x144.png`
|
||||
},
|
||||
{
|
||||
rel: 'apple-touch-icon',
|
||||
sizes: '192x192',
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "192x192",
|
||||
href: `${routerBase.router.base}icons/icon-192x192.png`
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
/*
|
||||
** Customize the progress-bar color
|
||||
*/
|
||||
loading: {
|
||||
color: 'var(--ac-color)'
|
||||
color: "var(--ac-color)"
|
||||
},
|
||||
/*
|
||||
** Customize the loading indicator
|
||||
*/
|
||||
loadingIndicator: {
|
||||
name: 'pulse',
|
||||
color: 'var(--ac-color)',
|
||||
background: 'var(--bg-color)'
|
||||
name: "pulse",
|
||||
color: "var(--ac-color)",
|
||||
background: "var(--bg-color)"
|
||||
},
|
||||
/*
|
||||
** Global CSS
|
||||
*/
|
||||
css: [
|
||||
'@/assets/css/themes.scss',
|
||||
'@/assets/css/fonts.scss',
|
||||
'@/assets/css/styles.scss'
|
||||
"~/assets/css/styles.scss",
|
||||
"~/assets/css/themes.scss",
|
||||
"~/assets/css/fonts.scss"
|
||||
],
|
||||
/*
|
||||
** Plugins to load before mounting the App
|
||||
*/
|
||||
plugins: [{
|
||||
src: '~/plugins/vuex-persist'
|
||||
plugins: [
|
||||
{
|
||||
src: "~/plugins/vuex-persist"
|
||||
},
|
||||
{
|
||||
src: '~/plugins/v-tooltip'
|
||||
src: "~/plugins/v-tooltip"
|
||||
}
|
||||
],
|
||||
/*
|
||||
@@ -220,15 +236,19 @@ export default {
|
||||
*/
|
||||
modules: [
|
||||
// See https://goo.gl/OOhYW5
|
||||
['@nuxtjs/pwa'],
|
||||
['@nuxtjs/axios'],
|
||||
['@nuxtjs/toast'],
|
||||
['@nuxtjs/google-analytics'],
|
||||
['@nuxtjs/sitemap'],
|
||||
['@nuxtjs/google-tag-manager', {
|
||||
id: process.env.GTM_ID || 'GTM-MXWD8NQ'
|
||||
}],
|
||||
['@nuxtjs/robots']
|
||||
["@nuxtjs/pwa"],
|
||||
["@nuxtjs/axios"],
|
||||
["@nuxtjs/toast"],
|
||||
["@nuxtjs/google-analytics"],
|
||||
["@nuxtjs/sitemap"],
|
||||
[
|
||||
"@nuxtjs/google-tag-manager",
|
||||
{
|
||||
id: process.env.GTM_ID || "GTM-MXWD8NQ"
|
||||
}
|
||||
],
|
||||
["@nuxtjs/robots"],
|
||||
["nuxt-i18n"]
|
||||
],
|
||||
pwa: {
|
||||
manifest: {
|
||||
@@ -237,45 +257,112 @@ export default {
|
||||
|
||||
display: "standalone",
|
||||
|
||||
theme_color: "#252628",
|
||||
background_color: "#252628",
|
||||
theme_color: "#202124",
|
||||
background_color: "#202124",
|
||||
start_url: `${routerBase.router.base}`
|
||||
},
|
||||
|
||||
meta: {
|
||||
description: meta.shortDescription,
|
||||
theme_color: "#252628",
|
||||
theme_color: "#202124"
|
||||
},
|
||||
|
||||
icons: ((sizes) => {
|
||||
icons: (sizes => {
|
||||
let icons = [];
|
||||
for (let size of sizes) {
|
||||
icons.push({
|
||||
"src": `${routerBase.router.base}icons/icon-${size}x${size}.png`,
|
||||
"type": "image/png",
|
||||
"sizes": `${size}x${size}`
|
||||
src: `${routerBase.router.base}icons/icon-${size}x${size}.png`,
|
||||
type: "image/png",
|
||||
sizes: `${size}x${size}`
|
||||
});
|
||||
}
|
||||
return icons;
|
||||
})([48, 72, 96, 144, 192, 512])
|
||||
},
|
||||
toast: {
|
||||
position: 'bottom-center',
|
||||
position: "bottom-center",
|
||||
duration: 3000,
|
||||
theme: 'bubble',
|
||||
theme: "bubble",
|
||||
keepOnHover: true
|
||||
},
|
||||
googleAnalytics: {
|
||||
id: process.env.GA_ID || 'UA-61422507-2'
|
||||
id: process.env.GA_ID || "UA-61422507-2"
|
||||
},
|
||||
sitemap: {
|
||||
hostname: 'https://postwoman.io'
|
||||
hostname: "https://postwoman.io"
|
||||
},
|
||||
robots: {
|
||||
UserAgent: '*',
|
||||
Disallow: '',
|
||||
Allow: '/',
|
||||
Sitemap: 'https://postwoman.io/sitemap.xml'
|
||||
UserAgent: "*",
|
||||
Disallow: "",
|
||||
Allow: "/",
|
||||
Sitemap: "https://postwoman.io/sitemap.xml"
|
||||
},
|
||||
i18n: {
|
||||
locales: [
|
||||
{
|
||||
code: "en",
|
||||
name: "English",
|
||||
iso: "en-US",
|
||||
file: "en-US.js"
|
||||
},
|
||||
{
|
||||
code: "es",
|
||||
name: "Español",
|
||||
iso: "es-ES",
|
||||
file: "es-ES.js"
|
||||
},
|
||||
{
|
||||
code: "fr",
|
||||
name: "Français",
|
||||
iso: "fr-FR",
|
||||
file: "fr-FR.js"
|
||||
},
|
||||
{
|
||||
code: "fa",
|
||||
name: "Farsi",
|
||||
iso: "fa-IR",
|
||||
file: "fa-IR.js"
|
||||
},
|
||||
{
|
||||
code: "pt",
|
||||
name: "Português Brasileiro",
|
||||
iso: "pt-BR",
|
||||
file: "pt-BR.js"
|
||||
},
|
||||
{
|
||||
code: "cn",
|
||||
name: "简体中文",
|
||||
iso: "zh-CN",
|
||||
file: "zh-CN.js"
|
||||
},
|
||||
{
|
||||
code: "id",
|
||||
name: "Bahasa Indonesia",
|
||||
iso: "id-ID",
|
||||
file: "id-ID.js"
|
||||
},
|
||||
{
|
||||
code: "tr",
|
||||
name: "Türkçe",
|
||||
iso: "tr-TR",
|
||||
file: "tr-TR.js"
|
||||
},
|
||||
{
|
||||
code: "de",
|
||||
name: "Deutsch",
|
||||
iso: "de-DE",
|
||||
file: "de-DE.js"
|
||||
},
|
||||
{
|
||||
code: "ja",
|
||||
name: "日本語",
|
||||
iso: "ja-JP",
|
||||
file: "ja-JP.js"
|
||||
}
|
||||
],
|
||||
defaultLocale: "en",
|
||||
lazy: true,
|
||||
langDir: "lang/"
|
||||
},
|
||||
/*
|
||||
** Build configuration
|
||||
@@ -296,4 +383,4 @@ export default {
|
||||
** Router configuration
|
||||
*/
|
||||
...routerBase
|
||||
}
|
||||
};
|
||||
|
||||
3212
package-lock.json
generated
24
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "postwoman",
|
||||
"version": "1.0.0",
|
||||
"description": "A free, fast, and beautiful API request builder",
|
||||
"version": "1.5.0",
|
||||
"description": "A free, fast and beautiful API request builder",
|
||||
"author": "liyasthomas",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -18,25 +18,27 @@
|
||||
"test": "start-server-and-test dev http://localhost:3000 e2e"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nuxtjs/axios": "^5.8.0",
|
||||
"@nuxtjs/google-analytics": "^2.2.1",
|
||||
"@nuxtjs/axios": "^5.9.2",
|
||||
"@nuxtjs/google-analytics": "^2.2.2",
|
||||
"@nuxtjs/google-tag-manager": "^2.3.1",
|
||||
"@nuxtjs/pwa": "^3.0.0-beta.19",
|
||||
"@nuxtjs/robots": "^2.4.2",
|
||||
"@nuxtjs/sitemap": "^2.0.0",
|
||||
"@nuxtjs/sitemap": "^2.0.1",
|
||||
"@nuxtjs/toast": "^3.3.0",
|
||||
"highlight.js": "^9.16.2",
|
||||
"nuxt": "^2.10.2",
|
||||
"ace-builds": "^1.4.7",
|
||||
"graphql": "^14.5.8",
|
||||
"nuxt": "^2.11.0",
|
||||
"nuxt-i18n": "^6.4.1",
|
||||
"v-tooltip": "^2.0.2",
|
||||
"vue-virtual-scroll-list": "^1.4.2",
|
||||
"vue-virtual-scroll-list": "^1.4.4",
|
||||
"vuejs-auto-complete": "^0.9.0",
|
||||
"vuex-persist": "^2.1.1",
|
||||
"vuex-persist": "^2.2.0",
|
||||
"yargs-parser": "^16.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cypress": "^3.6.0",
|
||||
"cypress": "^3.8.1",
|
||||
"node-sass": "^4.13.0",
|
||||
"sass-loader": "^7.3.1",
|
||||
"sass-loader": "^8.0.0",
|
||||
"start-server-and-test": "^1.10.6"
|
||||
}
|
||||
}
|
||||
|
||||
387
pages/doc.vue
Normal file
@@ -0,0 +1,387 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<pw-section class="blue" label="Collections" ref="collections">
|
||||
<ul>
|
||||
<li>
|
||||
<p class="info">
|
||||
Import any Postwoman Collection to Generate Documentation on-the-go.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="collectionUpload">
|
||||
<button
|
||||
class="icon"
|
||||
@click="$refs.collectionUpload.click()"
|
||||
v-tooltip="'JSON'"
|
||||
>
|
||||
<i class="material-icons">folder</i>
|
||||
<span>Import collections</span>
|
||||
</button>
|
||||
</label>
|
||||
<input
|
||||
ref="collectionUpload"
|
||||
name="collectionUpload"
|
||||
type="file"
|
||||
@change="uploadCollection"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<Editor
|
||||
v-model="collectionJSON"
|
||||
:lang="'json'"
|
||||
:options="{
|
||||
maxLines: '16',
|
||||
minLines: '8',
|
||||
fontSize: '16px',
|
||||
autoScrollEditorIntoView: true,
|
||||
showPrintMargin: false,
|
||||
useWorker: false
|
||||
}"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="getDoc">
|
||||
<i class="material-icons">book</i>
|
||||
<span>Generate Documentation</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section class="green" label="Documentation" ref="documentation">
|
||||
<p v-if="this.items.length === 0" class="info">
|
||||
Generate documentation first
|
||||
</p>
|
||||
<div>
|
||||
<span
|
||||
class="collection"
|
||||
v-for="(collection, index) in this.items"
|
||||
:key="index"
|
||||
>
|
||||
<h2>
|
||||
<i class="material-icons">folder</i>
|
||||
{{ collection.name || "None" }}
|
||||
</h2>
|
||||
<span
|
||||
class="folder"
|
||||
v-for="(folder, index) in collection.folders"
|
||||
:key="index"
|
||||
>
|
||||
<h3>
|
||||
<i class="material-icons">folder_open</i>
|
||||
{{ folder.name || "None" }}
|
||||
</h3>
|
||||
<span
|
||||
class="request"
|
||||
v-for="(request, index) in folder.requests"
|
||||
:key="index"
|
||||
>
|
||||
<h4>
|
||||
<i class="material-icons">insert_drive_file</i>
|
||||
{{ request.name || "None" }}
|
||||
</h4>
|
||||
<p class="doc-desc" v-if="request.url">
|
||||
<span>
|
||||
URL: <code>{{ request.url || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.path">
|
||||
<span>
|
||||
Path: <code>{{ request.path || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.method">
|
||||
<span>
|
||||
Method: <code>{{ request.method || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.auth">
|
||||
<span>
|
||||
Authentication:
|
||||
<code>{{ request.auth || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.httpUser">
|
||||
<span>
|
||||
Username: <code>{{ request.httpUser || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.httpPassword">
|
||||
<span>
|
||||
Password:
|
||||
<code>{{ request.httpPassword || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.bearerToken">
|
||||
<span>
|
||||
Token: <code>{{ request.bearerToken || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<h4 v-if="request.headers.length > 0">Headers</h4>
|
||||
<span
|
||||
v-if="request.headers"
|
||||
v-for="header in request.headers"
|
||||
:key="header.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ header.key || "None" }}:
|
||||
<code>{{ header.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<h4 v-if="request.params.length > 0">Parameters</h4>
|
||||
<span
|
||||
v-if="request.params"
|
||||
v-for="parameter in request.params"
|
||||
:key="parameter.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ parameter.key || "None" }}:
|
||||
<code>{{ parameter.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<h4 v-if="request.bodyParam">Payload</h4>
|
||||
<span
|
||||
v-if="request.bodyParam"
|
||||
v-for="payload in request.bodyParam"
|
||||
:key="payload.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ payload.key || "None" }}:
|
||||
<code>{{ payload.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<p class="doc-desc" v-if="request.rawParams">
|
||||
<span>
|
||||
Parameters: <code>{{ request.rawParams || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.contentType">
|
||||
<span>
|
||||
Content Type:
|
||||
<code>{{ request.contentType || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.requestType">
|
||||
<span>
|
||||
Request Type:
|
||||
<code>{{ request.requestType || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="request"
|
||||
v-for="(request, index) in collection.requests"
|
||||
:key="`request-${index}`"
|
||||
>
|
||||
<h4>
|
||||
<i class="material-icons">insert_drive_file</i>
|
||||
{{ request.name || "None" }}
|
||||
</h4>
|
||||
<p class="doc-desc" v-if="request.url">
|
||||
<span>
|
||||
URL: <code>{{ request.url || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.path">
|
||||
<span>
|
||||
Path: <code>{{ request.path || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.method">
|
||||
<span>
|
||||
Method: <code>{{ request.method || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.auth">
|
||||
<span>
|
||||
Authentication:
|
||||
<code>{{ request.auth || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.httpUser">
|
||||
<span>
|
||||
Username: <code>{{ request.httpUser || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.httpPassword">
|
||||
<span>
|
||||
Password: <code>{{ request.httpPassword || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.bearerToken">
|
||||
<span>
|
||||
Token: <code>{{ request.bearerToken || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<h4 v-if="request.headers.length > 0">Headers</h4>
|
||||
<span
|
||||
v-if="request.headers"
|
||||
v-for="header in request.headers"
|
||||
:key="header.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ header.key || "None" }}:
|
||||
<code>{{ header.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<h4 v-if="request.params.length > 0">Parameters</h4>
|
||||
<span
|
||||
v-if="request.params"
|
||||
v-for="parameter in request.params"
|
||||
:key="parameter.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ parameter.key || "None" }}:
|
||||
<code>{{ parameter.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<h4 v-if="request.bodyParam">Payload</h4>
|
||||
<span
|
||||
v-if="request.bodyParam"
|
||||
v-for="payload in request.bodyParam"
|
||||
:key="payload.key"
|
||||
>
|
||||
<p class="doc-desc">
|
||||
<span>
|
||||
{{ payload.key || "None" }}:
|
||||
<code>{{ payload.value || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
<p class="doc-desc" v-if="request.rawParams">
|
||||
<span>
|
||||
Parameters: <code>{{ request.rawParams || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.contentType">
|
||||
<span>
|
||||
Content Type:
|
||||
<code>{{ request.contentType || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
<p class="doc-desc" v-if="request.requestType">
|
||||
<span>
|
||||
Request Type:
|
||||
<code>{{ request.requestType || "None" }}</code>
|
||||
</span>
|
||||
</p>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</pw-section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.collection,
|
||||
.folder,
|
||||
.request,
|
||||
.doc-desc {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
|
||||
.material-icons {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.collection {
|
||||
}
|
||||
|
||||
.folder {
|
||||
border-left: 1px solid var(--brd-color);
|
||||
margin: 16px 0 0;
|
||||
}
|
||||
|
||||
.request {
|
||||
border: 1px solid var(--brd-color);
|
||||
border-radius: 8px;
|
||||
margin: 16px 0 0;
|
||||
|
||||
h4 {
|
||||
margin: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.doc-desc {
|
||||
color: var(--fg-light-color);
|
||||
border-bottom: 1px dashed var(--brd-color);
|
||||
margin: 0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import AceEditor from "../components/ace-editor";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": () => import("../components/section"),
|
||||
Editor: AceEditor
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
collectionJSON: "[]",
|
||||
items: []
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
uploadCollection() {
|
||||
this.rawInput = true;
|
||||
let file = this.$refs.collectionUpload.files[0];
|
||||
if (file !== undefined && file !== null) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = e => {
|
||||
this.collectionJSON = e.target.result;
|
||||
};
|
||||
reader.readAsText(file);
|
||||
this.$toast.info("File imported", {
|
||||
icon: "attach_file"
|
||||
});
|
||||
} else {
|
||||
this.$toast.error("Choose a file", {
|
||||
icon: "attach_file"
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getDoc() {
|
||||
try {
|
||||
this.items = JSON.parse(this.collectionJSON);
|
||||
this.$toast.info("Documentation generated", {
|
||||
icon: "book"
|
||||
});
|
||||
} catch (e) {
|
||||
this.$toast.error(e, {
|
||||
icon: "code"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
888
pages/graphql.vue
Normal file
@@ -0,0 +1,888 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<div class="content">
|
||||
<div class="page-columns inner-left">
|
||||
<pw-section class="blue" label="Endpoint" ref="endpoint">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="url">{{ $t("url") }}</label>
|
||||
<input
|
||||
id="url"
|
||||
type="url"
|
||||
v-model="url"
|
||||
@keyup.enter="getSchema()"
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<label for="get" class="hide-on-small-screen"> </label>
|
||||
<button id="get" name="get" @click="getSchema">
|
||||
{{ $t("get_schema") }}
|
||||
<span><i class="material-icons">send</i></span>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section class="orange" label="Headers" ref="headers">
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<label for="headerList">{{ $t("header_list") }}</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="headers = []"
|
||||
v-tooltip.bottom="'Clear'"
|
||||
>
|
||||
<i class="material-icons">clear_all</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<textarea
|
||||
id="headerList"
|
||||
readonly
|
||||
v-textarea-auto-height="headerString"
|
||||
v-model="headerString"
|
||||
placeholder="(add at least one header)"
|
||||
rows="1"
|
||||
></textarea>
|
||||
</li>
|
||||
</ul>
|
||||
<ul v-for="(header, index) in headers" :key="index">
|
||||
<li>
|
||||
<autocomplete
|
||||
:placeholder="'header ' + (index + 1)"
|
||||
:source="commonHeaders"
|
||||
:spellcheck="false"
|
||||
:value="header.key"
|
||||
@input="
|
||||
$store.commit('setGQLHeaderKey', {
|
||||
index,
|
||||
value: $event
|
||||
})
|
||||
"
|
||||
autofocus
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
:placeholder="'value ' + (index + 1)"
|
||||
:name="'value' + index"
|
||||
:value="header.value"
|
||||
@change="
|
||||
$store.commit('setGQLHeaderValue', {
|
||||
index,
|
||||
value: $event.target.value
|
||||
})
|
||||
"
|
||||
autofocus
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<button
|
||||
class="icon"
|
||||
@click="removeRequestHeader(index)"
|
||||
id="header"
|
||||
>
|
||||
<i class="material-icons">delete</i>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="addRequestHeader">
|
||||
<i class="material-icons">add</i>
|
||||
<span>{{ $t("add_new") }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section class="green" label="Schema" ref="schema">
|
||||
<div class="flex-wrap">
|
||||
<label>{{ $t("response") }}</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="ToggleExpandResponse"
|
||||
ref="ToggleExpandResponse"
|
||||
v-tooltip="{
|
||||
content: !expandResponse
|
||||
? 'Expand response'
|
||||
: 'Collapse response'
|
||||
}"
|
||||
>
|
||||
<i class="material-icons">
|
||||
{{ !expandResponse ? "unfold_more" : "unfold_less" }}
|
||||
</i>
|
||||
</button>
|
||||
<button
|
||||
class="icon"
|
||||
@click="downloadResponse"
|
||||
ref="downloadResponse"
|
||||
v-tooltip="'Download file'"
|
||||
>
|
||||
<i class="material-icons">get_app</i>
|
||||
</button>
|
||||
<button
|
||||
class="icon"
|
||||
ref="copySchemaCode"
|
||||
@click="copySchema"
|
||||
v-tooltip="'Copy Schema'"
|
||||
>
|
||||
<i class="material-icons">file_copy</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<Editor
|
||||
:value="schemaString"
|
||||
:lang="'graphqlschema'"
|
||||
:options="{
|
||||
maxLines: responseBodyMaxLines,
|
||||
minLines: '16',
|
||||
fontSize: '16px',
|
||||
autoScrollEditorIntoView: true,
|
||||
readOnly: true,
|
||||
showPrintMargin: false,
|
||||
useWorker: false
|
||||
}"
|
||||
/>
|
||||
</pw-section>
|
||||
|
||||
<pw-section class="cyan" label="Query" ref="query">
|
||||
<div class="flex-wrap">
|
||||
<label for="gqlQuery">{{ $t("query") }}</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="runQuery()"
|
||||
v-tooltip.bottom="'Run Query'"
|
||||
>
|
||||
<i class="material-icons">play_arrow</i>
|
||||
</button>
|
||||
<button
|
||||
class="icon"
|
||||
@click="copyQuery"
|
||||
ref="copyQueryButton"
|
||||
v-tooltip="'Copy Query'"
|
||||
>
|
||||
<i class="material-icons">file_copy</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<Editor
|
||||
v-model="gqlQueryString"
|
||||
:options="{
|
||||
maxLines: responseBodyMaxLines,
|
||||
minLines: '16',
|
||||
fontSize: '16px',
|
||||
autoScrollEditorIntoView: true,
|
||||
showPrintMargin: false,
|
||||
useWorker: false
|
||||
}"
|
||||
/>
|
||||
<div class="flex-wrap">
|
||||
<label>{{ $t("query_variables") }}</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="variables = []"
|
||||
v-tooltip.bottom="'Clear'"
|
||||
>
|
||||
<i class="material-icons">clear_all</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul v-for="(variable, index) in variables" :key="index">
|
||||
<li>
|
||||
<input
|
||||
:placeholder="'variable ' + (index + 1)"
|
||||
:name="'variable_key_' + index"
|
||||
:value="variable.key"
|
||||
@change="
|
||||
$store.commit('setGQLVariableKey', {
|
||||
index,
|
||||
value: $event.target.value
|
||||
})
|
||||
"
|
||||
autofocus
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<input
|
||||
:placeholder="'value ' + (index + 1)"
|
||||
:name="'variable_value_' + index"
|
||||
:value="variable.value"
|
||||
@change="
|
||||
$store.commit('setGQLVariableValue', {
|
||||
index,
|
||||
value: $event.target.value
|
||||
})
|
||||
"
|
||||
autofocus
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<button class="icon" @click="removeQueryVariable(index)">
|
||||
<i class="material-icons">delete</i>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<button class="icon" @click="addQueryVariable">
|
||||
<i class="material-icons">add</i>
|
||||
<span>{{ $t("add_new") }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section class="purple" label="Response" ref="response">
|
||||
<div class="flex-wrap">
|
||||
<label for="responseField">{{ $t("response") }}</label>
|
||||
<div>
|
||||
<button
|
||||
class="icon"
|
||||
@click="copyResponse"
|
||||
ref="copyResponseButton"
|
||||
v-tooltip="'Copy Response'"
|
||||
>
|
||||
<i class="material-icons">file_copy</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<Editor
|
||||
:value="responseString"
|
||||
:lang="'json'"
|
||||
:options="{
|
||||
maxLines: responseBodyMaxLines,
|
||||
minLines: '16',
|
||||
fontSize: '16px',
|
||||
autoScrollEditorIntoView: true,
|
||||
readOnly: true,
|
||||
showPrintMargin: false,
|
||||
useWorker: false
|
||||
}"
|
||||
/>
|
||||
</pw-section>
|
||||
</div>
|
||||
<aside class="sticky-inner inner-right">
|
||||
<pw-section class="purple" label="Docs" ref="docs">
|
||||
<section>
|
||||
<input
|
||||
v-if="queryFields.length > 0"
|
||||
id="queries-tab"
|
||||
type="radio"
|
||||
name="side"
|
||||
checked="checked"
|
||||
/>
|
||||
<label v-if="queryFields.length > 0" for="queries-tab">
|
||||
{{ $t("queries") }}
|
||||
</label>
|
||||
<div v-if="queryFields.length > 0" class="tab">
|
||||
<div v-for="field in queryFields" :key="field.name">
|
||||
<gql-field :gqlField="field" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
v-if="mutationFields.length > 0"
|
||||
id="mutations-tab"
|
||||
type="radio"
|
||||
name="side"
|
||||
checked="checked"
|
||||
/>
|
||||
<label v-if="mutationFields.length > 0" for="mutations-tab">
|
||||
{{ $t("mutations") }}
|
||||
</label>
|
||||
<div v-if="mutationFields.length > 0" class="tab">
|
||||
<div v-for="field in mutationFields" :key="field.name">
|
||||
<gql-field :gqlField="field" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
v-if="subscriptionFields.length > 0"
|
||||
id="subscriptions-tab"
|
||||
type="radio"
|
||||
name="side"
|
||||
checked="checked"
|
||||
/>
|
||||
<label v-if="subscriptionFields.length > 0" for="subscriptions-tab">
|
||||
{{ $t("subscriptions") }}
|
||||
</label>
|
||||
<div v-if="subscriptionFields.length > 0" class="tab">
|
||||
<div v-for="field in subscriptionFields" :key="field.name">
|
||||
<gql-field :gqlField="field" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input
|
||||
v-if="gqlTypes.length > 0"
|
||||
id="gqltypes-tab"
|
||||
type="radio"
|
||||
name="side"
|
||||
checked="checked"
|
||||
/>
|
||||
<label v-if="gqlTypes.length > 0" for="gqltypes-tab">
|
||||
{{ $t("types") }}
|
||||
</label>
|
||||
<div v-if="gqlTypes.length > 0" class="tab">
|
||||
<div v-for="type in gqlTypes" :key="type.name">
|
||||
<gql-type :gqlType="type" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p
|
||||
v-if="
|
||||
queryFields.length === 0 &&
|
||||
mutationFields.length === 0 &&
|
||||
subscriptionFields.length === 0 &&
|
||||
gqlTypes.length === 0
|
||||
"
|
||||
class="info"
|
||||
>
|
||||
Send a request first
|
||||
</p>
|
||||
</pw-section>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tab {
|
||||
max-height: calc(100vh - 186px);
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import * as gql from "graphql";
|
||||
import textareaAutoHeight from "../directives/textareaAutoHeight";
|
||||
import AceEditor from "../components/ace-editor";
|
||||
|
||||
export default {
|
||||
directives: {
|
||||
textareaAutoHeight
|
||||
},
|
||||
components: {
|
||||
"pw-section": () => import("../components/section"),
|
||||
"gql-field": () => import("../components/graphql/field"),
|
||||
"gql-type": () => import("../components/graphql/type"),
|
||||
autocomplete: () => import("../components/autocomplete"),
|
||||
Editor: AceEditor
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
schemaString: "",
|
||||
commonHeaders: [
|
||||
"WWW-Authenticate",
|
||||
"Authorization",
|
||||
"Proxy-Authenticate",
|
||||
"Proxy-Authorization",
|
||||
"Age",
|
||||
"Cache-Control",
|
||||
"Clear-Site-Data",
|
||||
"Expires",
|
||||
"Pragma",
|
||||
"Warning",
|
||||
"Accept-CH",
|
||||
"Accept-CH-Lifetime",
|
||||
"Early-Data",
|
||||
"Content-DPR",
|
||||
"DPR",
|
||||
"Device-Memory",
|
||||
"Save-Data",
|
||||
"Viewport-Width",
|
||||
"Width",
|
||||
"Last-Modified",
|
||||
"ETag",
|
||||
"If-Match",
|
||||
"If-None-Match",
|
||||
"If-Modified-Since",
|
||||
"If-Unmodified-Since",
|
||||
"Vary",
|
||||
"Connection",
|
||||
"Keep-Alive",
|
||||
"Accept",
|
||||
"Accept-Charset",
|
||||
"Accept-Encoding",
|
||||
"Accept-Language",
|
||||
"Expect",
|
||||
"Max-Forwards",
|
||||
"Cookie",
|
||||
"Set-Cookie",
|
||||
"Cookie2",
|
||||
"Set-Cookie2",
|
||||
"Access-Control-Allow-Origin",
|
||||
"Access-Control-Allow-Credentials",
|
||||
"Access-Control-Allow-Headers",
|
||||
"Access-Control-Allow-Methods",
|
||||
"Access-Control-Expose-Headers",
|
||||
"Access-Control-Max-Age",
|
||||
"Access-Control-Request-Headers",
|
||||
"Access-Control-Request-Method",
|
||||
"Origin",
|
||||
"Service-Worker-Allowed",
|
||||
"Timing-Allow-Origin",
|
||||
"X-Permitted-Cross-Domain-Policies",
|
||||
"DNT",
|
||||
"Tk",
|
||||
"Content-Disposition",
|
||||
"Content-Length",
|
||||
"Content-Type",
|
||||
"Content-Encoding",
|
||||
"Content-Language",
|
||||
"Content-Location",
|
||||
"Forwarded",
|
||||
"X-Forwarded-For",
|
||||
"X-Forwarded-Host",
|
||||
"X-Forwarded-Proto",
|
||||
"Via",
|
||||
"Location",
|
||||
"From",
|
||||
"Host",
|
||||
"Referer",
|
||||
"Referrer-Policy",
|
||||
"User-Agent",
|
||||
"Allow",
|
||||
"Server",
|
||||
"Accept-Ranges",
|
||||
"Range",
|
||||
"If-Range",
|
||||
"Content-Range",
|
||||
"Cross-Origin-Opener-Policy",
|
||||
"Cross-Origin-Resource-Policy",
|
||||
"Content-Security-Policy",
|
||||
"Content-Security-Policy-Report-Only",
|
||||
"Expect-CT",
|
||||
"Feature-Policy",
|
||||
"Public-Key-Pins",
|
||||
"Public-Key-Pins-Report-Only",
|
||||
"Strict-Transport-Security",
|
||||
"Upgrade-Insecure-Requests",
|
||||
"X-Content-Type-Options",
|
||||
"X-Download-Options",
|
||||
"X-Frame-Options",
|
||||
"X-Powered-By",
|
||||
"X-XSS-Protection",
|
||||
"Last-Event-ID",
|
||||
"NEL",
|
||||
"Ping-From",
|
||||
"Ping-To",
|
||||
"Report-To",
|
||||
"Transfer-Encoding",
|
||||
"TE",
|
||||
"Trailer",
|
||||
"Sec-WebSocket-Key",
|
||||
"Sec-WebSocket-Extensions",
|
||||
"Sec-WebSocket-Accept",
|
||||
"Sec-WebSocket-Protocol",
|
||||
"Sec-WebSocket-Version",
|
||||
"Accept-Push-Policy",
|
||||
"Accept-Signature",
|
||||
"Alt-Svc",
|
||||
"Date",
|
||||
"Large-Allocation",
|
||||
"Link",
|
||||
"Push-Policy",
|
||||
"Retry-After",
|
||||
"Signature",
|
||||
"Signed-Headers",
|
||||
"Server-Timing",
|
||||
"SourceMap",
|
||||
"Upgrade",
|
||||
"X-DNS-Prefetch-Control",
|
||||
"X-Firefox-Spdy",
|
||||
"X-Pingback",
|
||||
"X-Requested-With",
|
||||
"X-Robots-Tag",
|
||||
"X-UA-Compatible"
|
||||
],
|
||||
queryFields: [],
|
||||
mutationFields: [],
|
||||
subscriptionFields: [],
|
||||
gqlTypes: [],
|
||||
responseString: "",
|
||||
copyButton: '<i class="material-icons">file_copy</i>',
|
||||
downloadButton: '<i class="material-icons">get_app</i>',
|
||||
doneButton: '<i class="material-icons">done</i>',
|
||||
expandResponse: false,
|
||||
responseBodyMaxLines: 16
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
url: {
|
||||
get() {
|
||||
return this.$store.state.gql.url;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit("setGQLState", { value, attribute: "url" });
|
||||
}
|
||||
},
|
||||
headers: {
|
||||
get() {
|
||||
return this.$store.state.gql.headers;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit("setGQLState", { value, attribute: "headers" });
|
||||
}
|
||||
},
|
||||
variables: {
|
||||
get() {
|
||||
return this.$store.state.gql.variables;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit("setGQLState", { value, attribute: "variables" });
|
||||
}
|
||||
},
|
||||
gqlQueryString: {
|
||||
get() {
|
||||
return this.$store.state.gql.query;
|
||||
},
|
||||
set(value) {
|
||||
this.$store.commit("setGQLState", { value, attribute: "query" });
|
||||
}
|
||||
},
|
||||
headerString() {
|
||||
const result = this.headers
|
||||
.filter(({ key }) => !!key)
|
||||
.map(({ key, value }) => `${key}: ${value}`)
|
||||
.join(",\n");
|
||||
return result === "" ? "" : `${result}`;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copySchema() {
|
||||
this.$refs.copySchemaCode.innerHTML = this.doneButton;
|
||||
const aux = document.createElement("textarea");
|
||||
aux.innerText = this.schemaString;
|
||||
document.body.appendChild(aux);
|
||||
aux.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(aux);
|
||||
this.$toast.success("Copied to clipboard", {
|
||||
icon: "done"
|
||||
});
|
||||
setTimeout(
|
||||
() => (this.$refs.copySchemaCode.innerHTML = this.copyButton),
|
||||
1000
|
||||
);
|
||||
},
|
||||
copyQuery() {
|
||||
this.$refs.copyQueryButton.innerHTML = this.doneButton;
|
||||
const aux = document.createElement("textarea");
|
||||
aux.innerText = this.gqlQueryString;
|
||||
document.body.appendChild(aux);
|
||||
aux.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(aux);
|
||||
this.$toast.success("Copied to clipboard", {
|
||||
icon: "done"
|
||||
});
|
||||
setTimeout(
|
||||
() => (this.$refs.copyQueryButton.innerHTML = this.copyButton),
|
||||
1000
|
||||
);
|
||||
},
|
||||
copyResponse() {
|
||||
this.$refs.copyResponseButton.innerHTML = this.doneButton;
|
||||
const aux = document.createElement("textarea");
|
||||
aux.innerText = this.responseString;
|
||||
document.body.appendChild(aux);
|
||||
aux.select();
|
||||
document.execCommand("copy");
|
||||
document.body.removeChild(aux);
|
||||
this.$toast.success("Copied to clipboard", {
|
||||
icon: "done"
|
||||
});
|
||||
setTimeout(
|
||||
() => (this.$refs.copyResponseButton.innerHTML = this.copyButton),
|
||||
1000
|
||||
);
|
||||
},
|
||||
async runQuery() {
|
||||
const startTime = Date.now();
|
||||
|
||||
this.$nuxt.$loading.start();
|
||||
this.scrollInto("response");
|
||||
|
||||
try {
|
||||
let headers = {};
|
||||
this.headers.forEach(header => {
|
||||
headers[header.key] = header.value;
|
||||
});
|
||||
|
||||
let variables = {};
|
||||
const gqlQueryString = this.gqlQueryString;
|
||||
this.variables.forEach(variable => {
|
||||
// todo: better variable type validation
|
||||
const intRex = new RegExp(`\$${variable.key}\: Int`);
|
||||
intRex.compile();
|
||||
const floatRex = new RegExp(`\$${variable.key}\: Float`);
|
||||
floatRex.compile();
|
||||
|
||||
if (intRex.test(gqlQueryString)) {
|
||||
variables[variable.key] = parseInt(variable.value);
|
||||
} else if (floatRex.test(gqlQueryString)) {
|
||||
variables[variable.key] = parseFloat(variable.value);
|
||||
} else {
|
||||
variables[variable.key] = variable.value;
|
||||
}
|
||||
});
|
||||
|
||||
const reqOptions = {
|
||||
method: "post",
|
||||
url: this.url,
|
||||
headers: {
|
||||
...headers,
|
||||
"content-type": "application/json"
|
||||
},
|
||||
data: JSON.stringify({ query: gqlQueryString, variables })
|
||||
};
|
||||
|
||||
const reqConfig = this.$store.state.postwoman.settings.PROXY_ENABLED
|
||||
? {
|
||||
method: "post",
|
||||
url:
|
||||
this.$store.state.postwoman.settings.PROXY_URL ||
|
||||
`https://postwoman.apollotv.xyz/`,
|
||||
data: reqOptions
|
||||
}
|
||||
: reqOptions;
|
||||
|
||||
const res = await axios(reqConfig);
|
||||
|
||||
const data = this.$store.state.postwoman.settings.PROXY_ENABLED
|
||||
? res.data
|
||||
: res;
|
||||
|
||||
this.responseString = JSON.stringify(data.data, null, 2);
|
||||
|
||||
this.$nuxt.$loading.finish();
|
||||
const duration = Date.now() - startTime;
|
||||
this.$toast.info(`Finished in ${duration}ms`, {
|
||||
icon: "done"
|
||||
});
|
||||
} catch (error) {
|
||||
this.$nuxt.$loading.finish();
|
||||
|
||||
this.$toast.error(error + " (F12 for details)", {
|
||||
icon: "error"
|
||||
});
|
||||
console.log("Error", error);
|
||||
}
|
||||
},
|
||||
async getSchema() {
|
||||
const startTime = Date.now();
|
||||
this.schemaString = "Loading...";
|
||||
this.scrollInto("schema");
|
||||
|
||||
// Start showing the loading bar as soon as possible.
|
||||
// The nuxt axios module will hide it when the request is made.
|
||||
this.$nuxt.$loading.start();
|
||||
|
||||
try {
|
||||
const query = JSON.stringify({
|
||||
query: gql.getIntrospectionQuery()
|
||||
});
|
||||
|
||||
let headers = {};
|
||||
this.headers.forEach(header => {
|
||||
headers[header.key] = header.value;
|
||||
});
|
||||
|
||||
const reqOptions = {
|
||||
method: "post",
|
||||
url: this.url,
|
||||
headers: {
|
||||
...headers,
|
||||
"content-type": "application/json"
|
||||
},
|
||||
data: query
|
||||
};
|
||||
|
||||
// console.log(reqOptions);
|
||||
|
||||
const reqConfig = this.$store.state.postwoman.settings.PROXY_ENABLED
|
||||
? {
|
||||
method: "post",
|
||||
url:
|
||||
this.$store.state.postwoman.settings.PROXY_URL ||
|
||||
`https://postwoman.apollotv.xyz/`,
|
||||
data: reqOptions
|
||||
}
|
||||
: reqOptions;
|
||||
|
||||
const res = await axios(reqConfig);
|
||||
|
||||
const data = this.$store.state.postwoman.settings.PROXY_ENABLED
|
||||
? res.data
|
||||
: res;
|
||||
|
||||
const schema = gql.buildClientSchema(data.data.data);
|
||||
this.schemaString = gql.printSchema(schema, {
|
||||
commentDescriptions: true
|
||||
});
|
||||
|
||||
if (schema.getQueryType()) {
|
||||
const fields = schema.getQueryType().getFields();
|
||||
const qFields = [];
|
||||
for (const field in fields) {
|
||||
qFields.push(fields[field]);
|
||||
}
|
||||
this.queryFields = qFields;
|
||||
}
|
||||
|
||||
if (schema.getMutationType()) {
|
||||
const fields = schema.getMutationType().getFields();
|
||||
const mFields = [];
|
||||
for (const field in fields) {
|
||||
mFields.push(fields[field]);
|
||||
}
|
||||
this.mutationFields = mFields;
|
||||
}
|
||||
|
||||
if (schema.getSubscriptionType()) {
|
||||
const fields = schema.getSubscriptionType().getFields();
|
||||
const sFields = [];
|
||||
for (const field in fields) {
|
||||
sFields.push(fields[field]);
|
||||
}
|
||||
this.subscriptionFields = sFields;
|
||||
}
|
||||
|
||||
const typeMap = schema.getTypeMap();
|
||||
const types = [];
|
||||
|
||||
const queryTypeName = schema.getQueryType()
|
||||
? schema.getQueryType().name
|
||||
: "";
|
||||
const mutationTypeName = schema.getMutationType()
|
||||
? schema.getMutationType().name
|
||||
: "";
|
||||
const subscriptionTypeName = schema.getSubscriptionType()
|
||||
? schema.getSubscriptionType().name
|
||||
: "";
|
||||
|
||||
for (const type in typeMap) {
|
||||
if (
|
||||
!typeMap[type].name.startsWith("__") &&
|
||||
![queryTypeName, mutationTypeName, subscriptionTypeName].includes(
|
||||
typeMap[type].name
|
||||
) &&
|
||||
typeMap[type] instanceof gql.GraphQLObjectType
|
||||
) {
|
||||
types.push(typeMap[type]);
|
||||
}
|
||||
}
|
||||
this.gqlTypes = types;
|
||||
|
||||
this.$nuxt.$loading.finish();
|
||||
const duration = Date.now() - startTime;
|
||||
this.$toast.info(`Finished in ${duration}ms`, {
|
||||
icon: "done"
|
||||
});
|
||||
} catch (error) {
|
||||
this.$nuxt.$loading.finish();
|
||||
this.schemaString = error + ". Check console for details.";
|
||||
this.$toast.error(error + " (F12 for details)", {
|
||||
icon: "error"
|
||||
});
|
||||
console.log("Error", error);
|
||||
}
|
||||
},
|
||||
ToggleExpandResponse() {
|
||||
this.expandResponse = !this.expandResponse;
|
||||
this.responseBodyMaxLines =
|
||||
this.responseBodyMaxLines == Infinity ? 16 : Infinity;
|
||||
},
|
||||
downloadResponse() {
|
||||
const dataToWrite = JSON.stringify(this.schemaString, null, 2);
|
||||
const file = new Blob([dataToWrite], { type: "application/json" });
|
||||
const a = document.createElement("a"),
|
||||
url = URL.createObjectURL(file);
|
||||
a.href = url;
|
||||
a.download = (this.url + " on " + Date() + ".graphql").replace(
|
||||
/\./g,
|
||||
"[dot]"
|
||||
);
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
this.$refs.downloadResponse.innerHTML = this.doneButton;
|
||||
this.$toast.success("Download started", {
|
||||
icon: "done"
|
||||
});
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
this.$refs.downloadResponse.innerHTML = this.downloadButton;
|
||||
}, 1000);
|
||||
},
|
||||
addRequestHeader(index) {
|
||||
this.$store.commit("addGQLHeader", {
|
||||
key: "",
|
||||
value: ""
|
||||
});
|
||||
return false;
|
||||
},
|
||||
removeRequestHeader(index) {
|
||||
// .slice() is used so we get a separate array, rather than just a reference
|
||||
const oldHeaders = this.headers.slice();
|
||||
|
||||
this.$store.commit("removeGQLHeader", index);
|
||||
this.$toast.error("Deleted", {
|
||||
icon: "delete",
|
||||
action: {
|
||||
text: "Undo",
|
||||
duration: 4000,
|
||||
onClick: (e, toastObject) => {
|
||||
this.headers = oldHeaders;
|
||||
toastObject.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
// console.log(oldHeaders);
|
||||
},
|
||||
addQueryVariable(index) {
|
||||
this.$store.commit("addGQLVariable", {
|
||||
key: "",
|
||||
value: ""
|
||||
});
|
||||
return false;
|
||||
},
|
||||
removeQueryVariable(index) {
|
||||
const oldVariables = this.variables.slice();
|
||||
|
||||
this.$store.commit("removeGQLVariable", index);
|
||||
this.$toast.error("Deleted", {
|
||||
icon: "delete",
|
||||
action: {
|
||||
text: "Undo",
|
||||
duration: 4000,
|
||||
onClick: (e, toastObject) => {
|
||||
this.variables = oldVariables;
|
||||
toastObject.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
// console.log(oldVariables);
|
||||
},
|
||||
scrollInto(view) {
|
||||
this.$refs[view].$el.scrollIntoView({
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1839
pages/index.vue
442
pages/realtime.vue
Normal file
@@ -0,0 +1,442 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<section id="options">
|
||||
<input id="tab-one" type="radio" name="options" checked="checked" />
|
||||
<label for="tab-one">{{ $t("websocket") }}</label>
|
||||
<div class="tab">
|
||||
<pw-section class="blue" label="Request" ref="request">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="url">{{ $t("url") }}</label>
|
||||
<input
|
||||
id="url"
|
||||
type="url"
|
||||
:class="{ error: !urlValid }"
|
||||
v-model="url"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<label for="connect" class="hide-on-small-screen"> </label>
|
||||
<button
|
||||
:disabled="!urlValid"
|
||||
id="connect"
|
||||
name="connect"
|
||||
@click="toggleConnection"
|
||||
>
|
||||
{{ !connectionState ? $t("connect") : $t("disconnect") }}
|
||||
<span>
|
||||
<i class="material-icons">
|
||||
{{ !connectionState ? "sync" : "sync_disabled" }}
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section
|
||||
class="purple"
|
||||
label="Communication"
|
||||
id="response"
|
||||
ref="response"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="log">Log</label>
|
||||
<div id="log" name="log" class="log">
|
||||
<span v-if="communication.log">
|
||||
<span
|
||||
v-for="(logEntry, index) in communication.log"
|
||||
:style="{ color: logEntry.color }"
|
||||
:key="index"
|
||||
>@ {{ logEntry.ts }}{{ getSourcePrefix(logEntry.source)
|
||||
}}{{ logEntry.payload }}</span
|
||||
>
|
||||
</span>
|
||||
<span v-else>{{ $t("waiting_for_connection") }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="message">{{ $t("message") }}</label>
|
||||
<input
|
||||
id="message"
|
||||
name="message"
|
||||
type="text"
|
||||
v-model="communication.input"
|
||||
:readonly="!connectionState"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<label for="send" class="hide-on-small-screen"> </label>
|
||||
<button
|
||||
id="send"
|
||||
name="send"
|
||||
:disabled="!connectionState"
|
||||
@click="sendMessage"
|
||||
>
|
||||
{{ $t("send") }}
|
||||
<span>
|
||||
<i class="material-icons">send</i>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</pw-section>
|
||||
</div>
|
||||
<input id="tab-two" type="radio" name="options" />
|
||||
<label for="tab-two">{{ $t("sse") }}</label>
|
||||
<div class="tab">
|
||||
<pw-section class="blue" label="Request" ref="request">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="server">{{ $t("server") }}</label>
|
||||
<input
|
||||
id="server"
|
||||
type="url"
|
||||
:class="{ error: !serverValid }"
|
||||
v-model="server"
|
||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
</li>
|
||||
<div>
|
||||
<li>
|
||||
<label for="start" class="hide-on-small-screen"> </label>
|
||||
<button
|
||||
:disabled="!serverValid"
|
||||
id="start"
|
||||
name="start"
|
||||
@click="toggleSSEConnection"
|
||||
>
|
||||
{{ !connectionSSEState ? $t("start") : $t("stop") }}
|
||||
<span>
|
||||
<i class="material-icons">
|
||||
{{ !connectionSSEState ? "sync" : "sync_disabled" }}
|
||||
</i>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</div>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<pw-section
|
||||
class="purple"
|
||||
label="Communication"
|
||||
id="response"
|
||||
ref="response"
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="log">{{ $t("events") }}</label>
|
||||
<div id="log" name="log" class="log">
|
||||
<span v-if="events.log">
|
||||
<span
|
||||
v-for="(logEntry, index) in events.log"
|
||||
:style="{ color: logEntry.color }"
|
||||
:key="index"
|
||||
>@ {{ logEntry.ts }}{{ getSourcePrefix(logEntry.source)
|
||||
}}{{ logEntry.payload }}</span
|
||||
>
|
||||
</span>
|
||||
<span v-else>{{ $t("waiting_for_connection") }}</span>
|
||||
</div>
|
||||
<div id="result"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
div.log {
|
||||
margin: 4px;
|
||||
padding: 8px 16px;
|
||||
width: calc(100% - 8px);
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-dark-color);
|
||||
color: var(--fg-color);
|
||||
height: 256px;
|
||||
overflow: auto;
|
||||
|
||||
&,
|
||||
span {
|
||||
font-size: 16px;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": () => import("../components/section")
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionState: false,
|
||||
url: "wss://echo.websocket.org",
|
||||
socket: null,
|
||||
communication: {
|
||||
log: null,
|
||||
input: ""
|
||||
},
|
||||
connectionSSEState: false,
|
||||
server: "https://express-eventsource.herokuapp.com/events",
|
||||
sse: null,
|
||||
events: {
|
||||
log: null,
|
||||
input: ""
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
urlValid() {
|
||||
const protocol = "^(wss?:\\/\\/)?";
|
||||
const validIP = new RegExp(
|
||||
protocol +
|
||||
"(([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])$"
|
||||
);
|
||||
const validHostname = new RegExp(
|
||||
protocol +
|
||||
"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9/])$"
|
||||
);
|
||||
return validIP.test(this.url) || validHostname.test(this.url);
|
||||
},
|
||||
serverValid() {
|
||||
const protocol = "^(https?:\\/\\/)?";
|
||||
const validIP = new RegExp(
|
||||
protocol +
|
||||
"(([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])$"
|
||||
);
|
||||
const validHostname = new RegExp(
|
||||
protocol +
|
||||
"(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9/])$"
|
||||
);
|
||||
return validIP.test(this.server) || validHostname.test(this.server);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleConnection() {
|
||||
// If it is connecting:
|
||||
if (!this.connectionState) return this.connect();
|
||||
// Otherwise, it's disconnecting.
|
||||
else return this.disconnect();
|
||||
},
|
||||
connect() {
|
||||
this.communication.log = [
|
||||
{
|
||||
payload: `Connecting to ${this.url}...`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)"
|
||||
}
|
||||
];
|
||||
try {
|
||||
this.socket = new WebSocket(this.url);
|
||||
this.socket.onopen = event => {
|
||||
this.connectionState = true;
|
||||
this.communication.log = [
|
||||
{
|
||||
payload: `Connected to ${this.url}.`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
}
|
||||
];
|
||||
this.$toast.success("Connected", {
|
||||
icon: "sync"
|
||||
});
|
||||
};
|
||||
this.socket.onerror = event => {
|
||||
this.handleError();
|
||||
};
|
||||
this.socket.onclose = event => {
|
||||
this.connectionState = false;
|
||||
this.communication.log.push({
|
||||
payload: `Disconnected from ${this.url}.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
this.$toast.error("Disconnected", {
|
||||
icon: "sync_disabled"
|
||||
});
|
||||
};
|
||||
this.socket.onmessage = event => {
|
||||
this.communication.log.push({
|
||||
payload: event.data,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
};
|
||||
} catch (ex) {
|
||||
this.handleError(ex);
|
||||
this.$toast.error("Something went wrong!", {
|
||||
icon: "error"
|
||||
});
|
||||
}
|
||||
},
|
||||
disconnect() {
|
||||
this.socket.close();
|
||||
},
|
||||
handleError(error) {
|
||||
this.disconnect();
|
||||
this.connectionState = false;
|
||||
this.communication.log.push({
|
||||
payload: `An error has occurred.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
if (error !== null)
|
||||
this.communication.log.push({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
},
|
||||
sendMessage() {
|
||||
const message = this.communication.input;
|
||||
this.socket.send(message);
|
||||
this.communication.log.push({
|
||||
payload: message,
|
||||
source: "client",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
this.communication.input = "";
|
||||
},
|
||||
collapse({ target }) {
|
||||
const el = target.parentNode.className;
|
||||
document.getElementsByClassName(el)[0].classList.toggle("hidden");
|
||||
},
|
||||
getSourcePrefix(source) {
|
||||
const sourceEmojis = {
|
||||
// Source used for info messages.
|
||||
info: "\tℹ️ [INFO]:\t",
|
||||
// Source used for client to server messages.
|
||||
client: "\t👽 [SENT]:\t",
|
||||
// Source used for server to client messages.
|
||||
server: "\t📥 [RECEIVED]:\t"
|
||||
};
|
||||
if (Object.keys(sourceEmojis).includes(source))
|
||||
return sourceEmojis[source];
|
||||
return "";
|
||||
},
|
||||
toggleSSEConnection() {
|
||||
// If it is connecting:
|
||||
if (!this.connectionSSEState) return this.start();
|
||||
// Otherwise, it's disconnecting.
|
||||
else return this.stop();
|
||||
},
|
||||
start() {
|
||||
this.events.log = [
|
||||
{
|
||||
payload: `Connecting to ${this.server}...`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)"
|
||||
}
|
||||
];
|
||||
if (typeof EventSource !== "undefined") {
|
||||
try {
|
||||
this.sse = new EventSource(this.server);
|
||||
this.sse.onopen = event => {
|
||||
this.connectionSSEState = true;
|
||||
this.events.log = [
|
||||
{
|
||||
payload: `Connected to ${this.server}.`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
}
|
||||
];
|
||||
this.$toast.success("Connected", {
|
||||
icon: "sync"
|
||||
});
|
||||
};
|
||||
this.sse.onerror = event => {
|
||||
this.handleSSEError();
|
||||
};
|
||||
this.sse.onclose = event => {
|
||||
this.connectionSSEState = false;
|
||||
this.events.log.push({
|
||||
payload: `Disconnected from ${this.server}.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
this.$toast.error("Disconnected", {
|
||||
icon: "sync_disabled"
|
||||
});
|
||||
};
|
||||
this.sse.onmessage = event => {
|
||||
this.events.log.push({
|
||||
payload: event.data,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
};
|
||||
} catch (ex) {
|
||||
this.handleSSEError(ex);
|
||||
this.$toast.error("Something went wrong!", {
|
||||
icon: "error"
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.events.log = [
|
||||
{
|
||||
payload: `This browser doesn't seems to have Server Sent Events support.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
}
|
||||
];
|
||||
}
|
||||
},
|
||||
handleSSEError(error) {
|
||||
this.stop();
|
||||
this.connectionSSEState = false;
|
||||
this.events.log.push({
|
||||
payload: `An error has occurred.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
if (error !== null)
|
||||
this.events.log.push({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
this.sse.onclose();
|
||||
this.sse.close();
|
||||
}
|
||||
},
|
||||
updated: function() {
|
||||
this.$nextTick(function() {
|
||||
const divLog = document.getElementById("log");
|
||||
divLog.scrollBy(0, divLog.scrollHeight + 100);
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -3,11 +3,11 @@
|
||||
<pw-section class="cyan" label="Theme" ref="theme">
|
||||
<ul>
|
||||
<li>
|
||||
<h3 class="title">Background</h3>
|
||||
<label>{{ $t("background") }}</label>
|
||||
<div class="backgrounds">
|
||||
<span
|
||||
:key="theme.class"
|
||||
@click="applyTheme(theme.class, theme.color)"
|
||||
@click="applyTheme(theme)"
|
||||
v-for="theme in themes"
|
||||
>
|
||||
<swatch
|
||||
@@ -15,6 +15,7 @@
|
||||
:class="{ vibrant: theme.vibrant }"
|
||||
:color="theme.color"
|
||||
:name="theme.name"
|
||||
class="bg"
|
||||
></swatch>
|
||||
</span>
|
||||
</div>
|
||||
@@ -22,7 +23,7 @@
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<h3 class="title">Color</h3>
|
||||
<label>{{ $t("color") }}</label>
|
||||
<div class="colors">
|
||||
<span
|
||||
:key="entry.color"
|
||||
@@ -34,6 +35,7 @@
|
||||
:class="{ vibrant: entry.vibrant }"
|
||||
:color="entry.color"
|
||||
:name="entry.name"
|
||||
class="fg"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
@@ -41,39 +43,75 @@
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<h3 class="title">Labels</h3>
|
||||
<span>
|
||||
<pw-toggle
|
||||
:on="settings.FRAME_COLORS_ENABLED"
|
||||
@change="toggleSetting('FRAME_COLORS_ENABLED')"
|
||||
>Multi-color {{ settings.FRAME_COLORS_ENABLED ? "Enabled" : "Disabled" }}</pw-toggle>
|
||||
>
|
||||
{{ $t("multi_color") }}
|
||||
{{
|
||||
settings.FRAME_COLORS_ENABLED ? $t("enabled") : $t("disabled")
|
||||
}}
|
||||
</pw-toggle>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<br />
|
||||
|
||||
<pw-section class="blue" label="Proxy" ref="proxy">
|
||||
<ul>
|
||||
<li>
|
||||
<span>
|
||||
<pw-toggle
|
||||
:on="settings.PROXY_ENABLED"
|
||||
@change="toggleSetting('PROXY_ENABLED')"
|
||||
>Proxy {{ settings.PROXY_ENABLED ? "enabled" : "disabled" }}</pw-toggle>
|
||||
</span>
|
||||
<div class="flex-wrap">
|
||||
<span>
|
||||
<pw-toggle
|
||||
:on="settings.PROXY_ENABLED"
|
||||
@change="toggleSetting('PROXY_ENABLED')"
|
||||
>
|
||||
{{ $t("proxy") }}
|
||||
{{ settings.PROXY_ENABLED ? $t("enabled") : $t("disabled") }}
|
||||
</pw-toggle>
|
||||
</span>
|
||||
<a
|
||||
href="https://github.com/liyasthomas/postwoman/wiki/Proxy"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<button class="icon" v-tooltip="'Wiki'">
|
||||
<i class="material-icons">help</i>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<div class="flex-wrap">
|
||||
<label for="url">{{ $t("url") }}</label>
|
||||
<button
|
||||
class="icon"
|
||||
@click="settings.PROXY_URL = `https://postwoman.apollotv.xyz/`"
|
||||
v-tooltip.bottom="'Reset to default'"
|
||||
>
|
||||
<i class="material-icons">clear_all</i>
|
||||
</button>
|
||||
</div>
|
||||
<input
|
||||
id="url"
|
||||
type="url"
|
||||
v-model="settings.PROXY_URL"
|
||||
:disabled="!settings.PROXY_ENABLED"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="info">
|
||||
<li>
|
||||
<p>
|
||||
Postwoman's Proxy is hosted by ApolloTV.
|
||||
<br />Read the ApolloTV privacy policy
|
||||
<a
|
||||
href="https://apollotv.xyz/legal"
|
||||
target="_blank"
|
||||
>here</a>.
|
||||
{{ $t("postwoman_official_proxy_hosting") }}
|
||||
<br />
|
||||
{{ $t("read_the") }}
|
||||
<a href="https://apollotv.xyz/legal" target="_blank" rel="noopener">
|
||||
{{ $t("apollotv_privacy_policy") }} </a
|
||||
>.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -96,23 +134,14 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.info {
|
||||
margin-left: 4px;
|
||||
color: var(--fg-light-color);
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
<script>
|
||||
import section from "../components/section";
|
||||
import swatch from "../components/settings/swatch";
|
||||
import toggle from "../components/toggle";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": section,
|
||||
"pw-toggle": toggle,
|
||||
swatch: swatch
|
||||
"pw-section": () => import("../components/section"),
|
||||
"pw-toggle": () => import("../components/toggle"),
|
||||
swatch: () => import("../components/settings/swatch")
|
||||
},
|
||||
|
||||
data() {
|
||||
@@ -122,26 +151,32 @@ export default {
|
||||
// set the relevant values.
|
||||
themes: [
|
||||
{
|
||||
color: "#252628",
|
||||
color: "#202124",
|
||||
name: "Kinda Dark",
|
||||
class: ""
|
||||
class: "",
|
||||
aceEditor: "twilight"
|
||||
},
|
||||
{
|
||||
color: "#ffffff",
|
||||
name: "Clearly White",
|
||||
vibrant: true,
|
||||
class: "light"
|
||||
class: "light",
|
||||
aceEditor: "iplastic"
|
||||
},
|
||||
{
|
||||
color: "#000000",
|
||||
name: "Just Black",
|
||||
class: "black"
|
||||
class: "black",
|
||||
aceEditor: "vibrant_ink"
|
||||
},
|
||||
{
|
||||
color: "var(--bg-color)",
|
||||
name: "Auto (system)",
|
||||
vibrant: window.matchMedia("(prefers-color-scheme: light)").matches,
|
||||
class: "auto"
|
||||
class: "auto",
|
||||
aceEditor: window.matchMedia("(prefers-color-scheme: light)").matches
|
||||
? "iplastic"
|
||||
: "twilight"
|
||||
}
|
||||
],
|
||||
// You can define a new color here! It will simply store the color value.
|
||||
@@ -199,7 +234,9 @@ export default {
|
||||
this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false,
|
||||
PROXY_ENABLED:
|
||||
this.$store.state.postwoman.settings.PROXY_ENABLED || false,
|
||||
PROXY_URL: this.$store.state.postwoman.settings.PROXY_URL || "",
|
||||
PROXY_URL:
|
||||
this.$store.state.postwoman.settings.PROXY_URL ||
|
||||
"https://postwoman.apollotv.xyz/",
|
||||
PROXY_KEY: this.$store.state.postwoman.settings.PROXY_KEY || ""
|
||||
}
|
||||
};
|
||||
@@ -216,28 +253,22 @@ export default {
|
||||
},
|
||||
|
||||
methods: {
|
||||
applyTheme(name, color) {
|
||||
applyTheme({ class: name, color, aceEditor }) {
|
||||
this.applySetting("THEME_CLASS", name);
|
||||
this.applySetting("THEME_ACE_EDITOR", aceEditor);
|
||||
document
|
||||
.querySelector("meta[name=theme-color]")
|
||||
.setAttribute("content", color);
|
||||
this.applySetting("THEME_TAB_COLOR", color);
|
||||
document.documentElement.className = name;
|
||||
let imgGitHub = document.getElementById("imgGitHub");
|
||||
imgGitHub.style["filter"] = "";
|
||||
imgGitHub.style["webkit-filter"] = "invert(100%)";
|
||||
if (name.includes("light")) {
|
||||
imgGitHub.style["filter"] = "invert(100%)";
|
||||
imgGitHub.style["webkit-filter"] = "invert(100%)";
|
||||
}
|
||||
},
|
||||
setActiveColor(color, vibrant) {
|
||||
// By default, the color is vibrant.
|
||||
if (vibrant == null) vibrant = true;
|
||||
if (vibrant === null) vibrant = true;
|
||||
document.documentElement.style.setProperty("--ac-color", color);
|
||||
document.documentElement.style.setProperty(
|
||||
"--act-color",
|
||||
vibrant ? "rgb(37, 38, 40)" : "#f8f8f2"
|
||||
vibrant ? "rgba(32, 33, 36, 1)" : "rgba(255, 255, 255, 1)"
|
||||
);
|
||||
this.applySetting("THEME_COLOR", color.toUpperCase());
|
||||
this.applySetting("THEME_COLOR_VIBRANT", vibrant);
|
||||
@@ -258,9 +289,6 @@ export default {
|
||||
toggleSetting(key) {
|
||||
this.settings[key] = !this.settings[key];
|
||||
this.$store.commit("postwoman/applySetting", [key, this.settings[key]]);
|
||||
this.$router.replace("/settings", {
|
||||
force: true
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
|
||||
@@ -1,244 +0,0 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<pw-section class="blue" label="Request" ref="request">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="url">URL</label>
|
||||
<input
|
||||
id="url"
|
||||
type="url"
|
||||
:class="{ error: !urlValid }"
|
||||
v-model="url"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<label for="connect" class="hide-on-small-screen"> </label>
|
||||
<button :disabled="!urlValid" id="connect" name="connect" @click="toggleConnection">
|
||||
{{ toggleConnectionVerb }}
|
||||
<span>
|
||||
<i class="material-icons" v-if="!connectionState">sync</i>
|
||||
<i class="material-icons" v-if="connectionState">sync_disabled</i>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
|
||||
<br />
|
||||
|
||||
<pw-section class="purple" label="Communication" id="response" ref="response">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="log">Log</label>
|
||||
<div id="log" name="log" class="log">
|
||||
<span v-if="communication.log">
|
||||
<span
|
||||
v-for="(logEntry, index) in communication.log"
|
||||
:style="{ color: logEntry.color }"
|
||||
:key="index"
|
||||
>@ {{ logEntry.ts }} {{ getSourcePrefix(logEntry.source) }} {{ logEntry.payload }}</span>
|
||||
</span>
|
||||
<span v-else>(waiting for connection)</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>
|
||||
<label for="message">Message</label>
|
||||
<input
|
||||
id="message"
|
||||
name="message"
|
||||
type="text"
|
||||
v-model="communication.input"
|
||||
:readonly="!connectionState"
|
||||
@keyup.enter="connectionState ? sendMessage() : null"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
<label for="send" class="hide-on-small-screen"> </label>
|
||||
<button id="send" name="send" :disabled="!connectionState" @click="sendMessage">
|
||||
Send
|
||||
<span>
|
||||
<i class="material-icons">send</i>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</pw-section>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
div.log {
|
||||
margin: 4px;
|
||||
padding: 8px 16px;
|
||||
width: calc(100% - 8px);
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-dark-color);
|
||||
color: var(--fg-color);
|
||||
height: 256px;
|
||||
overflow: auto;
|
||||
|
||||
&,
|
||||
span {
|
||||
font-size: 18px;
|
||||
font-family: "Roboto Mono", monospace;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import section from "../components/section";
|
||||
export default {
|
||||
components: {
|
||||
"pw-section": section
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
connectionState: false,
|
||||
url: "wss://echo.websocket.org",
|
||||
socket: null,
|
||||
communication: {
|
||||
log: null,
|
||||
input: ""
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
toggleConnectionVerb() {
|
||||
return !this.connectionState ? "Connect" : "Disconnect";
|
||||
},
|
||||
urlValid() {
|
||||
const pattern = new RegExp(
|
||||
"^(wss?:\\/\\/)?" +
|
||||
"((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" +
|
||||
"((\\d{1,3}\\.){3}\\d{1,3}))" +
|
||||
"(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" +
|
||||
"(\\?[;&a-z\\d%_.~+=-]*)?" +
|
||||
"(\\#[-a-z\\d_]*)?$",
|
||||
"i"
|
||||
);
|
||||
return pattern.test(this.url);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleConnection() {
|
||||
// If it is connecting:
|
||||
if (!this.connectionState) return this.connect();
|
||||
// Otherwise, it's disconnecting.
|
||||
else return this.disconnect();
|
||||
},
|
||||
connect() {
|
||||
this.communication.log = [
|
||||
{
|
||||
payload: `Connecting to ${this.url}...`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)"
|
||||
}
|
||||
];
|
||||
try {
|
||||
this.socket = new WebSocket(this.url);
|
||||
this.socket.onopen = event => {
|
||||
this.connectionState = true;
|
||||
this.communication.log = [
|
||||
{
|
||||
payload: `Connected to ${this.url}.`,
|
||||
source: "info",
|
||||
color: "var(--ac-color)",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
}
|
||||
];
|
||||
this.$toast.success("Connected", {
|
||||
icon: "sync"
|
||||
});
|
||||
};
|
||||
this.socket.onerror = event => {
|
||||
this.handleError();
|
||||
};
|
||||
this.socket.onclose = event => {
|
||||
this.connectionState = false;
|
||||
this.communication.log.push({
|
||||
payload: `Disconnected from ${this.url}.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
this.$toast.error("Disconnected", {
|
||||
icon: "sync_disabled"
|
||||
});
|
||||
};
|
||||
this.socket.onmessage = event => {
|
||||
this.communication.log.push({
|
||||
payload: event.data,
|
||||
source: "server",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
};
|
||||
} catch (ex) {
|
||||
this.handleError(ex);
|
||||
this.$toast.error("Something went wrong!", {
|
||||
icon: "error"
|
||||
});
|
||||
}
|
||||
},
|
||||
disconnect() {
|
||||
if (this.socket != null) this.socket.close();
|
||||
},
|
||||
handleError(error) {
|
||||
this.disconnect();
|
||||
this.connectionState = false;
|
||||
this.communication.log.push({
|
||||
payload: `An error has occurred.`,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
if (error != null)
|
||||
this.communication.log.push({
|
||||
payload: error,
|
||||
source: "info",
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
},
|
||||
sendMessage() {
|
||||
const message = this.communication.input;
|
||||
this.socket.send(message);
|
||||
this.communication.log.push({
|
||||
payload: message,
|
||||
source: "client",
|
||||
ts: new Date().toLocaleTimeString()
|
||||
});
|
||||
this.communication.input = "";
|
||||
},
|
||||
collapse({ target }) {
|
||||
const el = target.parentNode.className;
|
||||
document.getElementsByClassName(el)[0].classList.toggle("hidden");
|
||||
},
|
||||
getSourcePrefix(source) {
|
||||
const sourceEmojis = {
|
||||
// Source used for info messages.
|
||||
info: "\tℹ️ [INFO]:\t",
|
||||
// Source used for client to server messages.
|
||||
client: "\t👽 [SENT]:\t",
|
||||
// Source used for server to client messages.
|
||||
server: "\t📥 [RECEIVED]:\t"
|
||||
};
|
||||
if (Object.keys(sourceEmojis).includes(source))
|
||||
return sourceEmojis[source];
|
||||
return "";
|
||||
}
|
||||
},
|
||||
updated: function() {
|
||||
this.$nextTick(function() {
|
||||
var divLog = document.getElementById("log");
|
||||
divLog.scrollBy(0, divLog.scrollHeight + 100);
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,4 +1,4 @@
|
||||
import Vue from 'vue';
|
||||
import VTooltip from 'v-tooltip';
|
||||
import Vue from "vue";
|
||||
import VTooltip from "v-tooltip";
|
||||
|
||||
Vue.use(VTooltip);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import VuexPersistence from "vuex-persist";
|
||||
|
||||
export default ({
|
||||
store
|
||||
}) => {
|
||||
export default ({ store }) => {
|
||||
new VuexPersistence().plugin(store);
|
||||
}
|
||||
};
|
||||
|
||||
62
static/icons/alien-head.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 612.001 612.001"
|
||||
style="enable-background:new 0 0 612.001 612.001;"
|
||||
xml:space="preserve"
|
||||
width="512px"
|
||||
height="512px"
|
||||
class=""
|
||||
sodipodi:docname="logo.svg"
|
||||
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"><metadata
|
||||
id="metadata13"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs11" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1533"
|
||||
inkscape:window-height="845"
|
||||
id="namedview9"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.921875"
|
||||
inkscape:cx="380.48543"
|
||||
inkscape:cy="276.92414"
|
||||
inkscape:window-x="67"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" /> <g
|
||||
id="g3826"
|
||||
transform="translate(-516.40798,-163.88978)"><circle
|
||||
transform="scale(1,-1)"
|
||||
style="stroke-width:1.19531453"
|
||||
r="178.70923"
|
||||
cy="-501.55591"
|
||||
cx="822.40845"
|
||||
id="circle3814" /><g
|
||||
id="g3820"
|
||||
transform="translate(516.40798,163.89028)"><g
|
||||
id="g3818"><path
|
||||
id="path3816"
|
||||
data-old_color="#202124"
|
||||
class="active-path"
|
||||
data-original="#202124"
|
||||
d="M 64.601,236.822 C 64.601,394.256 192.786,612 306.001,612 412.582,612 547.4,394.256 547.4,236.822 547.4,79.388 439.322,0 306,0 172.678,0 64.601,79.388 64.601,236.822 Z m 304.12,116.415 c 29.475,-29.475 70.598,-40.195 108.552,-32.173 8.021,37.954 -2.698,79.077 -32.173,108.552 -29.475,29.475 -70.598,40.195 -108.552,32.173 -8.022,-37.955 2.698,-79.078 32.173,-108.552 z M 134.727,321.063 c 37.954,-8.021 79.077,2.698 108.552,32.173 29.475,29.475 40.195,70.598 32.173,108.552 -37.954,8.021 -79.077,-2.698 -108.552,-32.173 -29.475,-29.476 -40.194,-70.598 -32.173,-108.552 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#50fa7b" /></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 11 KiB |
@@ -13,10 +13,10 @@
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 20 20"
|
||||
viewBox="0 0 24 24"
|
||||
xml:space="preserve"
|
||||
width="20"
|
||||
height="20"
|
||||
width="24"
|
||||
height="24"
|
||||
sodipodi:docname="github.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
|
||||
id="metadata13"><rdf:RDF><cc:Work
|
||||
@@ -59,4 +59,4 @@
|
||||
id="path6"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#fff" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
74
static/icons/graphql.svg
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 400 400">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="122" y="-0.4" transform="matrix(-0.866 -0.5 0.5 -0.866 163.3196 363.3136)" fill="#FFFFFF" width="16.6"
|
||||
height="320.3"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="39.8" y="272.2" fill="#FFFFFF" width="320.3" height="16.6"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="37.9" y="312.2" transform="matrix(-0.866 -0.5 0.5 -0.866 83.0693 663.3409)" fill="#FFFFFF" width="185"
|
||||
height="16.6"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="177.1" y="71.1" transform="matrix(-0.866 -0.5 0.5 -0.866 463.3409 283.0693)" fill="#FFFFFF" width="185"
|
||||
height="16.6"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="122.1" y="-13" transform="matrix(-0.5 -0.866 0.866 -0.5 126.7903 232.1221)" fill="#FFFFFF" width="16.6"
|
||||
height="185"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="109.6" y="151.6" transform="matrix(-0.5 -0.866 0.866 -0.5 266.0828 473.3766)" fill="#FFFFFF"
|
||||
width="320.3" height="16.6"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<rect x="52.5" y="107.5" fill="#FFFFFF" width="16.6" height="185"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>s
|
||||
<g>
|
||||
<rect x="330.9" y="107.5" fill="#FFFFFF" width="16.6" height="185"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
|
||||
<rect x="262.4" y="240.1" transform="matrix(-0.5 -0.866 0.866 -0.5 126.7953 714.2875)" fill="#FFFFFF"
|
||||
width="14.5" height="160.9"/>
|
||||
</g>
|
||||
</g>
|
||||
<path fill="#FFFFFF" d="M369.5,297.9c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8
|
||||
C373.5,259.9,379.2,281.2,369.5,297.9"/>
|
||||
<path fill="#FFFFFF" d="M90.9,137c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8
|
||||
C94.8,99,100.5,120.3,90.9,137"/>
|
||||
<path fill="#FFFFFF" d="M30.5,297.9c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6,16.7,3.9,38-12.8,47.7
|
||||
C61.4,320.3,40.1,314.6,30.5,297.9"/>
|
||||
<path fill="#FFFFFF" d="M309.1,137c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6,16.7,3.9,38-12.8,47.7
|
||||
C340.1,159.4,318.7,153.7,309.1,137"/>
|
||||
<path fill="#FFFFFF" d="M200,395.8c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9
|
||||
C234.9,380.1,219.3,395.8,200,395.8"/>
|
||||
<path fill="#FFFFFF" d="M200,74c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9
|
||||
C234.9,58.4,219.3,74,200,74"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="1952" height="734.935" viewBox="0 0 1952.00 734.93" enable-background="new 0 0 1952.00 734.93" xml:space="preserve">
|
||||
<g>
|
||||
<path fill="#121212" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 1436.62,603.304L 1493.01,460.705L 1655.83,460.705L 1578.56,244.39L 1675.2,0.000528336L 1952,734.933L 1747.87,734.933L 1700.57,603.304L 1436.62,603.304 Z "/>
|
||||
<path fill="#5A0FC8" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 1262.47,734.935L 1558.79,0.00156593L 1362.34,0.0025425L 1159.64,474.933L 1015.5,0.00351906L 864.499,0.00351906L 709.731,474.933L 600.585,258.517L 501.812,562.819L 602.096,734.935L 795.427,734.935L 935.284,309.025L 1068.63,734.935L 1262.47,734.935 Z "/>
|
||||
<path fill="#121212" fill-opacity="1" stroke-width="0.2" stroke-linejoin="round" d="M 186.476,482.643L 307.479,482.643C 344.133,482.643 376.772,478.552 405.396,470.37L 436.689,373.962L 524.148,104.516C 517.484,93.9535 509.876,83.9667 501.324,74.5569C 456.419,24.852 390.719,0.000406265 304.222,0.000406265L -3.8147e-006,0.000406265L -3.8147e-006,734.933L 186.476,734.933L 186.476,482.643 Z M 346.642,169.079C 364.182,186.732 372.951,210.355 372.951,239.95C 372.951,269.772 365.238,293.424 349.813,310.906C 332.903,330.331 301.766,340.043 256.404,340.043L 186.476,340.043L 186.476,142.598L 256.918,142.598C 299.195,142.598 329.103,151.425 346.642,169.079 Z "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 154 KiB |
BIN
static/logo.jpg
Normal file
|
After Width: | Height: | Size: 24 KiB |
@@ -1,20 +1,18 @@
|
||||
import Vuex from 'vuex';
|
||||
import state from './state';
|
||||
import VuexPersist from 'vuex-persist'
|
||||
import Vuex from "vuex";
|
||||
import state from "./state";
|
||||
import VuexPersist from "vuex-persist";
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.use(Vuex);
|
||||
|
||||
const vuexLocalStorage = new VuexPersist({
|
||||
key: 'vuex',
|
||||
key: "vuex",
|
||||
storage: window.localStorage,
|
||||
reducer: ({
|
||||
...request
|
||||
}) => ({
|
||||
reducer: ({ ...request }) => ({
|
||||
...request
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state,
|
||||
@@ -22,5 +20,5 @@ export default {
|
||||
});
|
||||
|
||||
Vue.prototype.$store = store;
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,53 +1,89 @@
|
||||
export default {
|
||||
setState(state, object) {
|
||||
state.request[object.attribute] = object.value
|
||||
setState({ request }, { attribute, value }) {
|
||||
request[attribute] = value;
|
||||
},
|
||||
|
||||
addHeaders(state, value) {
|
||||
state.request.headers.push(value);
|
||||
setGQLState({ gql }, { attribute, value }) {
|
||||
gql[attribute] = value;
|
||||
},
|
||||
|
||||
removeHeaders(state, index) {
|
||||
state.request.headers.splice(index, 1)
|
||||
addGQLHeader({ gql }, object) {
|
||||
gql.headers.push(object);
|
||||
},
|
||||
|
||||
setKeyHeader(state, object) {
|
||||
state.request.headers[object.index].key = object.value
|
||||
removeGQLHeader({ gql }, index) {
|
||||
gql.headers.splice(index, 1);
|
||||
},
|
||||
|
||||
setValueHeader(state, object) {
|
||||
state.request.headers[object.index].value = object.value
|
||||
setGQLHeaderKey({ gql }, { index, value }) {
|
||||
gql.headers[index].key = value;
|
||||
},
|
||||
|
||||
addParams(state, value) {
|
||||
state.request.params.push(value);
|
||||
setGQLHeaderValue({ gql }, { index, value }) {
|
||||
gql.headers[index].value = value;
|
||||
},
|
||||
|
||||
removeParams(state, index) {
|
||||
state.request.params.splice(index, 1)
|
||||
addGQLVariable({ gql }, object) {
|
||||
gql.variables.push(object);
|
||||
},
|
||||
|
||||
setKeyParams(state, object) {
|
||||
state.request.params[object.index].key = object.value
|
||||
removeGQLVariable({ gql }, index) {
|
||||
gql.variables.splice(index, 1);
|
||||
},
|
||||
|
||||
setValueParams(state, object) {
|
||||
state.request.params[object.index].value = object.value
|
||||
setGQLVariableKey({ gql }, { index, value }) {
|
||||
gql.variables[index].key = value;
|
||||
},
|
||||
|
||||
addBodyParams(state, value) {
|
||||
state.request.bodyParams.push(value);
|
||||
setGQLVariableValue({ gql }, { index, value }) {
|
||||
gql.variables[index].value = value;
|
||||
},
|
||||
|
||||
removeBodyParams(state, index) {
|
||||
state.request.bodyParams.splice(index, 1)
|
||||
addHeaders({ request }, value) {
|
||||
request.headers.push(value);
|
||||
},
|
||||
|
||||
setKeyBodyParams(state, object) {
|
||||
state.request.bodyParams[object.index].key = object.value
|
||||
removeHeaders({ request }, index) {
|
||||
request.headers.splice(index, 1);
|
||||
},
|
||||
|
||||
setValueBodyParams(state, object) {
|
||||
state.request.bodyParams[object.index].value = object.value
|
||||
setKeyHeader({ request }, { index, value }) {
|
||||
request.headers[index].key = value;
|
||||
},
|
||||
|
||||
setValueHeader({ request }, { index, value }) {
|
||||
request.headers[index].value = value;
|
||||
},
|
||||
|
||||
addParams({ request }, value) {
|
||||
request.params.push(value);
|
||||
},
|
||||
|
||||
removeParams({ request }, index) {
|
||||
request.params.splice(index, 1);
|
||||
},
|
||||
|
||||
setKeyParams({ request }, { index, value }) {
|
||||
request.params[index].key = value;
|
||||
},
|
||||
|
||||
setValueParams({ request }, { index, value }) {
|
||||
request.params[index].value = value;
|
||||
},
|
||||
|
||||
addBodyParams({ request }, value) {
|
||||
request.bodyParams.push(value);
|
||||
},
|
||||
|
||||
removeBodyParams({ request }, index) {
|
||||
request.bodyParams.splice(index, 1);
|
||||
},
|
||||
|
||||
setKeyBodyParams({ request }, { index, value }) {
|
||||
request.bodyParams[index].key = value;
|
||||
},
|
||||
|
||||
setValueBodyParams({ request }, { index, value }) {
|
||||
request.bodyParams[index].value = value;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Vue from 'vue'
|
||||
import Vue from "vue";
|
||||
|
||||
export const SETTINGS_KEYS = [
|
||||
/**
|
||||
@@ -26,6 +26,11 @@ export const SETTINGS_KEYS = [
|
||||
*/
|
||||
"THEME_COLOR_VIBRANT",
|
||||
|
||||
/**
|
||||
* The Ace editor theme
|
||||
*/
|
||||
"THEME_ACE_EDITOR",
|
||||
|
||||
/**
|
||||
* Normally, section frames are multicolored in the UI
|
||||
* to emphasise the different sections.
|
||||
@@ -56,29 +61,39 @@ export const SETTINGS_KEYS = [
|
||||
|
||||
export const state = () => ({
|
||||
settings: {},
|
||||
collections: [{
|
||||
name: 'My First Collection',
|
||||
folders: [],
|
||||
requests: [],
|
||||
}],
|
||||
collections: [
|
||||
{
|
||||
name: "My Collection",
|
||||
folders: [],
|
||||
requests: []
|
||||
}
|
||||
],
|
||||
selectedRequest: {},
|
||||
editingRequest: {},
|
||||
editingRequest: {}
|
||||
});
|
||||
|
||||
export const mutations = {
|
||||
|
||||
applySetting(state, setting) {
|
||||
if (setting == null || !(setting instanceof Array) || setting.length !== 2)
|
||||
throw new Error("You must provide a setting (array in the form [key, value])");
|
||||
applySetting({ settings }, setting) {
|
||||
if (
|
||||
setting == null ||
|
||||
!(setting instanceof Array) ||
|
||||
setting.length !== 2
|
||||
) {
|
||||
throw new Error(
|
||||
"You must provide a setting (array in the form [key, value])"
|
||||
);
|
||||
}
|
||||
|
||||
const [key, value] = setting;
|
||||
// Do not just remove this check.
|
||||
// Add your settings key to the SETTINGS_KEYS array at the
|
||||
// top of the file.
|
||||
// This is to ensure that application settings remain documented.
|
||||
if (!SETTINGS_KEYS.includes(key)) throw new Error("The settings structure does not include the key " + key);
|
||||
if (!SETTINGS_KEYS.includes(key)) {
|
||||
throw new Error(`The settings structure does not include the key ${key}`);
|
||||
}
|
||||
|
||||
state.settings[key] = value;
|
||||
settings[key] = value;
|
||||
},
|
||||
|
||||
replaceCollections(state, collections) {
|
||||
@@ -95,147 +110,160 @@ export const mutations = {
|
||||
}
|
||||
},
|
||||
|
||||
addNewCollection(state, collection) {
|
||||
state.collections.push({
|
||||
name: '',
|
||||
addNewCollection({ collections }, collection) {
|
||||
collections.push({
|
||||
name: "",
|
||||
folders: [],
|
||||
requests: [],
|
||||
...collection,
|
||||
})
|
||||
},
|
||||
|
||||
removeCollection(state, payload) {
|
||||
const {
|
||||
collectionIndex
|
||||
} = payload;
|
||||
state.collections.splice(collectionIndex, 1)
|
||||
},
|
||||
|
||||
editCollection(state, payload) {
|
||||
const {
|
||||
collection,
|
||||
collectionIndex
|
||||
} = payload
|
||||
state.collections[collectionIndex] = collection
|
||||
},
|
||||
|
||||
addNewFolder(state, payload) {
|
||||
const {
|
||||
collectionIndex,
|
||||
folder
|
||||
} = payload;
|
||||
state.collections[collectionIndex].folders.push({
|
||||
name: '',
|
||||
requests: [],
|
||||
...folder,
|
||||
...collection
|
||||
});
|
||||
},
|
||||
|
||||
editFolder(state, payload) {
|
||||
const {
|
||||
collectionIndex,
|
||||
folder,
|
||||
folderIndex
|
||||
} = payload;
|
||||
Vue.set(state.collections[collectionIndex].folders, folderIndex, folder)
|
||||
removeCollection({ collections }, payload) {
|
||||
const { collectionIndex } = payload;
|
||||
collections.splice(collectionIndex, 1);
|
||||
},
|
||||
|
||||
removeFolder(state, payload) {
|
||||
const {
|
||||
collectionIndex,
|
||||
folderIndex
|
||||
} = payload;
|
||||
state.collections[collectionIndex].folders.splice(folderIndex, 1)
|
||||
editCollection({ collections }, payload) {
|
||||
const { collection, collectionIndex } = payload;
|
||||
collections[collectionIndex] = collection;
|
||||
},
|
||||
|
||||
addRequest(state, payload) {
|
||||
const {
|
||||
request
|
||||
} = payload;
|
||||
addNewFolder({ collections }, payload) {
|
||||
const { collectionIndex, folder } = payload;
|
||||
collections[collectionIndex].folders.push({
|
||||
name: "",
|
||||
requests: [],
|
||||
...folder
|
||||
});
|
||||
},
|
||||
|
||||
editFolder({ collections }, payload) {
|
||||
const { collectionIndex, folder, folderIndex } = payload;
|
||||
Vue.set(collections[collectionIndex].folders, folderIndex, folder);
|
||||
},
|
||||
|
||||
removeFolder({ collections }, payload) {
|
||||
const { collectionIndex, folderIndex } = payload;
|
||||
collections[collectionIndex].folders.splice(folderIndex, 1);
|
||||
},
|
||||
|
||||
addRequest({ collections }, payload) {
|
||||
const { request } = payload;
|
||||
|
||||
// Request that is directly attached to collection
|
||||
if (request.folder === -1) {
|
||||
state.collections[request.collection].requests.push(request);
|
||||
return
|
||||
collections[request.collection].requests.push(request);
|
||||
return;
|
||||
}
|
||||
|
||||
state.collections[request.collection].folders[request.folder].requests.push(request);
|
||||
collections[request.collection].folders[request.folder].requests.push(
|
||||
request
|
||||
);
|
||||
},
|
||||
|
||||
editRequest(state, payload) {
|
||||
editRequest({ collections }, payload) {
|
||||
const {
|
||||
requestOld,
|
||||
requestOldCollectionIndex,
|
||||
requestOldFolderIndex,
|
||||
requestOldIndex,
|
||||
requestNew,
|
||||
requestNewCollectionIndex,
|
||||
requestNewFolderIndex,
|
||||
} = payload
|
||||
requestNewFolderIndex
|
||||
} = payload;
|
||||
|
||||
const changedCollection = requestOldCollectionIndex !== requestNewCollectionIndex
|
||||
const changedFolder = requestOldFolderIndex !== requestNewFolderIndex
|
||||
const changedPlace = changedCollection || changedFolder
|
||||
const changedCollection =
|
||||
requestOldCollectionIndex !== requestNewCollectionIndex;
|
||||
const changedFolder = requestOldFolderIndex !== requestNewFolderIndex;
|
||||
const changedPlace = changedCollection || changedFolder;
|
||||
|
||||
// set new request
|
||||
if (requestNewFolderIndex !== undefined)
|
||||
Vue.set(state.collections[requestNewCollectionIndex].folders[requestNewFolderIndex].requests, requestOldIndex, requestNew)
|
||||
else
|
||||
Vue.set(state.collections[requestNewCollectionIndex].requests, requestOldIndex, requestNew)
|
||||
if (requestNewFolderIndex !== undefined) {
|
||||
Vue.set(
|
||||
collections[requestNewCollectionIndex].folders[requestNewFolderIndex]
|
||||
.requests,
|
||||
requestOldIndex,
|
||||
requestNew
|
||||
);
|
||||
} else {
|
||||
Vue.set(
|
||||
collections[requestNewCollectionIndex].requests,
|
||||
requestOldIndex,
|
||||
requestNew
|
||||
);
|
||||
}
|
||||
|
||||
// remove old request
|
||||
if (changedPlace) {
|
||||
if (requestOldFolderIndex !== undefined)
|
||||
state.collections[requestOldCollectionIndex].folders[requestOldFolderIndex].requests.splice(requestOldIndex, 1)
|
||||
else
|
||||
state.collections[requestOldCollectionIndex].requests.splice(requestOldIndex, 1)
|
||||
if (requestOldFolderIndex !== undefined) {
|
||||
collections[requestOldCollectionIndex].folders[
|
||||
requestOldFolderIndex
|
||||
].requests.splice(requestOldIndex, 1);
|
||||
} else {
|
||||
collections[requestOldCollectionIndex].requests.splice(
|
||||
requestOldIndex,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
saveRequestAs(state, payload) {
|
||||
const {
|
||||
request,
|
||||
collectionIndex,
|
||||
folderIndex,
|
||||
requestIndex,
|
||||
} = payload
|
||||
saveRequestAs({ collections }, payload) {
|
||||
const { request, collectionIndex, folderIndex, requestIndex } = payload;
|
||||
|
||||
const specifiedCollection = collectionIndex !== undefined
|
||||
const specifiedFolder = folderIndex !== undefined
|
||||
const specifiedRequest = requestIndex !== undefined
|
||||
const specifiedCollection = collectionIndex !== undefined;
|
||||
const specifiedFolder = folderIndex !== undefined;
|
||||
const specifiedRequest = requestIndex !== undefined;
|
||||
|
||||
if (specifiedCollection && specifiedFolder && specifiedRequest)
|
||||
Vue.set(state.collections[collectionIndex].folders[folderIndex].requests, requestIndex, request)
|
||||
else if (specifiedCollection && specifiedFolder && !specifiedRequest) {
|
||||
const requests = state.collections[collectionIndex].folders[folderIndex].requests
|
||||
if (specifiedCollection && specifiedFolder && specifiedRequest) {
|
||||
Vue.set(
|
||||
collections[collectionIndex].folders[folderIndex].requests,
|
||||
requestIndex,
|
||||
request
|
||||
);
|
||||
} else if (specifiedCollection && specifiedFolder && !specifiedRequest) {
|
||||
const requests =
|
||||
collections[collectionIndex].folders[folderIndex].requests;
|
||||
const lastRequestIndex = requests.length - 1;
|
||||
Vue.set(requests, lastRequestIndex + 1, request)
|
||||
Vue.set(requests, lastRequestIndex + 1, request);
|
||||
} else if (specifiedCollection && !specifiedFolder && specifiedRequest) {
|
||||
const requests = state.collections[collectionIndex].requests
|
||||
Vue.set(requests, requestIndex, request)
|
||||
const requests = collections[collectionIndex].requests;
|
||||
Vue.set(requests, requestIndex, request);
|
||||
} else if (specifiedCollection && !specifiedFolder && !specifiedRequest) {
|
||||
const requests = state.collections[collectionIndex].requests
|
||||
const requests = collections[collectionIndex].requests;
|
||||
const lastRequestIndex = requests.length - 1;
|
||||
Vue.set(requests, lastRequestIndex + 1, request)
|
||||
Vue.set(requests, lastRequestIndex + 1, request);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
saveRequest(state, payload) {
|
||||
const {
|
||||
request
|
||||
} = payload;
|
||||
saveRequest({ collections }, payload) {
|
||||
const { request } = payload;
|
||||
|
||||
// Remove the old request from collection
|
||||
if (request.hasOwnProperty('oldCollection') && request.oldCollection > -1) {
|
||||
const folder = request.hasOwnProperty('oldFolder') && request.oldFolder >= -1 ? request.oldFolder : request.folder;
|
||||
if (request.hasOwnProperty("oldCollection") && request.oldCollection > -1) {
|
||||
const folder =
|
||||
request.hasOwnProperty("oldFolder") && request.oldFolder >= -1
|
||||
? request.oldFolder
|
||||
: request.folder;
|
||||
if (folder > -1) {
|
||||
state.collections[request.oldCollection].folders[folder].requests.splice(request.requestIndex, 1)
|
||||
collections[request.oldCollection].folders[folder].requests.splice(
|
||||
request.requestIndex,
|
||||
1
|
||||
);
|
||||
} else {
|
||||
state.collections[request.oldCollection].requests.splice(request.requestIndex, 1)
|
||||
collections[request.oldCollection].requests.splice(
|
||||
request.requestIndex,
|
||||
1
|
||||
);
|
||||
}
|
||||
} else if (request.hasOwnProperty('oldFolder') && request.oldFolder !== -1) {
|
||||
state.collections[request.collection].folders[folder].requests.splice(request.requestIndex, 1)
|
||||
} else if (
|
||||
request.hasOwnProperty("oldFolder") &&
|
||||
request.oldFolder !== -1
|
||||
) {
|
||||
collections[request.collection].folders[folder].requests.splice(
|
||||
request.requestIndex,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
delete request.oldCollection;
|
||||
@@ -243,31 +271,37 @@ export const mutations = {
|
||||
|
||||
// Request that is directly attached to collection
|
||||
if (request.folder === -1) {
|
||||
Vue.set(state.collections[request.collection].requests, request.requestIndex, request)
|
||||
return
|
||||
Vue.set(
|
||||
collections[request.collection].requests,
|
||||
request.requestIndex,
|
||||
request
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Vue.set(state.collections[request.collection].folders[request.folder].requests, request.requestIndex, request)
|
||||
Vue.set(
|
||||
collections[request.collection].folders[request.folder].requests,
|
||||
request.requestIndex,
|
||||
request
|
||||
);
|
||||
},
|
||||
|
||||
removeRequest(state, payload) {
|
||||
const {
|
||||
collectionIndex,
|
||||
folderIndex,
|
||||
requestIndex
|
||||
} = payload;
|
||||
removeRequest({ collections }, payload) {
|
||||
const { collectionIndex, folderIndex, requestIndex } = payload;
|
||||
|
||||
// Request that is directly attached to collection
|
||||
if (folderIndex === -1) {
|
||||
state.collections[collectionIndex].requests.splice(requestIndex, 1)
|
||||
return
|
||||
collections[collectionIndex].requests.splice(requestIndex, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
state.collections[collectionIndex].folders[folderIndex].requests.splice(requestIndex, 1)
|
||||
},
|
||||
|
||||
selectRequest(state, payload) {
|
||||
state.selectedRequest = Object.assign({}, payload.request);
|
||||
collections[collectionIndex].folders[folderIndex].requests.splice(
|
||||
requestIndex,
|
||||
1
|
||||
);
|
||||
},
|
||||
|
||||
selectRequest(state, { request }) {
|
||||
state.selectedRequest = Object.assign({}, request);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
export default () => ({
|
||||
request: {
|
||||
method: 'GET',
|
||||
url: 'https://reqres.in',
|
||||
path: '/api/users',
|
||||
label: '',
|
||||
auth: 'None',
|
||||
httpUser: '',
|
||||
httpPassword: '',
|
||||
passwordFieldType: 'password',
|
||||
bearerToken: '',
|
||||
method: "GET",
|
||||
url: "https://reqres.in",
|
||||
path: "/api/users",
|
||||
label: "",
|
||||
auth: "None",
|
||||
httpUser: "",
|
||||
httpPassword: "",
|
||||
passwordFieldType: "password",
|
||||
bearerToken: "",
|
||||
headers: [],
|
||||
params: [],
|
||||
bodyParams: [],
|
||||
rawParams: '',
|
||||
rawParams: "",
|
||||
rawInput: false,
|
||||
requestType: 'JavaScript XHR',
|
||||
contentType: '',
|
||||
requestType: "",
|
||||
contentType: ""
|
||||
},
|
||||
gql: {
|
||||
url: "https://rickandmortyapi.com/graphql",
|
||||
headers: [],
|
||||
variables: [],
|
||||
query: ""
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
describe('Methods', () => {
|
||||
const methods = [ 'POST', 'HEAD', 'POST', 'PUT', 'DELETE','OPTIONS', 'PATCH']
|
||||
methods.forEach(method => {
|
||||
methods.forEach((method) => {
|
||||
it(`Change the default method GET to ${method} with url query`, () => {
|
||||
cy.visit(`/?method=${method}`)
|
||||
.get('#method').contains(method)
|
||||
.get('#method').should('have.value', method)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -11,8 +11,8 @@ describe('Methods', () => {
|
||||
describe('Url and path', () => {
|
||||
it('Change default url with query and reset default path to empty string and make a request to cat api', () => {
|
||||
cy.seedAndVisit('catapi', '/?url=https://api.thecatapi.com&path=')
|
||||
.get('#url').then(el => expect(el.val() === 'https://api.thecatapi.com').to.equal(true))
|
||||
.get("#path").then(el => expect(el.val() === '').to.equal(true))
|
||||
.get('#url').then((el) => expect(el.val() === 'https://api.thecatapi.com').to.equal(true))
|
||||
.get("#path").then((el) => expect(el.val() === '').to.equal(true))
|
||||
.get('#response-details-wrapper').should($wrapper => {
|
||||
expect($wrapper).to.contain('FAKE Cat API')
|
||||
})
|
||||
@@ -21,19 +21,19 @@ describe('Url and path', () => {
|
||||
|
||||
describe('Authentication', () => {
|
||||
it(`Change default auth 'None' to 'Basic' and set httpUser and httpPassword with url query`, () => {
|
||||
cy.visit(`?&auth=Basic&httpUser=foo&httpPassword=bar`, { retryOnStatusCodeFailure: true })
|
||||
cy.visit(`?&auth=Basic Auth&httpUser=foo&httpPassword=bar`, { retryOnStatusCodeFailure: true })
|
||||
.get('#authentication').contains('Authentication').click()
|
||||
.then(() => {
|
||||
.then(() => {
|
||||
cy.get('input[name="http_basic_user"]', { timeout: 500 })
|
||||
.invoke('val')
|
||||
.then(user => {
|
||||
.then((user) => {
|
||||
expect(user === 'foo').to.equal(true)
|
||||
cy.log('Success! user === foo')
|
||||
})
|
||||
|
||||
cy.get('input[name="http_basic_passwd"]')
|
||||
.invoke('val')
|
||||
.then(user => {
|
||||
.then((user) => {
|
||||
expect(user === 'bar').to.equal(true)
|
||||
cy.log('Success! password === bar')
|
||||
})
|
||||
@@ -48,7 +48,7 @@ describe('Authentication', () => {
|
||||
.then(() => {
|
||||
cy.get('input[name="bearer_token"]', { timeout: 500 })
|
||||
.invoke('val')
|
||||
.then(tkn => {
|
||||
.then((tkn) => {
|
||||
expect(tkn === base64Tkn).to.equal(true)
|
||||
cy.log(`Success! input[name="bearer_token"] === ${base64Tkn}`)
|
||||
})
|
||||
|
||||