Compare commits
2 Commits
feat/embed
...
bug/withDe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
407dad8c7f | ||
|
|
9f944506e0 |
57
.github/ISSUE_TEMPLATE/--bug-report.yaml
vendored
57
.github/ISSUE_TEMPLATE/--bug-report.yaml
vendored
@@ -1,57 +0,0 @@
|
|||||||
name: Bug report
|
|
||||||
description: Create a bug report to help us improve Hoppscotch
|
|
||||||
title: "[bug]: "
|
|
||||||
labels: [bug, need testing]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thank you for taking the time to fill out this bug report.
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Is there an existing issue for this?
|
|
||||||
description: Please search to see if an issue already exists for the bug you encountered
|
|
||||||
options:
|
|
||||||
- label: I have searched the existing issues
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Current behavior
|
|
||||||
description: A concise description of what you're experiencing and what you expect
|
|
||||||
placeholder: |
|
|
||||||
When I do <X>, <Y> happens and I see the error message attached below:
|
|
||||||
```...```
|
|
||||||
What I expect is <Z>
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Steps to reproduce
|
|
||||||
description: Add steps to reproduce this behaviour, include console or network logs and screenshots
|
|
||||||
placeholder: |
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: env
|
|
||||||
attributes:
|
|
||||||
label: Environment
|
|
||||||
options:
|
|
||||||
- Production
|
|
||||||
- Release
|
|
||||||
- Deploy preview
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: dropdown
|
|
||||||
id: version
|
|
||||||
attributes:
|
|
||||||
label: Version
|
|
||||||
options:
|
|
||||||
- Cloud
|
|
||||||
- Self-hosted
|
|
||||||
- Local
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
28
.github/ISSUE_TEMPLATE/--feature-request.yaml
vendored
28
.github/ISSUE_TEMPLATE/--feature-request.yaml
vendored
@@ -1,28 +0,0 @@
|
|||||||
name: Feature request
|
|
||||||
description: Suggest a feature to improve Hoppscotch
|
|
||||||
title: "[feature]: "
|
|
||||||
labels: [feature]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Thank you for taking the time to request a feature for Hoppscotch
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Is there an existing issue for this?
|
|
||||||
description: Please search to see if an issue related to this feature request already exists
|
|
||||||
options:
|
|
||||||
- label: I have searched the existing issues
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Summary
|
|
||||||
description: One paragraph description of the feature
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Why should this be worked on?
|
|
||||||
description: A concise description of the problems or use cases for this feature request
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen.
|
||||||
|
|
||||||
|
**Screenshots**
|
||||||
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
|
**Desktop (please complete the following information):**
|
||||||
|
- OS: [e.g. iOS]
|
||||||
|
- Browser [e.g. chrome, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Smartphone (please complete the following information):**
|
||||||
|
- Device: [e.g. iPhone6]
|
||||||
|
- OS: [e.g. iOS8.1]
|
||||||
|
- Browser [e.g. stock browser, safari]
|
||||||
|
- Version [e.g. 22]
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context about the problem here.
|
||||||
7
.github/ISSUE_TEMPLATE/config.yml
vendored
7
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,7 +0,0 @@
|
|||||||
contact_links:
|
|
||||||
- name: Help and support
|
|
||||||
url: https://github.com/hoppscotch/hoppscotch#support
|
|
||||||
about: Reach out to us on our Discord server or Telegram group or GitHub discussions.
|
|
||||||
- name: Dedicated support
|
|
||||||
url: mailto:support@hoppscotch.io
|
|
||||||
about: Write to us if you'd like dedicated support using Hoppscotch
|
|
||||||
8
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
8
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
name: Custom issue template
|
||||||
|
about: Describe this issue template's purpose here.
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#### **Support**
|
#### **Support**
|
||||||
|
|
||||||
[](https://hoppscotch.io/discord) [](https://hoppscotch.io/telegram) [](https://github.com/hoppscotch/hoppscotch/discussions)
|
[](https://hoppscotch.io/discord) [](https://hoppscotch.io/telegram)
|
||||||
|
|
||||||
<details open>
|
<details open>
|
||||||
<summary><b>Table of contents</b></summary>
|
<summary><b>Table of contents</b></summary>
|
||||||
|
|||||||
26
SECURITY.md
26
SECURITY.md
@@ -1,26 +0,0 @@
|
|||||||
# Security Policy
|
|
||||||
|
|
||||||
This document outlines security procedures and general policies for the Hoppscotch project.
|
|
||||||
|
|
||||||
1. [Reporting a security vulnerability](#reporting-a-security-vulnerability)
|
|
||||||
3. [Incident response process](#incident-response-process)
|
|
||||||
|
|
||||||
## Reporting a security vulnerability
|
|
||||||
|
|
||||||
Report security vulnerabilities by emailing the Hoppscotch Support team at support@hoppscotch.io.
|
|
||||||
|
|
||||||
The primary security point of contact from Hoppscotch Support team will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
|
||||||
|
|
||||||
**Do not create a GitHub issue ticket to report a security vulnerability.**
|
|
||||||
|
|
||||||
The Hoppscotch team and community take all security vulnerability reports in Hoppscotch seriously. Thank you for improving the security of Hoppscotch. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.
|
|
||||||
|
|
||||||
Report security bugs in third-party modules to the person or team maintaining the module.
|
|
||||||
|
|
||||||
## Incident response process
|
|
||||||
|
|
||||||
In case an incident is discovered or reported, we will follow the following process to contain, respond, and remediate:
|
|
||||||
|
|
||||||
1. Confirm the problem and determine the affected versions.
|
|
||||||
2. Audit code to find any potential similar problems.
|
|
||||||
3. Prepare fixes for all releases still under maintenance. These fixes will be deployed as fast as possible to production.
|
|
||||||
@@ -9,19 +9,16 @@ Before you start working on a new language, please look through the [open pull r
|
|||||||
if there is no existing translation, you can create a new one by following these steps:
|
if there is no existing translation, you can create a new one by following these steps:
|
||||||
|
|
||||||
1. **[Fork the repository](https://github.com/hoppscotch/hoppscotch/fork).**
|
1. **[Fork the repository](https://github.com/hoppscotch/hoppscotch/fork).**
|
||||||
2. **Checkout the `i18n` branch for latest translations.**
|
2. **Create a new branch for your translation.**
|
||||||
3. **Create a new branch for your translation with base branch `i18n`.**
|
3. **Create target language file in the [`locales`](https://github.com/hoppscotch/hoppscotch/tree/main/packages/hoppscotch-app/locales) directory.**
|
||||||
4. **Create target language file in the [`locales`](https://github.com/hoppscotch/hoppscotch/tree/main/packages/hoppscotch-app/locales) directory.**
|
4. **Copy the contents of the source file [`locales/en.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-app/locales/en.json) to the target language file.**
|
||||||
5. **Copy the contents of the source file [`locales/en.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-app/locales/en.json) to the target language file.**
|
5. **Translate the strings in the target language file.**
|
||||||
6. **Translate the strings in the target language file.**
|
6. **Add your language entry to [`languages.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-app/languages.json).**
|
||||||
7. **Add your language entry to [`languages.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-app/languages.json).**
|
7. **Save & commit changes.**
|
||||||
8. **Save & commit changes.**
|
8. **Send a pull request.**
|
||||||
9. **Send a pull request.**
|
|
||||||
|
|
||||||
_You may send a pull request before all steps above are complete: e.g., you may want to ask for help with translations, or getting tests to pass. However, your pull request will not be merged until all steps above are complete._
|
_You may send a pull request before all steps above are complete: e.g., you may want to ask for help with translations, or getting tests to pass. However, your pull request will not be merged until all steps above are complete._
|
||||||
|
|
||||||
`i18n` branch will be merged into `main` branch once every week.
|
|
||||||
|
|
||||||
Completing an initial translation of the whole site is a fairly large task. One way to break that task up is to work with other translators through pull requests on your fork. You can also [add collaborators to your fork](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) if you'd like to invite other translators to commit directly to your fork and share responsibility for merging pull requests.
|
Completing an initial translation of the whole site is a fairly large task. One way to break that task up is to work with other translators through pull requests on your fork. You can also [add collaborators to your fork](https://help.github.com/en/github/setting-up-and-managing-your-github-user-account/inviting-collaborators-to-a-personal-repository) if you'd like to invite other translators to commit directly to your fork and share responsibility for merging pull requests.
|
||||||
|
|
||||||
## Updating a translation
|
## Updating a translation
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"description": "Open source API development ecosystem",
|
"description": "Open source API development ecosystem",
|
||||||
"author": "Hoppscotch (support@hoppscotch.io)",
|
"author": "Hoppscotch (support@hoppscotch.io)",
|
||||||
"private": true,
|
"private": true,
|
||||||
"license": "MIT",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"preinstall": "npx only-allow pnpm",
|
"preinstall": "npx only-allow pnpm",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
@@ -21,10 +20,10 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"lint-staged": "^12.1.2"
|
"lint-staged": "^12.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^15.0.0",
|
"@commitlint/cli": "^14.1.0",
|
||||||
"@commitlint/config-conventional": "^15.0.0"
|
"@commitlint/config-conventional": "^14.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
"name": "@hoppscotch/codemirror-lang-graphql",
|
"name": "@hoppscotch/codemirror-lang-graphql",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "GraphQL language support for CodeMirror",
|
"description": "GraphQL language support for CodeMirror",
|
||||||
"author": "Hoppscotch (support@hoppscotch.io)",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "rollup -c"
|
"prepare": "rollup -c"
|
||||||
},
|
},
|
||||||
@@ -16,17 +15,17 @@
|
|||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/highlight": "^0.19.6",
|
"@codemirror/highlight": "^0.19.0",
|
||||||
"@codemirror/language": "^0.19.6",
|
"@codemirror/language": "^0.19.0",
|
||||||
"@lezer/lr": "^0.15.0"
|
"@lezer/lr": "^0.15.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lezer/generator": "^0.15.0",
|
"@lezer/generator": "^0.15.0",
|
||||||
"mocha": "^9.0.1",
|
"mocha": "^9.0.1",
|
||||||
"rollup": "^2.60.1",
|
"rollup": "^2.35.1",
|
||||||
"rollup-plugin-dts": "^4.0.1",
|
"rollup-plugin-dts": "^3.0.2",
|
||||||
"rollup-plugin-ts": "^2.0.4",
|
"rollup-plugin-ts": "^1.4.0",
|
||||||
"typescript": "^4.5.2"
|
"typescript": "^4.3.4"
|
||||||
},
|
},
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M21 12a9 9 0 11-6.219-8.56"></path>
|
<line x1="12" y1="2" x2="12" y2="6"></line>
|
||||||
|
<line x1="12" y1="18" x2="12" y2="22"></line>
|
||||||
|
<line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line>
|
||||||
|
<line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line>
|
||||||
|
<line x1="2" y1="12" x2="6" y2="12"></line>
|
||||||
|
<line x1="18" y1="12" x2="22" y2="12"></line>
|
||||||
|
<line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line>
|
||||||
|
<line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 608 B |
@@ -27,24 +27,23 @@
|
|||||||
@apply h-4;
|
@apply h-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hide-scrollbar {
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide-scrollbar::-webkit-scrollbar {
|
.hide-scrollbar::-webkit-scrollbar {
|
||||||
@apply hidden;
|
@apply hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
@apply bg-accentDark;
|
@apply bg-divider;
|
||||||
@apply text-accentContrast;
|
}
|
||||||
|
|
||||||
|
.cm-focused {
|
||||||
|
@apply !outline-none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input::placeholder,
|
input::placeholder,
|
||||||
textarea::placeholder {
|
textarea::placeholder,
|
||||||
|
.CodeMirror-empty {
|
||||||
@apply text-secondary;
|
@apply text-secondary;
|
||||||
@apply opacity-35;
|
@apply opacity-25;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
@@ -67,6 +66,7 @@ body {
|
|||||||
animation: fade 300ms forwards;
|
animation: fade 300ms forwards;
|
||||||
font-size: var(--body-font-size);
|
font-size: var(--body-font-size);
|
||||||
line-height: var(--body-line-height);
|
line-height: var(--body-line-height);
|
||||||
|
overflow: overlay;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
}
|
}
|
||||||
@@ -318,7 +318,7 @@ pre.ace_editor {
|
|||||||
&.toasted-primary {
|
&.toasted-primary {
|
||||||
@apply bg-tooltip;
|
@apply bg-tooltip;
|
||||||
@apply text-primary;
|
@apply text-primary;
|
||||||
@apply justify-between;
|
@apply justify-start;
|
||||||
@apply shadow;
|
@apply shadow;
|
||||||
@apply font-medium;
|
@apply font-medium;
|
||||||
@apply transition;
|
@apply transition;
|
||||||
@@ -391,7 +391,7 @@ pre.ace_editor {
|
|||||||
.smart-splitter .splitpanes__splitter::before {
|
.smart-splitter .splitpanes__splitter::before {
|
||||||
@apply absolute;
|
@apply absolute;
|
||||||
@apply inset-0;
|
@apply inset-0;
|
||||||
@apply bg-accentLight;
|
@apply bg-dividerLight;
|
||||||
@apply opacity-0;
|
@apply opacity-0;
|
||||||
@apply z-20;
|
@apply z-20;
|
||||||
@apply transition;
|
@apply transition;
|
||||||
@@ -435,16 +435,29 @@ pre.ace_editor {
|
|||||||
@apply w-full;
|
@apply w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-focused {
|
.CodeMirror {
|
||||||
@apply select-auto;
|
@apply !h-auto;
|
||||||
@apply !outline-none;
|
|
||||||
|
|
||||||
.cm-activeLine {
|
font-size: var(--body-font-size);
|
||||||
@apply bg-primaryLight;
|
|
||||||
|
&:not(.CodeMirror-focused) .CodeMirror-activeline-background {
|
||||||
|
background: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-activeLineGutter {
|
.CodeMirror-dialog-top {
|
||||||
@apply bg-primaryDark;
|
@apply bg-primaryLight;
|
||||||
|
@apply border-dividerLight;
|
||||||
|
@apply px-4;
|
||||||
|
@apply py-2;
|
||||||
|
@apply z-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-scroll {
|
||||||
|
@apply min-h-64;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
font-family: "Roboto Mono", monospace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,17 +53,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin dark-editor-theme {
|
@mixin dark-editor-theme {
|
||||||
--editor-type-color: theme("colors.purple.400");
|
--editor-type-color: theme("colors.purple.500");
|
||||||
--editor-name-color: theme("colors.blue.400");
|
--editor-name-color: theme("colors.blue.500");
|
||||||
--editor-operator-color: theme("colors.indigo.400");
|
--editor-operator-color: theme("colors.indigo.500");
|
||||||
--editor-invalid-color: theme("colors.red.400");
|
--editor-invalid-color: theme("colors.red.500");
|
||||||
--editor-separator-color: theme("colors.gray.400");
|
--editor-separator-color: theme("colors.gray.500");
|
||||||
--editor-meta-color: theme("colors.gray.400");
|
--editor-meta-color: theme("colors.gray.500");
|
||||||
--editor-variable-color: theme("colors.green.400");
|
--editor-variable-color: theme("colors.green.500");
|
||||||
--editor-link-color: theme("colors.cyan.400");
|
--editor-link-color: theme("colors.cyan.500");
|
||||||
--editor-process-color: theme("colors.fuchsia.400");
|
--editor-process-color: theme("colors.gray.400");
|
||||||
--editor-constant-color: theme("colors.violet.400");
|
--editor-constant-color: theme("colors.fuchsia.500");
|
||||||
--editor-keyword-color: theme("colors.pink.400");
|
--editor-keyword-color: theme("colors.pink.500");
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin light-editor-theme {
|
@mixin light-editor-theme {
|
||||||
@@ -82,15 +82,15 @@
|
|||||||
|
|
||||||
@mixin black-editor-theme {
|
@mixin black-editor-theme {
|
||||||
--editor-type-color: theme("colors.purple.400");
|
--editor-type-color: theme("colors.purple.400");
|
||||||
--editor-name-color: theme("colors.fuchsia.400");
|
--editor-name-color: theme("colors.gray.400");
|
||||||
--editor-operator-color: theme("colors.indigo.400");
|
--editor-operator-color: theme("colors.indigo.400");
|
||||||
--editor-invalid-color: theme("colors.red.400");
|
--editor-invalid-color: theme("colors.red.400");
|
||||||
--editor-separator-color: theme("colors.gray.400");
|
--editor-separator-color: theme("colors.gray.400");
|
||||||
--editor-meta-color: theme("colors.gray.400");
|
--editor-meta-color: theme("colors.gray.400");
|
||||||
--editor-variable-color: theme("colors.green.400");
|
--editor-variable-color: theme("colors.green.400");
|
||||||
--editor-link-color: theme("colors.cyan.400");
|
--editor-link-color: theme("colors.cyan.400");
|
||||||
--editor-process-color: theme("colors.violet.400");
|
--editor-process-color: theme("colors.blue.400");
|
||||||
--editor-constant-color: theme("colors.blue.400");
|
--editor-constant-color: theme("colors.fuchsia.400");
|
||||||
--editor-keyword-color: theme("colors.pink.400");
|
--editor-keyword-color: theme("colors.pink.400");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="bg-error flex justify-between">
|
<div class="bg-error flex justify-between">
|
||||||
<span
|
<span
|
||||||
class="group relative flex items-center justify-center px-4 py-2 transition"
|
class="
|
||||||
|
flex
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
transition
|
||||||
|
relative
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
group
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons mr-2">info_outline</i>
|
<i class="mr-2 material-icons">info_outline</i>
|
||||||
<span class="text-secondaryDark">
|
<span class="text-secondaryDark">
|
||||||
<span class="md:hidden">
|
<span class="md:hidden">
|
||||||
{{ t("helpers.offline_short") }}
|
{{ $t("helpers.offline_short") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="md:inline hidden">
|
<span class="hidden md:inline">
|
||||||
{{ t("helpers.offline") }}
|
{{ $t("helpers.offline") }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
</script>
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="EXPAND_NAVIGATION ? t('hide.sidebar') : t('show.sidebar')"
|
:title="EXPAND_NAVIGATION ? $t('hide.sidebar') : $t('show.sidebar')"
|
||||||
svg="sidebar"
|
svg="sidebar"
|
||||||
class="transform"
|
class="transform"
|
||||||
:class="{ '-rotate-180': !EXPAND_NAVIGATION }"
|
:class="{ '-rotate-180': !EXPAND_NAVIGATION }"
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="`${ZEN_MODE ? t('action.turn_off') : t('action.turn_on')} ${t(
|
:title="`${
|
||||||
'layout.zen_mode'
|
ZEN_MODE ? $t('action.turn_off') : $t('action.turn_on')
|
||||||
)}`"
|
} ${$t('layout.zen_mode')}`"
|
||||||
:svg="ZEN_MODE ? 'minimize' : 'maximize'"
|
:svg="ZEN_MODE ? 'minimize' : 'maximize'"
|
||||||
:class="{
|
:class="{
|
||||||
'!text-accent !focus-visible:text-accentDark !hover:text-accentDark':
|
'!text-accent !focus-visible:text-accentDark !hover:text-accentDark':
|
||||||
@@ -36,20 +36,20 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
class="!rounded-none"
|
class="!rounded-none"
|
||||||
:label="`${t('app.help')}`"
|
:label="`${$t('app.help')}`"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="book"
|
svg="book"
|
||||||
:label="`${t('app.documentation')}`"
|
:label="`${$t('app.documentation')}`"
|
||||||
to="https://docs.hoppscotch.io"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
@click.native="$refs.options.tippy().hide()"
|
@click.native="$refs.options.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="zap"
|
svg="zap"
|
||||||
:label="`${t('app.keyboard_shortcuts')}`"
|
:label="`${$t('app.keyboard_shortcuts')}`"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
showShortcuts = true
|
showShortcuts = true
|
||||||
@@ -59,14 +59,14 @@
|
|||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="gift"
|
svg="gift"
|
||||||
:label="`${t('app.whats_new')}`"
|
:label="`${$t('app.whats_new')}`"
|
||||||
to="https://docs.hoppscotch.io/changelog"
|
to="https://docs.hoppscotch.io/changelog"
|
||||||
blank
|
blank
|
||||||
@click.native="$refs.options.tippy().hide()"
|
@click.native="$refs.options.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="message-circle"
|
svg="message-circle"
|
||||||
:label="`${t('app.chat_with_us')}`"
|
:label="`${$t('app.chat_with_us')}`"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
chatWithUs()
|
chatWithUs()
|
||||||
@@ -77,21 +77,21 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="github"
|
svg="github"
|
||||||
:label="`${t('app.github')}`"
|
:label="`${$t('app.github')}`"
|
||||||
to="https://github.com/hoppscotch/hoppscotch"
|
to="https://github.com/hoppscotch/hoppscotch"
|
||||||
blank
|
blank
|
||||||
@click.native="$refs.options.tippy().hide()"
|
@click.native="$refs.options.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="twitter"
|
svg="twitter"
|
||||||
:label="`${t('app.twitter')}`"
|
:label="`${$t('app.twitter')}`"
|
||||||
to="https://hoppscotch.io/twitter"
|
to="https://hoppscotch.io/twitter"
|
||||||
blank
|
blank
|
||||||
@click.native="$refs.options.tippy().hide()"
|
@click.native="$refs.options.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="user-plus"
|
svg="user-plus"
|
||||||
:label="`${t('app.invite')}`"
|
:label="`${$t('app.invite')}`"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
showShare = true
|
showShare = true
|
||||||
@@ -101,14 +101,14 @@
|
|||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="lock"
|
svg="lock"
|
||||||
:label="`${t('app.terms_and_privacy')}`"
|
:label="`${$t('app.terms_and_privacy')}`"
|
||||||
to="https://docs.hoppscotch.io/privacy"
|
to="https://docs.hoppscotch.io/privacy"
|
||||||
blank
|
blank
|
||||||
@click.native="$refs.options.tippy().hide()"
|
@click.native="$refs.options.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<!-- <SmartItem :label="t('app.status')" /> -->
|
<!-- <SmartItem :label="$t('app.status')" /> -->
|
||||||
<div class="flex px-4 py-2 opacity-50">
|
<div class="flex opacity-50 py-2 px-4">
|
||||||
{{ `${t("app.name")} ${t("app.version")}` }}
|
{{ `${$t("app.name")} ${$t("app.version")}` }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</tippy>
|
</tippy>
|
||||||
@@ -116,33 +116,33 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="zap"
|
svg="zap"
|
||||||
:title="t('app.shortcuts')"
|
:title="$t('app.shortcuts')"
|
||||||
@click.native="showShortcuts = true"
|
@click.native="showShortcuts = true"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="navigatorShare"
|
v-if="navigatorShare"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="share-2"
|
svg="share-2"
|
||||||
:title="t('request.share')"
|
:title="$t('request.share')"
|
||||||
@click.native="nativeShare()"
|
@click.native="nativeShare()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="COLUMN_LAYOUT ? t('layout.row') : t('layout.column')"
|
:title="COLUMN_LAYOUT ? $t('layout.row') : $t('layout.column')"
|
||||||
svg="columns"
|
svg="columns"
|
||||||
class="transform"
|
class="transform"
|
||||||
:class="{ 'rotate-90': !COLUMN_LAYOUT }"
|
:class="{ 'rotate-90': !COLUMN_LAYOUT }"
|
||||||
@click.native="COLUMN_LAYOUT = !COLUMN_LAYOUT"
|
@click.native="COLUMN_LAYOUT = !COLUMN_LAYOUT"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="transition transform"
|
class="transform transition"
|
||||||
:class="{
|
:class="{
|
||||||
'rotate-180': SIDEBAR_ON_LEFT,
|
'rotate-180': SIDEBAR_ON_LEFT,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="SIDEBAR ? t('hide.sidebar') : t('show.sidebar')"
|
:title="SIDEBAR ? $t('hide.sidebar') : $t('show.sidebar')"
|
||||||
svg="sidebar-open"
|
svg="sidebar-open"
|
||||||
class="transform"
|
class="transform"
|
||||||
:class="{ 'rotate-180': !SIDEBAR }"
|
:class="{ 'rotate-180': !SIDEBAR }"
|
||||||
@@ -161,9 +161,7 @@ import { ref, watch } from "@nuxtjs/composition-api"
|
|||||||
import { defineActionHandler } from "~/helpers/actions"
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
import { showChat } from "~/helpers/support"
|
import { showChat } from "~/helpers/support"
|
||||||
import { useSetting } from "~/newstore/settings"
|
import { useSetting } from "~/newstore/settings"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
const showShortcuts = ref(false)
|
const showShortcuts = ref(false)
|
||||||
const showShare = ref(false)
|
const showShare = ref(false)
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,11 @@
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-if="searchResults.length === 0"
|
v-if="searchResults.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
{{ t("state.nothing_found") }} "{{ search }}"
|
{{ $t("state.nothing_found") }} "{{ search }}"
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,9 +26,6 @@ import { computed, onUnmounted, onMounted } from "@nuxtjs/composition-api"
|
|||||||
import Fuse from "fuse.js"
|
import Fuse from "fuse.js"
|
||||||
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
||||||
import { HoppAction } from "~/helpers/actions"
|
import { HoppAction } from "~/helpers/actions"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
input: Record<string, any>[]
|
input: Record<string, any>[]
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<header
|
<header
|
||||||
class="flex items-center justify-between flex-1 px-2 py-2 space-x-2"
|
class="flex space-x-2 flex-1 py-2 px-2 items-center justify-between"
|
||||||
>
|
>
|
||||||
<div class="inline-flex items-center space-x-2">
|
<div class="space-x-2 inline-flex items-center">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
class="tracking-wide !font-bold !text-secondaryDark"
|
class="tracking-wide !font-bold !text-secondaryDark"
|
||||||
label="HOPPSCOTCH"
|
label="HOPPSCOTCH"
|
||||||
@@ -11,25 +11,25 @@
|
|||||||
/>
|
/>
|
||||||
<AppGitHubStarButton class="mt-1.5 transition hidden sm:flex" />
|
<AppGitHubStarButton class="mt-1.5 transition hidden sm:flex" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-flex items-center space-x-2">
|
<div class="space-x-2 inline-flex items-center">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
id="installPWA"
|
id="installPWA"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('header.install_pwa')"
|
:title="$t('header.install_pwa')"
|
||||||
svg="download"
|
svg="download"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
@click.native="showInstallPrompt()"
|
@click.native="showInstallPrompt()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="`${t('app.search')} <kbd>/</kbd>`"
|
:title="`${$t('app.search')} <kbd>/</kbd>`"
|
||||||
svg="search"
|
svg="search"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
@click.native="showSearch = true"
|
@click.native="showSearch = true"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="`${t('support.title')} <kbd>?</kbd>`"
|
:title="`${$t('support.title')} <kbd>?</kbd>`"
|
||||||
svg="life-buoy"
|
svg="life-buoy"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
@click.native="showSupport = true"
|
@click.native="showSupport = true"
|
||||||
@@ -37,23 +37,28 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="currentUser === null"
|
v-if="currentUser === null"
|
||||||
svg="upload-cloud"
|
svg="upload-cloud"
|
||||||
:label="t('header.save_workspace')"
|
:label="$t('header.save_workspace')"
|
||||||
filled
|
filled
|
||||||
class="md:flex hidden"
|
class="hidden md:flex"
|
||||||
@click.native="showLogin = true"
|
@click.native="showLogin = true"
|
||||||
/>
|
/>
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
v-if="currentUser === null"
|
v-if="currentUser === null"
|
||||||
:label="t('header.login')"
|
:label="$t('header.login')"
|
||||||
@click.native="showLogin = true"
|
@click.native="showLogin = true"
|
||||||
/>
|
/>
|
||||||
<div v-else class="inline-flex items-center space-x-2">
|
<div v-else class="space-x-2 inline-flex items-center">
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('team.invite_tooltip')"
|
:title="$t('team.invite_tooltip')"
|
||||||
:label="t('team.invite')"
|
:label="$t('team.invite')"
|
||||||
svg="user-plus"
|
svg="user-plus"
|
||||||
class="!bg-green-500 !text-green-500 !bg-opacity-15 !hover:bg-opacity-10 !hover:text-green-600 !hover:bg-green-400"
|
class="
|
||||||
|
!bg-green-500
|
||||||
|
!text-green-500
|
||||||
|
!bg-opacity-15
|
||||||
|
!hover:bg-opacity-10 !hover:text-green-600 !hover:bg-green-400
|
||||||
|
"
|
||||||
@click.native="showTeamsModal = true"
|
@click.native="showTeamsModal = true"
|
||||||
/>
|
/>
|
||||||
<span class="px-2">
|
<span class="px-2">
|
||||||
@@ -73,7 +78,7 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-else
|
v-else
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('header.account')"
|
:title="$t('header.account')"
|
||||||
class="rounded"
|
class="rounded"
|
||||||
svg="user"
|
svg="user"
|
||||||
/>
|
/>
|
||||||
@@ -81,13 +86,13 @@
|
|||||||
<SmartItem
|
<SmartItem
|
||||||
to="/profile"
|
to="/profile"
|
||||||
svg="user"
|
svg="user"
|
||||||
:label="t('navigation.profile')"
|
:label="$t('navigation.profile')"
|
||||||
@click.native="$refs.user.tippy().hide()"
|
@click.native="$refs.user.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
to="/settings"
|
to="/settings"
|
||||||
svg="settings"
|
svg="settings"
|
||||||
:label="t('navigation.settings')"
|
:label="$t('navigation.settings')"
|
||||||
@click.native="$refs.user.tippy().hide()"
|
@click.native="$refs.user.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<FirebaseLogout @confirm-logout="$refs.user.tippy().hide()" />
|
<FirebaseLogout @confirm-logout="$refs.user.tippy().hide()" />
|
||||||
@@ -105,20 +110,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref } from "@nuxtjs/composition-api"
|
import { onMounted, ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import intializePwa from "~/helpers/pwa"
|
import intializePwa from "~/helpers/pwa"
|
||||||
import { probableUser$ } from "~/helpers/fb/auth"
|
import { probableUser$ } from "~/helpers/fb/auth"
|
||||||
import { getLocalConfig, setLocalConfig } from "~/newstore/localpersistence"
|
import { getLocalConfig, setLocalConfig } from "~/newstore/localpersistence"
|
||||||
import {
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import { defineActionHandler } from "~/helpers/actions"
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Once the PWA code is initialized, this holds a method
|
* Once the PWA code is initialized, this holds a method
|
||||||
@@ -157,11 +160,12 @@ onMounted(() => {
|
|||||||
|
|
||||||
const cookiesAllowed = getLocalConfig("cookiesAllowed") === "yes"
|
const cookiesAllowed = getLocalConfig("cookiesAllowed") === "yes"
|
||||||
if (!cookiesAllowed) {
|
if (!cookiesAllowed) {
|
||||||
toast.show(`${t("app.we_use_cookies")}`, {
|
$toast.show(t("app.we_use_cookies").toString(), {
|
||||||
|
icon: "cookie",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
action: [
|
action: [
|
||||||
{
|
{
|
||||||
text: `${t("action.learn_more")}`,
|
text: t("action.learn_more").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
setLocalConfig("cookiesAllowed", "yes")
|
setLocalConfig("cookiesAllowed", "yes")
|
||||||
toastObject.goAway(0)
|
toastObject.goAway(0)
|
||||||
@@ -169,7 +173,7 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: `${t("action.dismiss")}`,
|
text: t("action.dismiss").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
setLocalConfig("cookiesAllowed", "yes")
|
setLocalConfig("cookiesAllowed", "yes")
|
||||||
toastObject.goAway(0)
|
toastObject.goAway(0)
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col items-start p-4 space-y-4">
|
<div class="flex p-4 space-y-4 items-start flex-col">
|
||||||
<SmartToggle
|
<SmartToggle
|
||||||
:on="PROXY_ENABLED"
|
:on="PROXY_ENABLED"
|
||||||
@change="toggleSettingKey('PROXY_ENABLED')"
|
@change="toggleSettingKey('PROXY_ENABLED')"
|
||||||
>
|
>
|
||||||
{{ t("settings.proxy") }}
|
{{ $t("settings.proxy") }}
|
||||||
</SmartToggle>
|
</SmartToggle>
|
||||||
<SmartToggle
|
<SmartToggle
|
||||||
:on="EXTENSIONS_ENABLED"
|
:on="EXTENSIONS_ENABLED"
|
||||||
@change="toggleSettingKey('EXTENSIONS_ENABLED')"
|
@change="toggleSettingKey('EXTENSIONS_ENABLED')"
|
||||||
>
|
>
|
||||||
{{ t("settings.extensions") }}:
|
{{ $t("settings.extensions") }}:
|
||||||
{{
|
{{
|
||||||
extensionVersion != null
|
extensionVersion != null
|
||||||
? `v${extensionVersion.major}.${extensionVersion.minor}`
|
? `v${extensionVersion.major}.${extensionVersion.minor}`
|
||||||
: t("settings.extension_ver_not_reported")
|
: $t("settings.extension_ver_not_reported")
|
||||||
}}
|
}}
|
||||||
</SmartToggle>
|
</SmartToggle>
|
||||||
</div>
|
</div>
|
||||||
@@ -25,9 +25,6 @@ import { defineComponent } from "@nuxtjs/composition-api"
|
|||||||
import { KeysMatching } from "~/types/ts-utils"
|
import { KeysMatching } from "~/types/ts-utils"
|
||||||
import { SettingsType, toggleSetting, useSetting } from "~/newstore/settings"
|
import { SettingsType, toggleSetting, useSetting } from "~/newstore/settings"
|
||||||
import { hasExtensionInstalled } from "~/helpers/strategies/ExtensionStrategy"
|
import { hasExtensionInstalled } from "~/helpers/strategies/ExtensionStrategy"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const PROXY_ENABLED = useSetting("PROXY_ENABLED")
|
const PROXY_ENABLED = useSetting("PROXY_ENABLED")
|
||||||
const EXTENSIONS_ENABLED = useSetting("EXTENSIONS_ENABLED")
|
const EXTENSIONS_ENABLED = useSetting("EXTENSIONS_ENABLED")
|
||||||
|
|||||||
@@ -13,8 +13,14 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
name="command"
|
name="command"
|
||||||
:placeholder="`${t('app.type_a_command_search')}`"
|
:placeholder="`${$t('app.type_a_command_search')}`"
|
||||||
class="border-dividerLight text-secondaryDark flex flex-shrink-0 p-6 text-base bg-transparent border-b"
|
class="
|
||||||
|
bg-transparent
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-shrink-0
|
||||||
|
text-secondaryDark text-base
|
||||||
|
p-6
|
||||||
|
"
|
||||||
/>
|
/>
|
||||||
<AppFuse
|
<AppFuse
|
||||||
v-if="search && show"
|
v-if="search && show"
|
||||||
@@ -24,15 +30,22 @@
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 space-y-4 overflow-auto divide-y"
|
class="
|
||||||
|
divide-y divide-dividerLight
|
||||||
|
flex flex-col
|
||||||
|
space-y-4
|
||||||
|
flex-1
|
||||||
|
overflow-auto
|
||||||
|
hide-scrollbar
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(map, mapIndex) in mappings"
|
v-for="(map, mapIndex) in mappings"
|
||||||
:key="`map-${mapIndex}`"
|
:key="`map-${mapIndex}`"
|
||||||
class="flex flex-col"
|
class="flex flex-col"
|
||||||
>
|
>
|
||||||
<h5 class="text-secondaryLight px-6 py-2 my-2">
|
<h5 class="my-2 text-secondaryLight py-2 px-6">
|
||||||
{{ t(map.section) }}
|
{{ $t(map.section) }}
|
||||||
</h5>
|
</h5>
|
||||||
<AppPowerSearchEntry
|
<AppPowerSearchEntry
|
||||||
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
||||||
@@ -53,9 +66,6 @@ import { ref, computed, watch } from "@nuxtjs/composition-api"
|
|||||||
import { HoppAction, invokeAction } from "~/helpers/actions"
|
import { HoppAction, invokeAction } from "~/helpers/actions"
|
||||||
import { spotlight as mappings, fuse } from "~/helpers/shortcuts"
|
import { spotlight as mappings, fuse } from "~/helpers/shortcuts"
|
||||||
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
show: boolean
|
show: boolean
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<button
|
<button
|
||||||
class="search-entry focus:outline-none flex items-center flex-1 px-6 py-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
py-2
|
||||||
|
px-6
|
||||||
|
transition
|
||||||
|
items-center
|
||||||
|
search-entry
|
||||||
|
focus:outline-none
|
||||||
|
"
|
||||||
:class="{ active: active }"
|
:class="{ active: active }"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@click="$emit('action', shortcut.action)"
|
@click="$emit('action', shortcut.action)"
|
||||||
@keydown.enter="$emit('action', shortcut.action)"
|
@keydown.enter="$emit('action', shortcut.action)"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
class="svg-icons mr-4 transition opacity-50"
|
class="mr-4 opacity-50 transition svg-icons"
|
||||||
:class="{ 'opacity-100 text-secondaryDark': active }"
|
:class="{ 'opacity-100 text-secondaryDark': active }"
|
||||||
:name="shortcut.icon"
|
:name="shortcut.icon"
|
||||||
/>
|
/>
|
||||||
@@ -15,7 +24,7 @@
|
|||||||
class="flex flex-1 mr-4 font-medium transition"
|
class="flex flex-1 mr-4 font-medium transition"
|
||||||
:class="{ 'text-secondaryDark': active }"
|
:class="{ 'text-secondaryDark': active }"
|
||||||
>
|
>
|
||||||
{{ t(shortcut.label) }}
|
{{ $t(shortcut.label) }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-for="(key, keyIndex) in shortcut.keys"
|
v-for="(key, keyIndex) in shortcut.keys"
|
||||||
@@ -28,10 +37,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
shortcut: Object
|
shortcut: Object
|
||||||
active: Boolean
|
active: Boolean
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<section :id="label.toLowerCase()" class="relative flex flex-col flex-1">
|
<section :id="label.toLowerCase()" class="flex flex-col flex-1 relative">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="t('app.invite_your_friends')"
|
:title="$t('app.invite_your_friends')"
|
||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
<template #body>
|
<template #body>
|
||||||
<p class="text-secondaryLight px-2 mb-8">
|
<p class="text-secondaryLight mb-8 px-2">
|
||||||
{{ t("app.invite_description") }}
|
{{ $t("app.invite_description") }}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-col px-2 space-y-2">
|
<div class="flex flex-col space-y-2 px-2">
|
||||||
<div class="grid grid-cols-3 gap-4">
|
<div class="grid gap-4 grid-cols-3">
|
||||||
<a
|
<a
|
||||||
v-for="(platform, index) in platforms"
|
v-for="(platform, index) in platforms"
|
||||||
:key="`platform-${index}`"
|
:key="`platform-${index}`"
|
||||||
@@ -17,15 +17,15 @@
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
class="share-link"
|
class="share-link"
|
||||||
>
|
>
|
||||||
<SmartIcon :name="platform.icon" class="w-6 h-6" />
|
<SmartIcon :name="platform.icon" class="h-6 w-6" />
|
||||||
<span class="mt-3">
|
<span class="mt-3">
|
||||||
{{ platform.name }}
|
{{ platform.name }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<button class="share-link" @click="copyAppLink">
|
<button class="share-link" @click="copyAppLink">
|
||||||
<SmartIcon class="w-6 h-6 text-xl" :name="copyIcon" />
|
<SmartIcon class="h-6 text-xl w-6" :name="copyIcon" />
|
||||||
<span class="mt-3">
|
<span class="mt-3">
|
||||||
{{ t("app.copy") }}
|
{{ $t("app.copy") }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,13 +35,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "@nuxtjs/composition-api"
|
import { ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
show: Boolean
|
show: Boolean
|
||||||
@@ -91,7 +92,9 @@ const platforms = [
|
|||||||
const copyAppLink = () => {
|
const copyAppLink = () => {
|
||||||
copyToClipboard(url)
|
copyToClipboard(url)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(t("state.copied_to_clipboard").toString(), {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,35 +2,51 @@
|
|||||||
<AppSlideOver :show="show" @close="close()">
|
<AppSlideOver :show="show" @close="close()">
|
||||||
<template #content>
|
<template #content>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between p-2 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex
|
||||||
|
p-2
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
items-center
|
||||||
|
sticky
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<h3 class="heading ml-4">{{ t("app.shortcuts") }}</h3>
|
<h3 class="ml-4 heading">{{ $t("app.shortcuts") }}</h3>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary svg="x" class="rounded" @click.native="close()" />
|
<ButtonSecondary svg="x" class="rounded" @click.native="close()" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-primary border-dividerLight border-b">
|
<div class="bg-primary border-b border-dividerLight">
|
||||||
<div class="flex flex-col mx-6 my-4">
|
<div class="flex flex-col my-4 mx-6">
|
||||||
<input
|
<input
|
||||||
v-model="filterText"
|
v-model="filterText"
|
||||||
type="search"
|
type="search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
class="bg-primaryLight border-dividerLight focus-visible:border-divider flex w-full px-4 py-2 border rounded"
|
class="
|
||||||
:placeholder="`${t('action.search')}`"
|
bg-primaryLight
|
||||||
|
border border-dividerLight
|
||||||
|
rounded
|
||||||
|
flex
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
focus-visible:border-divider
|
||||||
|
"
|
||||||
|
:placeholder="`${$t('action.search')}`"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="filterText">
|
||||||
v-if="filterText"
|
|
||||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-for="(map, mapIndex) in searchResults"
|
v-for="(map, mapIndex) in searchResults"
|
||||||
:key="`map-${mapIndex}`"
|
:key="`map-${mapIndex}`"
|
||||||
class="px-6 py-4 space-y-4"
|
class="space-y-4 py-4 px-6"
|
||||||
>
|
>
|
||||||
<h1 class="text-secondaryDark font-semibold">
|
<h1 class="font-semibold text-secondaryDark">
|
||||||
{{ t(map.item.section) }}
|
{{ $t(map.item.section) }}
|
||||||
</h1>
|
</h1>
|
||||||
<AppShortcutsEntry
|
<AppShortcutsEntry
|
||||||
v-for="(shortcut, index) in map.item.shortcuts"
|
v-for="(shortcut, index) in map.item.shortcuts"
|
||||||
@@ -40,25 +56,36 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="searchResults.length === 0"
|
v-if="searchResults.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
{{ t("state.nothing_found") }} "{{ filterText }}"
|
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
class="
|
||||||
|
divide-y divide-dividerLight
|
||||||
|
flex flex-col flex-1
|
||||||
|
overflow-auto
|
||||||
|
hide-scrollbar
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(map, mapIndex) in mappings"
|
v-for="(map, mapIndex) in mappings"
|
||||||
:key="`map-${mapIndex}`"
|
:key="`map-${mapIndex}`"
|
||||||
class="px-6 py-4 space-y-4"
|
class="space-y-4 py-4 px-6"
|
||||||
>
|
>
|
||||||
<h1 class="text-secondaryDark font-semibold">
|
<h1 class="font-semibold text-secondaryDark">
|
||||||
{{ t(map.section) }}
|
{{ $t(map.section) }}
|
||||||
</h1>
|
</h1>
|
||||||
<AppShortcutsEntry
|
<AppShortcutsEntry
|
||||||
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
||||||
@@ -75,9 +102,6 @@
|
|||||||
import { computed, ref } from "@nuxtjs/composition-api"
|
import { computed, ref } from "@nuxtjs/composition-api"
|
||||||
import Fuse from "fuse.js"
|
import Fuse from "fuse.js"
|
||||||
import mappings from "~/helpers/shortcuts"
|
import mappings from "~/helpers/shortcuts"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
show: boolean
|
show: boolean
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span class="flex flex-1 mr-4">
|
<span class="flex flex-1 mr-4">
|
||||||
{{ t(shortcut.label) }}
|
{{ $t(shortcut.label) }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
v-for="(key, index) in shortcut.keys"
|
v-for="(key, index) in shortcut.keys"
|
||||||
@@ -14,10 +14,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
shortcut: Object
|
shortcut: Object
|
||||||
}>()
|
}>()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<aside class="md:flex-col flex justify-between h-full">
|
<aside class="flex h-full justify-between md:flex-col">
|
||||||
<nav class="flex-nowrap md:flex-col md:flex-none flex flex-1">
|
<nav class="flex flex-nowrap md:flex-col flex-1 md:flex-none">
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
v-for="(navigation, index) in primaryNavigation"
|
v-for="(navigation, index) in primaryNavigation"
|
||||||
:key="`navigation-${index}`"
|
:key="`navigation-${index}`"
|
||||||
@@ -27,11 +27,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useContext } from "@nuxtjs/composition-api"
|
||||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||||
import { useSetting } from "~/newstore/settings"
|
import { useSetting } from "~/newstore/settings"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const windowInnerWidth = useWindowSize()
|
const windowInnerWidth = useWindowSize()
|
||||||
const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
|
const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
|
||||||
|
|||||||
@@ -1,16 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<transition v-if="show" name="fade" appear>
|
<transition v-if="show" name="fade" appear>
|
||||||
<div class="fixed inset-0 z-20 transition-opacity" @keydown.esc="close()">
|
<div class="inset-0 transition-opacity z-20 fixed" @keydown.esc="close()">
|
||||||
<div
|
<div
|
||||||
class="bg-primaryLight opacity-90 absolute inset-0"
|
class="bg-primaryLight opacity-90 inset-0 absolute"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
@click="close()"
|
@click="close()"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
<aside
|
<aside
|
||||||
class="bg-primary w-96 fixed top-0 right-0 z-30 flex flex-col h-full max-w-full overflow-auto transition duration-300 ease-in-out transform"
|
class="
|
||||||
|
bg-primary
|
||||||
|
flex flex-col
|
||||||
|
h-full
|
||||||
|
max-w-full
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
top-0
|
||||||
|
ease-in-out
|
||||||
|
right-0
|
||||||
|
w-96
|
||||||
|
z-30
|
||||||
|
duration-300
|
||||||
|
fixed
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
:class="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
|
:class="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
|
||||||
>
|
>
|
||||||
<slot name="content"></slot>
|
<slot name="content"></slot>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="t('support.title')"
|
:title="$t('support.title')"
|
||||||
max-width="sm:max-w-md"
|
max-width="sm:max-w-md"
|
||||||
@close="$emit('hide-modal')"
|
@close="$emit('hide-modal')"
|
||||||
>
|
>
|
||||||
@@ -9,9 +9,9 @@
|
|||||||
<div class="flex flex-col space-y-2">
|
<div class="flex flex-col space-y-2">
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="book"
|
svg="book"
|
||||||
:label="t('app.documentation')"
|
:label="$t('app.documentation')"
|
||||||
to="https://docs.hoppscotch.io"
|
to="https://docs.hoppscotch.io"
|
||||||
:description="t('support.documentation')"
|
:description="$t('support.documentation')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
blank
|
blank
|
||||||
@@ -19,17 +19,17 @@
|
|||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="zap"
|
svg="zap"
|
||||||
:label="t('app.keyboard_shortcuts')"
|
:label="$t('app.keyboard_shortcuts')"
|
||||||
:description="t('support.shortcuts')"
|
:description="$t('support.shortcuts')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
@click.native="showShortcuts()"
|
@click.native="showShortcuts()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="gift"
|
svg="gift"
|
||||||
:label="t('app.whats_new')"
|
:label="$t('app.whats_new')"
|
||||||
to="https://docs.hoppscotch.io/changelog"
|
to="https://docs.hoppscotch.io/changelog"
|
||||||
:description="t('support.changelog')"
|
:description="$t('support.changelog')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
blank
|
blank
|
||||||
@@ -37,28 +37,28 @@
|
|||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="message-circle"
|
svg="message-circle"
|
||||||
:label="t('app.chat_with_us')"
|
:label="$t('app.chat_with_us')"
|
||||||
:description="t('support.chat')"
|
:description="$t('support.chat')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
@click.native="chatWithUs()"
|
@click.native="chatWithUs()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="brands/discord"
|
svg="brands/discord"
|
||||||
:label="t('app.join_discord_community')"
|
:label="$t('app.join_discord_community')"
|
||||||
to="https://hoppscotch.io/discord"
|
to="https://hoppscotch.io/discord"
|
||||||
blank
|
blank
|
||||||
:description="t('support.community')"
|
:description="$t('support.community')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
@click.native="hideModal()"
|
@click.native="hideModal()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
svg="brands/twitter"
|
svg="brands/twitter"
|
||||||
:label="t('app.twitter')"
|
:label="$t('app.twitter')"
|
||||||
to="https://hoppscotch.io/twitter"
|
to="https://hoppscotch.io/twitter"
|
||||||
blank
|
blank
|
||||||
:description="t('support.twitter')"
|
:description="$t('support.twitter')"
|
||||||
info-icon="chevron_right"
|
info-icon="chevron_right"
|
||||||
active
|
active
|
||||||
@click.native="hideModal()"
|
@click.native="hideModal()"
|
||||||
@@ -71,9 +71,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { invokeAction } from "~/helpers/actions"
|
import { invokeAction } from "~/helpers/actions"
|
||||||
import { showChat } from "~/helpers/support"
|
import { showChat } from "~/helpers/support"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
show: Boolean
|
show: Boolean
|
||||||
@@ -90,7 +87,6 @@ const chatWithUs = () => {
|
|||||||
|
|
||||||
const showShortcuts = () => {
|
const showShortcuts = () => {
|
||||||
invokeAction("flyouts.keybinds.toggle")
|
invokeAction("flyouts.keybinds.toggle")
|
||||||
hideModal()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideModal = () => {
|
const hideModal = () => {
|
||||||
|
|||||||
@@ -3,7 +3,16 @@
|
|||||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||||
:exact="exact"
|
:exact="exact"
|
||||||
:blank="blank"
|
:blank="blank"
|
||||||
class="focus:outline-none focus-visible:bg-accentDark inline-flex items-center justify-center py-2 font-bold transition"
|
class="
|
||||||
|
font-bold
|
||||||
|
py-2
|
||||||
|
transition
|
||||||
|
inline-flex
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
focus:outline-none
|
||||||
|
focus-visible:bg-accentDark
|
||||||
|
"
|
||||||
:class="[
|
:class="[
|
||||||
color
|
color
|
||||||
? `text-${color}-800 bg-${color}-200 hover:(text-${color}-900 bg-${color}-300) focus-visible:(text-${color}-900 bg-${color}-300)`
|
? `text-${color}-800 bg-${color}-200 hover:(text-${color}-900 bg-${color}-300) focus-visible:(text-${color}-900 bg-${color}-300)`
|
||||||
@@ -29,7 +38,7 @@
|
|||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
v-if="!loading"
|
v-if="!loading"
|
||||||
class="whitespace-nowrap inline-flex items-center justify-center"
|
class="inline-flex items-center justify-center whitespace-nowrap"
|
||||||
:class="{ 'flex-row-reverse': reverse }"
|
:class="{ 'flex-row-reverse': reverse }"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
@@ -56,7 +65,7 @@
|
|||||||
<kbd
|
<kbd
|
||||||
v-for="(key, index) in shortcut"
|
v-for="(key, index) in shortcut"
|
||||||
:key="`key-${index}`"
|
:key="`key-${index}`"
|
||||||
class="bg-accentLight inline-flex px-1 ml-1 rounded"
|
class="bg-accentLight rounded ml-1 px-1 inline-flex"
|
||||||
>
|
>
|
||||||
{{ key }}
|
{{ key }}
|
||||||
</kbd>
|
</kbd>
|
||||||
|
|||||||
@@ -3,7 +3,18 @@
|
|||||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||||
:exact="exact"
|
:exact="exact"
|
||||||
:blank="blank"
|
:blank="blank"
|
||||||
class="whitespace-nowrap hover:bg-primaryDark focus:outline-none focus-visible:bg-primaryDark inline-flex items-center justify-center py-2 font-semibold transition"
|
class="
|
||||||
|
font-semibold
|
||||||
|
py-2
|
||||||
|
transition
|
||||||
|
inline-flex
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
whitespace-nowrap
|
||||||
|
hover:bg-primaryDark
|
||||||
|
focus:outline-none
|
||||||
|
focus-visible:bg-primaryDark
|
||||||
|
"
|
||||||
:class="[
|
:class="[
|
||||||
color
|
color
|
||||||
? `text-${color}-500 hover:(text-${color}-600 text-${color}-600)`
|
? `text-${color}-500 hover:(text-${color}-600 text-${color}-600)`
|
||||||
@@ -17,7 +28,7 @@
|
|||||||
'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
|
'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
|
||||||
outline,
|
outline,
|
||||||
},
|
},
|
||||||
{ '!bg-primaryLight !hover:bg-primaryDark': filled },
|
{ '!bg-primaryDark': filled },
|
||||||
]"
|
]"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
>
|
>
|
||||||
@@ -45,7 +56,14 @@
|
|||||||
<kbd
|
<kbd
|
||||||
v-for="(key, index) in shortcut"
|
v-for="(key, index) in shortcut"
|
||||||
:key="`key-${index}`"
|
:key="`key-${index}`"
|
||||||
class="bg-dividerLight text-secondaryLight inline-flex px-1 ml-1 rounded"
|
class="
|
||||||
|
bg-dividerLight
|
||||||
|
rounded
|
||||||
|
text-secondaryLight
|
||||||
|
ml-1
|
||||||
|
px-1
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ key }}
|
{{ key }}
|
||||||
</kbd>
|
</kbd>
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
addNewCollection() {
|
addNewCollection() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(this.$t("collection.invalid_name"))
|
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit("submit", this.name)
|
this.$emit("submit", this.name)
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
addFolder() {
|
addFolder() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(this.$t("folder.invalid_name"))
|
this.$toast.error(this.$t("folder.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit("add-folder", {
|
this.$emit("add-folder", {
|
||||||
|
|||||||
@@ -18,7 +18,18 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
autofocus
|
autofocus
|
||||||
class="border-dividerLight hover:bg-primaryDark flex w-full px-4 py-2 font-semibold bg-transparent border-t appearance-none cursor-pointer"
|
class="
|
||||||
|
bg-transparent
|
||||||
|
border-t border-dividerLight
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
font-semibold
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
appearance-none
|
||||||
|
hover:bg-primaryDark
|
||||||
|
"
|
||||||
@change="updateSelectedTeam(myTeams[$event.target.value])"
|
@change="updateSelectedTeam(myTeams[$event.target.value])"
|
||||||
>
|
>
|
||||||
<option
|
<option
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
saveCollection() {
|
saveCollection() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(this.$t("collection.invalid_name"))
|
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit("submit", this.name)
|
this.$emit("submit", this.name)
|
||||||
|
|||||||
@@ -48,7 +48,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
editFolder() {
|
editFolder() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(this.$t("folder.invalid_name"))
|
this.$toast.error(this.$t("folder.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit("submit", this.name)
|
this.$emit("submit", this.name)
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
saveRequest() {
|
saveRequest() {
|
||||||
if (!this.requestUpdateData.name) {
|
if (!this.requestUpdateData.name) {
|
||||||
this.$toast.error(this.$t("request.invalid_name"))
|
this.$toast.error(this.$t("request.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$emit("submit", this.requestUpdateData)
|
this.$emit("submit", this.requestUpdateData)
|
||||||
|
|||||||
@@ -229,11 +229,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$toast.success(this.$t("export.gist_created"))
|
this.$toast.success(this.$t("export.gist_created"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
window.open(res.html_url)
|
window.open(res.html_url)
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -411,17 +415,23 @@ export default defineComponent({
|
|||||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
this.$toast.success(this.$t("state.download_started"))
|
this.$toast.success(this.$t("state.download_started"), {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
fileImported() {
|
fileImported() {
|
||||||
this.$toast.success(this.$t("state.file_imported"))
|
this.$toast.success(this.$t("state.file_imported"), {
|
||||||
|
icon: "folder_shared",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
failedImport() {
|
failedImport() {
|
||||||
this.$toast.error(this.$t("import.failed"))
|
this.$toast.error(this.$t("import.failed"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
parsePostmanCollection({ info, name, item }) {
|
parsePostmanCollection({ info, name, item }) {
|
||||||
const hoppscotchCollection = {
|
const hoppscotchCollection = {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal
|
<SmartModal
|
||||||
v-if="show"
|
v-if="show"
|
||||||
:title="`${t('collection.save_as')}`"
|
:title="`${$t('collection.save_as')}`"
|
||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="flex flex-col px-2">
|
<div class="flex flex-col px-2">
|
||||||
<div class="relative flex">
|
<div class="flex relative">
|
||||||
<input
|
<input
|
||||||
id="selectLabelSaveReq"
|
id="selectLabelSaveReq"
|
||||||
v-model="requestName"
|
v-model="requestName"
|
||||||
@@ -18,11 +18,11 @@
|
|||||||
@keyup.enter="saveRequestAs"
|
@keyup.enter="saveRequestAs"
|
||||||
/>
|
/>
|
||||||
<label for="selectLabelSaveReq">
|
<label for="selectLabelSaveReq">
|
||||||
{{ t("request.name") }}
|
{{ $t("request.name") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<label class="p-4">
|
<label class="p-4">
|
||||||
{{ t("collection.select_location") }}
|
{{ $t("collection.select_location") }}
|
||||||
</label>
|
</label>
|
||||||
<CollectionsGraphql
|
<CollectionsGraphql
|
||||||
v-if="mode === 'graphql'"
|
v-if="mode === 'graphql'"
|
||||||
@@ -45,11 +45,11 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<span>
|
<span>
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
:label="`${t('action.save')}`"
|
:label="`${$t('action.save')}`"
|
||||||
@click.native="saveRequestAs"
|
@click.native="saveRequestAs"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('action.cancel')}`"
|
:label="`${$t('action.cancel')}`"
|
||||||
@click.native="hideModal"
|
@click.native="hideModal"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, watch } from "@nuxtjs/composition-api"
|
import { reactive, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||||
import { isHoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
|
import { isHoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
|
||||||
import {
|
import {
|
||||||
editGraphqlRequest,
|
editGraphqlRequest,
|
||||||
@@ -75,9 +75,6 @@ import {
|
|||||||
import * as teamUtils from "~/helpers/teams/utils"
|
import * as teamUtils from "~/helpers/teams/utils"
|
||||||
import { apolloClient } from "~/helpers/apollo"
|
import { apolloClient } from "~/helpers/apollo"
|
||||||
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
type CollectionType =
|
type CollectionType =
|
||||||
| {
|
| {
|
||||||
@@ -140,7 +137,12 @@ const emit = defineEmits<{
|
|||||||
(e: "hide-modal"): void
|
(e: "hide-modal"): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
// TODO: Use a better implementation with computed ?
|
// TODO: Use a better implementation with computed ?
|
||||||
// This implementation can't work across updates to mode prop (which won't happen tho)
|
// This implementation can't work across updates to mode prop (which won't happen tho)
|
||||||
@@ -192,11 +194,15 @@ const hideModal = () => {
|
|||||||
|
|
||||||
const saveRequestAs = async () => {
|
const saveRequestAs = async () => {
|
||||||
if (!requestName.value) {
|
if (!requestName.value) {
|
||||||
toast.error(`${t("error.empty_req_name")}`)
|
$toast.error(`${t("error.empty_req_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (picked.value === null) {
|
if (picked.value === null) {
|
||||||
toast.error(`${t("collection.select")}`)
|
$toast.error(`${t("collection.select")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +283,9 @@ const saveRequestAs = async () => {
|
|||||||
requestSaved()
|
requestSaved()
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
toast.error(`${t("profile.no_permission")}`)
|
$toast.error(t("profile.no_permission").toString(), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
throw new Error(error)
|
throw new Error(error)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -312,7 +320,9 @@ const saveRequestAs = async () => {
|
|||||||
|
|
||||||
requestSaved()
|
requestSaved()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(`${t("profile.no_permission")}`)
|
$toast.error(t("profile.no_permission").toString(), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else if (picked.value.pickedType === "teams-collection") {
|
} else if (picked.value.pickedType === "teams-collection") {
|
||||||
@@ -342,7 +352,9 @@ const saveRequestAs = async () => {
|
|||||||
|
|
||||||
requestSaved()
|
requestSaved()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(`${t("profile.no_permission")}`)
|
$toast.error(t("profile.no_permission").toString(), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else if (picked.value.pickedType === "gql-my-request") {
|
} else if (picked.value.pickedType === "gql-my-request") {
|
||||||
@@ -374,7 +386,9 @@ const saveRequestAs = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const requestSaved = () => {
|
const requestSaved = () => {
|
||||||
toast.success(`${t("request.added")}`)
|
$toast.success(`${t("request.added")}`, {
|
||||||
|
icon: "post_add",
|
||||||
|
})
|
||||||
hideModal()
|
hideModal()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
addNewCollection() {
|
addNewCollection() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -20,7 +20,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ collection.name }} </span>
|
<span class="truncate"> {{ collection.name }} </span>
|
||||||
@@ -30,7 +38,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="
|
@click.native="
|
||||||
$emit('add-folder', {
|
$emit('add-folder', {
|
||||||
path: `${collectionIndex}`,
|
path: `${collectionIndex}`,
|
||||||
@@ -91,7 +99,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -132,12 +149,25 @@
|
|||||||
v-if="
|
v-if="
|
||||||
collection.folders.length === 0 && collection.requests.length === 0
|
collection.folders.length === 0 && collection.requests.length === 0
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.collection')"
|
:alt="$t('empty.collection')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
@@ -221,7 +251,9 @@ export default defineComponent({
|
|||||||
this.$emit("select", { picked: null })
|
this.$emit("select", { picked: null })
|
||||||
}
|
}
|
||||||
removeGraphqlCollection(this.collectionIndex)
|
removeGraphqlCollection(this.collectionIndex)
|
||||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
dropEvent({ dataTransfer }: any) {
|
dropEvent({ dataTransfer }: any) {
|
||||||
this.dragging = !this.dragging
|
this.dragging = !this.dragging
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
saveCollection() {
|
saveCollection() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const collectionUpdated = {
|
const collectionUpdated = {
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
editFolder() {
|
editFolder() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
editGraphqlFolder(this.folderPath, {
|
editGraphqlFolder(this.folderPath, {
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
saveRequest() {
|
saveRequest() {
|
||||||
if (!this.requestUpdateData.name) {
|
if (!this.requestUpdateData.name) {
|
||||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const requestUpdated = {
|
const requestUpdated = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -20,7 +20,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
@@ -32,7 +40,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
@@ -87,7 +95,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -131,12 +148,25 @@
|
|||||||
folder.requests &&
|
folder.requests &&
|
||||||
folder.requests.length === 0
|
folder.requests.length === 0
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.folder')"
|
:alt="$t('empty.folder')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
@@ -220,7 +250,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeGraphqlFolder(this.folderPath)
|
removeGraphqlFolder(this.folderPath)
|
||||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
dropEvent({ dataTransfer }: any) {
|
dropEvent({ dataTransfer }: any) {
|
||||||
this.dragging = !this.dragging
|
this.dragging = !this.dragging
|
||||||
|
|||||||
@@ -140,11 +140,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$toast.success(this.$t("export.gist_created"))
|
this.$toast.success(this.$t("export.gist_created"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
window.open(res.html_url)
|
window.open(res.html_url)
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -248,17 +252,23 @@ export default defineComponent({
|
|||||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
this.$toast.success(this.$t("state.download_started"))
|
this.$toast.success(this.$t("state.download_started"), {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
fileImported() {
|
fileImported() {
|
||||||
this.$toast.success(this.$t("state.file_imported"))
|
this.$toast.success(this.$t("state.file_imported"), {
|
||||||
|
icon: "folder_shared",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
failedImport() {
|
failedImport() {
|
||||||
this.$toast.error(this.$t("import.failed"))
|
this.$toast.error(this.$t("import.failed"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
parsePostmanCollection({ info, name, item }) {
|
parsePostmanCollection({ info, name, item }) {
|
||||||
const hoppscotchCollection = {
|
const hoppscotchCollection = {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover.stop
|
@dragover.stop
|
||||||
@@ -9,7 +9,15 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
px-2
|
||||||
|
w-16
|
||||||
|
justify-center
|
||||||
|
items-center
|
||||||
|
truncate
|
||||||
|
"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -19,7 +27,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ request.name }} </span>
|
<span class="truncate"> {{ request.name }} </span>
|
||||||
@@ -30,7 +46,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="rotate-ccw"
|
svg="rotate-ccw"
|
||||||
:title="$t('action.restore')"
|
:title="$t('action.restore')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="!doc ? selectRequest() : {}"
|
@click.native="!doc ? selectRequest() : {}"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
@@ -178,7 +194,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeGraphqlRequest(this.folderPath, this.requestIndex)
|
removeGraphqlRequest(this.folderPath, this.requestIndex)
|
||||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -4,7 +4,14 @@
|
|||||||
:class="{ 'rounded border border-divider': savingMode }"
|
:class="{ 'rounded border border-divider': savingMode }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="divide-dividerLight border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y"
|
class="
|
||||||
|
divide-y divide-dividerLight
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-col
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
"
|
||||||
:class="{ 'bg-primary': !savingMode }"
|
:class="{ 'bg-primary': !savingMode }"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -13,9 +20,9 @@
|
|||||||
type="search"
|
type="search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:placeholder="$t('action.search')"
|
:placeholder="$t('action.search')"
|
||||||
class="flex w-full px-4 py-2 bg-transparent"
|
class="bg-transparent flex w-full py-2 px-4"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-between flex-1">
|
<div class="flex flex-1 justify-between">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
svg="plus"
|
svg="plus"
|
||||||
:label="$t('action.new')"
|
:label="$t('action.new')"
|
||||||
@@ -62,15 +69,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="collections.length === 0"
|
v-if="collections.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.collections')"
|
:alt="$t('empty.collections')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.collections") }}
|
{{ $t("empty.collections") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
@@ -81,9 +88,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!(filteredCollections.length !== 0 || collections.length === 0)"
|
v-if="!(filteredCollections.length !== 0 || collections.length === 0)"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -4,7 +4,16 @@
|
|||||||
:class="{ 'rounded border border-divider': saveRequest }"
|
:class="{ 'rounded border border-divider': saveRequest }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="divide-dividerLight bg-primary border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y rounded-t"
|
class="
|
||||||
|
divide-y divide-dividerLight
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
rounded-t
|
||||||
|
flex flex-col
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div v-if="!saveRequest" class="search-wrappe">
|
<div v-if="!saveRequest" class="search-wrappe">
|
||||||
<input
|
<input
|
||||||
@@ -12,7 +21,7 @@
|
|||||||
type="search"
|
type="search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:placeholder="$t('action.search')"
|
:placeholder="$t('action.search')"
|
||||||
class="flex w-full py-2 pl-4 pr-2 bg-transparent"
|
class="bg-transparent flex w-full py-2 pr-2 pl-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CollectionsChooseType
|
<CollectionsChooseType
|
||||||
@@ -22,7 +31,7 @@
|
|||||||
@update-collection-type="updateCollectionType"
|
@update-collection-type="updateCollectionType"
|
||||||
@update-selected-team="updateSelectedTeam"
|
@update-selected-team="updateSelectedTeam"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-between flex-1">
|
<div class="flex flex-1 justify-between">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="
|
v-if="
|
||||||
collectionsType.type == 'team-collections' &&
|
collectionsType.type == 'team-collections' &&
|
||||||
@@ -98,15 +107,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="filteredCollections.length === 0 && filterText.length === 0"
|
v-if="filteredCollections.length === 0 && filterText.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.collections')"
|
:alt="$t('empty.collections')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.collections") }}
|
{{ $t("empty.collections") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
@@ -131,9 +140,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="filterText.length !== 0 && filteredCollections.length === 0"
|
v-if="filterText.length !== 0 && filteredCollections.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||||
</span>
|
</span>
|
||||||
@@ -352,10 +361,14 @@ export default defineComponent({
|
|||||||
this.collectionsType.selectedTeam.id
|
this.collectionsType.selectedTeam.id
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("collection.created"))
|
this.$toast.success(this.$t("collection.created"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -364,7 +377,9 @@ export default defineComponent({
|
|||||||
// Intented to be called by CollectionEdit modal submit event
|
// Intented to be called by CollectionEdit modal submit event
|
||||||
updateEditingCollection(newName) {
|
updateEditingCollection(newName) {
|
||||||
if (!newName) {
|
if (!newName) {
|
||||||
this.$toast.error(this.$t("collection.invalid_name"))
|
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (this.collectionsType.type === "my-collections") {
|
if (this.collectionsType.type === "my-collections") {
|
||||||
@@ -381,10 +396,14 @@ export default defineComponent({
|
|||||||
teamUtils
|
teamUtils
|
||||||
.renameCollection(this.$apollo, newName, this.editingCollection.id)
|
.renameCollection(this.$apollo, newName, this.editingCollection.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("collection.renamed"))
|
this.$toast.success(this.$t("collection.renamed"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -401,10 +420,14 @@ export default defineComponent({
|
|||||||
teamUtils
|
teamUtils
|
||||||
.renameCollection(this.$apollo, name, this.editingFolder.id)
|
.renameCollection(this.$apollo, name, this.editingFolder.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("folder.renamed"))
|
this.$toast.success(this.$t("folder.renamed"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -437,11 +460,15 @@ export default defineComponent({
|
|||||||
this.editingRequestIndex
|
this.editingRequestIndex
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("request.renamed"))
|
this.$toast.success(this.$t("request.renamed"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
this.$emit("update-team-collections")
|
this.$emit("update-team-collections")
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -506,11 +533,15 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("folder.created"))
|
this.$toast.success(this.$t("folder.created"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
this.$emit("update-team-collections")
|
this.$emit("update-team-collections")
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -574,7 +605,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeRESTCollection(collectionIndex)
|
removeRESTCollection(collectionIndex)
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
} else if (collectionsType.type === "team-collections") {
|
} else if (collectionsType.type === "team-collections") {
|
||||||
// Cancel pick if picked collection is deleted
|
// Cancel pick if picked collection is deleted
|
||||||
if (
|
if (
|
||||||
@@ -600,10 +633,14 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -621,7 +658,9 @@ export default defineComponent({
|
|||||||
this.$emit("select", { picked: null })
|
this.$emit("select", { picked: null })
|
||||||
}
|
}
|
||||||
removeRESTRequest(folderPath, requestIndex)
|
removeRESTRequest(folderPath, requestIndex)
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
} else if (this.collectionsType.type === "team-collections") {
|
} else if (this.collectionsType.type === "team-collections") {
|
||||||
// Cancel pick if the picked item is being deleted
|
// Cancel pick if the picked item is being deleted
|
||||||
if (
|
if (
|
||||||
@@ -635,10 +674,14 @@ export default defineComponent({
|
|||||||
teamUtils
|
teamUtils
|
||||||
.deleteRequest(this.$apollo, requestIndex)
|
.deleteRequest(this.$apollo, requestIndex)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -20,7 +20,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ collection.name }} </span>
|
<span class="truncate"> {{ collection.name }} </span>
|
||||||
@@ -47,7 +55,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="
|
@click.native="
|
||||||
$emit('add-folder', {
|
$emit('add-folder', {
|
||||||
folder: collection,
|
folder: collection,
|
||||||
@@ -110,7 +118,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -158,12 +175,25 @@
|
|||||||
(collection.requests == undefined ||
|
(collection.requests == undefined ||
|
||||||
collection.requests.length === 0)
|
collection.requests.length === 0)
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.collection')"
|
:alt="$t('empty.collection')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
@dragover.prevent
|
@dragover.prevent
|
||||||
@drop.prevent="dropEvent"
|
@drop.prevent="dropEvent"
|
||||||
@dragover="dragging = true"
|
@dragover="dragging = true"
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -20,7 +20,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
@@ -32,7 +40,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
@@ -92,7 +100,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -140,12 +157,25 @@
|
|||||||
folder.requests &&
|
folder.requests &&
|
||||||
folder.requests.length === 0
|
folder.requests.length === 0
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.folder')"
|
:alt="$t('empty.folder')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
@@ -232,7 +262,9 @@ export default defineComponent({
|
|||||||
this.$emit("select", { picked: null })
|
this.$emit("select", { picked: null })
|
||||||
}
|
}
|
||||||
removeRESTFolder(this.folderPath)
|
removeRESTFolder(this.folderPath)
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
dropEvent({ dataTransfer }) {
|
dropEvent({ dataTransfer }) {
|
||||||
this.dragging = !this.dragging
|
this.dragging = !this.dragging
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||||
<div
|
<div
|
||||||
class="group flex items-center"
|
class="flex items-center group"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="dragStart"
|
@dragstart="dragStart"
|
||||||
@dragover.stop
|
@dragover.stop
|
||||||
@@ -9,7 +9,15 @@
|
|||||||
@dragend="dragging = false"
|
@dragend="dragging = false"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
px-2
|
||||||
|
w-16
|
||||||
|
justify-center
|
||||||
|
items-center
|
||||||
|
truncate
|
||||||
|
"
|
||||||
:class="getRequestLabelColor(request.method)"
|
:class="getRequestLabelColor(request.method)"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
@@ -24,7 +32,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
items-center
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ request.name }} </span>
|
<span class="truncate"> {{ request.name }} </span>
|
||||||
@@ -44,7 +61,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="rotate-ccw"
|
svg="rotate-ccw"
|
||||||
:title="$t('action.restore')"
|
:title="$t('action.restore')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="!doc ? selectRequest() : {}"
|
@click.native="!doc ? selectRequest() : {}"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="group flex items-center">
|
<div class="flex items-center group">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -12,7 +12,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ collection.title }} </span>
|
<span class="truncate"> {{ collection.title }} </span>
|
||||||
@@ -39,7 +47,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="
|
@click.native="
|
||||||
$emit('add-folder', {
|
$emit('add-folder', {
|
||||||
folder: collection,
|
folder: collection,
|
||||||
@@ -106,7 +114,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -152,12 +169,25 @@
|
|||||||
(collection.requests == undefined ||
|
(collection.requests == undefined ||
|
||||||
collection.requests.length === 0)
|
collection.requests.length === 0)
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.collection')"
|
:alt="$t('empty.collection')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="group flex items-center">
|
<div class="flex items-center group">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<SmartIcon
|
<SmartIcon
|
||||||
@@ -12,7 +12,15 @@
|
|||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
>
|
>
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
@@ -25,7 +33,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
:title="$t('folder.new')"
|
:title="$t('folder.new')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
@@ -89,7 +97,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showChildren || isFiltered" class="flex">
|
<div v-if="showChildren || isFiltered" class="flex">
|
||||||
<div
|
<div
|
||||||
class="flex w-1 transform transition cursor-nsResize ml-5.5 bg-dividerLight hover:scale-x-125 hover:bg-dividerDark"
|
class="
|
||||||
|
flex
|
||||||
|
w-1
|
||||||
|
transform
|
||||||
|
transition
|
||||||
|
cursor-nsResize
|
||||||
|
ml-5.5
|
||||||
|
bg-dividerLight
|
||||||
|
hover:scale-x-125 hover:bg-dividerDark
|
||||||
|
"
|
||||||
@click="toggleShowChildren()"
|
@click="toggleShowChildren()"
|
||||||
></div>
|
></div>
|
||||||
<div class="flex flex-col flex-1 truncate">
|
<div class="flex flex-col flex-1 truncate">
|
||||||
@@ -133,12 +150,25 @@
|
|||||||
(folder.children == undefined || folder.children.length === 0) &&
|
(folder.children == undefined || folder.children.length === 0) &&
|
||||||
(folder.requests == undefined || folder.requests.length === 0)
|
(folder.requests == undefined || folder.requests.length === 0)
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
mb-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.folder')"
|
:alt="$t('empty.folder')"
|
||||||
/>
|
/>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
@@ -223,11 +253,15 @@ export default defineComponent({
|
|||||||
teamUtils
|
teamUtils
|
||||||
.deleteCollection(this.$apollo, this.folder.id)
|
.deleteCollection(this.$apollo, this.folder.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$toast.success(this.$t("state.deleted"))
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
this.$emit("update-team-collections")
|
this.$emit("update-team-collections")
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
this.$emit("update-team-collections")
|
this.$emit("update-team-collections")
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="group flex items-center">
|
<div class="flex items-center group">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
px-2
|
||||||
|
w-16
|
||||||
|
justify-center
|
||||||
|
items-center
|
||||||
|
truncate
|
||||||
|
"
|
||||||
:class="getRequestLabelColor(request.method)"
|
:class="getRequestLabelColor(request.method)"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
@@ -17,7 +25,16 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
items-center
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="!doc ? selectRequest() : {}"
|
@click="!doc ? selectRequest() : {}"
|
||||||
>
|
>
|
||||||
<span class="truncate"> {{ request.name }} </span>
|
<span class="truncate"> {{ request.name }} </span>
|
||||||
@@ -36,7 +53,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
svg="rotate-ccw"
|
svg="rotate-ccw"
|
||||||
:title="$t('action.restore')"
|
:title="$t('action.restore')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="!doc ? selectRequest() : {}"
|
@click.native="!doc ? selectRequest() : {}"
|
||||||
/>
|
/>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ export default defineComponent({
|
|||||||
methods: {
|
methods: {
|
||||||
addNewEnvironment() {
|
addNewEnvironment() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(`${this.$t("environment.invalid_name")}`)
|
this.$toast.error(`${this.$t("environment.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
createEnvironment(this.name)
|
createEnvironment(this.name)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
>
|
>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="flex flex-col px-2">
|
<div class="flex flex-col px-2">
|
||||||
<div class="relative flex">
|
<div class="flex relative">
|
||||||
<input
|
<input
|
||||||
id="selectLabelEnvEdit"
|
id="selectLabelEnvEdit"
|
||||||
v-model="name"
|
v-model="name"
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
{{ $t("action.label") }}
|
{{ $t("action.label") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between flex-1">
|
<div class="flex flex-1 justify-between items-center">
|
||||||
<label for="variableList" class="p-4">
|
<label for="variableList" class="p-4">
|
||||||
{{ $t("environment.variable_list") }}
|
{{ $t("environment.variable_list") }}
|
||||||
</label>
|
</label>
|
||||||
@@ -43,21 +43,21 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="divide-dividerLight border-divider border divide-y rounded">
|
<div class="divide-y divide-dividerLight border-divider border rounded">
|
||||||
<div
|
<div
|
||||||
v-for="(variable, index) in vars"
|
v-for="(variable, index) in vars"
|
||||||
:key="`variable-${index}`"
|
:key="`variable-${index}`"
|
||||||
class="divide-dividerLight flex divide-x"
|
class="divide-x divide-dividerLight flex"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-model="variable.key"
|
v-model="variable.key"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
:placeholder="`${$t('count.variable', { count: index + 1 })}`"
|
:placeholder="`${$t('count.variable', { count: index + 1 })}`"
|
||||||
:name="'param' + index"
|
:name="'param' + index"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-model="variable.value"
|
v-model="variable.value"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||||
:name="'value' + index"
|
:name="'value' + index"
|
||||||
/>
|
/>
|
||||||
@@ -74,15 +74,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="vars.length === 0"
|
v-if="vars.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.environments')"
|
:alt="$t('empty.environments')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.environments") }}
|
{{ $t("empty.environments") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
@@ -164,7 +177,9 @@ export default defineComponent({
|
|||||||
clearContent() {
|
clearContent() {
|
||||||
this.vars = []
|
this.vars = []
|
||||||
this.clearIcon = "check"
|
this.clearIcon = "check"
|
||||||
this.$toast.success(`${this.$t("state.cleared")}`)
|
this.$toast.success(`${this.$t("state.cleared")}`, {
|
||||||
|
icon: "clear_all",
|
||||||
|
})
|
||||||
setTimeout(() => (this.clearIcon = "trash-2"), 1000)
|
setTimeout(() => (this.clearIcon = "trash-2"), 1000)
|
||||||
},
|
},
|
||||||
addEnvironmentVariable() {
|
addEnvironmentVariable() {
|
||||||
@@ -178,7 +193,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
saveEnvironment() {
|
saveEnvironment() {
|
||||||
if (!this.name) {
|
if (!this.name) {
|
||||||
this.$toast.error(`${this.$t("environment.invalid_name")}`)
|
this.$toast.error(`${this.$t("environment.invalid_name")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="group flex items-center">
|
<div class="flex items-center group">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center px-4 cursor-pointer"
|
class="cursor-pointer flex px-4 justify-center items-center"
|
||||||
@click="$emit('edit-environment')"
|
@click="$emit('edit-environment')"
|
||||||
>
|
>
|
||||||
<SmartIcon class="svg-icons" name="layers" />
|
<SmartIcon class="svg-icons" name="layers" />
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="$emit('edit-environment')"
|
@click="$emit('edit-environment')"
|
||||||
>
|
>
|
||||||
<span class="truncate">
|
<span class="truncate">
|
||||||
@@ -94,7 +102,9 @@ export default defineComponent({
|
|||||||
removeEnvironment() {
|
removeEnvironment() {
|
||||||
if (this.environmentIndex !== "Global")
|
if (this.environmentIndex !== "Global")
|
||||||
deleteEnvironment(this.environmentIndex)
|
deleteEnvironment(this.environmentIndex)
|
||||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
duplicateEnvironment() {
|
duplicateEnvironment() {
|
||||||
if (this.environmentIndex === "Global") {
|
if (this.environmentIndex === "Global") {
|
||||||
|
|||||||
@@ -140,11 +140,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
this.$toast.success(this.$t("export.gist_created"))
|
this.$toast.success(this.$t("export.gist_created"), {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
window.open(res.html_url)
|
window.open(res.html_url)
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -226,14 +230,18 @@ export default defineComponent({
|
|||||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
this.$toast.success(this.$t("state.download_started"))
|
this.$toast.success(this.$t("state.download_started"), {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
}, 1000)
|
}, 1000)
|
||||||
},
|
},
|
||||||
fileImported() {
|
fileImported() {
|
||||||
this.$toast.success(this.$t("state.file_imported"))
|
this.$toast.success(this.$t("state.file_imported"), {
|
||||||
|
icon: "folder_shared",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,22 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection :label="`${$t('environment.title')}`">
|
<AppSection :label="`${$t('environment.title')}`">
|
||||||
<div class="bg-primary sticky top-0 z-10 flex flex-col rounded-t">
|
<div class="bg-primary rounded-t flex flex-col top-0 z-10 sticky">
|
||||||
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<span
|
<span
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="`${$t('environment.select')}`"
|
:title="`${$t('environment.select')}`"
|
||||||
class="border-dividerLight select-wrapper flex-1 bg-transparent border-b"
|
class="
|
||||||
|
bg-transparent
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex-1
|
||||||
|
select-wrapper
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="selectedEnvironmentIndex !== -1"
|
v-if="selectedEnvironmentIndex !== -1"
|
||||||
:label="environments[selectedEnvironmentIndex].name"
|
:label="environments[selectedEnvironmentIndex].name"
|
||||||
class="flex-1 pr-8 rounded-none"
|
class="rounded-none flex-1 pr-8"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-else
|
v-else
|
||||||
:label="`${$t('environment.no_environment')}`"
|
:label="`${$t('environment.no_environment')}`"
|
||||||
class="flex-1 pr-8 rounded-none"
|
class="rounded-none flex-1 pr-8"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -45,7 +50,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</tippy>
|
</tippy>
|
||||||
<div class="border-dividerLight flex justify-between flex-1 border-b">
|
<div class="border-b border-dividerLight flex flex-1 justify-between">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
svg="plus"
|
svg="plus"
|
||||||
:label="`${$t('action.new')}`"
|
:label="`${$t('action.new')}`"
|
||||||
@@ -86,7 +91,7 @@
|
|||||||
<EnvironmentsEnvironment
|
<EnvironmentsEnvironment
|
||||||
environment-index="Global"
|
environment-index="Global"
|
||||||
:environment="globalEnvironment"
|
:environment="globalEnvironment"
|
||||||
class="border-dividerLight border-b border-dashed"
|
class="border-b border-dashed border-dividerLight"
|
||||||
@edit-environment="editEnvironment('Global')"
|
@edit-environment="editEnvironment('Global')"
|
||||||
/>
|
/>
|
||||||
<EnvironmentsEnvironment
|
<EnvironmentsEnvironment
|
||||||
@@ -99,15 +104,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="environments.length === 0"
|
v-if="environments.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.environments')"
|
:alt="$t('empty.environments')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.environments") }}
|
{{ $t("empty.environments") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
@close="hideModal"
|
@close="hideModal"
|
||||||
>
|
>
|
||||||
<template #body>
|
<template #body>
|
||||||
<div v-if="mode === 'sign-in'" class="flex flex-col px-2 space-y-2">
|
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2 px-2">
|
||||||
<SmartItem
|
<SmartItem
|
||||||
:loading="signingInWithGitHub"
|
:loading="signingInWithGitHub"
|
||||||
svg="auth/github"
|
svg="auth/github"
|
||||||
@@ -56,9 +56,9 @@
|
|||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
||||||
<div class="flex flex-col items-center justify-center max-w-md">
|
<div class="flex flex-col max-w-md justify-center items-center">
|
||||||
<SmartIcon class="text-accent w-6 h-6" name="inbox" />
|
<SmartIcon class="h-6 text-accent w-6" name="inbox" />
|
||||||
<h3 class="my-2 text-lg text-center">
|
<h3 class="my-2 text-center text-lg">
|
||||||
{{ $t("auth.we_sent_magic_link") }}
|
{{ $t("auth.we_sent_magic_link") }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
v-if="mode === 'email-sent'"
|
v-if="mode === 'email-sent'"
|
||||||
class="text-secondaryLight flex justify-between flex-1"
|
class="flex flex-1 text-secondaryLight justify-between"
|
||||||
>
|
>
|
||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
class="link"
|
class="link"
|
||||||
@@ -155,7 +155,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
showLoginSuccess() {
|
showLoginSuccess() {
|
||||||
this.$toast.success(`${this.$t("auth.login_success")}`)
|
this.$toast.success(`${this.$t("auth.login_success")}`, {
|
||||||
|
icon: "vpn_key",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
async signInWithGoogle() {
|
async signInWithGoogle() {
|
||||||
this.signingInWithGoogle = true
|
this.signingInWithGoogle = true
|
||||||
@@ -172,6 +174,7 @@ export default defineComponent({
|
|||||||
// The pending Google credential.
|
// The pending Google credential.
|
||||||
const pendingCred = e.credential
|
const pendingCred = e.credential
|
||||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||||
|
icon: "vpn_key",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
closeOnSwipe: false,
|
closeOnSwipe: false,
|
||||||
action: {
|
action: {
|
||||||
@@ -187,7 +190,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,6 +218,7 @@ export default defineComponent({
|
|||||||
// The pending Google credential.
|
// The pending Google credential.
|
||||||
const pendingCred = e.credential
|
const pendingCred = e.credential
|
||||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||||
|
icon: "vpn_key",
|
||||||
duration: 0,
|
duration: 0,
|
||||||
closeOnSwipe: false,
|
closeOnSwipe: false,
|
||||||
action: {
|
action: {
|
||||||
@@ -228,7 +234,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +256,9 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
this.$toast.error(e.message)
|
this.$toast.error(e.message, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
this.signingInWithEmail = false
|
this.signingInWithEmail = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
|
|||||||
@@ -40,10 +40,14 @@ export default defineComponent({
|
|||||||
async logout() {
|
async logout() {
|
||||||
try {
|
try {
|
||||||
await signOutUser()
|
await signOutUser()
|
||||||
this.$toast.success(`${this.$t("auth.logged_out")}`)
|
this.$toast.success(`${this.$t("auth.logged_out")}`, {
|
||||||
|
icon: "vpn_key",
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,19 +21,28 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="gqlField.description"
|
v-if="gqlField.description"
|
||||||
class="text-secondaryLight field-desc py-2"
|
class="text-secondaryLight py-2 field-desc"
|
||||||
>
|
>
|
||||||
{{ gqlField.description }}
|
{{ gqlField.description }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="gqlField.isDeprecated"
|
v-if="gqlField.isDeprecated"
|
||||||
class="field-deprecated inline-block px-2 py-1 my-1 text-black bg-yellow-200 rounded"
|
class="
|
||||||
|
rounded
|
||||||
|
bg-yellow-200
|
||||||
|
my-1
|
||||||
|
text-black
|
||||||
|
py-1
|
||||||
|
px-2
|
||||||
|
inline-block
|
||||||
|
field-deprecated
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t("state.deprecated") }}
|
{{ $t("state.deprecated") }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="fieldArgs.length > 0">
|
<div v-if="fieldArgs.length > 0">
|
||||||
<h5 class="my-2">Arguments:</h5>
|
<h5 class="my-2">Arguments:</h5>
|
||||||
<div class="border-divider pl-4 border-l-2">
|
<div class="border-divider border-l-2 pl-4">
|
||||||
<div v-for="(field, index) in fieldArgs" :key="`field-${index}`">
|
<div v-for="(field, index) in fieldArgs" :key="`field-${index}`">
|
||||||
<span>
|
<span>
|
||||||
{{ field.name }}:
|
{{ field.name }}:
|
||||||
@@ -44,7 +53,7 @@
|
|||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
v-if="field.description"
|
v-if="field.description"
|
||||||
class="text-secondaryLight field-desc py-2"
|
class="text-secondaryLight py-2 field-desc"
|
||||||
>
|
>
|
||||||
{{ field.description }}
|
{{ field.description }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,21 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||||
<div class="inline-flex flex-1 space-x-2">
|
<div class="space-x-2 flex-1 inline-flex">
|
||||||
<input
|
<input
|
||||||
id="url"
|
id="url"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
type="url"
|
type="url"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
class="
|
||||||
:placeholder="`${t('request.url')}`"
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
|
:placeholder="$t('request.url')"
|
||||||
:disabled="connected"
|
:disabled="connected"
|
||||||
@keyup.enter="onConnectClick"
|
@keyup.enter="onConnectClick"
|
||||||
/>
|
/>
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
id="get"
|
id="get"
|
||||||
name="get"
|
name="get"
|
||||||
:label="!connected ? t('action.connect') : t('action.disconnect')"
|
:label="!connected ? $t('action.connect') : $t('action.disconnect')"
|
||||||
class="w-32"
|
class="w-32"
|
||||||
@click.native="onConnectClick"
|
@click.native="onConnectClick"
|
||||||
/>
|
/>
|
||||||
@@ -27,15 +37,9 @@
|
|||||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||||
import { getCurrentStrategyID } from "~/helpers/network"
|
import { getCurrentStrategyID } from "~/helpers/network"
|
||||||
import {
|
import { useReadonlyStream, useStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useStream,
|
|
||||||
useI18n,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import { gqlHeaders$, gqlURL$, setGQLURL } from "~/newstore/GQLSession"
|
import { gqlHeaders$, gqlURL$, setGQLURL } from "~/newstore/GQLSession"
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
conn: GQLConnection
|
conn: GQLConnection
|
||||||
}>()
|
}>()
|
||||||
|
|||||||
@@ -3,44 +3,55 @@
|
|||||||
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('request.run')}`"
|
:label="`${$t('request.run')}`"
|
||||||
svg="play"
|
svg="play"
|
||||||
class="rounded-none !text-accent"
|
class="rounded-none !text-accent"
|
||||||
@click.native="runQuery()"
|
@click.native="runQuery()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
ref="saveRequest"
|
ref="saveRequest"
|
||||||
:label="`${t('request.save')}`"
|
:label="`${$t('request.save')}`"
|
||||||
class="rounded-none"
|
class="rounded-none"
|
||||||
@click.native="saveRequest"
|
@click.native="saveRequest"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<SmartTab :id="'query'" :label="`${t('tab.query')}`" :selected="true">
|
<SmartTab :id="'query'" :label="`${$t('tab.query')}`" :selected="true">
|
||||||
<AppSection label="query">
|
<AppSection label="query">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold gqlRunQuery sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
gqlRunQuery
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.query") }}
|
{{ $t("request.query") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/graphql/#queries"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.prettify')"
|
:title="$t('action.prettify')"
|
||||||
:svg="`${prettifyQueryIcon}`"
|
:svg="`${prettifyQueryIcon}`"
|
||||||
@click.native="prettifyQuery"
|
@click.native="prettifyQuery"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="`${copyQueryIcon}`"
|
:svg="`${copyQueryIcon}`"
|
||||||
@click.native="copyQuery"
|
@click.native="copyQuery"
|
||||||
/>
|
/>
|
||||||
@@ -50,25 +61,35 @@
|
|||||||
</AppSection>
|
</AppSection>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
<SmartTab :id="'variables'" :label="`${t('tab.variables')}`">
|
<SmartTab :id="'variables'" :label="`${$t('tab.variables')}`">
|
||||||
<AppSection label="variables">
|
<AppSection label="variables">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.variables") }}
|
{{ $t("request.variables") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/graphql/#queries"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="`${copyVariablesIcon}`"
|
:svg="`${copyVariablesIcon}`"
|
||||||
@click.native="copyVariables"
|
@click.native="copyVariables"
|
||||||
/>
|
/>
|
||||||
@@ -78,38 +99,48 @@
|
|||||||
</AppSection>
|
</AppSection>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
<SmartTab :id="'headers'" :label="`${t('tab.headers')}`">
|
<SmartTab :id="'headers'" :label="`${$t('tab.headers')}`">
|
||||||
<AppSection label="headers">
|
<AppSection label="headers">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("tab.headers") }}
|
{{ $t("tab.headers") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/graphql/#headers"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear_all')"
|
:title="$t('action.clear_all')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent()"
|
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.bulk_mode')"
|
:title="$t('state.bulk_mode')"
|
||||||
svg="edit"
|
svg="edit"
|
||||||
:class="{ '!text-accent': bulkMode }"
|
:class="{ '!text-accent': bulkMode }"
|
||||||
@click.native="bulkMode = !bulkMode"
|
@click.native="bulkMode = !bulkMode"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('add.new')"
|
:title="$t('add.new')"
|
||||||
svg="plus"
|
svg="plus"
|
||||||
:disabled="bulkMode"
|
:disabled="bulkMode"
|
||||||
@click.native="addRequestHeader"
|
@click.native="addRequestHeader"
|
||||||
@@ -121,10 +152,14 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(header, index) in headers"
|
v-for="(header, index) in headers"
|
||||||
:key="`header-${String(index)}`"
|
:key="`header-${String(index)}`"
|
||||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
class="
|
||||||
|
divide-x divide-dividerLight
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<SmartAutoComplete
|
<SmartAutoComplete
|
||||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
:placeholder="`${$t('count.header', { count: index + 1 })}`"
|
||||||
:source="commonHeaders"
|
:source="commonHeaders"
|
||||||
:spellcheck="false"
|
:spellcheck="false"
|
||||||
:value="header.key"
|
:value="header.key"
|
||||||
@@ -147,8 +182,8 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||||
:name="`value ${String(index)}`"
|
:name="`value ${String(index)}`"
|
||||||
:value="header.value"
|
:value="header.value"
|
||||||
autofocus
|
autofocus
|
||||||
@@ -166,9 +201,9 @@
|
|||||||
:title="
|
:title="
|
||||||
header.hasOwnProperty('active')
|
header.hasOwnProperty('active')
|
||||||
? header.active
|
? header.active
|
||||||
? t('action.turn_off')
|
? $t('action.turn_off')
|
||||||
: t('action.turn_on')
|
: $t('action.turn_on')
|
||||||
: t('action.turn_off')
|
: $t('action.turn_off')
|
||||||
"
|
"
|
||||||
:svg="
|
:svg="
|
||||||
header.hasOwnProperty('active')
|
header.hasOwnProperty('active')
|
||||||
@@ -190,7 +225,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.remove')"
|
:title="$t('action.remove')"
|
||||||
svg="trash"
|
svg="trash"
|
||||||
color="red"
|
color="red"
|
||||||
@click.native="removeRequestHeader(index)"
|
@click.native="removeRequestHeader(index)"
|
||||||
@@ -199,19 +234,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="headers.length === 0"
|
v-if="headers.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
:alt="`${t('empty.headers')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.headers')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ t("empty.headers") }}
|
{{ $t("empty.headers") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('add.new')}`"
|
:label="`${$t('add.new')}`"
|
||||||
filled
|
filled
|
||||||
svg="plus"
|
svg="plus"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
@@ -232,7 +280,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, ref, watch } from "@nuxtjs/composition-api"
|
import { onMounted, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||||
import clone from "lodash/clone"
|
import clone from "lodash/clone"
|
||||||
import * as gql from "graphql"
|
import * as gql from "graphql"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
@@ -240,8 +288,6 @@ import {
|
|||||||
useNuxt,
|
useNuxt,
|
||||||
useReadonlyStream,
|
useReadonlyStream,
|
||||||
useStream,
|
useStream,
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
} from "~/helpers/utils/composables"
|
||||||
import {
|
import {
|
||||||
addGQLHeader,
|
addGQLHeader,
|
||||||
@@ -268,14 +314,15 @@ import jsonLinter from "~/helpers/editor/linting/json"
|
|||||||
import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery"
|
import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery"
|
||||||
import queryCompleter from "~/helpers/editor/completion/gqlQuery"
|
import queryCompleter from "~/helpers/editor/completion/gqlQuery"
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
conn: GQLConnection
|
conn: GQLConnection
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
const bulkMode = ref(false)
|
const bulkMode = ref(false)
|
||||||
@@ -288,9 +335,11 @@ watch(bulkHeaders, () => {
|
|||||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||||
active: !item.trim().startsWith("//"),
|
active: !item.trim().startsWith("//"),
|
||||||
}))
|
}))
|
||||||
setGQLHeaders(transformation as GQLHeader[])
|
setGQLHeaders(transformation)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`${t("error.something_went_wrong")}`)
|
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -343,13 +392,12 @@ const showSaveRequestModal = ref(false)
|
|||||||
watch(
|
watch(
|
||||||
headers,
|
headers,
|
||||||
() => {
|
() => {
|
||||||
if (!bulkMode.value)
|
if (
|
||||||
if (
|
(headers.value[headers.value.length - 1]?.key !== "" ||
|
||||||
(headers.value[headers.value.length - 1]?.key !== "" ||
|
headers.value[headers.value.length - 1]?.value !== "") &&
|
||||||
headers.value[headers.value.length - 1]?.value !== "") &&
|
headers.value.length
|
||||||
headers.value.length
|
)
|
||||||
)
|
addRequestHeader()
|
||||||
addRequestHeader()
|
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
@@ -379,7 +427,6 @@ onMounted(() => {
|
|||||||
const copyQuery = () => {
|
const copyQuery = () => {
|
||||||
copyToClipboard(gqlQueryString.value)
|
copyToClipboard(gqlQueryString.value)
|
||||||
copyQueryIcon.value = "check"
|
copyQueryIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
|
||||||
setTimeout(() => (copyQueryIcon.value = "copy"), 1000)
|
setTimeout(() => (copyQueryIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,14 +470,18 @@ const runQuery = async () => {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
toast.success(`${t("state.finished_in", { duration })}`)
|
$toast.success(`${t("state.finished_in", { duration })}`, {
|
||||||
|
icon: "done",
|
||||||
|
})
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
response.value = `${e}`
|
response.value = `${e}`
|
||||||
nuxt.value.$loading.finish()
|
nuxt.value.$loading.finish()
|
||||||
|
|
||||||
toast.error(
|
$toast.error(
|
||||||
`${t("error.something_went_wrong")}. ${t("error.check_console_details")}`,
|
`${t("error.something_went_wrong")}. ${t("error.check_console_details")}`,
|
||||||
{}
|
{
|
||||||
|
icon: "error_outline",
|
||||||
|
}
|
||||||
)
|
)
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
@@ -448,11 +499,12 @@ const hideRequestModal = () => {
|
|||||||
const prettifyQuery = () => {
|
const prettifyQuery = () => {
|
||||||
try {
|
try {
|
||||||
gqlQueryString.value = gql.print(gql.parse(gqlQueryString.value))
|
gqlQueryString.value = gql.print(gql.parse(gqlQueryString.value))
|
||||||
prettifyQueryIcon.value = "check"
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`${t("error.gql_prettify_invalid_query")}`)
|
$toast.error(`${t("error.gql_prettify_invalid_query")}`, {
|
||||||
prettifyQueryIcon.value = "info"
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
prettifyQueryIcon.value = "check"
|
||||||
setTimeout(() => (prettifyQueryIcon.value = "wand"), 1000)
|
setTimeout(() => (prettifyQueryIcon.value = "wand"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,7 +515,6 @@ const saveRequest = () => {
|
|||||||
const copyVariables = () => {
|
const copyVariables = () => {
|
||||||
copyToClipboard(variableString.value)
|
copyToClipboard(variableString.value)
|
||||||
copyVariablesIcon.value = "check"
|
copyVariablesIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
|
||||||
setTimeout(() => (copyVariablesIcon.value = "copy"), 1000)
|
setTimeout(() => (copyVariablesIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,10 +542,11 @@ const removeRequestHeader = (index: number) => {
|
|||||||
|
|
||||||
const deletedItem = headersBeforeDeletion[index]
|
const deletedItem = headersBeforeDeletion[index]
|
||||||
if (deletedItem.key || deletedItem.value) {
|
if (deletedItem.key || deletedItem.value) {
|
||||||
toast.success(`${t("state.deleted")}`, {
|
$toast.success(t("state.deleted").toString(), {
|
||||||
|
icon: "delete",
|
||||||
action: [
|
action: [
|
||||||
{
|
{
|
||||||
text: `${t("action.undo")}`,
|
text: t("action.undo").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
setGQLHeaders(headersBeforeDeletion as GQLHeader[])
|
setGQLHeaders(headersBeforeDeletion as GQLHeader[])
|
||||||
editBulkHeadersLine(index, deletedItem)
|
editBulkHeadersLine(index, deletedItem)
|
||||||
|
|||||||
@@ -2,22 +2,32 @@
|
|||||||
<AppSection ref="response" label="response">
|
<AppSection ref="response" label="response">
|
||||||
<div
|
<div
|
||||||
v-if="responseString === 'loading'"
|
v-if="responseString === 'loading'"
|
||||||
class="flex flex-col items-center justify-center p-4"
|
class="flex flex-col p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<SmartSpinner class="my-4" />
|
<SmartSpinner class="my-4" />
|
||||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="responseString">
|
<div v-else-if="responseString">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
pl-4
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("response.title") }}
|
{{ $t("response.title") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -25,14 +35,14 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
ref="downloadResponse"
|
ref="downloadResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadResponseIcon"
|
:svg="downloadResponseIcon"
|
||||||
@click.native="downloadResponse"
|
@click.native="downloadResponse"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
ref="copyResponseButton"
|
ref="copyResponseButton"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyResponseIcon"
|
:svg="copyResponseIcon"
|
||||||
@click.native="copyResponse"
|
@click.native="copyResponse"
|
||||||
/>
|
/>
|
||||||
@@ -42,15 +52,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1 p-4"
|
class="
|
||||||
|
flex flex-col flex-1
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="flex pb-4 my-4 space-x-2">
|
<div class="flex space-x-2 pb-4 my-4">
|
||||||
<div class="flex flex-col items-end space-y-4 text-right">
|
<div class="flex flex-col space-y-4 text-right items-end">
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.general.command_menu") }}
|
{{ $t("shortcut.general.command_menu") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.general.help_menu") }}
|
{{ $t("shortcut.general.help_menu") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
@@ -63,8 +79,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('app.documentation')}`"
|
:label="`${$t('app.documentation')}`"
|
||||||
to="https://docs.hoppscotch.io/features/response"
|
to="https://docs.hoppscotch.io"
|
||||||
svg="external-link"
|
svg="external-link"
|
||||||
blank
|
blank
|
||||||
outline
|
outline
|
||||||
@@ -75,19 +91,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import {
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import { gqlResponse$ } from "~/newstore/GQLSession"
|
import { gqlResponse$ } from "~/newstore/GQLSession"
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const responseString = useReadonlyStream(gqlResponse$, "")
|
const responseString = useReadonlyStream(gqlResponse$, "")
|
||||||
|
|
||||||
@@ -114,7 +128,6 @@ const copyResponseIcon = ref("copy")
|
|||||||
const copyResponse = () => {
|
const copyResponse = () => {
|
||||||
copyToClipboard(responseString.value!)
|
copyToClipboard(responseString.value!)
|
||||||
copyResponseIcon.value = "check"
|
copyResponseIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
|
||||||
setTimeout(() => (copyResponseIcon.value = "copy"), 1000)
|
setTimeout(() => (copyResponseIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +141,9 @@ const downloadResponse = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadResponseIcon.value = "check"
|
downloadResponseIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
:id="'history'"
|
:id="'history'"
|
||||||
icon="clock"
|
icon="clock"
|
||||||
:label="`${t('tab.history')}`"
|
:label="`${$t('tab.history')}`"
|
||||||
:selected="true"
|
:selected="true"
|
||||||
>
|
>
|
||||||
<History
|
<History
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
:id="'collections'"
|
:id="'collections'"
|
||||||
icon="folder"
|
icon="folder"
|
||||||
:label="`${t('tab.collections')}`"
|
:label="`${$t('tab.collections')}`"
|
||||||
>
|
>
|
||||||
<CollectionsGraphql />
|
<CollectionsGraphql />
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
:id="'docs'"
|
:id="'docs'"
|
||||||
icon="book-open"
|
icon="book-open"
|
||||||
:label="`${t('tab.documentation')}`"
|
:label="`${$t('tab.documentation')}`"
|
||||||
>
|
>
|
||||||
<AppSection label="docs">
|
<AppSection label="docs">
|
||||||
<div
|
<div
|
||||||
@@ -34,33 +34,46 @@
|
|||||||
subscriptionFields.length === 0 &&
|
subscriptionFields.length === 0 &&
|
||||||
graphqlTypes.length === 0
|
graphqlTypes.length === 0
|
||||||
"
|
"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/add_comment.svg`"
|
:src="`/images/states/${$colorMode.value}/add_comment.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
:alt="`${t('empty.documentation')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.documentation')"
|
||||||
/>
|
/>
|
||||||
<span class="mb-4 text-center">
|
<span class="text-center mb-4">
|
||||||
{{ t("empty.documentation") }}
|
{{ $t("empty.documentation") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="bg-primary sticky top-0 z-10 flex">
|
<div class="bg-primary flex top-0 z-10 sticky">
|
||||||
<input
|
<input
|
||||||
v-model="graphqlFieldsFilterText"
|
v-model="graphqlFieldsFilterText"
|
||||||
type="search"
|
type="search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:placeholder="`${t('action.search')}`"
|
:placeholder="`${$t('action.search')}`"
|
||||||
class="flex w-full p-4 py-2 bg-transparent"
|
class="bg-transparent flex w-full p-4 py-2"
|
||||||
/>
|
/>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/quickstart/graphql"
|
to="https://docs.hoppscotch.io/quickstart/graphql"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -73,9 +86,9 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
v-if="queryFields.length > 0"
|
v-if="queryFields.length > 0"
|
||||||
:id="'queries'"
|
:id="'queries'"
|
||||||
:label="`${t('tab.queries')}`"
|
:label="`${$t('tab.queries')}`"
|
||||||
:selected="true"
|
:selected="true"
|
||||||
class="divide-dividerLight divide-y"
|
class="divide-y divide-dividerLight"
|
||||||
>
|
>
|
||||||
<GraphqlField
|
<GraphqlField
|
||||||
v-for="(field, index) in filteredQueryFields"
|
v-for="(field, index) in filteredQueryFields"
|
||||||
@@ -88,8 +101,8 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
v-if="mutationFields.length > 0"
|
v-if="mutationFields.length > 0"
|
||||||
:id="'mutations'"
|
:id="'mutations'"
|
||||||
:label="`${t('graphql.mutations')}`"
|
:label="`${$t('graphql.mutations')}`"
|
||||||
class="divide-dividerLight divide-y"
|
class="divide-y divide-dividerLight"
|
||||||
>
|
>
|
||||||
<GraphqlField
|
<GraphqlField
|
||||||
v-for="(field, index) in filteredMutationFields"
|
v-for="(field, index) in filteredMutationFields"
|
||||||
@@ -102,8 +115,8 @@
|
|||||||
<SmartTab
|
<SmartTab
|
||||||
v-if="subscriptionFields.length > 0"
|
v-if="subscriptionFields.length > 0"
|
||||||
:id="'subscriptions'"
|
:id="'subscriptions'"
|
||||||
:label="`${t('graphql.subscriptions')}`"
|
:label="`${$t('graphql.subscriptions')}`"
|
||||||
class="divide-dividerLight divide-y"
|
class="divide-y divide-dividerLight"
|
||||||
>
|
>
|
||||||
<GraphqlField
|
<GraphqlField
|
||||||
v-for="(field, index) in filteredSubscriptionFields"
|
v-for="(field, index) in filteredSubscriptionFields"
|
||||||
@@ -117,8 +130,8 @@
|
|||||||
v-if="graphqlTypes.length > 0"
|
v-if="graphqlTypes.length > 0"
|
||||||
:id="'types'"
|
:id="'types'"
|
||||||
ref="typesTab"
|
ref="typesTab"
|
||||||
:label="`${t('tab.types')}`"
|
:label="`${$t('tab.types')}`"
|
||||||
class="divide-dividerLight divide-y"
|
class="divide-y divide-dividerLight"
|
||||||
>
|
>
|
||||||
<GraphqlType
|
<GraphqlType
|
||||||
v-for="(type, index) in filteredGraphqlTypes"
|
v-for="(type, index) in filteredGraphqlTypes"
|
||||||
@@ -136,26 +149,36 @@
|
|||||||
</AppSection>
|
</AppSection>
|
||||||
</SmartTab>
|
</SmartTab>
|
||||||
|
|
||||||
<SmartTab :id="'schema'" icon="box" :label="`${t('tab.schema')}`">
|
<SmartTab :id="'schema'" icon="box" :label="`${$t('tab.schema')}`">
|
||||||
<AppSection ref="schema" label="schema">
|
<AppSection ref="schema" label="schema">
|
||||||
<div
|
<div
|
||||||
v-if="schemaString"
|
v-if="schemaString"
|
||||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
flex flex-1
|
||||||
|
top-0
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
border-b border-dividerLight
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("graphql.schema") }}
|
{{ $t("graphql.schema") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/quickstart/graphql"
|
to="https://docs.hoppscotch.io/quickstart/graphql"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -163,14 +186,14 @@
|
|||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
ref="downloadSchema"
|
ref="downloadSchema"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadSchemaIcon"
|
:svg="downloadSchemaIcon"
|
||||||
@click.native="downloadSchema"
|
@click.native="downloadSchema"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
ref="copySchemaCode"
|
ref="copySchemaCode"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copySchemaIcon"
|
:svg="copySchemaIcon"
|
||||||
@click.native="copySchema"
|
@click.native="copySchema"
|
||||||
/>
|
/>
|
||||||
@@ -179,16 +202,29 @@
|
|||||||
<div v-if="schemaString" ref="schemaEditor"></div>
|
<div v-if="schemaString" ref="schemaEditor"></div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
:alt="`${t('empty.schema')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.schema')"
|
||||||
/>
|
/>
|
||||||
<span class="mb-4 text-center">
|
<span class="text-center mb-4">
|
||||||
{{ t("empty.schema") }}
|
{{ $t("empty.schema") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
@@ -197,18 +233,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, reactive, ref } from "@nuxtjs/composition-api"
|
import {
|
||||||
|
computed,
|
||||||
|
nextTick,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
useContext,
|
||||||
|
} from "@nuxtjs/composition-api"
|
||||||
import { GraphQLField, GraphQLType } from "graphql"
|
import { GraphQLField, GraphQLType } from "graphql"
|
||||||
import { map } from "rxjs/operators"
|
import { map } from "rxjs/operators"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||||
import { GQLHeader } from "~/helpers/types/HoppGQLRequest"
|
import { GQLHeader } from "~/helpers/types/HoppGQLRequest"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import {
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import {
|
import {
|
||||||
setGQLHeaders,
|
setGQLHeaders,
|
||||||
setGQLQuery,
|
setGQLQuery,
|
||||||
@@ -217,8 +255,6 @@ import {
|
|||||||
setGQLVariables,
|
setGQLVariables,
|
||||||
} from "~/newstore/GQLSession"
|
} from "~/newstore/GQLSession"
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
function isTextFoundInGraphqlFieldObject(
|
function isTextFoundInGraphqlFieldObject(
|
||||||
text: string,
|
text: string,
|
||||||
field: GraphQLField<any, any>
|
field: GraphQLField<any, any>
|
||||||
@@ -285,7 +321,11 @@ const props = defineProps<{
|
|||||||
conn: GQLConnection
|
conn: GQLConnection
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const queryFields = useReadonlyStream(
|
const queryFields = useReadonlyStream(
|
||||||
props.conn.queryFields$.pipe(map((x) => x ?? [])),
|
props.conn.queryFields$.pipe(map((x) => x ?? [])),
|
||||||
@@ -368,25 +408,12 @@ const handleJumpToType = async (type: GraphQLType) => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
||||||
const rootTypeName = resolveRootType(type).name
|
const rootTypeName = resolveRootType(type).name
|
||||||
|
|
||||||
const target = document.getElementById(`type_${rootTypeName}`)
|
const target = document.getElementById(`type_${rootTypeName}`)
|
||||||
if (target) {
|
if (target) {
|
||||||
target.scrollIntoView({ block: "center", behavior: "smooth" })
|
gqlTabs.value.$el
|
||||||
target.classList.add(
|
.querySelector(".gqlTabs")
|
||||||
"transition-all",
|
.scrollTo({ top: target.offsetTop, behavior: "smooth" })
|
||||||
"ring-inset",
|
|
||||||
"ring-accentLight",
|
|
||||||
"ring-4"
|
|
||||||
)
|
|
||||||
setTimeout(
|
|
||||||
() =>
|
|
||||||
target.classList.remove(
|
|
||||||
"ring-inset",
|
|
||||||
"ring-accentLight",
|
|
||||||
"ring-4",
|
|
||||||
"transition-all"
|
|
||||||
),
|
|
||||||
2000
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,7 +449,9 @@ const downloadSchema = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadSchemaIcon.value = "check"
|
downloadSchemaIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<span v-else-if="isEnum" class="text-accent">enum </span>
|
<span v-else-if="isEnum" class="text-accent">enum </span>
|
||||||
{{ gqlType.name }}
|
{{ gqlType.name }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="gqlType.description" class="py-2 text-secondaryLight type-desc">
|
<div v-if="gqlType.description" class="text-secondaryLight py-2 type-desc">
|
||||||
{{ gqlType.description }}
|
{{ gqlType.description }}
|
||||||
</div>
|
</div>
|
||||||
<div v-if="interfaces.length > 0">
|
<div v-if="interfaces.length > 0">
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
<GraphqlTypeLink
|
<GraphqlTypeLink
|
||||||
:gql-type="gqlInterface"
|
:gql-type="gqlInterface"
|
||||||
:jump-type-callback="jumpTypeCallback"
|
:jump-type-callback="jumpTypeCallback"
|
||||||
class="pl-4 border-l-2 border-divider"
|
class="border-divider border-l-2 pl-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
:key="`child-${index}`"
|
:key="`child-${index}`"
|
||||||
:gql-type="child"
|
:gql-type="child"
|
||||||
:jump-type-callback="jumpTypeCallback"
|
:jump-type-callback="jumpTypeCallback"
|
||||||
class="pl-4 border-l-2 border-divider"
|
class="border-divider border-l-2 pl-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="gqlType.getFields">
|
<div v-if="gqlType.getFields">
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<GraphqlField
|
<GraphqlField
|
||||||
v-for="(field, index) in gqlType.getFields()"
|
v-for="(field, index) in gqlType.getFields()"
|
||||||
:key="`field-${index}`"
|
:key="`field-${index}`"
|
||||||
class="pl-4 border-l-2 border-divider"
|
class="border-divider border-l-2 pl-4"
|
||||||
:gql-field="field"
|
:gql-field="field"
|
||||||
:is-highlighted="isFieldHighlighted({ field })"
|
:is-highlighted="isFieldHighlighted({ field })"
|
||||||
:jump-type-callback="jumpTypeCallback"
|
:jump-type-callback="jumpTypeCallback"
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(value, index) in gqlType.getValues()"
|
v-for="(value, index) in gqlType.getValues()"
|
||||||
:key="`value-${index}`"
|
:key="`value-${index}`"
|
||||||
class="pl-4 border-l-2 border-divider"
|
class="border-divider border-l-2 pl-4"
|
||||||
v-text="value.name"
|
v-text="value.name"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="group flex flex-col">
|
<div class="flex flex-col group">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pl-4 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
pl-4
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
data-testid="restore_history_entry"
|
data-testid="restore_history_entry"
|
||||||
@click="useEntry"
|
@click="useEntry"
|
||||||
>
|
>
|
||||||
@@ -15,7 +24,7 @@
|
|||||||
svg="trash"
|
svg="trash"
|
||||||
color="red"
|
color="red"
|
||||||
:title="$t('action.remove')"
|
:title="$t('action.remove')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
data-testid="delete_history_entry"
|
data-testid="delete_history_entry"
|
||||||
@click.native="$emit('delete-entry')"
|
@click.native="$emit('delete-entry')"
|
||||||
/>
|
/>
|
||||||
@@ -23,7 +32,7 @@
|
|||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="expand ? $t('hide.more') : $t('show.more')"
|
:title="expand ? $t('hide.more') : $t('show.more')"
|
||||||
:svg="expand ? 'minimize-2' : 'maximize-2'"
|
:svg="expand ? 'minimize-2' : 'maximize-2'"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
@click.native="expand = !expand"
|
@click.native="expand = !expand"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
@@ -40,7 +49,7 @@
|
|||||||
<span
|
<span
|
||||||
v-for="(line, index) in query"
|
v-for="(line, index) in query"
|
||||||
:key="`line-${index}`"
|
:key="`line-${index}`"
|
||||||
class="text-secondaryLight px-4 truncate whitespace-pre cursor-pointer"
|
class="cursor-pointer text-secondaryLight px-4 whitespace-pre truncate"
|
||||||
data-testid="restore_history_entry"
|
data-testid="restore_history_entry"
|
||||||
@click="useEntry"
|
@click="useEntry"
|
||||||
>{{ line }}</span
|
>{{ line }}</span
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection label="history">
|
<AppSection label="history">
|
||||||
<div class="sticky top-0 z-10 flex border-b bg-primary border-dividerLight">
|
<div class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky">
|
||||||
<input
|
<input
|
||||||
v-model="filterText"
|
v-model="filterText"
|
||||||
type="search"
|
type="search"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
class="flex w-full p-4 py-2 bg-transparent"
|
class="bg-transparent flex w-full p-4 py-2"
|
||||||
:placeholder="`${$t('action.search')}`"
|
:placeholder="`${$t('action.search')}`"
|
||||||
/>
|
/>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -49,24 +49,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="!(filteredHistory.length !== 0 || history.length === 0)"
|
v-if="!(filteredHistory.length !== 0 || history.length === 0)"
|
||||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<i class="pb-2 opacity-75 material-icons">manage_search</i>
|
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||||
<span class="text-center">
|
<span class="text-center">
|
||||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="history.length === 0"
|
v-if="history.length === 0"
|
||||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/history.svg`"
|
:src="`/images/states/${$colorMode.value}/history.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.history')"
|
:alt="$t('empty.history')"
|
||||||
/>
|
/>
|
||||||
<span class="mb-4 text-center">
|
<span class="text-center mb-4">
|
||||||
{{ $t("empty.history") }}
|
{{ $t("empty.history") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -140,7 +140,9 @@ export default defineComponent({
|
|||||||
clearHistory() {
|
clearHistory() {
|
||||||
if (this.page === "rest") clearRESTHistory()
|
if (this.page === "rest") clearRESTHistory()
|
||||||
else clearGraphqlHistory()
|
else clearGraphqlHistory()
|
||||||
this.$toast.success(`${this.$t("state.history_deleted")}`)
|
this.$toast.success(`${this.$t("state.history_deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
useHistory(entry: any) {
|
useHistory(entry: any) {
|
||||||
if (this.page === "rest") setRESTRequest(entry.request)
|
if (this.page === "rest") setRESTRequest(entry.request)
|
||||||
@@ -148,7 +150,9 @@ export default defineComponent({
|
|||||||
deleteHistory(entry: any) {
|
deleteHistory(entry: any) {
|
||||||
if (this.page === "rest") deleteRESTHistoryEntry(entry)
|
if (this.page === "rest") deleteRESTHistoryEntry(entry)
|
||||||
else deleteGraphqlHistoryEntry(entry)
|
else deleteGraphqlHistoryEntry(entry)
|
||||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||||
|
icon: "delete",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
toggleStar(entry: any) {
|
toggleStar(entry: any) {
|
||||||
if (this.page === "rest") toggleRESTHistoryEntryStar(entry)
|
if (this.page === "rest") toggleRESTHistoryEntryStar(entry)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="group flex items-center">
|
<div class="flex items-center group">
|
||||||
<span
|
<span
|
||||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
class="cursor-pointer flex px-2 w-16 justify-center items-center truncate"
|
||||||
:class="entryStatus.className"
|
:class="entryStatus.className"
|
||||||
data-testid="restore_history_entry"
|
data-testid="restore_history_entry"
|
||||||
:title="`${duration}`"
|
:title="`${duration}`"
|
||||||
@@ -10,7 +10,15 @@
|
|||||||
{{ entry.request.method }}
|
{{ entry.request.method }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
pr-2
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
data-testid="restore_history_entry"
|
data-testid="restore_history_entry"
|
||||||
:title="`${duration}`"
|
:title="`${duration}`"
|
||||||
@click="$emit('use-entry')"
|
@click="$emit('use-entry')"
|
||||||
@@ -24,7 +32,7 @@
|
|||||||
svg="trash"
|
svg="trash"
|
||||||
color="red"
|
color="red"
|
||||||
:title="$t('action.remove')"
|
:title="$t('action.remove')"
|
||||||
class="group-hover:inline-flex hidden"
|
class="hidden group-hover:inline-flex"
|
||||||
data-testid="delete_history_entry"
|
data-testid="delete_history_entry"
|
||||||
@click.native="$emit('delete-entry')"
|
@click.native="$emit('delete-entry')"
|
||||||
/>
|
/>
|
||||||
@@ -41,9 +49,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType } from "@nuxtjs/composition-api"
|
import {
|
||||||
|
computed,
|
||||||
|
defineComponent,
|
||||||
|
PropType,
|
||||||
|
useContext,
|
||||||
|
} from "@nuxtjs/composition-api"
|
||||||
import findStatusGroup from "~/helpers/findStatusGroup"
|
import findStatusGroup from "~/helpers/findStatusGroup"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
import { RESTHistoryEntry } from "~/newstore/history"
|
import { RESTHistoryEntry } from "~/newstore/history"
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -52,7 +64,10 @@ export default defineComponent({
|
|||||||
showMore: Boolean,
|
showMore: Boolean,
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const t = useI18n()
|
const {
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const $t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const duration = computed(() => {
|
const duration = computed(() => {
|
||||||
if (props.entry.responseMeta.duration) {
|
if (props.entry.responseMeta.duration) {
|
||||||
@@ -60,9 +75,9 @@ export default defineComponent({
|
|||||||
if (!responseDuration) return ""
|
if (!responseDuration) return ""
|
||||||
|
|
||||||
return responseDuration > 0
|
return responseDuration > 0
|
||||||
? `${t("request.duration")}: ${responseDuration}ms`
|
? `${$t("request.duration")}: ${responseDuration}ms`
|
||||||
: t("error.no_duration")
|
: $t("error.no_duration")
|
||||||
} else return t("error.no_duration")
|
} else return $t("error.no_duration")
|
||||||
})
|
})
|
||||||
|
|
||||||
const entryStatus = computed(() => {
|
const entryStatus = computed(() => {
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("authorization.type") }}
|
{{ $t("authorization.type") }}
|
||||||
</label>
|
</label>
|
||||||
<tippy
|
<tippy
|
||||||
@@ -17,7 +27,7 @@
|
|||||||
<template #trigger>
|
<template #trigger>
|
||||||
<span class="select-wrapper">
|
<span class="select-wrapper">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
class="pr-8 ml-2 rounded-none"
|
class="rounded-none ml-2 pr-8"
|
||||||
:label="authName"
|
:label="authName"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@@ -83,37 +93,37 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="authType === 'none'"
|
v-if="authType === 'none'"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/login.svg`"
|
:src="`/images/states/${$colorMode.value}/login.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.authorization')"
|
:alt="$t('empty.authorization')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.authorization") }}
|
{{ $t("empty.authorization") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
outline
|
outline
|
||||||
:label="$t('app.documentation')"
|
:label="$t('app.documentation')"
|
||||||
to="https://docs.hoppscotch.io/features/authorization"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
svg="external-link"
|
svg="external-link"
|
||||||
reverse
|
reverse
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="authType === 'basic'" class="border-dividerLight flex border-b">
|
<div v-if="authType === 'basic'" class="border-b border-dividerLight flex">
|
||||||
<div class="border-dividerLight w-2/3 border-r">
|
<div class="border-r border-dividerLight w-2/3">
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="basicUsername"
|
v-model="basicUsername"
|
||||||
:placeholder="$t('authorization.username')"
|
:placeholder="$t('authorization.username')"
|
||||||
styles="bg-transparent flex flex-1 py-1 px-4"
|
styles="bg-transparent flex flex-1 py-1 px-4"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="basicPassword"
|
v-model="basicPassword"
|
||||||
:placeholder="$t('authorization.password')"
|
:placeholder="$t('authorization.password')"
|
||||||
@@ -122,7 +132,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
h-full
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
min-w-46
|
||||||
|
max-w-1/3
|
||||||
|
p-4
|
||||||
|
z-9
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<div class="text-secondaryLight pb-2">
|
<div class="text-secondaryLight pb-2">
|
||||||
@@ -131,15 +151,15 @@
|
|||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
class="link"
|
class="link"
|
||||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||||
to="https://docs.hoppscotch.io/features/authorization"
|
to="https://docs.hoppscotch.io/"
|
||||||
blank
|
blank
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="authType === 'bearer'" class="border-dividerLight flex border-b">
|
<div v-if="authType === 'bearer'" class="border-b border-dividerLight flex">
|
||||||
<div class="border-dividerLight w-2/3 border-r">
|
<div class="border-r border-dividerLight w-2/3">
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="bearerToken"
|
v-model="bearerToken"
|
||||||
placeholder="Token"
|
placeholder="Token"
|
||||||
@@ -148,7 +168,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
h-full
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
min-w-46
|
||||||
|
max-w-1/3
|
||||||
|
p-4
|
||||||
|
z-9
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<div class="text-secondaryLight pb-2">
|
<div class="text-secondaryLight pb-2">
|
||||||
@@ -157,7 +187,7 @@
|
|||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
class="link"
|
class="link"
|
||||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||||
to="https://docs.hoppscotch.io/features/authorization"
|
to="https://docs.hoppscotch.io/"
|
||||||
blank
|
blank
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -165,10 +195,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="authType === 'oauth-2'"
|
v-if="authType === 'oauth-2'"
|
||||||
class="border-dividerLight flex border-b"
|
class="border-b border-dividerLight flex"
|
||||||
>
|
>
|
||||||
<div class="border-dividerLight w-2/3 border-r">
|
<div class="border-r border-dividerLight w-2/3">
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="oauth2Token"
|
v-model="oauth2Token"
|
||||||
placeholder="Token"
|
placeholder="Token"
|
||||||
@@ -178,7 +208,17 @@
|
|||||||
<HttpOAuth2Authorization />
|
<HttpOAuth2Authorization />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
h-full
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
min-w-46
|
||||||
|
max-w-1/3
|
||||||
|
p-4
|
||||||
|
z-9
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<div class="text-secondaryLight pb-2">
|
<div class="text-secondaryLight pb-2">
|
||||||
@@ -187,7 +227,7 @@
|
|||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
class="link"
|
class="link"
|
||||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||||
to="https://docs.hoppscotch.io/features/authorization"
|
to="https://docs.hoppscotch.io/"
|
||||||
blank
|
blank
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span class="flex items-center">
|
<span class="flex items-center">
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("request.content_type") }}
|
{{ $t("request.content_type") }}
|
||||||
</label>
|
</label>
|
||||||
<tippy
|
<tippy
|
||||||
@@ -18,7 +28,7 @@
|
|||||||
<span class="select-wrapper">
|
<span class="select-wrapper">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="contentType || $t('state.none').toLowerCase()"
|
:label="contentType || $t('state.none').toLowerCase()"
|
||||||
class="pr-8 ml-2 rounded-none"
|
class="rounded-none ml-2 pr-8"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -53,21 +63,21 @@
|
|||||||
<HttpRawBody v-else-if="contentType !== null" :content-type="contentType" />
|
<HttpRawBody v-else-if="contentType !== null" :content-type="contentType" />
|
||||||
<div
|
<div
|
||||||
v-if="contentType == null"
|
v-if="contentType == null"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.body')"
|
:alt="$t('empty.body')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.body") }}
|
{{ $t("empty.body") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
outline
|
outline
|
||||||
:label="`${$t('app.documentation')}`"
|
:label="`${$t('app.documentation')}`"
|
||||||
to="https://docs.hoppscotch.io/features/body"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
svg="external-link"
|
svg="external-link"
|
||||||
reverse
|
reverse
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection label="bodyParameters">
|
<AppSection label="bodyParameters">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("request.body") }}
|
{{ $t("request.body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -31,7 +41,7 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(param, index) in bodyParams"
|
v-for="(param, index) in bodyParams"
|
||||||
:key="`param-${index}`"
|
:key="`param-${index}`"
|
||||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||||
>
|
>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="param.key"
|
v-model="param.key"
|
||||||
@@ -53,7 +63,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<div v-if="param.isFile" class="file-chips-container hide-scrollbar">
|
<div v-if="param.isFile" class="file-chips-container hide-scrollbar">
|
||||||
<div class="file-chips-wrapper space-x-2">
|
<div class="space-x-2 file-chips-wrapper">
|
||||||
<SmartDeletableChip
|
<SmartDeletableChip
|
||||||
v-for="(file, fileIndex) in param.value"
|
v-for="(file, fileIndex) in param.value"
|
||||||
:key="`param-${index}-file-${fileIndex}`"
|
:key="`param-${index}-file-${fileIndex}`"
|
||||||
@@ -141,15 +151,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="bodyParams.length === 0"
|
v-if="bodyParams.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="$t('empty.body')"
|
:alt="$t('empty.body')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ $t("empty.body") }}
|
{{ $t("empty.body") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<template #body>
|
<template #body>
|
||||||
<div class="flex flex-col px-2">
|
<div class="flex flex-col px-2">
|
||||||
<label for="requestType" class="px-4 pb-4">
|
<label for="requestType" class="px-4 pb-4">
|
||||||
{{ t("request.choose_language") }}
|
{{ $t("request.choose_language") }}
|
||||||
</label>
|
</label>
|
||||||
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</tippy>
|
</tippy>
|
||||||
<div class="flex justify-between flex-1">
|
<div class="flex flex-1 justify-between">
|
||||||
<label for="generatedCode" class="p-4">
|
<label for="generatedCode" class="p-4">
|
||||||
{{ t("request.generated_code") }}
|
{{ t("request.generated_code") }}
|
||||||
</label>
|
</label>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
<div
|
<div
|
||||||
v-if="codegenType"
|
v-if="codegenType"
|
||||||
ref="generatedCode"
|
ref="generatedCode"
|
||||||
class="border rounded border-dividerLight"
|
class="border border-dividerLight rounded"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -62,16 +62,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||||
import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen"
|
import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL"
|
import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL"
|
||||||
import { getCurrentEnvironment } from "~/newstore/environments"
|
import { getCurrentEnvironment } from "~/newstore/environments"
|
||||||
import { getRESTRequest } from "~/newstore/RESTSession"
|
import { getRESTRequest } from "~/newstore/RESTSession"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
show: boolean
|
show: boolean
|
||||||
@@ -81,7 +78,11 @@ const emit = defineEmits<{
|
|||||||
(e: "hide-modal"): void
|
(e: "hide-modal"): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const options = ref<any | null>(null)
|
const options = ref<any | null>(null)
|
||||||
|
|
||||||
@@ -125,7 +126,9 @@ const hideModal = () => emit("hide-modal")
|
|||||||
const copyRequestCode = () => {
|
const copyRequestCode = () => {
|
||||||
copyToClipboard(requestCode.value)
|
copyToClipboard(requestCode.value)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,35 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection label="headers">
|
<AppSection label="headers">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.header_list") }}
|
{{ $t("request.header_list") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/features/headers"
|
to="https://docs.hoppscotch.io/features/headers"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear_all')"
|
:title="$t('action.clear_all')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent()"
|
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.bulk_mode')"
|
:title="$t('state.bulk_mode')"
|
||||||
svg="edit"
|
svg="edit"
|
||||||
:class="{ '!text-accent': bulkMode }"
|
:class="{ '!text-accent': bulkMode }"
|
||||||
@click.native="bulkMode = !bulkMode"
|
@click.native="bulkMode = !bulkMode"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('add.new')"
|
:title="$t('add.new')"
|
||||||
svg="plus"
|
svg="plus"
|
||||||
:disabled="bulkMode"
|
:disabled="bulkMode"
|
||||||
@click.native="addHeader"
|
@click.native="addHeader"
|
||||||
@@ -41,10 +51,10 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(header, index) in headers$"
|
v-for="(header, index) in headers$"
|
||||||
:key="`header-${index}`"
|
:key="`header-${index}`"
|
||||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||||
>
|
>
|
||||||
<SmartAutoComplete
|
<SmartAutoComplete
|
||||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
:placeholder="`${$t('count.header', { count: index + 1 })}`"
|
||||||
:source="commonHeaders"
|
:source="commonHeaders"
|
||||||
:spellcheck="false"
|
:spellcheck="false"
|
||||||
:value="header.key"
|
:value="header.key"
|
||||||
@@ -68,7 +78,7 @@
|
|||||||
/>
|
/>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="header.value"
|
v-model="header.value"
|
||||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||||
styles="
|
styles="
|
||||||
bg-transparent
|
bg-transparent
|
||||||
flex
|
flex
|
||||||
@@ -90,9 +100,9 @@
|
|||||||
:title="
|
:title="
|
||||||
header.hasOwnProperty('active')
|
header.hasOwnProperty('active')
|
||||||
? header.active
|
? header.active
|
||||||
? t('action.turn_off')
|
? $t('action.turn_off')
|
||||||
: t('action.turn_on')
|
: $t('action.turn_on')
|
||||||
: t('action.turn_off')
|
: $t('action.turn_off')
|
||||||
"
|
"
|
||||||
:svg="
|
:svg="
|
||||||
header.hasOwnProperty('active')
|
header.hasOwnProperty('active')
|
||||||
@@ -116,7 +126,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.remove')"
|
:title="$t('action.remove')"
|
||||||
svg="trash"
|
svg="trash"
|
||||||
color="red"
|
color="red"
|
||||||
@click.native="deleteHeader(index)"
|
@click.native="deleteHeader(index)"
|
||||||
@@ -125,20 +135,33 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="headers$.length === 0"
|
v-if="headers$.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
:alt="`${t('empty.headers')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.headers')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ t("empty.headers") }}
|
{{ $t("empty.headers") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
filled
|
filled
|
||||||
:label="`${t('add.new')}`"
|
:label="`${$t('add.new')}`"
|
||||||
svg="plus"
|
svg="plus"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
@click.native="addHeader"
|
@click.native="addHeader"
|
||||||
@@ -149,7 +172,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onBeforeUpdate, ref, watch } from "@nuxtjs/composition-api"
|
import { onBeforeUpdate, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import {
|
import {
|
||||||
addRESTHeader,
|
addRESTHeader,
|
||||||
@@ -160,16 +183,14 @@ import {
|
|||||||
updateRESTHeader,
|
updateRESTHeader,
|
||||||
} from "~/newstore/RESTSession"
|
} from "~/newstore/RESTSession"
|
||||||
import { commonHeaders } from "~/helpers/headers"
|
import { commonHeaders } from "~/helpers/headers"
|
||||||
import {
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const bulkMode = ref(false)
|
const bulkMode = ref(false)
|
||||||
const bulkHeaders = ref("")
|
const bulkHeaders = ref("")
|
||||||
@@ -191,9 +212,11 @@ watch(bulkHeaders, () => {
|
|||||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||||
active: !item.trim().startsWith("//"),
|
active: !item.trim().startsWith("//"),
|
||||||
}))
|
}))
|
||||||
setRESTHeaders(transformation as HoppRESTHeader[])
|
setRESTHeaders(transformation)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`${t("error.something_went_wrong")}`)
|
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -203,13 +226,12 @@ const headers$ = useReadonlyStream(restHeaders$, [])
|
|||||||
watch(
|
watch(
|
||||||
headers$,
|
headers$,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (!bulkMode.value)
|
if (
|
||||||
if (
|
(newValue[newValue.length - 1]?.key !== "" ||
|
||||||
(newValue[newValue.length - 1]?.key !== "" ||
|
newValue[newValue.length - 1]?.value !== "") &&
|
||||||
newValue[newValue.length - 1]?.value !== "") &&
|
newValue.length
|
||||||
newValue.length
|
)
|
||||||
)
|
addHeader()
|
||||||
addHeader()
|
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
@@ -255,10 +277,11 @@ const deleteHeader = (index: number) => {
|
|||||||
|
|
||||||
const deletedItem = headersBeforeDeletion[index]
|
const deletedItem = headersBeforeDeletion[index]
|
||||||
if (deletedItem.key || deletedItem.value) {
|
if (deletedItem.key || deletedItem.value) {
|
||||||
toast.success(`${t("state.deleted")}`, {
|
$toast.success(t("state.deleted").toString(), {
|
||||||
|
icon: "delete",
|
||||||
action: [
|
action: [
|
||||||
{
|
{
|
||||||
text: `${t("action.undo")}`,
|
text: t("action.undo").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
setRESTHeaders(headersBeforeDeletion as HoppRESTHeader[])
|
setRESTHeaders(headersBeforeDeletion as HoppRESTHeader[])
|
||||||
editBulkHeadersLine(index, deletedItem)
|
editBulkHeadersLine(index, deletedItem)
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<SmartModal v-if="show" :title="`${t('import.curl')}`" @close="hideModal">
|
<SmartModal v-if="show" :title="`${$t('import.curl')}`" @close="hideModal">
|
||||||
<template #body>
|
<template #body>
|
||||||
<div class="flex flex-col px-2">
|
<div class="flex flex-col px-2">
|
||||||
<div ref="curlEditor" class="border rounded border-dividerLight"></div>
|
<div ref="curlEditor" class="border border-dividerLight rounded"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="flex">
|
<span class="flex">
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
:label="`${t('import.title')}`"
|
:label="`${$t('import.title')}`"
|
||||||
@click.native="handleImport"
|
@click.native="handleImport"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('action.cancel')}`"
|
:label="`${$t('action.cancel')}`"
|
||||||
@click.native="hideModal"
|
@click.native="hideModal"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "@nuxtjs/composition-api"
|
import { ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import parseCurlCommand from "~/helpers/curlparser"
|
import parseCurlCommand from "~/helpers/curlparser"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import {
|
import {
|
||||||
@@ -30,11 +30,12 @@ import {
|
|||||||
makeRESTRequest,
|
makeRESTRequest,
|
||||||
} from "~/helpers/types/HoppRESTRequest"
|
} from "~/helpers/types/HoppRESTRequest"
|
||||||
import { setRESTRequest } from "~/newstore/RESTSession"
|
import { setRESTRequest } from "~/newstore/RESTSession"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const curl = ref("")
|
const curl = ref("")
|
||||||
|
|
||||||
@@ -122,7 +123,9 @@ const handleImport = () => {
|
|||||||
)
|
)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
toast.error(`${t("error.curl_invalid_format")}`)
|
$toast.error(`${t("error.curl_invalid_format")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
hideModal()
|
hideModal()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="flex border-b border-dividerLight">
|
<div class="border-b border-dividerLight flex">
|
||||||
<input
|
<input
|
||||||
id="oidcDiscoveryURL"
|
id="oidcDiscoveryURL"
|
||||||
v-model="oidcDiscoveryURL"
|
v-model="oidcDiscoveryURL"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
placeholder="OpenID Connect Discovery URL"
|
placeholder="OpenID Connect Discovery URL"
|
||||||
name="oidcDiscoveryURL"
|
name="oidcDiscoveryURL"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex border-b border-dividerLight">
|
<div class="border-b border-dividerLight flex">
|
||||||
<input
|
<input
|
||||||
id="authURL"
|
id="authURL"
|
||||||
v-model="authURL"
|
v-model="authURL"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
placeholder="Authentication URL"
|
placeholder="Authentication URL"
|
||||||
name="authURL"
|
name="authURL"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex border-b border-dividerLight">
|
<div class="border-b border-dividerLight flex">
|
||||||
<input
|
<input
|
||||||
id="accessTokenURL"
|
id="accessTokenURL"
|
||||||
v-model="accessTokenURL"
|
v-model="accessTokenURL"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
placeholder="Access Token URL"
|
placeholder="Access Token URL"
|
||||||
name="accessTokenURL"
|
name="accessTokenURL"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex border-b border-dividerLight">
|
<div class="border-b border-dividerLight flex">
|
||||||
<input
|
<input
|
||||||
id="clientID"
|
id="clientID"
|
||||||
v-model="clientID"
|
v-model="clientID"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
placeholder="Client ID"
|
placeholder="Client ID"
|
||||||
name="clientID"
|
name="clientID"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex border-b border-dividerLight">
|
<div class="border-b border-dividerLight flex">
|
||||||
<input
|
<input
|
||||||
id="scope"
|
id="scope"
|
||||||
v-model="scope"
|
v-model="scope"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
placeholder="Scope"
|
placeholder="Scope"
|
||||||
name="scope"
|
name="scope"
|
||||||
/>
|
/>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
filled
|
filled
|
||||||
:label="`${t('authorization.generate_token')}`"
|
:label="`${$t('authorization.generate_token')}`"
|
||||||
@click.native="handleAccessTokenRequest()"
|
@click.native="handleAccessTokenRequest()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,21 +56,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Ref } from "@nuxtjs/composition-api"
|
import { Ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import {
|
import { pluckRef, useStream } from "~/helpers/utils/composables"
|
||||||
pluckRef,
|
|
||||||
useI18n,
|
|
||||||
useStream,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import { HoppRESTAuthOAuth2 } from "~/helpers/types/HoppRESTAuth"
|
import { HoppRESTAuthOAuth2 } from "~/helpers/types/HoppRESTAuth"
|
||||||
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
|
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
|
||||||
import { tokenRequest } from "~/helpers/oauth"
|
import { tokenRequest } from "~/helpers/oauth"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setup() {
|
setup() {
|
||||||
const t = useI18n()
|
const {
|
||||||
const toast = useToast()
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const $t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const auth = useStream(
|
const auth = useStream(
|
||||||
restAuth$,
|
restAuth$,
|
||||||
@@ -99,7 +97,9 @@ export default {
|
|||||||
oidcDiscoveryURL.value === "" &&
|
oidcDiscoveryURL.value === "" &&
|
||||||
(authURL.value === "" || accessTokenURL.value === "")
|
(authURL.value === "" || accessTokenURL.value === "")
|
||||||
) {
|
) {
|
||||||
toast.error(`${t("complete_config_urls")}`)
|
$toast.error(`${$t("complete_config_urls")}`, {
|
||||||
|
icon: "error",
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -113,7 +113,9 @@ export default {
|
|||||||
}
|
}
|
||||||
await tokenRequest(tokenReqParams)
|
await tokenRequest(tokenReqParams)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`${e}`)
|
$toast.error(`${e}`, {
|
||||||
|
icon: "code",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,45 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection label="parameters">
|
<AppSection label="parameters">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.parameter_list") }}
|
{{ $t("request.parameter_list") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/features/parameters"
|
to="https://docs.hoppscotch.io/features/parameters"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear_all')"
|
:title="$t('action.clear_all')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent()"
|
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.bulk_mode')"
|
:title="$t('state.bulk_mode')"
|
||||||
svg="edit"
|
svg="edit"
|
||||||
:class="{ '!text-accent': bulkMode }"
|
:class="{ '!text-accent': bulkMode }"
|
||||||
@click.native="bulkMode = !bulkMode"
|
@click.native="bulkMode = !bulkMode"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('add.new')"
|
:title="$t('add.new')"
|
||||||
svg="plus"
|
svg="plus"
|
||||||
:disabled="bulkMode"
|
:disabled="bulkMode"
|
||||||
@click.native="addParam"
|
@click.native="addParam"
|
||||||
@@ -41,11 +51,11 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(param, index) in params$"
|
v-for="(param, index) in params$"
|
||||||
:key="`param-${index}`"
|
:key="`param-${index}`"
|
||||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||||
>
|
>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="param.key"
|
v-model="param.key"
|
||||||
:placeholder="`${t('count.parameter', { count: index + 1 })}`"
|
:placeholder="`${$t('count.parameter', { count: index + 1 })}`"
|
||||||
styles="
|
styles="
|
||||||
bg-transparent
|
bg-transparent
|
||||||
flex
|
flex
|
||||||
@@ -63,7 +73,7 @@
|
|||||||
/>
|
/>
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="param.value"
|
v-model="param.value"
|
||||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||||
styles="
|
styles="
|
||||||
bg-transparent
|
bg-transparent
|
||||||
flex
|
flex
|
||||||
@@ -85,9 +95,9 @@
|
|||||||
:title="
|
:title="
|
||||||
param.hasOwnProperty('active')
|
param.hasOwnProperty('active')
|
||||||
? param.active
|
? param.active
|
||||||
? t('action.turn_off')
|
? $t('action.turn_off')
|
||||||
: t('action.turn_on')
|
: $t('action.turn_on')
|
||||||
: t('action.turn_off')
|
: $t('action.turn_off')
|
||||||
"
|
"
|
||||||
:svg="
|
:svg="
|
||||||
param.hasOwnProperty('active')
|
param.hasOwnProperty('active')
|
||||||
@@ -109,7 +119,7 @@
|
|||||||
<span>
|
<span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.remove')"
|
:title="$t('action.remove')"
|
||||||
svg="trash"
|
svg="trash"
|
||||||
color="red"
|
color="red"
|
||||||
@click.native="deleteParam(index)"
|
@click.native="deleteParam(index)"
|
||||||
@@ -118,19 +128,32 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="params$.length === 0"
|
v-if="params$.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/add_files.svg`"
|
:src="`/images/states/${$colorMode.value}/add_files.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
:alt="`${t('empty.parameters')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.parameters')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ t("empty.parameters") }}
|
{{ $t("empty.parameters") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="`${t('add.new')}`"
|
:label="`${$t('add.new')}`"
|
||||||
svg="plus"
|
svg="plus"
|
||||||
filled
|
filled
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
@@ -142,14 +165,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, onBeforeUpdate } from "@nuxtjs/composition-api"
|
import { ref, useContext, watch, onBeforeUpdate } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
|
import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
|
||||||
import {
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
useReadonlyStream,
|
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
} from "~/helpers/utils/composables"
|
|
||||||
import {
|
import {
|
||||||
restParams$,
|
restParams$,
|
||||||
addRESTParam,
|
addRESTParam,
|
||||||
@@ -159,9 +178,11 @@ import {
|
|||||||
setRESTParams,
|
setRESTParams,
|
||||||
} from "~/newstore/RESTSession"
|
} from "~/newstore/RESTSession"
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
$toast,
|
||||||
const toast = useToast()
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const bulkMode = ref(false)
|
const bulkMode = ref(false)
|
||||||
const bulkParams = ref("")
|
const bulkParams = ref("")
|
||||||
@@ -173,9 +194,11 @@ watch(bulkParams, () => {
|
|||||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||||
active: !item.trim().startsWith("//"),
|
active: !item.trim().startsWith("//"),
|
||||||
}))
|
}))
|
||||||
setRESTParams(transformation as HoppRESTParam[])
|
setRESTParams(transformation)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(`${t("error.something_went_wrong")}`)
|
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(e)
|
console.error(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -196,13 +219,12 @@ const params$ = useReadonlyStream(restParams$, [])
|
|||||||
watch(
|
watch(
|
||||||
params$,
|
params$,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (!bulkMode.value)
|
if (
|
||||||
if (
|
(newValue[newValue.length - 1]?.key !== "" ||
|
||||||
(newValue[newValue.length - 1]?.key !== "" ||
|
newValue[newValue.length - 1]?.value !== "") &&
|
||||||
newValue[newValue.length - 1]?.value !== "") &&
|
newValue.length
|
||||||
newValue.length
|
)
|
||||||
)
|
addParam()
|
||||||
addParam()
|
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
@@ -248,10 +270,11 @@ const deleteParam = (index: number) => {
|
|||||||
|
|
||||||
const deletedItem = parametersBeforeDeletion[index]
|
const deletedItem = parametersBeforeDeletion[index]
|
||||||
if (deletedItem.key || deletedItem.value) {
|
if (deletedItem.key || deletedItem.value) {
|
||||||
toast.success(`${t("state.deleted")}`, {
|
$toast.success(t("state.deleted").toString(), {
|
||||||
|
icon: "delete",
|
||||||
action: [
|
action: [
|
||||||
{
|
{
|
||||||
text: `${t("action.undo")}`,
|
text: t("action.undo").toString(),
|
||||||
onClick: (_, toastObject) => {
|
onClick: (_, toastObject) => {
|
||||||
setRESTParams(parametersBeforeDeletion as HoppRESTParam[])
|
setRESTParams(parametersBeforeDeletion as HoppRESTParam[])
|
||||||
editBulkParamsLine(index, deletedItem)
|
editBulkParamsLine(index, deletedItem)
|
||||||
|
|||||||
@@ -1,51 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection id="script" :label="`${t('preRequest.script')}`">
|
<AppSection id="script" :label="`${$t('preRequest.script')}`">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("preRequest.javascript_code") }}
|
{{ $t("preRequest.javascript_code") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/features/pre-request-script"
|
to="https://docs.hoppscotch.io/features/pre-request-script"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear')"
|
:title="$t('action.clear')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent"
|
@click.native="clearContent"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<div class="border-dividerLight w-2/3 border-r">
|
<div class="border-r border-dividerLight w-2/3">
|
||||||
<div ref="preRrequestEditor"></div>
|
<div ref="preRrequestEditor"></div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
h-full
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
min-w-46
|
||||||
|
max-w-1/3
|
||||||
|
p-4
|
||||||
|
z-9
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="text-secondaryLight pb-2">
|
<div class="text-secondaryLight pb-2">
|
||||||
{{ t("helpers.pre_request_script") }}
|
{{ $t("helpers.pre_request_script") }}
|
||||||
</div>
|
</div>
|
||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
:label="`${t('preRequest.learn')}`"
|
:label="`${$t('preRequest.learn')}`"
|
||||||
to="https://docs.hoppscotch.io/features/pre-request-script"
|
to="https://docs.hoppscotch.io/features/pre-request-script"
|
||||||
blank
|
blank
|
||||||
/>
|
/>
|
||||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
<h4 class="font-bold text-secondaryLight pt-6">
|
||||||
{{ t("preRequest.snippets") }}
|
{{ $t("preRequest.snippets") }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="flex flex-col pt-4">
|
<div class="flex flex-col pt-4">
|
||||||
<TabSecondary
|
<TabSecondary
|
||||||
@@ -62,15 +82,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import { usePreRequestScript } from "~/newstore/RESTSession"
|
import { usePreRequestScript } from "~/newstore/RESTSession"
|
||||||
import snippets from "~/helpers/preRequestScriptSnippets"
|
import snippets from "~/helpers/preRequestScriptSnippets"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import linter from "~/helpers/editor/linting/preRequest"
|
import linter from "~/helpers/editor/linting/preRequest"
|
||||||
import completer from "~/helpers/editor/completion/preRequest"
|
import completer from "~/helpers/editor/completion/preRequest"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const preRequestScript = usePreRequestScript()
|
const preRequestScript = usePreRequestScript()
|
||||||
|
|
||||||
|
|||||||
@@ -1,29 +1,39 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.raw_body") }}
|
{{ $t("request.raw_body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/features/body"
|
to="https://docs.hoppscotch.io/features/body"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear')"
|
:title="$t('action.clear')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent"
|
@click.native="clearContent"
|
||||||
/>
|
/>
|
||||||
@@ -31,14 +41,14 @@
|
|||||||
v-if="contentType && contentType.endsWith('json')"
|
v-if="contentType && contentType.endsWith('json')"
|
||||||
ref="prettifyRequest"
|
ref="prettifyRequest"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.prettify')"
|
:title="$t('action.prettify')"
|
||||||
:svg="prettifyIcon"
|
:svg="prettifyIcon"
|
||||||
@click.native="prettifyRequestBody"
|
@click.native="prettifyRequestBody"
|
||||||
/>
|
/>
|
||||||
<label for="payload">
|
<label for="payload">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('import.json')"
|
:title="$t('import.json')"
|
||||||
svg="file-plus"
|
svg="file-plus"
|
||||||
@click.native="$refs.payload.click()"
|
@click.native="$refs.payload.click()"
|
||||||
/>
|
/>
|
||||||
@@ -57,19 +67,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, reactive, ref } from "@nuxtjs/composition-api"
|
import { computed, reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { getEditorLangForMimeType } from "~/helpers/editorutils"
|
import { getEditorLangForMimeType } from "~/helpers/editorutils"
|
||||||
import { pluckRef, useI18n, useToast } from "~/helpers/utils/composables"
|
import { pluckRef } from "~/helpers/utils/composables"
|
||||||
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
contentType: string
|
contentType: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const rawParamsBody = pluckRef(useRESTRequestBody(), "body")
|
const rawParamsBody = pluckRef(useRESTRequestBody(), "body")
|
||||||
const prettifyIcon = ref("wand")
|
const prettifyIcon = ref("wand")
|
||||||
@@ -106,9 +118,13 @@ const uploadPayload = (e: InputEvent) => {
|
|||||||
rawParamsBody.value = target?.result
|
rawParamsBody.value = target?.result
|
||||||
}
|
}
|
||||||
reader.readAsText(file)
|
reader.readAsText(file)
|
||||||
toast.success(`${t("state.file_imported")}`)
|
$toast.success(`${t("state.file_imported")}`, {
|
||||||
|
icon: "attach_file",
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
toast.error(`${t("action.choose_file")}`)
|
$toast.error(`${t("action.choose_file")}`, {
|
||||||
|
icon: "attach_file",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const prettifyRequestBody = () => {
|
const prettifyRequestBody = () => {
|
||||||
@@ -119,7 +135,9 @@ const prettifyRequestBody = () => {
|
|||||||
setTimeout(() => (prettifyIcon.value = "wand"), 1000)
|
setTimeout(() => (prettifyIcon.value = "wand"), 1000)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
toast.error(`${t("error.json_prettify_invalid_body")}`)
|
$toast.error(`${t("error.json_prettify_invalid_body")}`, {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="bg-primary hide-scrollbar sticky top-0 z-10 flex p-4 space-x-2 overflow-x-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
flex
|
||||||
|
space-x-2
|
||||||
|
p-4
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
overflow-x-auto
|
||||||
|
hide-scrollbar
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="flex flex-1">
|
<div class="flex flex-1">
|
||||||
<div class="relative flex">
|
<div class="flex relative">
|
||||||
<label for="method">
|
<label for="method">
|
||||||
<tippy
|
<tippy
|
||||||
ref="methodOptions"
|
ref="methodOptions"
|
||||||
@@ -16,10 +26,24 @@
|
|||||||
<span class="select-wrapper">
|
<span class="select-wrapper">
|
||||||
<input
|
<input
|
||||||
id="method"
|
id="method"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex px-4 py-2 font-semibold border rounded-l cursor-pointer"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded-l
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
font-semibold
|
||||||
|
text-secondaryDark
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
w-26
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
:value="newMethod"
|
:value="newMethod"
|
||||||
:readonly="!isCustomMethod"
|
:readonly="!isCustomMethod"
|
||||||
:placeholder="`${t('request.method')}`"
|
:placeholder="`${$t('request.method')}`"
|
||||||
@input="onSelectMethod($event.target.value)"
|
@input="onSelectMethod($event.target.value)"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
@@ -36,7 +60,7 @@
|
|||||||
<div class="flex flex-1">
|
<div class="flex flex-1">
|
||||||
<SmartEnvInput
|
<SmartEnvInput
|
||||||
v-model="newEndpoint"
|
v-model="newEndpoint"
|
||||||
:placeholder="`${t('request.url')}`"
|
:placeholder="`${$t('request.url')}`"
|
||||||
styles="
|
styles="
|
||||||
bg-primaryLight
|
bg-primaryLight
|
||||||
border border-divider
|
border border-divider
|
||||||
@@ -58,8 +82,8 @@
|
|||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonPrimary
|
<ButtonPrimary
|
||||||
id="send"
|
id="send"
|
||||||
class="min-w-20 flex-1 rounded-r-none"
|
class="rounded-r-none flex-1 min-w-20"
|
||||||
:label="`${!loading ? t('action.send') : t('action.cancel')}`"
|
:label="`${!loading ? $t('action.send') : $t('action.cancel')}`"
|
||||||
@click.native="!loading ? newSendRequest() : cancelRequest()"
|
@click.native="!loading ? newSendRequest() : cancelRequest()"
|
||||||
/>
|
/>
|
||||||
<span class="flex">
|
<span class="flex">
|
||||||
@@ -74,7 +98,7 @@
|
|||||||
<ButtonPrimary class="rounded-l-none" filled svg="chevron-down" />
|
<ButtonPrimary class="rounded-l-none" filled svg="chevron-down" />
|
||||||
</template>
|
</template>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
:label="`${t('import.curl')}`"
|
:label="`${$t('import.curl')}`"
|
||||||
svg="file-code"
|
svg="file-code"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
@@ -84,7 +108,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
:label="`${t('show.code')}`"
|
:label="`${$t('show.code')}`"
|
||||||
svg="code-2"
|
svg="code-2"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
@@ -95,7 +119,7 @@
|
|||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
ref="clearAll"
|
ref="clearAll"
|
||||||
:label="`${t('action.clear_all')}`"
|
:label="`${$t('action.clear_all')}`"
|
||||||
svg="rotate-ccw"
|
svg="rotate-ccw"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
@@ -107,10 +131,10 @@
|
|||||||
</tippy>
|
</tippy>
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
class="ml-2 rounded rounded-r-none"
|
class="rounded rounded-r-none ml-2"
|
||||||
:label="
|
:label="
|
||||||
windowInnerWidth.x.value >= 768 && COLUMN_LAYOUT
|
windowInnerWidth.x.value >= 768 && COLUMN_LAYOUT
|
||||||
? `${t('request.save')}`
|
? `${$t('request.save')}`
|
||||||
: ''
|
: ''
|
||||||
"
|
"
|
||||||
filled
|
filled
|
||||||
@@ -135,27 +159,27 @@
|
|||||||
<input
|
<input
|
||||||
id="request-name"
|
id="request-name"
|
||||||
v-model="requestName"
|
v-model="requestName"
|
||||||
:placeholder="`${t('request.name')}`"
|
:placeholder="`${$t('request.name')}`"
|
||||||
name="request-name"
|
name="request-name"
|
||||||
type="text"
|
type="text"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
class="input mb-2"
|
class="mb-2 input"
|
||||||
@keyup.enter="saveOptions.tippy().hide()"
|
@keyup.enter="saveOptions.tippy().hide()"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
ref="copyRequest"
|
ref="copyRequest"
|
||||||
:label="shareButtonText"
|
:label="`${$t('request.copy_link')}`"
|
||||||
:svg="copyLinkIcon"
|
:svg="hasNavigatorShare ? 'share-2' : 'copy'"
|
||||||
:loading="fetchingShareLink"
|
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
copyRequest()
|
copyRequest()
|
||||||
|
saveOptions.tippy().hide()
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<SmartItem
|
<SmartItem
|
||||||
ref="saveRequest"
|
ref="saveRequest"
|
||||||
:label="`${t('request.save_as')}`"
|
:label="`${$t('request.save_as')}`"
|
||||||
svg="folder-plus"
|
svg="folder-plus"
|
||||||
@click.native="
|
@click.native="
|
||||||
() => {
|
() => {
|
||||||
@@ -184,9 +208,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||||
import { isRight } from "fp-ts/lib/Either"
|
import { isRight } from "fp-ts/lib/Either"
|
||||||
import * as E from "fp-ts/Either"
|
|
||||||
import {
|
import {
|
||||||
updateRESTResponse,
|
updateRESTResponse,
|
||||||
restEndpoint$,
|
restEndpoint$,
|
||||||
@@ -197,7 +220,6 @@ import {
|
|||||||
useRESTRequestName,
|
useRESTRequestName,
|
||||||
getRESTSaveContext,
|
getRESTSaveContext,
|
||||||
getRESTRequest,
|
getRESTRequest,
|
||||||
restRequest$,
|
|
||||||
} from "~/newstore/RESTSession"
|
} from "~/newstore/RESTSession"
|
||||||
import { editRESTRequest } from "~/newstore/collections"
|
import { editRESTRequest } from "~/newstore/collections"
|
||||||
import { runRESTRequest$ } from "~/helpers/RequestRunner"
|
import { runRESTRequest$ } from "~/helpers/RequestRunner"
|
||||||
@@ -205,9 +227,6 @@ import {
|
|||||||
useStreamSubscriber,
|
useStreamSubscriber,
|
||||||
useStream,
|
useStream,
|
||||||
useNuxt,
|
useNuxt,
|
||||||
useI18n,
|
|
||||||
useToast,
|
|
||||||
useReadonlyStream,
|
|
||||||
} from "~/helpers/utils/composables"
|
} from "~/helpers/utils/composables"
|
||||||
import { defineActionHandler } from "~/helpers/actions"
|
import { defineActionHandler } from "~/helpers/actions"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
@@ -215,9 +234,6 @@ import { useSetting } from "~/newstore/settings"
|
|||||||
import { overwriteRequestTeams } from "~/helpers/teams/utils"
|
import { overwriteRequestTeams } from "~/helpers/teams/utils"
|
||||||
import { apolloClient } from "~/helpers/apollo"
|
import { apolloClient } from "~/helpers/apollo"
|
||||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||||
import { createShortcode } from "~/helpers/backend/mutations/Shortcode"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const methods = [
|
const methods = [
|
||||||
"GET",
|
"GET",
|
||||||
@@ -232,9 +248,12 @@ const methods = [
|
|||||||
"CUSTOM",
|
"CUSTOM",
|
||||||
]
|
]
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
const nuxt = useNuxt()
|
const nuxt = useNuxt()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
const { subscribeToStream } = useStreamSubscriber()
|
const { subscribeToStream } = useStreamSubscriber()
|
||||||
|
|
||||||
const newEndpoint = useStream(restEndpoint$, "", setRESTEndpoint)
|
const newEndpoint = useStream(restEndpoint$, "", setRESTEndpoint)
|
||||||
@@ -263,11 +282,6 @@ watch(loading, () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const newSendRequest = async () => {
|
const newSendRequest = async () => {
|
||||||
if (newEndpoint.value === "" || /^\s+$/.test(newEndpoint.value)) {
|
|
||||||
toast.error(`${t("empty.endpoint")}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
// Double calling is because the function returns a TaskEither than should be executed
|
// Double calling is because the function returns a TaskEither than should be executed
|
||||||
@@ -313,46 +327,7 @@ const clearContent = () => {
|
|||||||
resetRESTRequest()
|
resetRESTRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyLinkIcon = hasNavigatorShare ? ref("share-2") : ref("copy")
|
const copyRequest = () => {
|
||||||
const shareLink = ref<string | null>("")
|
|
||||||
const fetchingShareLink = ref(false)
|
|
||||||
|
|
||||||
const shareButtonText = computed(() => {
|
|
||||||
if (shareLink.value) {
|
|
||||||
return shareLink.value
|
|
||||||
} else if (fetchingShareLink.value) {
|
|
||||||
return t("state.loading")
|
|
||||||
} else {
|
|
||||||
return t("request.copy_link")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const request = useReadonlyStream(restRequest$, getRESTRequest())
|
|
||||||
|
|
||||||
watch(request, () => {
|
|
||||||
shareLink.value = null
|
|
||||||
})
|
|
||||||
|
|
||||||
const copyRequest = async () => {
|
|
||||||
if (shareLink.value) {
|
|
||||||
copyShareLink(shareLink.value)
|
|
||||||
} else {
|
|
||||||
shareLink.value = ""
|
|
||||||
fetchingShareLink.value = true
|
|
||||||
const request = getRESTRequest()
|
|
||||||
const shortcodeResult = await createShortcode(request)()
|
|
||||||
if (E.isLeft(shortcodeResult)) {
|
|
||||||
toast.error(`${shortcodeResult.left.error}`)
|
|
||||||
shareLink.value = `${t("error.something_went_wrong")}`
|
|
||||||
} else if (E.isRight(shortcodeResult)) {
|
|
||||||
shareLink.value = `/${shortcodeResult.right.createShortcode.id}`
|
|
||||||
copyShareLink(shareLink.value)
|
|
||||||
}
|
|
||||||
fetchingShareLink.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const copyShareLink = (shareLink: string) => {
|
|
||||||
if (navigator.share) {
|
if (navigator.share) {
|
||||||
const time = new Date().toLocaleTimeString()
|
const time = new Date().toLocaleTimeString()
|
||||||
const date = new Date().toLocaleDateString()
|
const date = new Date().toLocaleDateString()
|
||||||
@@ -360,15 +335,15 @@ const copyShareLink = (shareLink: string) => {
|
|||||||
.share({
|
.share({
|
||||||
title: "Hoppscotch",
|
title: "Hoppscotch",
|
||||||
text: `Hoppscotch • Open source API development ecosystem at ${time} on ${date}`,
|
text: `Hoppscotch • Open source API development ecosystem at ${time} on ${date}`,
|
||||||
url: `https://hopp.sh/r${shareLink}`,
|
url: window.location.href,
|
||||||
})
|
})
|
||||||
.then(() => {})
|
.then(() => {})
|
||||||
.catch(() => {})
|
.catch(() => {})
|
||||||
} else {
|
} else {
|
||||||
copyLinkIcon.value = "check"
|
copyToClipboard(window.location.href)
|
||||||
copyToClipboard(`https://hopp.sh/r${shareLink}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
icon: "content_paste",
|
||||||
setTimeout(() => (copyLinkIcon.value = "copy"), 2000)
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,7 +382,9 @@ const saveRequest = () => {
|
|||||||
|
|
||||||
if (saveCtx.originLocation === "user-collection") {
|
if (saveCtx.originLocation === "user-collection") {
|
||||||
editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, getRESTRequest())
|
editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, getRESTRequest())
|
||||||
toast.success(`${t("request.saved")}`)
|
$toast.success(`${t("request.saved")}`, {
|
||||||
|
icon: "playlist_add_check",
|
||||||
|
})
|
||||||
} else if (saveCtx.originLocation === "team-collection") {
|
} else if (saveCtx.originLocation === "team-collection") {
|
||||||
const req = getRESTRequest()
|
const req = getRESTRequest()
|
||||||
|
|
||||||
@@ -420,14 +397,20 @@ const saveRequest = () => {
|
|||||||
saveCtx.requestID
|
saveCtx.requestID
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success(`${t("request.saved")}`)
|
$toast.success(`${t("request.saved")}`, {
|
||||||
|
icon: "playlist_add_check",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
toast.error(`${t("profile.no_permission")}`)
|
$toast.error(t("profile.no_permission").toString(), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showSaveRequestModal.value = true
|
showSaveRequestModal.value = true
|
||||||
toast.error(`${t("error.something_went_wrong")}`)
|
$toast.error(t("error.something_went_wrong").toString(), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="bg-primary flex p-4 top-0 z-10 sticky items-center">
|
||||||
class="bg-primary hide-scrollbar whitespace-nowrap sticky top-0 z-10 flex items-center p-4 overflow-auto"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-if="response == null"
|
v-if="response == null"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1"
|
class="
|
||||||
|
flex flex-col flex-1
|
||||||
|
text-secondaryLight
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="flex pb-4 my-4 space-x-2">
|
<div class="flex space-x-2 pb-4 my-4">
|
||||||
<div class="flex flex-col items-end space-y-4 text-right">
|
<div class="flex flex-col space-y-4 text-right items-end">
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.request.send_request") }}
|
{{ $t("shortcut.request.send_request") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.general.show_all") }}
|
{{ $t("shortcut.general.show_all") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.general.command_menu") }}
|
{{ $t("shortcut.general.command_menu") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="flex items-center flex-1">
|
<span class="flex flex-1 items-center">
|
||||||
{{ t("shortcut.general.help_menu") }}
|
{{ $t("shortcut.general.help_menu") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col space-y-4">
|
<div class="flex flex-col space-y-4">
|
||||||
@@ -39,8 +42,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
:label="t('app.documentation')"
|
:label="$t('app.documentation')"
|
||||||
to="https://docs.hoppscotch.io/features/response"
|
to="https://docs.hoppscotch.io"
|
||||||
svg="external-link"
|
svg="external-link"
|
||||||
blank
|
blank
|
||||||
outline
|
outline
|
||||||
@@ -53,41 +56,48 @@
|
|||||||
class="flex flex-col items-center justify-center"
|
class="flex flex-col items-center justify-center"
|
||||||
>
|
>
|
||||||
<SmartSpinner class="my-4" />
|
<SmartSpinner class="my-4" />
|
||||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="response.type === 'network_fail'"
|
v-if="response.type === 'network_fail'"
|
||||||
class="flex flex-col items-center justify-center flex-1 p-4"
|
class="flex flex-col flex-1 p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/youre_lost.svg`"
|
:src="`/images/states/${$colorMode.value}/youre_lost.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-32 h-32 my-4"
|
class="
|
||||||
:alt="`${t('error.network_fail')}`"
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-32
|
||||||
|
w-32
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
|
:alt="$t('empty.network_fail')"
|
||||||
/>
|
/>
|
||||||
<span class="mb-2 font-semibold text-center">
|
<span class="text-center font-semibold mb-2">
|
||||||
{{ t("error.network_fail") }}
|
{{ $t("error.network_fail") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-secondaryLight max-w-sm mb-4 text-center">
|
<span class="text-center text-secondaryLight mb-4 max-w-sm">
|
||||||
{{ t("helpers.network_fail") }}
|
{{ $t("helpers.network_fail") }}
|
||||||
</span>
|
</span>
|
||||||
<AppInterceptor />
|
<AppInterceptor />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="response.type === 'success' || 'fail'"
|
v-if="response.type === 'success' || 'fail'"
|
||||||
:class="statusCategory.className"
|
:class="statusCategory.className"
|
||||||
class="space-x-4 font-semibold"
|
class="font-semibold space-x-4"
|
||||||
>
|
>
|
||||||
<span v-if="response.statusCode">
|
<span v-if="response.statusCode">
|
||||||
<span class="text-secondary"> {{ t("response.status") }}: </span>
|
<span class="text-secondary"> {{ $t("response.status") }}: </span>
|
||||||
{{ response.statusCode || t("state.waiting_send_request") }}
|
{{ response.statusCode || $t("state.waiting_send_request") }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="response.meta && response.meta.responseDuration">
|
<span v-if="response.meta && response.meta.responseDuration">
|
||||||
<span class="text-secondary"> {{ t("response.time") }}: </span>
|
<span class="text-secondary"> {{ $t("response.time") }}: </span>
|
||||||
{{ `${response.meta.responseDuration} ms` }}
|
{{ `${response.meta.responseDuration} ms` }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="response.meta && response.meta.responseSize">
|
<span v-if="response.meta && response.meta.responseSize">
|
||||||
<span class="text-secondary"> {{ t("response.size") }}: </span>
|
<span class="text-secondary"> {{ $t("response.size") }}: </span>
|
||||||
{{ `${response.meta.responseSize} B` }}
|
{{ `${response.meta.responseSize} B` }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,9 +110,6 @@ import { computed } from "@nuxtjs/composition-api"
|
|||||||
import findStatusGroup from "~/helpers/findStatusGroup"
|
import findStatusGroup from "~/helpers/findStatusGroup"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
|
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
response: HoppRESTResponse
|
response: HoppRESTResponse
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection :label="`${t('test.results')}`">
|
<AppSection :label="`${$t('test.results')}`">
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="
|
||||||
testResults &&
|
testResults &&
|
||||||
@@ -7,14 +7,24 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-dividerLight border-b
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("test.report") }}
|
{{ $t("test.report") }}
|
||||||
</label>
|
</label>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear')"
|
:title="$t('action.clear')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent()"
|
@click.native="clearContent()"
|
||||||
/>
|
/>
|
||||||
@@ -38,10 +48,10 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(result, index) in testResults.expectResults"
|
v-for="(result, index) in testResults.expectResults"
|
||||||
:key="`result-${index}`"
|
:key="`result-${index}`"
|
||||||
class="flex items-center px-4 py-2"
|
class="flex py-2 px-4 items-center"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="material-icons mr-4"
|
class="mr-4 material-icons"
|
||||||
:class="
|
:class="
|
||||||
result.status === 'pass' ? 'text-green-500' : 'text-red-500'
|
result.status === 'pass' ? 'text-green-500' : 'text-red-500'
|
||||||
"
|
"
|
||||||
@@ -54,7 +64,9 @@
|
|||||||
<span class="text-secondaryLight">
|
<span class="text-secondaryLight">
|
||||||
{{
|
{{
|
||||||
` \xA0 — \xA0 ${
|
` \xA0 — \xA0 ${
|
||||||
result.status === "pass" ? t("test.passed") : t("test.failed")
|
result.status === "pass"
|
||||||
|
? $t("test.passed")
|
||||||
|
: $t("test.failed")
|
||||||
}`
|
}`
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
@@ -64,24 +76,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/validation.svg`"
|
:src="`/images/states/${$colorMode.value}/validation.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||||
:alt="`${t('empty.tests')}`"
|
:alt="$t('empty.tests')"
|
||||||
/>
|
/>
|
||||||
<span class="pb-2 text-center">
|
<span class="text-center pb-2">
|
||||||
{{ t("empty.tests") }}
|
{{ $t("empty.tests") }}
|
||||||
</span>
|
</span>
|
||||||
<span class="pb-4 text-center">
|
<span class="text-center pb-4">
|
||||||
{{ t("helpers.tests") }}
|
{{ $t("helpers.tests") }}
|
||||||
</span>
|
</span>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
outline
|
outline
|
||||||
:label="`${t('action.learn_more')}`"
|
:label="`${$t('action.learn_more')}`"
|
||||||
to="https://docs.hoppscotch.io/features/tests"
|
to="https://docs.hoppscotch.io"
|
||||||
blank
|
blank
|
||||||
svg="external-link"
|
svg="external-link"
|
||||||
reverse
|
reverse
|
||||||
@@ -92,11 +104,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useReadonlyStream, useI18n } from "~/helpers/utils/composables"
|
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||||
import { restTestResults$, setRESTTestResults } from "~/newstore/RESTSession"
|
import { restTestResults$, setRESTTestResults } from "~/newstore/RESTSession"
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const testResults = useReadonlyStream(restTestResults$, null)
|
const testResults = useReadonlyStream(restTestResults$, null)
|
||||||
|
|
||||||
const clearContent = () => setRESTTestResults(null)
|
const clearContent = () => setRESTTestResults(null)
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
<div>
|
<div>
|
||||||
<span
|
<span
|
||||||
v-if="testResults.description"
|
v-if="testResults.description"
|
||||||
class="flex items-center px-4 py-2 font-bold text-secondaryDark"
|
class="flex font-bold text-secondaryDark py-2 px-4 items-center"
|
||||||
>
|
>
|
||||||
{{ testResults.description }}
|
{{ testResults.description }}
|
||||||
</span>
|
</span>
|
||||||
<div v-if="testResults.expectResults" class="divide-dividerLight divide-y">
|
<div v-if="testResults.expectResults" class="divide-y divide-dividerLight">
|
||||||
<HttpTestResultReport
|
<HttpTestResultReport
|
||||||
v-if="testResults.expectResults.length"
|
v-if="testResults.expectResults.length"
|
||||||
:test-results="testResults"
|
:test-results="testResults"
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(result, index) in testResults.expectResults"
|
v-for="(result, index) in testResults.expectResults"
|
||||||
:key="`result-${index}`"
|
:key="`result-${index}`"
|
||||||
class="flex items-center px-4 py-2"
|
class="flex py-2 px-4 items-center"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="mr-4 material-icons"
|
class="mr-4 material-icons"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center p-2">
|
<div class="flex p-2 items-center">
|
||||||
<SmartProgressRing
|
<SmartProgressRing
|
||||||
class="text-red-500"
|
class="text-red-500"
|
||||||
:radius="16"
|
:radius="16"
|
||||||
|
|||||||
@@ -1,51 +1,71 @@
|
|||||||
<template>
|
<template>
|
||||||
<AppSection id="script" :label="`${t('test.script')}`">
|
<AppSection id="script" :label="`${$t('test.script')}`">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("test.javascript_code") }}
|
{{ $t("test.javascript_code") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
to="https://docs.hoppscotch.io/features/tests"
|
to="https://docs.hoppscotch.io/features/tests"
|
||||||
blank
|
blank
|
||||||
:title="t('app.wiki')"
|
:title="$t('app.wiki')"
|
||||||
svg="help-circle"
|
svg="help-circle"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
/>
|
/>
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.clear')"
|
:title="$t('action.clear')"
|
||||||
svg="trash-2"
|
svg="trash-2"
|
||||||
@click.native="clearContent"
|
@click.native="clearContent"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="border-dividerLight flex border-b">
|
<div class="border-b border-dividerLight flex">
|
||||||
<div class="border-dividerLight w-2/3 border-r">
|
<div class="border-r border-dividerLight w-2/3">
|
||||||
<div ref="testScriptEditor"></div>
|
<div ref="testScriptEditor"></div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
class="
|
||||||
|
bg-primary
|
||||||
|
h-full
|
||||||
|
top-upperTertiaryStickyFold
|
||||||
|
min-w-46
|
||||||
|
max-w-1/3
|
||||||
|
p-4
|
||||||
|
z-9
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div class="text-secondaryLight pb-2">
|
<div class="text-secondaryLight pb-2">
|
||||||
{{ t("helpers.post_request_tests") }}
|
{{ $t("helpers.post_request_tests") }}
|
||||||
</div>
|
</div>
|
||||||
<SmartAnchor
|
<SmartAnchor
|
||||||
:label="`${t('test.learn')}`"
|
:label="`${$t('test.learn')}`"
|
||||||
to="https://docs.hoppscotch.io/features/tests"
|
to="https://docs.hoppscotch.io/features/tests"
|
||||||
blank
|
blank
|
||||||
/>
|
/>
|
||||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
<h4 class="font-bold text-secondaryLight pt-6">
|
||||||
{{ t("test.snippets") }}
|
{{ $t("test.snippets") }}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="flex flex-col pt-4">
|
<div class="flex flex-col pt-4">
|
||||||
<TabSecondary
|
<TabSecondary
|
||||||
@@ -62,15 +82,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||||
import { useTestScript } from "~/newstore/RESTSession"
|
import { useTestScript } from "~/newstore/RESTSession"
|
||||||
import testSnippets from "~/helpers/testSnippets"
|
import testSnippets from "~/helpers/testSnippets"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import linter from "~/helpers/editor/linting/testScript"
|
import linter from "~/helpers/editor/linting/testScript"
|
||||||
import completer from "~/helpers/editor/completion/testScript"
|
import completer from "~/helpers/editor/completion/testScript"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
const {
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const testScript = useTestScript()
|
const testScript = useTestScript()
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("request.header_list") }}
|
{{ $t("request.header_list") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="headers"
|
v-if="headers"
|
||||||
ref="copyHeaders"
|
ref="copyHeaders"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyIcon"
|
:svg="copyIcon"
|
||||||
@click.native="copyHeaders"
|
@click.native="copyHeaders"
|
||||||
/>
|
/>
|
||||||
@@ -20,19 +30,38 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(header, index) in headers"
|
v-for="(header, index) in headers"
|
||||||
:key="`header-${index}`"
|
:key="`header-${index}`"
|
||||||
class="divide-dividerLight border-dividerLight group flex border-b divide-x"
|
class="
|
||||||
|
divide-x divide-dividerLight
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex
|
||||||
|
group
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
class="
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span class="truncate rounded-sm select-all">
|
<span class="rounded-sm select-all truncate">
|
||||||
{{ header.key }}
|
{{ header.key }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
class="
|
||||||
|
flex flex-1
|
||||||
|
min-w-0
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
transition
|
||||||
|
group-hover:text-secondaryDark
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<span class="truncate rounded-sm select-all">
|
<span class="rounded-sm select-all truncate">
|
||||||
{{ header.value }}
|
{{ header.value }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
@@ -40,26 +69,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script>
|
||||||
import { ref } from "@nuxtjs/composition-api"
|
import { defineComponent } from "@nuxtjs/composition-api"
|
||||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
export default defineComponent({
|
||||||
|
props: {
|
||||||
const toast = useToast()
|
headers: { type: Array, default: () => [] },
|
||||||
|
},
|
||||||
const props = defineProps<{
|
data() {
|
||||||
headers: Array<HoppRESTHeader>
|
return {
|
||||||
}>()
|
copyIcon: "copy",
|
||||||
|
}
|
||||||
const copyIcon = ref("copy")
|
},
|
||||||
|
methods: {
|
||||||
const copyHeaders = () => {
|
copyHeaders() {
|
||||||
copyToClipboard(JSON.stringify(props.headers))
|
copyToClipboard(JSON.stringify(this.headers))
|
||||||
copyIcon.value = "check"
|
this.copyIcon = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
this.$toast.success(this.$t("state.copied_to_clipboard"), {
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
icon: "content_paste",
|
||||||
}
|
})
|
||||||
|
setTimeout(() => (this.copyIcon = "copy"), 1000)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col flex-1">
|
<div class="flex flex-col flex-1">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("response.body") }}
|
{{ $t("response.body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -19,7 +29,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="
|
:title="
|
||||||
previewEnabled ? t('hide.preview') : t('response.preview_html')
|
previewEnabled ? $t('hide.preview') : $t('response.preview_html')
|
||||||
"
|
"
|
||||||
:svg="!previewEnabled ? 'eye' : 'eye-off'"
|
:svg="!previewEnabled ? 'eye' : 'eye-off'"
|
||||||
@click.native.prevent="togglePreview"
|
@click.native.prevent="togglePreview"
|
||||||
@@ -28,7 +38,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="downloadResponse"
|
ref="downloadResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadIcon"
|
:svg="downloadIcon"
|
||||||
@click.native="downloadResponse"
|
@click.native="downloadResponse"
|
||||||
/>
|
/>
|
||||||
@@ -36,7 +46,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="copyResponse"
|
ref="copyResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyIcon"
|
:svg="copyIcon"
|
||||||
@click.native="copyResponse"
|
@click.native="copyResponse"
|
||||||
/>
|
/>
|
||||||
@@ -54,19 +64,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
response: HoppRESTResponse
|
response: HoppRESTResponse
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const responseBodyText = computed(() => {
|
const responseBodyText = computed(() => {
|
||||||
if (
|
if (
|
||||||
@@ -116,7 +127,9 @@ const downloadResponse = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadIcon.value = "check"
|
downloadIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
@@ -127,7 +140,9 @@ const downloadResponse = () => {
|
|||||||
const copyResponse = () => {
|
const copyResponse = () => {
|
||||||
copyToClipboard(responseBodyText.value)
|
copyToClipboard(responseBodyText.value)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("response.body") }}
|
{{ $t("response.body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -18,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<img
|
<img
|
||||||
class="border-dividerLight flex flex-1 max-w-full border-b"
|
class="border-b border-dividerLight flex max-w-full flex-1"
|
||||||
:src="imageSource"
|
:src="imageSource"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
:alt="imageSource"
|
:alt="imageSource"
|
||||||
@@ -93,7 +103,9 @@ export default defineComponent({
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
this.downloadIcon = "check"
|
this.downloadIcon = "check"
|
||||||
this.$toast.success(this.$t("state.download_started"))
|
this.$toast.success(this.$t("state.download_started"), {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">{{
|
<label class="font-semibold text-secondaryLight">{{
|
||||||
t("response.body")
|
$t("response.body")
|
||||||
}}</label>
|
}}</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -19,7 +29,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="downloadResponse"
|
ref="downloadResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadIcon"
|
:svg="downloadIcon"
|
||||||
@click.native="downloadResponse"
|
@click.native="downloadResponse"
|
||||||
/>
|
/>
|
||||||
@@ -27,7 +37,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="copyResponse"
|
ref="copyResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyIcon"
|
:svg="copyIcon"
|
||||||
@click.native="copyResponse"
|
@click.native="copyResponse"
|
||||||
/>
|
/>
|
||||||
@@ -36,7 +46,17 @@
|
|||||||
<div ref="jsonResponse"></div>
|
<div ref="jsonResponse"></div>
|
||||||
<div
|
<div
|
||||||
v-if="outlinePath"
|
v-if="outlinePath"
|
||||||
class="bg-primaryLight border-dividerLight flex-nowrap hide-scrollbar sticky bottom-0 z-10 flex flex-1 px-2 overflow-auto border-t"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border-t border-dividerLight
|
||||||
|
flex flex-nowrap flex-1
|
||||||
|
px-2
|
||||||
|
bottom-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
overflow-auto
|
||||||
|
hide-scrollbar
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="(item, index) in outlinePath"
|
v-for="(item, index) in outlinePath"
|
||||||
@@ -115,7 +135,7 @@
|
|||||||
</tippy>
|
</tippy>
|
||||||
<i
|
<i
|
||||||
v-if="index + 1 !== outlinePath.length"
|
v-if="index + 1 !== outlinePath.length"
|
||||||
class="text-secondaryLight material-icons opacity-50"
|
class="text-secondaryLight opacity-50 material-icons"
|
||||||
>chevron_right</i
|
>chevron_right</i
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -124,7 +144,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
@@ -134,15 +154,16 @@ import {
|
|||||||
convertIndexToLineCh,
|
convertIndexToLineCh,
|
||||||
convertLineChToIndex,
|
convertLineChToIndex,
|
||||||
} from "~/helpers/editor/utils"
|
} from "~/helpers/editor/utils"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
response: HoppRESTResponse
|
response: HoppRESTResponse
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const responseBodyText = computed(() => {
|
const responseBodyText = computed(() => {
|
||||||
if (
|
if (
|
||||||
@@ -213,7 +234,9 @@ const downloadResponse = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadIcon.value = "check"
|
downloadIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
@@ -233,7 +256,9 @@ const outlinePath = computed(() => {
|
|||||||
const copyResponse = () => {
|
const copyResponse = () => {
|
||||||
copyToClipboard(responseBodyText.value)
|
copyToClipboard(responseBodyText.value)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("response.body") }}
|
{{ $t("response.body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -19,7 +29,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="downloadResponse"
|
ref="downloadResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadIcon"
|
:svg="downloadIcon"
|
||||||
@click.native="downloadResponse"
|
@click.native="downloadResponse"
|
||||||
/>
|
/>
|
||||||
@@ -27,7 +37,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="copyResponse"
|
ref="copyResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyIcon"
|
:svg="copyIcon"
|
||||||
@click.native="copyResponse"
|
@click.native="copyResponse"
|
||||||
/>
|
/>
|
||||||
@@ -38,19 +48,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, reactive } from "@nuxtjs/composition-api"
|
import { ref, useContext, computed, reactive } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
response: HoppRESTResponse
|
response: HoppRESTResponse
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const responseBodyText = computed(() => {
|
const responseBodyText = computed(() => {
|
||||||
if (
|
if (
|
||||||
@@ -106,7 +117,9 @@ const downloadResponse = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadIcon.value = "check"
|
downloadIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
@@ -117,7 +130,9 @@ const downloadResponse = () => {
|
|||||||
const copyResponse = () => {
|
const copyResponse = () => {
|
||||||
copyToClipboard(responseBodyText.value)
|
copyToClipboard(responseBodyText.value)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-lowerSecondaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ t("response.body") }}
|
{{ $t("response.body") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<ButtonSecondary
|
<ButtonSecondary
|
||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('state.linewrap')"
|
:title="$t('state.linewrap')"
|
||||||
:class="{ '!text-accent': linewrapEnabled }"
|
:class="{ '!text-accent': linewrapEnabled }"
|
||||||
svg="corner-down-left"
|
svg="corner-down-left"
|
||||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||||
@@ -19,7 +29,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="downloadResponse"
|
ref="downloadResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.download_file')"
|
:title="$t('action.download_file')"
|
||||||
:svg="downloadIcon"
|
:svg="downloadIcon"
|
||||||
@click.native="downloadResponse"
|
@click.native="downloadResponse"
|
||||||
/>
|
/>
|
||||||
@@ -27,7 +37,7 @@
|
|||||||
v-if="response.body"
|
v-if="response.body"
|
||||||
ref="copyResponse"
|
ref="copyResponse"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t('action.copy')"
|
:title="$t('action.copy')"
|
||||||
:svg="copyIcon"
|
:svg="copyIcon"
|
||||||
@click.native="copyResponse"
|
@click.native="copyResponse"
|
||||||
/>
|
/>
|
||||||
@@ -38,19 +48,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
response: HoppRESTResponse
|
response: HoppRESTResponse
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const toast = useToast()
|
const {
|
||||||
|
$toast,
|
||||||
|
app: { i18n },
|
||||||
|
} = useContext()
|
||||||
|
const t = i18n.t.bind(i18n)
|
||||||
|
|
||||||
const responseBodyText = computed(() => {
|
const responseBodyText = computed(() => {
|
||||||
if (
|
if (
|
||||||
@@ -106,7 +117,9 @@ const downloadResponse = () => {
|
|||||||
document.body.appendChild(a)
|
document.body.appendChild(a)
|
||||||
a.click()
|
a.click()
|
||||||
downloadIcon.value = "check"
|
downloadIcon.value = "check"
|
||||||
toast.success(`${t("state.download_started")}`)
|
$toast.success(`${t("state.download_started")}`, {
|
||||||
|
icon: "downloading",
|
||||||
|
})
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
document.body.removeChild(a)
|
document.body.removeChild(a)
|
||||||
URL.revokeObjectURL(url)
|
URL.revokeObjectURL(url)
|
||||||
@@ -117,7 +130,9 @@ const downloadResponse = () => {
|
|||||||
const copyResponse = () => {
|
const copyResponse = () => {
|
||||||
copyToClipboard(responseBodyText.value)
|
copyToClipboard(responseBodyText.value)
|
||||||
copyIcon.value = "check"
|
copyIcon.value = "check"
|
||||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||||
|
icon: "content_paste",
|
||||||
|
})
|
||||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,15 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="relative flex items-center justify-center w-5 h-5 cursor-pointer">
|
<div class="cursor-pointer flex h-5 w-5 relative items-center justify-center">
|
||||||
<img
|
<img
|
||||||
class="bg-primaryDark absolute object-cover object-center w-5 h-5 transition rounded-full"
|
class="
|
||||||
|
bg-primaryDark bg-primaryLight
|
||||||
|
rounded-full
|
||||||
|
object-cover object-center
|
||||||
|
h-5
|
||||||
|
transition
|
||||||
|
w-5
|
||||||
|
absolute
|
||||||
|
"
|
||||||
:src="url"
|
:src="url"
|
||||||
:alt="alt"
|
:alt="alt"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
<div class="absolute inset-0 rounded-full shadow-inner"></div>
|
<div class="rounded-full shadow-inner inset-0 absolute"></div>
|
||||||
<span
|
<span
|
||||||
v-if="indicator"
|
v-if="indicator"
|
||||||
class="border-primary rounded-full border-2 h-2.5 -top-0.5 -right-0.5 w-2.5 absolute"
|
class="
|
||||||
|
border-primary
|
||||||
|
rounded-full
|
||||||
|
border-2
|
||||||
|
h-2.5
|
||||||
|
-top-0.5
|
||||||
|
-right-0.5
|
||||||
|
w-2.5
|
||||||
|
absolute
|
||||||
|
"
|
||||||
:class="indicatorStyles"
|
:class="indicatorStyles"
|
||||||
></span>
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
pl-4
|
||||||
|
top-0
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label for="log" class="text-secondaryLight py-2 font-semibold">
|
<label for="log" class="font-semibold text-secondaryLight py-2">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,7 +26,7 @@
|
|||||||
>{{ entry.ts }}{{ source(entry.source) }}{{ entry.payload }}</span
|
>{{ entry.ts }}{{ source(entry.source) }}{{ entry.payload }}</span
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
<span v-else>{{ t("response.waiting_for_connection") }}</span>
|
<span v-else>{{ $t("response.waiting_for_connection") }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -24,9 +34,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { nextTick, ref, watch } from "@nuxtjs/composition-api"
|
import { nextTick, ref, watch } from "@nuxtjs/composition-api"
|
||||||
import { getSourcePrefix as source } from "~/helpers/utils/string"
|
import { getSourcePrefix as source } from "~/helpers/utils/string"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
log: { type: Array, default: () => [] },
|
log: { type: Array, default: () => [] },
|
||||||
|
|||||||
@@ -9,22 +9,30 @@
|
|||||||
>
|
>
|
||||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="request">
|
<AppSection label="request">
|
||||||
<div
|
<div
|
||||||
class="bg-primary sticky top-0 z-10 flex flex-col p-4 space-y-4"
|
class="bg-primary flex flex-col space-y-4 p-4 top-0 z-10 sticky"
|
||||||
>
|
>
|
||||||
<div class="inline-flex flex-1 space-x-2">
|
<div class="space-x-2 flex-1 inline-flex">
|
||||||
<input
|
<input
|
||||||
id="mqtt-url"
|
id="mqtt-url"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
type="url"
|
type="url"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
:placeholder="$t('mqtt.url')"
|
:placeholder="$t('mqtt.url')"
|
||||||
:disabled="connectionState"
|
:disabled="connectionState"
|
||||||
@keyup.enter="validUrl ? toggleConnection() : null"
|
@keyup.enter="validUrl ? toggleConnection() : null"
|
||||||
@@ -63,10 +71,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="response">
|
<AppSection label="response">
|
||||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||||
</AppSection>
|
</AppSection>
|
||||||
@@ -80,8 +85,8 @@
|
|||||||
class="hide-scrollbar !overflow-auto"
|
class="hide-scrollbar !overflow-auto"
|
||||||
>
|
>
|
||||||
<AppSection label="messages">
|
<AppSection label="messages">
|
||||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||||
<label for="pub_topic" class="text-secondaryLight font-semibold">
|
<label for="pub_topic" class="font-semibold text-secondaryLight">
|
||||||
{{ $t("mqtt.topic") }}
|
{{ $t("mqtt.topic") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -96,12 +101,12 @@
|
|||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between flex-1 p-4">
|
<div class="flex flex-1 p-4 items-center justify-between">
|
||||||
<label for="mqtt-message" class="text-secondaryLight font-semibold">
|
<label for="mqtt-message" class="font-semibold text-secondaryLight">
|
||||||
{{ $t("mqtt.communication") }}
|
{{ $t("mqtt.communication") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex px-4 space-x-2">
|
<div class="flex space-x-2 px-4">
|
||||||
<input
|
<input
|
||||||
id="mqtt-message"
|
id="mqtt-message"
|
||||||
v-model="msg"
|
v-model="msg"
|
||||||
@@ -120,13 +125,19 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="border-dividerLight flex inline-flex flex-col flex-1 p-4 mt-4 border-t"
|
class="
|
||||||
|
border-t border-dividerLight
|
||||||
|
flex flex-col flex-1
|
||||||
|
mt-4
|
||||||
|
p-4
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label for="sub_topic" class="text-secondaryLight font-semibold">
|
<label for="sub_topic" class="font-semibold text-secondaryLight">
|
||||||
{{ $t("mqtt.topic") }}
|
{{ $t("mqtt.topic") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex px-4 space-x-2">
|
<div class="flex space-x-2 px-4">
|
||||||
<input
|
<input
|
||||||
id="sub_topic"
|
id="sub_topic"
|
||||||
v-model="sub_topic"
|
v-model="sub_topic"
|
||||||
@@ -277,7 +288,9 @@ export default defineComponent({
|
|||||||
color: "var(--accent-color)",
|
color: "var(--accent-color)",
|
||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
})
|
})
|
||||||
this.$toast.success(this.$t("state.connected"))
|
this.$toast.success(this.$t("state.connected"), {
|
||||||
|
icon: "sync",
|
||||||
|
})
|
||||||
},
|
},
|
||||||
onMessageArrived({ payloadString, destinationName }) {
|
onMessageArrived({ payloadString, destinationName }) {
|
||||||
this.log.push({
|
this.log.push({
|
||||||
@@ -308,9 +321,13 @@ export default defineComponent({
|
|||||||
this.connectingState = false
|
this.connectingState = false
|
||||||
this.connectionState = false
|
this.connectionState = false
|
||||||
if (this.manualDisconnect) {
|
if (this.manualDisconnect) {
|
||||||
this.$toast.error(this.$t("state.disconnected"))
|
this.$toast.error(this.$t("state.disconnected"), {
|
||||||
|
icon: "sync_disabled",
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.manualDisconnect = false
|
this.manualDisconnect = false
|
||||||
this.subscriptionState = false
|
this.subscriptionState = false
|
||||||
|
|||||||
@@ -9,13 +9,10 @@
|
|||||||
>
|
>
|
||||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="request">
|
<AppSection label="request">
|
||||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||||
<div class="inline-flex flex-1 space-x-2">
|
<div class="space-x-2 flex-1 inline-flex">
|
||||||
<div class="flex flex-1">
|
<div class="flex flex-1">
|
||||||
<label for="client-version">
|
<label for="client-version">
|
||||||
<tippy
|
<tippy
|
||||||
@@ -31,7 +28,21 @@
|
|||||||
id="client-version"
|
id="client-version"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
title="socket.io-client version"
|
title="socket.io-client version"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark w-26 hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex px-4 py-2 font-semibold border rounded-l cursor-pointer"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded-l
|
||||||
|
cursor-pointer
|
||||||
|
flex
|
||||||
|
font-semibold
|
||||||
|
text-secondaryDark
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
w-26
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
:value="`Client ${clientVersion}`"
|
:value="`Client ${clientVersion}`"
|
||||||
readonly
|
readonly
|
||||||
:disabled="connectionState"
|
:disabled="connectionState"
|
||||||
@@ -53,7 +64,18 @@
|
|||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
:class="{ error: !urlValid }"
|
:class="{ error: !urlValid }"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
flex flex-1
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
:placeholder="$t('socketio.url')"
|
:placeholder="$t('socketio.url')"
|
||||||
:disabled="connectionState"
|
:disabled="connectionState"
|
||||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||||
@@ -61,7 +83,19 @@
|
|||||||
<input
|
<input
|
||||||
id="socketio-path"
|
id="socketio-path"
|
||||||
v-model="path"
|
v-model="path"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-r"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded-r
|
||||||
|
flex flex-1
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
:disabled="connectionState"
|
:disabled="connectionState"
|
||||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||||
@@ -84,10 +118,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="response">
|
<AppSection label="response">
|
||||||
<RealtimeLog :title="$t('socketio.log')" :log="communication.log" />
|
<RealtimeLog :title="$t('socketio.log')" :log="communication.log" />
|
||||||
</AppSection>
|
</AppSection>
|
||||||
@@ -101,8 +132,8 @@
|
|||||||
class="hide-scrollbar !overflow-auto"
|
class="hide-scrollbar !overflow-auto"
|
||||||
>
|
>
|
||||||
<AppSection label="messages">
|
<AppSection label="messages">
|
||||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||||
<label for="events" class="text-secondaryLight font-semibold">
|
<label for="events" class="font-semibold text-secondaryLight">
|
||||||
{{ $t("socketio.events") }}
|
{{ $t("socketio.events") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -118,8 +149,8 @@
|
|||||||
:disabled="!connectionState"
|
:disabled="!connectionState"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between flex-1 p-4">
|
<div class="flex flex-1 p-4 items-center justify-between">
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("socketio.communication") }}
|
{{ $t("socketio.communication") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -132,7 +163,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col px-4 pb-4 space-y-2">
|
<div class="flex flex-col space-y-2 px-4 pb-4">
|
||||||
<div
|
<div
|
||||||
v-for="(input, index) of communication.inputs"
|
v-for="(input, index) of communication.inputs"
|
||||||
:key="`input-${index}`"
|
:key="`input-${index}`"
|
||||||
@@ -294,7 +325,9 @@ export default defineComponent({
|
|||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.$toast.success(this.$t("state.connected"))
|
this.$toast.success(this.$t("state.connected"), {
|
||||||
|
icon: "sync",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
this.io.on("*", ({ data }) => {
|
this.io.on("*", ({ data }) => {
|
||||||
const [eventName, message] = data
|
const [eventName, message] = data
|
||||||
@@ -322,11 +355,15 @@ export default defineComponent({
|
|||||||
color: "#ff5555",
|
color: "#ff5555",
|
||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
})
|
})
|
||||||
this.$toast.error(this.$t("state.disconnected"))
|
this.$toast.error(this.$t("state.disconnected"), {
|
||||||
|
icon: "sync_disabled",
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleError(e)
|
this.handleError(e)
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
logHoppRequestRunToAnalytics({
|
logHoppRequestRunToAnalytics({
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||||
<Pane :size="COLUMN_LAYOUT ? 45 : 50" class="hide-scrollbar !overflow-auto">
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||||
<div class="inline-flex flex-1 space-x-2">
|
<div class="space-x-2 flex-1 inline-flex">
|
||||||
<div class="flex flex-1">
|
<div class="flex flex-1">
|
||||||
<input
|
<input
|
||||||
id="server"
|
id="server"
|
||||||
@@ -10,21 +10,51 @@
|
|||||||
type="url"
|
type="url"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:class="{ error: !serverValid }"
|
:class="{ error: !serverValid }"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-l"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded-l
|
||||||
|
flex flex-1
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
:placeholder="$t('sse.url')"
|
:placeholder="$t('sse.url')"
|
||||||
:disabled="connectionSSEState"
|
:disabled="connectionSSEState"
|
||||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
for="event-type"
|
for="event-type"
|
||||||
class="bg-primaryLight border-divider text-secondaryLight px-4 py-2 font-semibold truncate border-t border-b"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border-t border-b border-divider
|
||||||
|
font-semibold
|
||||||
|
text-secondaryLight
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
truncate
|
||||||
|
"
|
||||||
>
|
>
|
||||||
{{ $t("sse.event_type") }}
|
{{ $t("sse.event_type") }}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
id="event-type"
|
id="event-type"
|
||||||
v-model="eventType"
|
v-model="eventType"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark flex flex-1 w-full px-4 py-2 border rounded-r"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded-r
|
||||||
|
flex flex-1
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
:disabled="connectionSSEState"
|
:disabled="connectionSSEState"
|
||||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||||
@@ -44,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane :size="COLUMN_LAYOUT ? 65 : 50" class="hide-scrollbar !overflow-auto">
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
<AppSection label="response">
|
<AppSection label="response">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
@@ -141,7 +171,9 @@ export default defineComponent({
|
|||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.$toast.success(this.$t("state.connected"))
|
this.$toast.success(this.$t("state.connected"), {
|
||||||
|
icon: "sync",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.sse.onerror = () => {
|
this.sse.onerror = () => {
|
||||||
this.handleSSEError()
|
this.handleSSEError()
|
||||||
@@ -156,7 +188,9 @@ export default defineComponent({
|
|||||||
color: "#ff5555",
|
color: "#ff5555",
|
||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
})
|
})
|
||||||
this.$toast.error(this.$t("state.disconnected"))
|
this.$toast.error(this.$t("state.disconnected"), {
|
||||||
|
icon: "sync_disabled",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.sse.addEventListener(this.eventType, ({ data }) => {
|
this.sse.addEventListener(this.eventType, ({ data }) => {
|
||||||
this.events.log.push({
|
this.events.log.push({
|
||||||
@@ -167,7 +201,9 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleSSEError(e)
|
this.handleSSEError(e)
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.events.log = [
|
this.events.log = [
|
||||||
|
|||||||
@@ -9,17 +9,25 @@
|
|||||||
>
|
>
|
||||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="request">
|
<AppSection label="request">
|
||||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||||
<div class="inline-flex flex-1 space-x-2">
|
<div class="space-x-2 flex-1 inline-flex">
|
||||||
<input
|
<input
|
||||||
id="websocket-url"
|
id="websocket-url"
|
||||||
v-model="url"
|
v-model="url"
|
||||||
class="bg-primaryLight border-divider text-secondaryDark hover:border-dividerDark focus-visible:bg-transparent focus-visible:border-dividerDark w-full px-4 py-2 border rounded"
|
class="
|
||||||
|
bg-primaryLight
|
||||||
|
border border-divider
|
||||||
|
rounded
|
||||||
|
text-secondaryDark
|
||||||
|
w-full
|
||||||
|
py-2
|
||||||
|
px-4
|
||||||
|
hover:border-dividerDark
|
||||||
|
focus-visible:bg-transparent
|
||||||
|
focus-visible:border-dividerDark
|
||||||
|
"
|
||||||
type="url"
|
type="url"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
@@ -44,9 +52,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="bg-primary border-dividerLight top-upperPrimaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
class="
|
||||||
|
bg-primary
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex flex-1
|
||||||
|
top-upperPrimaryStickyFold
|
||||||
|
pl-4
|
||||||
|
z-10
|
||||||
|
sticky
|
||||||
|
items-center
|
||||||
|
justify-between
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<label class="text-secondaryLight font-semibold">
|
<label class="font-semibold text-secondaryLight">
|
||||||
{{ $t("websocket.protocols") }}
|
{{ $t("websocket.protocols") }}
|
||||||
</label>
|
</label>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -67,11 +85,15 @@
|
|||||||
<div
|
<div
|
||||||
v-for="(protocol, index) of protocols"
|
v-for="(protocol, index) of protocols"
|
||||||
:key="`protocol-${index}`"
|
:key="`protocol-${index}`"
|
||||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
class="
|
||||||
|
divide-x divide-dividerLight
|
||||||
|
border-b border-dividerLight
|
||||||
|
flex
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-model="protocol.value"
|
v-model="protocol.value"
|
||||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
class="bg-transparent flex flex-1 py-2 px-4"
|
||||||
:placeholder="$t('count.protocol', { count: index + 1 })"
|
:placeholder="$t('count.protocol', { count: index + 1 })"
|
||||||
name="message"
|
name="message"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -114,24 +136,34 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="protocols.length === 0"
|
v-if="protocols.length === 0"
|
||||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
class="
|
||||||
|
flex flex-col
|
||||||
|
text-secondaryLight
|
||||||
|
p-4
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
class="
|
||||||
|
flex-col
|
||||||
|
my-4
|
||||||
|
object-contain object-center
|
||||||
|
h-16
|
||||||
|
w-16
|
||||||
|
inline-flex
|
||||||
|
"
|
||||||
:alt="$t('empty.protocols')"
|
:alt="$t('empty.protocols')"
|
||||||
/>
|
/>
|
||||||
<span class="mb-4 text-center">
|
<span class="text-center mb-4">
|
||||||
{{ $t("empty.protocols") }}
|
{{ $t("empty.protocols") }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</AppSection>
|
</AppSection>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane
|
<Pane class="hide-scrollbar !overflow-auto">
|
||||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
|
||||||
class="hide-scrollbar !overflow-auto"
|
|
||||||
>
|
|
||||||
<AppSection label="response">
|
<AppSection label="response">
|
||||||
<RealtimeLog
|
<RealtimeLog
|
||||||
:title="$t('websocket.log')"
|
:title="$t('websocket.log')"
|
||||||
@@ -148,15 +180,15 @@
|
|||||||
class="hide-scrollbar !overflow-auto"
|
class="hide-scrollbar !overflow-auto"
|
||||||
>
|
>
|
||||||
<AppSection label="messages">
|
<AppSection label="messages">
|
||||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||||
<label
|
<label
|
||||||
for="websocket-message"
|
for="websocket-message"
|
||||||
class="text-secondaryLight font-semibold"
|
class="font-semibold text-secondaryLight"
|
||||||
>
|
>
|
||||||
{{ $t("websocket.communication") }}
|
{{ $t("websocket.communication") }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex px-4 space-x-2">
|
<div class="flex space-x-2 px-4">
|
||||||
<input
|
<input
|
||||||
id="websocket-message"
|
id="websocket-message"
|
||||||
v-model="communication.input"
|
v-model="communication.input"
|
||||||
@@ -287,7 +319,9 @@ export default defineComponent({
|
|||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
this.$toast.success(this.$t("state.connected"))
|
this.$toast.success(this.$t("state.connected"), {
|
||||||
|
icon: "sync",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.socket.onerror = () => {
|
this.socket.onerror = () => {
|
||||||
this.handleError()
|
this.handleError()
|
||||||
@@ -300,7 +334,9 @@ export default defineComponent({
|
|||||||
color: "#ff5555",
|
color: "#ff5555",
|
||||||
ts: new Date().toLocaleTimeString(),
|
ts: new Date().toLocaleTimeString(),
|
||||||
})
|
})
|
||||||
this.$toast.error(this.$t("state.disconnected"))
|
this.$toast.error(this.$t("state.disconnected"), {
|
||||||
|
icon: "sync_disabled",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
this.socket.onmessage = ({ data }) => {
|
this.socket.onmessage = ({ data }) => {
|
||||||
this.communication.log.push({
|
this.communication.log.push({
|
||||||
@@ -311,7 +347,9 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.handleError(e)
|
this.handleError(e)
|
||||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||||
|
icon: "error_outline",
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
logHoppRequestRunToAnalytics({
|
logHoppRequestRunToAnalytics({
|
||||||
@@ -395,6 +433,7 @@ export default defineComponent({
|
|||||||
const oldProtocols = this.protocols.slice()
|
const oldProtocols = this.protocols.slice()
|
||||||
this.$delete(this.protocols, index)
|
this.$delete(this.protocols, index)
|
||||||
this.$toast.success(this.$t("state.deleted"), {
|
this.$toast.success(this.$t("state.deleted"), {
|
||||||
|
icon: "delete",
|
||||||
action: {
|
action: {
|
||||||
text: this.$t("action.undo"),
|
text: this.$t("action.undo"),
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="flex-nowrap group hover:text-secondaryDark inline-flex items-center justify-center transition cursor-pointer"
|
class="
|
||||||
|
cursor-pointer
|
||||||
|
flex-nowrap
|
||||||
|
group
|
||||||
|
inline-flex
|
||||||
|
items-center
|
||||||
|
justify-center
|
||||||
|
transition
|
||||||
|
hover:text-secondaryDark
|
||||||
|
"
|
||||||
@click="$emit('change')"
|
@click="$emit('change')"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@@ -12,24 +21,22 @@
|
|||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
for="checkbox"
|
for="checkbox"
|
||||||
class="pl-0 font-semibold align-middle cursor-pointer"
|
class="cursor-pointer pl-0 align-middle font-semibold"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { defineComponent } from "@nuxtjs/composition-api"
|
withDefaults(
|
||||||
|
defineProps<{
|
||||||
export default defineComponent({
|
on: Boolean
|
||||||
props: {
|
}>(),
|
||||||
on: {
|
{
|
||||||
type: Boolean,
|
on: false,
|
||||||
default: false,
|
}
|
||||||
},
|
)
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
v-for="(color, index) of colors"
|
v-for="(color, index) of colors"
|
||||||
:key="`color-${index}`"
|
:key="`color-${index}`"
|
||||||
v-tippy="{ theme: 'tooltip' }"
|
v-tippy="{ theme: 'tooltip' }"
|
||||||
:title="t(getColorModeName(color))"
|
:title="$t(getColorModeName(color))"
|
||||||
:class="{
|
:class="{
|
||||||
'bg-primaryLight !text-accent hover:text-accent': color === active,
|
'bg-primaryLight !text-accent hover:text-accent': color === active,
|
||||||
}"
|
}"
|
||||||
@@ -22,9 +22,6 @@ import {
|
|||||||
HoppBgColors,
|
HoppBgColors,
|
||||||
useSetting,
|
useSetting,
|
||||||
} from "~/newstore/settings"
|
} from "~/newstore/settings"
|
||||||
import { useI18n } from "~/helpers/utils/composables"
|
|
||||||
|
|
||||||
const t = useI18n()
|
|
||||||
|
|
||||||
const colors = HoppBgColors
|
const colors = HoppBgColors
|
||||||
const active = useSetting("BG_COLOR")
|
const active = useSetting("BG_COLOR")
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user