Compare commits
45 Commits
bug/withDe
...
feat/embed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
def1b494f4 | ||
|
|
99b9ffd293 | ||
|
|
63005c01ce | ||
|
|
190a4c43ef | ||
|
|
c3fcc6e35d | ||
|
|
520ac8ede5 | ||
|
|
2a59557851 | ||
|
|
4089bc288c | ||
|
|
1999819846 | ||
|
|
0bf856291c | ||
|
|
da8c446ad7 | ||
|
|
3614877964 | ||
|
|
85c8171aa8 | ||
|
|
b58278d55e | ||
|
|
b398ed1e90 | ||
|
|
afa750e409 | ||
|
|
fdf12a24ed | ||
|
|
4c5ca1b31d | ||
|
|
bcb9b97b6b | ||
|
|
757294ae38 | ||
|
|
8d4dd8c428 | ||
|
|
508809eba1 | ||
|
|
d0386ef86f | ||
|
|
56cdb79773 | ||
|
|
6ed4211004 | ||
|
|
222f0800d2 | ||
|
|
12a9dd1058 | ||
|
|
4a32fc6180 | ||
|
|
1e08e7f73d | ||
|
|
8b05b063ff | ||
|
|
0bcfeb86ae | ||
|
|
03a056b6c1 | ||
|
|
d57e465806 | ||
|
|
5ab24d1439 | ||
|
|
47661de974 | ||
|
|
26429466e9 | ||
|
|
cad8f3e856 | ||
|
|
1a4eb1fabe | ||
|
|
680f61b7dc | ||
|
|
f602a1e2d3 | ||
|
|
1572ff9e67 | ||
|
|
fe7b236ad9 | ||
|
|
3080af1ea5 | ||
|
|
0f83c8b490 | ||
|
|
7d590ab966 |
57
.github/ISSUE_TEMPLATE/--bug-report.yaml
vendored
Normal file
57
.github/ISSUE_TEMPLATE/--bug-report.yaml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
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
Normal file
28
.github/ISSUE_TEMPLATE/--feature-request.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
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
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
||||
---
|
||||
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
Normal file
7
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
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
8
.github/ISSUE_TEMPLATE/custom.md
vendored
@@ -1,8 +0,0 @@
|
||||
---
|
||||
name: Custom issue template
|
||||
about: Describe this issue template's purpose here.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
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**
|
||||
|
||||
[](https://hoppscotch.io/discord) [](https://hoppscotch.io/telegram)
|
||||
[](https://hoppscotch.io/discord) [](https://hoppscotch.io/telegram) [](https://github.com/hoppscotch/hoppscotch/discussions)
|
||||
|
||||
<details open>
|
||||
<summary><b>Table of contents</b></summary>
|
||||
|
||||
26
SECURITY.md
Normal file
26
SECURITY.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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,16 +9,19 @@ 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:
|
||||
|
||||
1. **[Fork the repository](https://github.com/hoppscotch/hoppscotch/fork).**
|
||||
2. **Create a new branch for your translation.**
|
||||
3. **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. **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. **Save & commit changes.**
|
||||
8. **Send a pull request.**
|
||||
2. **Checkout the `i18n` branch for latest translations.**
|
||||
3. **Create a new branch for your translation with base branch `i18n`.**
|
||||
4. **Create target language file in the [`locales`](https://github.com/hoppscotch/hoppscotch/tree/main/packages/hoppscotch-app/locales) directory.**
|
||||
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.**
|
||||
6. **Translate the strings in the target language file.**
|
||||
7. **Add your language entry to [`languages.json`](https://github.com/hoppscotch/hoppscotch/blob/main/packages/hoppscotch-app/languages.json).**
|
||||
8. **Save & commit changes.**
|
||||
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._
|
||||
|
||||
`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.
|
||||
|
||||
## Updating a translation
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"description": "Open source API development ecosystem",
|
||||
"author": "Hoppscotch (support@hoppscotch.io)",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"prepare": "husky install",
|
||||
@@ -20,10 +21,10 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"husky": "^7.0.4",
|
||||
"lint-staged": "^12.0.2"
|
||||
"lint-staged": "^12.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^14.1.0",
|
||||
"@commitlint/config-conventional": "^14.1.0"
|
||||
"@commitlint/cli": "^15.0.0",
|
||||
"@commitlint/config-conventional": "^15.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"name": "@hoppscotch/codemirror-lang-graphql",
|
||||
"version": "0.1.0",
|
||||
"description": "GraphQL language support for CodeMirror",
|
||||
"author": "Hoppscotch (support@hoppscotch.io)",
|
||||
"scripts": {
|
||||
"prepare": "rollup -c"
|
||||
},
|
||||
@@ -15,17 +16,17 @@
|
||||
"types": "dist/index.d.ts",
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"@codemirror/highlight": "^0.19.0",
|
||||
"@codemirror/language": "^0.19.0",
|
||||
"@codemirror/highlight": "^0.19.6",
|
||||
"@codemirror/language": "^0.19.6",
|
||||
"@lezer/lr": "^0.15.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lezer/generator": "^0.15.0",
|
||||
"mocha": "^9.0.1",
|
||||
"rollup": "^2.35.1",
|
||||
"rollup-plugin-dts": "^3.0.2",
|
||||
"rollup-plugin-ts": "^1.4.0",
|
||||
"typescript": "^4.3.4"
|
||||
"rollup": "^2.60.1",
|
||||
"rollup-plugin-dts": "^4.0.1",
|
||||
"rollup-plugin-ts": "^2.0.4",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
<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">
|
||||
<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>
|
||||
<path d="M21 12a9 9 0 11-6.219-8.56"></path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 608 B After Width: | Height: | Size: 235 B |
@@ -27,23 +27,24 @@
|
||||
@apply h-4;
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
::selection {
|
||||
@apply bg-divider;
|
||||
}
|
||||
|
||||
.cm-focused {
|
||||
@apply !outline-none;
|
||||
@apply bg-accentDark;
|
||||
@apply text-accentContrast;
|
||||
}
|
||||
|
||||
input::placeholder,
|
||||
textarea::placeholder,
|
||||
.CodeMirror-empty {
|
||||
textarea::placeholder {
|
||||
@apply text-secondary;
|
||||
@apply opacity-25;
|
||||
@apply opacity-35;
|
||||
}
|
||||
|
||||
input,
|
||||
@@ -66,7 +67,6 @@ body {
|
||||
animation: fade 300ms forwards;
|
||||
font-size: var(--body-font-size);
|
||||
line-height: var(--body-line-height);
|
||||
overflow: overlay;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
}
|
||||
@@ -318,7 +318,7 @@ pre.ace_editor {
|
||||
&.toasted-primary {
|
||||
@apply bg-tooltip;
|
||||
@apply text-primary;
|
||||
@apply justify-start;
|
||||
@apply justify-between;
|
||||
@apply shadow;
|
||||
@apply font-medium;
|
||||
@apply transition;
|
||||
@@ -391,7 +391,7 @@ pre.ace_editor {
|
||||
.smart-splitter .splitpanes__splitter::before {
|
||||
@apply absolute;
|
||||
@apply inset-0;
|
||||
@apply bg-dividerLight;
|
||||
@apply bg-accentLight;
|
||||
@apply opacity-0;
|
||||
@apply z-20;
|
||||
@apply transition;
|
||||
@@ -435,29 +435,16 @@ pre.ace_editor {
|
||||
@apply w-full;
|
||||
}
|
||||
|
||||
.CodeMirror {
|
||||
@apply !h-auto;
|
||||
.cm-focused {
|
||||
@apply select-auto;
|
||||
@apply !outline-none;
|
||||
|
||||
font-size: var(--body-font-size);
|
||||
|
||||
&:not(.CodeMirror-focused) .CodeMirror-activeline-background {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.CodeMirror-dialog-top {
|
||||
.cm-activeLine {
|
||||
@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;
|
||||
.cm-activeLineGutter {
|
||||
@apply bg-primaryDark;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,17 +53,17 @@
|
||||
}
|
||||
|
||||
@mixin dark-editor-theme {
|
||||
--editor-type-color: theme("colors.purple.500");
|
||||
--editor-name-color: theme("colors.blue.500");
|
||||
--editor-operator-color: theme("colors.indigo.500");
|
||||
--editor-invalid-color: theme("colors.red.500");
|
||||
--editor-separator-color: theme("colors.gray.500");
|
||||
--editor-meta-color: theme("colors.gray.500");
|
||||
--editor-variable-color: theme("colors.green.500");
|
||||
--editor-link-color: theme("colors.cyan.500");
|
||||
--editor-process-color: theme("colors.gray.400");
|
||||
--editor-constant-color: theme("colors.fuchsia.500");
|
||||
--editor-keyword-color: theme("colors.pink.500");
|
||||
--editor-type-color: theme("colors.purple.400");
|
||||
--editor-name-color: theme("colors.blue.400");
|
||||
--editor-operator-color: theme("colors.indigo.400");
|
||||
--editor-invalid-color: theme("colors.red.400");
|
||||
--editor-separator-color: theme("colors.gray.400");
|
||||
--editor-meta-color: theme("colors.gray.400");
|
||||
--editor-variable-color: theme("colors.green.400");
|
||||
--editor-link-color: theme("colors.cyan.400");
|
||||
--editor-process-color: theme("colors.fuchsia.400");
|
||||
--editor-constant-color: theme("colors.violet.400");
|
||||
--editor-keyword-color: theme("colors.pink.400");
|
||||
}
|
||||
|
||||
@mixin light-editor-theme {
|
||||
@@ -82,15 +82,15 @@
|
||||
|
||||
@mixin black-editor-theme {
|
||||
--editor-type-color: theme("colors.purple.400");
|
||||
--editor-name-color: theme("colors.gray.400");
|
||||
--editor-name-color: theme("colors.fuchsia.400");
|
||||
--editor-operator-color: theme("colors.indigo.400");
|
||||
--editor-invalid-color: theme("colors.red.400");
|
||||
--editor-separator-color: theme("colors.gray.400");
|
||||
--editor-meta-color: theme("colors.gray.400");
|
||||
--editor-variable-color: theme("colors.green.400");
|
||||
--editor-link-color: theme("colors.cyan.400");
|
||||
--editor-process-color: theme("colors.blue.400");
|
||||
--editor-constant-color: theme("colors.fuchsia.400");
|
||||
--editor-process-color: theme("colors.violet.400");
|
||||
--editor-constant-color: theme("colors.blue.400");
|
||||
--editor-keyword-color: theme("colors.pink.400");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,23 @@
|
||||
<template>
|
||||
<div class="bg-error flex justify-between">
|
||||
<span
|
||||
class="
|
||||
flex
|
||||
py-2
|
||||
px-4
|
||||
transition
|
||||
relative
|
||||
items-center
|
||||
justify-center
|
||||
group
|
||||
"
|
||||
class="group relative flex items-center justify-center px-4 py-2 transition"
|
||||
>
|
||||
<i class="mr-2 material-icons">info_outline</i>
|
||||
<i class="material-icons mr-2">info_outline</i>
|
||||
<span class="text-secondaryDark">
|
||||
<span class="md:hidden">
|
||||
{{ $t("helpers.offline_short") }}
|
||||
{{ t("helpers.offline_short") }}
|
||||
</span>
|
||||
<span class="hidden md:inline">
|
||||
{{ $t("helpers.offline") }}
|
||||
<span class="md:inline hidden">
|
||||
{{ t("helpers.offline") }}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="EXPAND_NAVIGATION ? $t('hide.sidebar') : $t('show.sidebar')"
|
||||
:title="EXPAND_NAVIGATION ? t('hide.sidebar') : t('show.sidebar')"
|
||||
svg="sidebar"
|
||||
class="transform"
|
||||
:class="{ '-rotate-180': !EXPAND_NAVIGATION }"
|
||||
@@ -12,9 +12,9 @@
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${
|
||||
ZEN_MODE ? $t('action.turn_off') : $t('action.turn_on')
|
||||
} ${$t('layout.zen_mode')}`"
|
||||
:title="`${ZEN_MODE ? t('action.turn_off') : t('action.turn_on')} ${t(
|
||||
'layout.zen_mode'
|
||||
)}`"
|
||||
:svg="ZEN_MODE ? 'minimize' : 'maximize'"
|
||||
:class="{
|
||||
'!text-accent !focus-visible:text-accentDark !hover:text-accentDark':
|
||||
@@ -36,20 +36,20 @@
|
||||
<ButtonSecondary
|
||||
svg="help-circle"
|
||||
class="!rounded-none"
|
||||
:label="`${$t('app.help')}`"
|
||||
:label="`${t('app.help')}`"
|
||||
/>
|
||||
</template>
|
||||
<div class="flex flex-col">
|
||||
<SmartItem
|
||||
svg="book"
|
||||
:label="`${$t('app.documentation')}`"
|
||||
:label="`${t('app.documentation')}`"
|
||||
to="https://docs.hoppscotch.io"
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="zap"
|
||||
:label="`${$t('app.keyboard_shortcuts')}`"
|
||||
:label="`${t('app.keyboard_shortcuts')}`"
|
||||
@click.native="
|
||||
() => {
|
||||
showShortcuts = true
|
||||
@@ -59,14 +59,14 @@
|
||||
/>
|
||||
<SmartItem
|
||||
svg="gift"
|
||||
:label="`${$t('app.whats_new')}`"
|
||||
:label="`${t('app.whats_new')}`"
|
||||
to="https://docs.hoppscotch.io/changelog"
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="message-circle"
|
||||
:label="`${$t('app.chat_with_us')}`"
|
||||
:label="`${t('app.chat_with_us')}`"
|
||||
@click.native="
|
||||
() => {
|
||||
chatWithUs()
|
||||
@@ -77,21 +77,21 @@
|
||||
<hr />
|
||||
<SmartItem
|
||||
svg="github"
|
||||
:label="`${$t('app.github')}`"
|
||||
:label="`${t('app.github')}`"
|
||||
to="https://github.com/hoppscotch/hoppscotch"
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="twitter"
|
||||
:label="`${$t('app.twitter')}`"
|
||||
:label="`${t('app.twitter')}`"
|
||||
to="https://hoppscotch.io/twitter"
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="user-plus"
|
||||
:label="`${$t('app.invite')}`"
|
||||
:label="`${t('app.invite')}`"
|
||||
@click.native="
|
||||
() => {
|
||||
showShare = true
|
||||
@@ -101,14 +101,14 @@
|
||||
/>
|
||||
<SmartItem
|
||||
svg="lock"
|
||||
:label="`${$t('app.terms_and_privacy')}`"
|
||||
:label="`${t('app.terms_and_privacy')}`"
|
||||
to="https://docs.hoppscotch.io/privacy"
|
||||
blank
|
||||
@click.native="$refs.options.tippy().hide()"
|
||||
/>
|
||||
<!-- <SmartItem :label="$t('app.status')" /> -->
|
||||
<div class="flex opacity-50 py-2 px-4">
|
||||
{{ `${$t("app.name")} ${$t("app.version")}` }}
|
||||
<!-- <SmartItem :label="t('app.status')" /> -->
|
||||
<div class="flex px-4 py-2 opacity-50">
|
||||
{{ `${t("app.name")} ${t("app.version")}` }}
|
||||
</div>
|
||||
</div>
|
||||
</tippy>
|
||||
@@ -116,33 +116,33 @@
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="zap"
|
||||
:title="$t('app.shortcuts')"
|
||||
:title="t('app.shortcuts')"
|
||||
@click.native="showShortcuts = true"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-if="navigatorShare"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="share-2"
|
||||
:title="$t('request.share')"
|
||||
:title="t('request.share')"
|
||||
@click.native="nativeShare()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="COLUMN_LAYOUT ? $t('layout.row') : $t('layout.column')"
|
||||
:title="COLUMN_LAYOUT ? t('layout.row') : t('layout.column')"
|
||||
svg="columns"
|
||||
class="transform"
|
||||
:class="{ 'rotate-90': !COLUMN_LAYOUT }"
|
||||
@click.native="COLUMN_LAYOUT = !COLUMN_LAYOUT"
|
||||
/>
|
||||
<span
|
||||
class="transform transition"
|
||||
class="transition transform"
|
||||
:class="{
|
||||
'rotate-180': SIDEBAR_ON_LEFT,
|
||||
}"
|
||||
>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="SIDEBAR ? $t('hide.sidebar') : $t('show.sidebar')"
|
||||
:title="SIDEBAR ? t('hide.sidebar') : t('show.sidebar')"
|
||||
svg="sidebar-open"
|
||||
class="transform"
|
||||
:class="{ 'rotate-180': !SIDEBAR }"
|
||||
@@ -161,7 +161,9 @@ import { ref, watch } from "@nuxtjs/composition-api"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
import { showChat } from "~/helpers/support"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
const showShortcuts = ref(false)
|
||||
const showShare = ref(false)
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@
|
||||
/>
|
||||
<div
|
||||
v-if="searchResults.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ search }}"
|
||||
{{ t("state.nothing_found") }} "{{ search }}"
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -26,6 +26,9 @@ import { computed, onUnmounted, onMounted } from "@nuxtjs/composition-api"
|
||||
import Fuse from "fuse.js"
|
||||
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
||||
import { HoppAction } from "~/helpers/actions"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
input: Record<string, any>[]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<header
|
||||
class="flex space-x-2 flex-1 py-2 px-2 items-center justify-between"
|
||||
class="flex items-center justify-between flex-1 px-2 py-2 space-x-2"
|
||||
>
|
||||
<div class="space-x-2 inline-flex items-center">
|
||||
<div class="inline-flex items-center space-x-2">
|
||||
<ButtonSecondary
|
||||
class="tracking-wide !font-bold !text-secondaryDark"
|
||||
label="HOPPSCOTCH"
|
||||
@@ -11,25 +11,25 @@
|
||||
/>
|
||||
<AppGitHubStarButton class="mt-1.5 transition hidden sm:flex" />
|
||||
</div>
|
||||
<div class="space-x-2 inline-flex items-center">
|
||||
<div class="inline-flex items-center space-x-2">
|
||||
<ButtonSecondary
|
||||
id="installPWA"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('header.install_pwa')"
|
||||
:title="t('header.install_pwa')"
|
||||
svg="download"
|
||||
class="rounded"
|
||||
@click.native="showInstallPrompt()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${$t('app.search')} <kbd>/</kbd>`"
|
||||
:title="`${t('app.search')} <kbd>/</kbd>`"
|
||||
svg="search"
|
||||
class="rounded"
|
||||
@click.native="showSearch = true"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${$t('support.title')} <kbd>?</kbd>`"
|
||||
:title="`${t('support.title')} <kbd>?</kbd>`"
|
||||
svg="life-buoy"
|
||||
class="rounded"
|
||||
@click.native="showSupport = true"
|
||||
@@ -37,28 +37,23 @@
|
||||
<ButtonSecondary
|
||||
v-if="currentUser === null"
|
||||
svg="upload-cloud"
|
||||
:label="$t('header.save_workspace')"
|
||||
:label="t('header.save_workspace')"
|
||||
filled
|
||||
class="hidden md:flex"
|
||||
class="md:flex hidden"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
v-if="currentUser === null"
|
||||
:label="$t('header.login')"
|
||||
:label="t('header.login')"
|
||||
@click.native="showLogin = true"
|
||||
/>
|
||||
<div v-else class="space-x-2 inline-flex items-center">
|
||||
<div v-else class="inline-flex items-center space-x-2">
|
||||
<ButtonPrimary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('team.invite_tooltip')"
|
||||
:label="$t('team.invite')"
|
||||
:title="t('team.invite_tooltip')"
|
||||
:label="t('team.invite')"
|
||||
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"
|
||||
/>
|
||||
<span class="px-2">
|
||||
@@ -78,7 +73,7 @@
|
||||
<ButtonSecondary
|
||||
v-else
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('header.account')"
|
||||
:title="t('header.account')"
|
||||
class="rounded"
|
||||
svg="user"
|
||||
/>
|
||||
@@ -86,13 +81,13 @@
|
||||
<SmartItem
|
||||
to="/profile"
|
||||
svg="user"
|
||||
:label="$t('navigation.profile')"
|
||||
:label="t('navigation.profile')"
|
||||
@click.native="$refs.user.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
to="/settings"
|
||||
svg="settings"
|
||||
:label="$t('navigation.settings')"
|
||||
:label="t('navigation.settings')"
|
||||
@click.native="$refs.user.tippy().hide()"
|
||||
/>
|
||||
<FirebaseLogout @confirm-logout="$refs.user.tippy().hide()" />
|
||||
@@ -110,18 +105,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { onMounted, ref } from "@nuxtjs/composition-api"
|
||||
import intializePwa from "~/helpers/pwa"
|
||||
import { probableUser$ } from "~/helpers/fb/auth"
|
||||
import { getLocalConfig, setLocalConfig } from "~/newstore/localpersistence"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
/**
|
||||
* Once the PWA code is initialized, this holds a method
|
||||
@@ -160,12 +157,11 @@ onMounted(() => {
|
||||
|
||||
const cookiesAllowed = getLocalConfig("cookiesAllowed") === "yes"
|
||||
if (!cookiesAllowed) {
|
||||
$toast.show(t("app.we_use_cookies").toString(), {
|
||||
icon: "cookie",
|
||||
toast.show(`${t("app.we_use_cookies")}`, {
|
||||
duration: 0,
|
||||
action: [
|
||||
{
|
||||
text: t("action.learn_more").toString(),
|
||||
text: `${t("action.learn_more")}`,
|
||||
onClick: (_, toastObject) => {
|
||||
setLocalConfig("cookiesAllowed", "yes")
|
||||
toastObject.goAway(0)
|
||||
@@ -173,7 +169,7 @@ onMounted(() => {
|
||||
},
|
||||
},
|
||||
{
|
||||
text: t("action.dismiss").toString(),
|
||||
text: `${t("action.dismiss")}`,
|
||||
onClick: (_, toastObject) => {
|
||||
setLocalConfig("cookiesAllowed", "yes")
|
||||
toastObject.goAway(0)
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div class="flex p-4 space-y-4 items-start flex-col">
|
||||
<div class="flex flex-col items-start p-4 space-y-4">
|
||||
<SmartToggle
|
||||
:on="PROXY_ENABLED"
|
||||
@change="toggleSettingKey('PROXY_ENABLED')"
|
||||
>
|
||||
{{ $t("settings.proxy") }}
|
||||
{{ t("settings.proxy") }}
|
||||
</SmartToggle>
|
||||
<SmartToggle
|
||||
:on="EXTENSIONS_ENABLED"
|
||||
@change="toggleSettingKey('EXTENSIONS_ENABLED')"
|
||||
>
|
||||
{{ $t("settings.extensions") }}:
|
||||
{{ t("settings.extensions") }}:
|
||||
{{
|
||||
extensionVersion != null
|
||||
? `v${extensionVersion.major}.${extensionVersion.minor}`
|
||||
: $t("settings.extension_ver_not_reported")
|
||||
: t("settings.extension_ver_not_reported")
|
||||
}}
|
||||
</SmartToggle>
|
||||
</div>
|
||||
@@ -25,6 +25,9 @@ import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import { KeysMatching } from "~/types/ts-utils"
|
||||
import { SettingsType, toggleSetting, useSetting } from "~/newstore/settings"
|
||||
import { hasExtensionInstalled } from "~/helpers/strategies/ExtensionStrategy"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const PROXY_ENABLED = useSetting("PROXY_ENABLED")
|
||||
const EXTENSIONS_ENABLED = useSetting("EXTENSIONS_ENABLED")
|
||||
|
||||
@@ -13,14 +13,8 @@
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
name="command"
|
||||
:placeholder="`${$t('app.type_a_command_search')}`"
|
||||
class="
|
||||
bg-transparent
|
||||
border-b border-dividerLight
|
||||
flex flex-shrink-0
|
||||
text-secondaryDark text-base
|
||||
p-6
|
||||
"
|
||||
:placeholder="`${t('app.type_a_command_search')}`"
|
||||
class="border-dividerLight text-secondaryDark flex flex-shrink-0 p-6 text-base bg-transparent border-b"
|
||||
/>
|
||||
<AppFuse
|
||||
v-if="search && show"
|
||||
@@ -30,22 +24,15 @@
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="
|
||||
divide-y divide-dividerLight
|
||||
flex flex-col
|
||||
space-y-4
|
||||
flex-1
|
||||
overflow-auto
|
||||
hide-scrollbar
|
||||
"
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 space-y-4 overflow-auto divide-y"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in mappings"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="flex flex-col"
|
||||
>
|
||||
<h5 class="my-2 text-secondaryLight py-2 px-6">
|
||||
{{ $t(map.section) }}
|
||||
<h5 class="text-secondaryLight px-6 py-2 my-2">
|
||||
{{ t(map.section) }}
|
||||
</h5>
|
||||
<AppPowerSearchEntry
|
||||
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
||||
@@ -66,6 +53,9 @@ import { ref, computed, watch } from "@nuxtjs/composition-api"
|
||||
import { HoppAction, invokeAction } from "~/helpers/actions"
|
||||
import { spotlight as mappings, fuse } from "~/helpers/shortcuts"
|
||||
import { useArrowKeysNavigation } from "~/helpers/powerSearchNavigation"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
<template>
|
||||
<button
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
py-2
|
||||
px-6
|
||||
transition
|
||||
items-center
|
||||
search-entry
|
||||
focus:outline-none
|
||||
"
|
||||
class="search-entry focus:outline-none flex items-center flex-1 px-6 py-2 transition cursor-pointer"
|
||||
:class="{ active: active }"
|
||||
tabindex="-1"
|
||||
@click="$emit('action', shortcut.action)"
|
||||
@keydown.enter="$emit('action', shortcut.action)"
|
||||
>
|
||||
<SmartIcon
|
||||
class="mr-4 opacity-50 transition svg-icons"
|
||||
class="svg-icons mr-4 transition opacity-50"
|
||||
:class="{ 'opacity-100 text-secondaryDark': active }"
|
||||
:name="shortcut.icon"
|
||||
/>
|
||||
@@ -24,7 +15,7 @@
|
||||
class="flex flex-1 mr-4 font-medium transition"
|
||||
:class="{ 'text-secondaryDark': active }"
|
||||
>
|
||||
{{ $t(shortcut.label) }}
|
||||
{{ t(shortcut.label) }}
|
||||
</span>
|
||||
<span
|
||||
v-for="(key, keyIndex) in shortcut.keys"
|
||||
@@ -37,6 +28,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
defineProps<{
|
||||
shortcut: Object
|
||||
active: Boolean
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<section :id="label.toLowerCase()" class="flex flex-col flex-1 relative">
|
||||
<section :id="label.toLowerCase()" class="relative flex flex-col flex-1">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<SmartModal
|
||||
v-if="show"
|
||||
:title="$t('app.invite_your_friends')"
|
||||
:title="t('app.invite_your_friends')"
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<p class="text-secondaryLight mb-8 px-2">
|
||||
{{ $t("app.invite_description") }}
|
||||
<p class="text-secondaryLight px-2 mb-8">
|
||||
{{ t("app.invite_description") }}
|
||||
</p>
|
||||
<div class="flex flex-col space-y-2 px-2">
|
||||
<div class="grid gap-4 grid-cols-3">
|
||||
<div class="flex flex-col px-2 space-y-2">
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<a
|
||||
v-for="(platform, index) in platforms"
|
||||
:key="`platform-${index}`"
|
||||
@@ -17,15 +17,15 @@
|
||||
target="_blank"
|
||||
class="share-link"
|
||||
>
|
||||
<SmartIcon :name="platform.icon" class="h-6 w-6" />
|
||||
<SmartIcon :name="platform.icon" class="w-6 h-6" />
|
||||
<span class="mt-3">
|
||||
{{ platform.name }}
|
||||
</span>
|
||||
</a>
|
||||
<button class="share-link" @click="copyAppLink">
|
||||
<SmartIcon class="h-6 text-xl w-6" :name="copyIcon" />
|
||||
<SmartIcon class="w-6 h-6 text-xl" :name="copyIcon" />
|
||||
<span class="mt-3">
|
||||
{{ $t("app.copy") }}
|
||||
{{ t("app.copy") }}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -35,14 +35,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { ref } from "@nuxtjs/composition-api"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
defineProps<{
|
||||
show: Boolean
|
||||
@@ -92,9 +91,7 @@ const platforms = [
|
||||
const copyAppLink = () => {
|
||||
copyToClipboard(url)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(t("state.copied_to_clipboard").toString(), {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,51 +2,35 @@
|
||||
<AppSlideOver :show="show" @close="close()">
|
||||
<template #content>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex
|
||||
p-2
|
||||
top-0
|
||||
z-10
|
||||
items-center
|
||||
sticky
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between p-2 border-b"
|
||||
>
|
||||
<h3 class="ml-4 heading">{{ $t("app.shortcuts") }}</h3>
|
||||
<h3 class="heading ml-4">{{ t("app.shortcuts") }}</h3>
|
||||
<div class="flex">
|
||||
<ButtonSecondary svg="x" class="rounded" @click.native="close()" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-primary border-b border-dividerLight">
|
||||
<div class="flex flex-col my-4 mx-6">
|
||||
<div class="bg-primary border-dividerLight border-b">
|
||||
<div class="flex flex-col mx-6 my-4">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
class="
|
||||
bg-primaryLight
|
||||
border border-dividerLight
|
||||
rounded
|
||||
flex
|
||||
w-full
|
||||
py-2
|
||||
px-4
|
||||
focus-visible:border-divider
|
||||
"
|
||||
:placeholder="`${$t('action.search')}`"
|
||||
class="bg-primaryLight border-dividerLight focus-visible:border-divider flex w-full px-4 py-2 border rounded"
|
||||
:placeholder="`${t('action.search')}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="filterText">
|
||||
<div
|
||||
v-if="filterText"
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in searchResults"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="space-y-4 py-4 px-6"
|
||||
class="px-6 py-4 space-y-4"
|
||||
>
|
||||
<h1 class="font-semibold text-secondaryDark">
|
||||
{{ $t(map.item.section) }}
|
||||
<h1 class="text-secondaryDark font-semibold">
|
||||
{{ t(map.item.section) }}
|
||||
</h1>
|
||||
<AppShortcutsEntry
|
||||
v-for="(shortcut, index) in map.item.shortcuts"
|
||||
@@ -56,36 +40,25 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="searchResults.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
{{ t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="
|
||||
divide-y divide-dividerLight
|
||||
flex flex-col flex-1
|
||||
overflow-auto
|
||||
hide-scrollbar
|
||||
"
|
||||
class="divide-dividerLight hide-scrollbar flex flex-col flex-1 overflow-auto divide-y"
|
||||
>
|
||||
<div
|
||||
v-for="(map, mapIndex) in mappings"
|
||||
:key="`map-${mapIndex}`"
|
||||
class="space-y-4 py-4 px-6"
|
||||
class="px-6 py-4 space-y-4"
|
||||
>
|
||||
<h1 class="font-semibold text-secondaryDark">
|
||||
{{ $t(map.section) }}
|
||||
<h1 class="text-secondaryDark font-semibold">
|
||||
{{ t(map.section) }}
|
||||
</h1>
|
||||
<AppShortcutsEntry
|
||||
v-for="(shortcut, shortcutIndex) in map.shortcuts"
|
||||
@@ -102,6 +75,9 @@
|
||||
import { computed, ref } from "@nuxtjs/composition-api"
|
||||
import Fuse from "fuse.js"
|
||||
import mappings from "~/helpers/shortcuts"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
defineProps<{
|
||||
show: boolean
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<span class="flex flex-1 mr-4">
|
||||
{{ $t(shortcut.label) }}
|
||||
{{ t(shortcut.label) }}
|
||||
</span>
|
||||
<span
|
||||
v-for="(key, index) in shortcut.keys"
|
||||
@@ -14,6 +14,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
defineProps<{
|
||||
shortcut: Object
|
||||
}>()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<aside class="flex h-full justify-between md:flex-col">
|
||||
<nav class="flex flex-nowrap md:flex-col flex-1 md:flex-none">
|
||||
<aside class="md:flex-col flex justify-between h-full">
|
||||
<nav class="flex-nowrap md:flex-col md:flex-none flex flex-1">
|
||||
<NuxtLink
|
||||
v-for="(navigation, index) in primaryNavigation"
|
||||
:key="`navigation-${index}`"
|
||||
@@ -27,14 +27,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useContext } from "@nuxtjs/composition-api"
|
||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||
import { useSetting } from "~/newstore/settings"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const {
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const windowInnerWidth = useWindowSize()
|
||||
const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
|
||||
|
||||
@@ -1,31 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<transition v-if="show" name="fade" appear>
|
||||
<div class="inset-0 transition-opacity z-20 fixed" @keydown.esc="close()">
|
||||
<div class="fixed inset-0 z-20 transition-opacity" @keydown.esc="close()">
|
||||
<div
|
||||
class="bg-primaryLight opacity-90 inset-0 absolute"
|
||||
class="bg-primaryLight opacity-90 absolute inset-0"
|
||||
tabindex="0"
|
||||
@click="close()"
|
||||
></div>
|
||||
</div>
|
||||
</transition>
|
||||
<aside
|
||||
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="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="show ? 'shadow-xl translate-x-0' : 'translate-x-full'"
|
||||
>
|
||||
<slot name="content"></slot>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<SmartModal
|
||||
v-if="show"
|
||||
:title="$t('support.title')"
|
||||
:title="t('support.title')"
|
||||
max-width="sm:max-w-md"
|
||||
@close="$emit('hide-modal')"
|
||||
>
|
||||
@@ -9,9 +9,9 @@
|
||||
<div class="flex flex-col space-y-2">
|
||||
<SmartItem
|
||||
svg="book"
|
||||
:label="$t('app.documentation')"
|
||||
:label="t('app.documentation')"
|
||||
to="https://docs.hoppscotch.io"
|
||||
:description="$t('support.documentation')"
|
||||
:description="t('support.documentation')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
blank
|
||||
@@ -19,17 +19,17 @@
|
||||
/>
|
||||
<SmartItem
|
||||
svg="zap"
|
||||
:label="$t('app.keyboard_shortcuts')"
|
||||
:description="$t('support.shortcuts')"
|
||||
:label="t('app.keyboard_shortcuts')"
|
||||
:description="t('support.shortcuts')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="showShortcuts()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="gift"
|
||||
:label="$t('app.whats_new')"
|
||||
:label="t('app.whats_new')"
|
||||
to="https://docs.hoppscotch.io/changelog"
|
||||
:description="$t('support.changelog')"
|
||||
:description="t('support.changelog')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
blank
|
||||
@@ -37,28 +37,28 @@
|
||||
/>
|
||||
<SmartItem
|
||||
svg="message-circle"
|
||||
:label="$t('app.chat_with_us')"
|
||||
:description="$t('support.chat')"
|
||||
:label="t('app.chat_with_us')"
|
||||
:description="t('support.chat')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="chatWithUs()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="brands/discord"
|
||||
:label="$t('app.join_discord_community')"
|
||||
:label="t('app.join_discord_community')"
|
||||
to="https://hoppscotch.io/discord"
|
||||
blank
|
||||
:description="$t('support.community')"
|
||||
:description="t('support.community')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="hideModal()"
|
||||
/>
|
||||
<SmartItem
|
||||
svg="brands/twitter"
|
||||
:label="$t('app.twitter')"
|
||||
:label="t('app.twitter')"
|
||||
to="https://hoppscotch.io/twitter"
|
||||
blank
|
||||
:description="$t('support.twitter')"
|
||||
:description="t('support.twitter')"
|
||||
info-icon="chevron_right"
|
||||
active
|
||||
@click.native="hideModal()"
|
||||
@@ -71,6 +71,9 @@
|
||||
<script setup lang="ts">
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
import { showChat } from "~/helpers/support"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
defineProps<{
|
||||
show: Boolean
|
||||
@@ -87,6 +90,7 @@ const chatWithUs = () => {
|
||||
|
||||
const showShortcuts = () => {
|
||||
invokeAction("flyouts.keybinds.toggle")
|
||||
hideModal()
|
||||
}
|
||||
|
||||
const hideModal = () => {
|
||||
|
||||
@@ -3,16 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
class="
|
||||
font-bold
|
||||
py-2
|
||||
transition
|
||||
inline-flex
|
||||
items-center
|
||||
justify-center
|
||||
focus:outline-none
|
||||
focus-visible:bg-accentDark
|
||||
"
|
||||
class="focus:outline-none focus-visible:bg-accentDark inline-flex items-center justify-center py-2 font-bold transition"
|
||||
:class="[
|
||||
color
|
||||
? `text-${color}-800 bg-${color}-200 hover:(text-${color}-900 bg-${color}-300) focus-visible:(text-${color}-900 bg-${color}-300)`
|
||||
@@ -38,7 +29,7 @@
|
||||
>
|
||||
<span
|
||||
v-if="!loading"
|
||||
class="inline-flex items-center justify-center whitespace-nowrap"
|
||||
class="whitespace-nowrap inline-flex items-center justify-center"
|
||||
:class="{ 'flex-row-reverse': reverse }"
|
||||
>
|
||||
<i
|
||||
@@ -65,7 +56,7 @@
|
||||
<kbd
|
||||
v-for="(key, index) in shortcut"
|
||||
:key="`key-${index}`"
|
||||
class="bg-accentLight rounded ml-1 px-1 inline-flex"
|
||||
class="bg-accentLight inline-flex px-1 ml-1 rounded"
|
||||
>
|
||||
{{ key }}
|
||||
</kbd>
|
||||
|
||||
@@ -3,18 +3,7 @@
|
||||
:to="`${/^\/(?!\/).*$/.test(to) ? localePath(to) : to}`"
|
||||
:exact="exact"
|
||||
:blank="blank"
|
||||
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="whitespace-nowrap hover:bg-primaryDark focus:outline-none focus-visible:bg-primaryDark inline-flex items-center justify-center py-2 font-semibold transition"
|
||||
:class="[
|
||||
color
|
||||
? `text-${color}-500 hover:(text-${color}-600 text-${color}-600)`
|
||||
@@ -28,7 +17,7 @@
|
||||
'border border-divider hover:border-dividerDark focus-visible:border-dividerDark':
|
||||
outline,
|
||||
},
|
||||
{ '!bg-primaryDark': filled },
|
||||
{ '!bg-primaryLight !hover:bg-primaryDark': filled },
|
||||
]"
|
||||
:disabled="disabled"
|
||||
>
|
||||
@@ -56,14 +45,7 @@
|
||||
<kbd
|
||||
v-for="(key, index) in shortcut"
|
||||
:key="`key-${index}`"
|
||||
class="
|
||||
bg-dividerLight
|
||||
rounded
|
||||
text-secondaryLight
|
||||
ml-1
|
||||
px-1
|
||||
inline-flex
|
||||
"
|
||||
class="bg-dividerLight text-secondaryLight inline-flex px-1 ml-1 rounded"
|
||||
>
|
||||
{{ key }}
|
||||
</kbd>
|
||||
|
||||
@@ -47,9 +47,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
addNewCollection() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("collection.invalid_name"))
|
||||
return
|
||||
}
|
||||
this.$emit("submit", this.name)
|
||||
|
||||
@@ -51,9 +51,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
addFolder() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(this.$t("folder.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("folder.invalid_name"))
|
||||
return
|
||||
}
|
||||
this.$emit("add-folder", {
|
||||
|
||||
@@ -18,18 +18,7 @@
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
autofocus
|
||||
class="
|
||||
bg-transparent
|
||||
border-t border-dividerLight
|
||||
cursor-pointer
|
||||
flex
|
||||
font-semibold
|
||||
w-full
|
||||
py-2
|
||||
px-4
|
||||
appearance-none
|
||||
hover:bg-primaryDark
|
||||
"
|
||||
class="border-dividerLight hover:bg-primaryDark flex w-full px-4 py-2 font-semibold bg-transparent border-t appearance-none cursor-pointer"
|
||||
@change="updateSelectedTeam(myTeams[$event.target.value])"
|
||||
>
|
||||
<option
|
||||
|
||||
@@ -48,9 +48,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
saveCollection() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("collection.invalid_name"))
|
||||
return
|
||||
}
|
||||
this.$emit("submit", this.name)
|
||||
|
||||
@@ -48,9 +48,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
editFolder() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(this.$t("folder.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("folder.invalid_name"))
|
||||
return
|
||||
}
|
||||
this.$emit("submit", this.name)
|
||||
|
||||
@@ -47,9 +47,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
saveRequest() {
|
||||
if (!this.requestUpdateData.name) {
|
||||
this.$toast.error(this.$t("request.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("request.invalid_name"))
|
||||
return
|
||||
}
|
||||
this.$emit("submit", this.requestUpdateData)
|
||||
|
||||
@@ -229,15 +229,11 @@ export default defineComponent({
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
this.$toast.success(this.$t("export.gist_created"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("export.gist_created"))
|
||||
window.open(res.html_url)
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
},
|
||||
@@ -415,23 +411,17 @@ export default defineComponent({
|
||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
this.$toast.success(this.$t("state.download_started"), {
|
||||
icon: "downloading",
|
||||
})
|
||||
this.$toast.success(this.$t("state.download_started"))
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
}, 1000)
|
||||
},
|
||||
fileImported() {
|
||||
this.$toast.success(this.$t("state.file_imported"), {
|
||||
icon: "folder_shared",
|
||||
})
|
||||
this.$toast.success(this.$t("state.file_imported"))
|
||||
},
|
||||
failedImport() {
|
||||
this.$toast.error(this.$t("import.failed"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("import.failed"))
|
||||
},
|
||||
parsePostmanCollection({ info, name, item }) {
|
||||
const hoppscotchCollection = {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<SmartModal
|
||||
v-if="show"
|
||||
:title="`${$t('collection.save_as')}`"
|
||||
:title="`${t('collection.save_as')}`"
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div class="flex relative">
|
||||
<div class="relative flex">
|
||||
<input
|
||||
id="selectLabelSaveReq"
|
||||
v-model="requestName"
|
||||
@@ -18,11 +18,11 @@
|
||||
@keyup.enter="saveRequestAs"
|
||||
/>
|
||||
<label for="selectLabelSaveReq">
|
||||
{{ $t("request.name") }}
|
||||
{{ t("request.name") }}
|
||||
</label>
|
||||
</div>
|
||||
<label class="p-4">
|
||||
{{ $t("collection.select_location") }}
|
||||
{{ t("collection.select_location") }}
|
||||
</label>
|
||||
<CollectionsGraphql
|
||||
v-if="mode === 'graphql'"
|
||||
@@ -45,11 +45,11 @@
|
||||
<template #footer>
|
||||
<span>
|
||||
<ButtonPrimary
|
||||
:label="`${$t('action.save')}`"
|
||||
:label="`${t('action.save')}`"
|
||||
@click.native="saveRequestAs"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('action.cancel')}`"
|
||||
:label="`${t('action.cancel')}`"
|
||||
@click.native="hideModal"
|
||||
/>
|
||||
</span>
|
||||
@@ -58,7 +58,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||
import { reactive, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { isHoppRESTRequest } from "~/helpers/types/HoppRESTRequest"
|
||||
import {
|
||||
editGraphqlRequest,
|
||||
@@ -75,6 +75,9 @@ import {
|
||||
import * as teamUtils from "~/helpers/teams/utils"
|
||||
import { apolloClient } from "~/helpers/apollo"
|
||||
import { HoppGQLRequest } from "~/helpers/types/HoppGQLRequest"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
type CollectionType =
|
||||
| {
|
||||
@@ -137,12 +140,7 @@ const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
// TODO: Use a better implementation with computed ?
|
||||
// This implementation can't work across updates to mode prop (which won't happen tho)
|
||||
@@ -194,15 +192,11 @@ const hideModal = () => {
|
||||
|
||||
const saveRequestAs = async () => {
|
||||
if (!requestName.value) {
|
||||
$toast.error(`${t("error.empty_req_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.empty_req_name")}`)
|
||||
return
|
||||
}
|
||||
if (picked.value === null) {
|
||||
$toast.error(`${t("collection.select")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("collection.select")}`)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -283,9 +277,7 @@ const saveRequestAs = async () => {
|
||||
requestSaved()
|
||||
})
|
||||
.catch((error) => {
|
||||
$toast.error(t("profile.no_permission").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("profile.no_permission")}`)
|
||||
throw new Error(error)
|
||||
})
|
||||
|
||||
@@ -320,9 +312,7 @@ const saveRequestAs = async () => {
|
||||
|
||||
requestSaved()
|
||||
} catch (error) {
|
||||
$toast.error(t("profile.no_permission").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("profile.no_permission")}`)
|
||||
console.error(error)
|
||||
}
|
||||
} else if (picked.value.pickedType === "teams-collection") {
|
||||
@@ -352,9 +342,7 @@ const saveRequestAs = async () => {
|
||||
|
||||
requestSaved()
|
||||
} catch (error) {
|
||||
$toast.error(t("profile.no_permission").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("profile.no_permission")}`)
|
||||
console.error(error)
|
||||
}
|
||||
} else if (picked.value.pickedType === "gql-my-request") {
|
||||
@@ -386,9 +374,7 @@ const saveRequestAs = async () => {
|
||||
}
|
||||
|
||||
const requestSaved = () => {
|
||||
$toast.success(`${t("request.added")}`, {
|
||||
icon: "post_add",
|
||||
})
|
||||
toast.success(`${t("request.added")}`)
|
||||
hideModal()
|
||||
}
|
||||
|
||||
|
||||
@@ -49,9 +49,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
addNewCollection() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@@ -10,7 +10,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,15 +20,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.name }} </span>
|
||||
@@ -38,7 +30,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
path: `${collectionIndex}`,
|
||||
@@ -99,16 +91,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -149,25 +132,12 @@
|
||||
v-if="
|
||||
collection.folders.length === 0 && collection.requests.length === 0
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -251,9 +221,7 @@ export default defineComponent({
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeGraphqlCollection(this.collectionIndex)
|
||||
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
||||
},
|
||||
dropEvent({ dataTransfer }: any) {
|
||||
this.dragging = !this.dragging
|
||||
|
||||
@@ -54,9 +54,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
saveCollection() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
const collectionUpdated = {
|
||||
|
||||
@@ -54,9 +54,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
editFolder() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
editGraphqlFolder(this.folderPath, {
|
||||
|
||||
@@ -58,9 +58,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
saveRequest() {
|
||||
if (!this.requestUpdateData.name) {
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("collection.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
const requestUpdated = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@@ -10,7 +10,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,15 +20,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -40,7 +32,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -95,16 +87,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -148,25 +131,12 @@
|
||||
folder.requests &&
|
||||
folder.requests.length === 0
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -250,9 +220,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
removeGraphqlFolder(this.folderPath)
|
||||
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
||||
},
|
||||
dropEvent({ dataTransfer }: any) {
|
||||
this.dragging = !this.dragging
|
||||
|
||||
@@ -140,15 +140,11 @@ export default defineComponent({
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
this.$toast.success(this.$t("export.gist_created"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("export.gist_created"))
|
||||
window.open(res.html_url)
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
},
|
||||
@@ -252,23 +248,17 @@ export default defineComponent({
|
||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
this.$toast.success(this.$t("state.download_started"), {
|
||||
icon: "downloading",
|
||||
})
|
||||
this.$toast.success(this.$t("state.download_started"))
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
}, 1000)
|
||||
},
|
||||
fileImported() {
|
||||
this.$toast.success(this.$t("state.file_imported"), {
|
||||
icon: "folder_shared",
|
||||
})
|
||||
this.$toast.success(this.$t("state.file_imported"))
|
||||
},
|
||||
failedImport() {
|
||||
this.$toast.error(this.$t("import.failed"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("import.failed"))
|
||||
},
|
||||
parsePostmanCollection({ info, name, item }) {
|
||||
const hoppscotchCollection = {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
@@ -9,15 +9,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex
|
||||
px-2
|
||||
w-16
|
||||
justify-center
|
||||
items-center
|
||||
truncate
|
||||
"
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -27,15 +19,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -46,7 +30,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
@@ -194,9 +178,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
removeGraphqlRequest(this.folderPath, this.requestIndex)
|
||||
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -4,14 +4,7 @@
|
||||
:class="{ 'rounded border border-divider': savingMode }"
|
||||
>
|
||||
<div
|
||||
class="
|
||||
divide-y divide-dividerLight
|
||||
border-b border-dividerLight
|
||||
flex flex-col
|
||||
top-0
|
||||
z-10
|
||||
sticky
|
||||
"
|
||||
class="divide-dividerLight border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y"
|
||||
:class="{ 'bg-primary': !savingMode }"
|
||||
>
|
||||
<input
|
||||
@@ -20,9 +13,9 @@
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="bg-transparent flex w-full py-2 px-4"
|
||||
class="flex w-full px-4 py-2 bg-transparent"
|
||||
/>
|
||||
<div class="flex flex-1 justify-between">
|
||||
<div class="flex justify-between flex-1">
|
||||
<ButtonSecondary
|
||||
svg="plus"
|
||||
:label="$t('action.new')"
|
||||
@@ -69,15 +62,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="collections.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.collections')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.collections") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -88,9 +81,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="!(filteredCollections.length !== 0 || collections.length === 0)"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
|
||||
@@ -4,16 +4,7 @@
|
||||
:class="{ 'rounded border border-divider': saveRequest }"
|
||||
>
|
||||
<div
|
||||
class="
|
||||
divide-y divide-dividerLight
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
rounded-t
|
||||
flex flex-col
|
||||
top-0
|
||||
z-10
|
||||
sticky
|
||||
"
|
||||
class="divide-dividerLight bg-primary border-dividerLight sticky top-0 z-10 flex flex-col border-b divide-y rounded-t"
|
||||
>
|
||||
<div v-if="!saveRequest" class="search-wrappe">
|
||||
<input
|
||||
@@ -21,7 +12,7 @@
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="$t('action.search')"
|
||||
class="bg-transparent flex w-full py-2 pr-2 pl-4"
|
||||
class="flex w-full py-2 pl-4 pr-2 bg-transparent"
|
||||
/>
|
||||
</div>
|
||||
<CollectionsChooseType
|
||||
@@ -31,7 +22,7 @@
|
||||
@update-collection-type="updateCollectionType"
|
||||
@update-selected-team="updateSelectedTeam"
|
||||
/>
|
||||
<div class="flex flex-1 justify-between">
|
||||
<div class="flex justify-between flex-1">
|
||||
<ButtonSecondary
|
||||
v-if="
|
||||
collectionsType.type == 'team-collections' &&
|
||||
@@ -107,15 +98,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="filteredCollections.length === 0 && filterText.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.collections')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.collections") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -140,9 +131,9 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="filterText.length !== 0 && filteredCollections.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<i class="material-icons pb-2 opacity-75">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
@@ -361,14 +352,10 @@ export default defineComponent({
|
||||
this.collectionsType.selectedTeam.id
|
||||
)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("collection.created"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("collection.created"))
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -377,9 +364,7 @@ export default defineComponent({
|
||||
// Intented to be called by CollectionEdit modal submit event
|
||||
updateEditingCollection(newName) {
|
||||
if (!newName) {
|
||||
this.$toast.error(this.$t("collection.invalid_name"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("collection.invalid_name"))
|
||||
return
|
||||
}
|
||||
if (this.collectionsType.type === "my-collections") {
|
||||
@@ -396,14 +381,10 @@ export default defineComponent({
|
||||
teamUtils
|
||||
.renameCollection(this.$apollo, newName, this.editingCollection.id)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("collection.renamed"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("collection.renamed"))
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -420,14 +401,10 @@ export default defineComponent({
|
||||
teamUtils
|
||||
.renameCollection(this.$apollo, name, this.editingFolder.id)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("folder.renamed"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("folder.renamed"))
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -460,15 +437,11 @@ export default defineComponent({
|
||||
this.editingRequestIndex
|
||||
)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("request.renamed"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("request.renamed"))
|
||||
this.$emit("update-team-collections")
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -533,15 +506,11 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("folder.created"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("folder.created"))
|
||||
this.$emit("update-team-collections")
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -605,9 +574,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
removeRESTCollection(collectionIndex)
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
} else if (collectionsType.type === "team-collections") {
|
||||
// Cancel pick if picked collection is deleted
|
||||
if (
|
||||
@@ -633,14 +600,10 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
@@ -658,9 +621,7 @@ export default defineComponent({
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeRESTRequest(folderPath, requestIndex)
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
} else if (this.collectionsType.type === "team-collections") {
|
||||
// Cancel pick if the picked item is being deleted
|
||||
if (
|
||||
@@ -674,14 +635,10 @@ export default defineComponent({
|
||||
teamUtils
|
||||
.deleteRequest(this.$apollo, requestIndex)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@@ -10,7 +10,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,15 +20,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.name }} </span>
|
||||
@@ -55,7 +47,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
folder: collection,
|
||||
@@ -118,16 +110,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -175,25 +158,12 @@
|
||||
(collection.requests == undefined ||
|
||||
collection.requests.length === 0)
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
@dragover.prevent
|
||||
@drop.prevent="dropEvent"
|
||||
@dragover="dragging = true"
|
||||
@@ -10,7 +10,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -20,15 +20,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -40,7 +32,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -100,16 +92,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -157,25 +140,12 @@
|
||||
folder.requests &&
|
||||
folder.requests.length === 0
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -262,9 +232,7 @@ export default defineComponent({
|
||||
this.$emit("select", { picked: null })
|
||||
}
|
||||
removeRESTFolder(this.folderPath)
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
},
|
||||
dropEvent({ dataTransfer }) {
|
||||
this.dragging = !this.dragging
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex flex-col" :class="[{ 'bg-primaryLight': dragging }]">
|
||||
<div
|
||||
class="flex items-center group"
|
||||
class="group flex items-center"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@dragover.stop
|
||||
@@ -9,15 +9,7 @@
|
||||
@dragend="dragging = false"
|
||||
>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex
|
||||
px-2
|
||||
w-16
|
||||
justify-center
|
||||
items-center
|
||||
truncate
|
||||
"
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
:class="getRequestLabelColor(request.method)"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
@@ -32,16 +24,7 @@
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
items-center
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -61,7 +44,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center group">
|
||||
<div class="group flex items-center">
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -12,15 +12,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate"> {{ collection.title }} </span>
|
||||
@@ -47,7 +39,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="
|
||||
$emit('add-folder', {
|
||||
folder: collection,
|
||||
@@ -114,16 +106,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -169,25 +152,12 @@
|
||||
(collection.requests == undefined ||
|
||||
collection.requests.length === 0)
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.collection')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center group">
|
||||
<div class="group flex items-center">
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<SmartIcon
|
||||
@@ -12,15 +12,7 @@
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="toggleShowChildren()"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -33,7 +25,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="folder-plus"
|
||||
:title="$t('folder.new')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="$emit('add-folder', { folder, path: folderPath })"
|
||||
/>
|
||||
<span>
|
||||
@@ -97,16 +89,7 @@
|
||||
</div>
|
||||
<div v-if="showChildren || isFiltered" class="flex">
|
||||
<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()"
|
||||
></div>
|
||||
<div class="flex flex-col flex-1 truncate">
|
||||
@@ -150,25 +133,12 @@
|
||||
(folder.children == undefined || folder.children.length === 0) &&
|
||||
(folder.requests == undefined || folder.requests.length === 0)
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/pack.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
mb-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 mb-4"
|
||||
:alt="$t('empty.folder')"
|
||||
/>
|
||||
<span class="text-center">
|
||||
@@ -253,15 +223,11 @@ export default defineComponent({
|
||||
teamUtils
|
||||
.deleteCollection(this.$apollo, this.folder.id)
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(this.$t("state.deleted"))
|
||||
this.$emit("update-team-collections")
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
this.$emit("update-team-collections")
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="flex items-center group">
|
||||
<div class="group flex items-center">
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex
|
||||
px-2
|
||||
w-16
|
||||
justify-center
|
||||
items-center
|
||||
truncate
|
||||
"
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
:class="getRequestLabelColor(request.method)"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
@@ -25,16 +17,7 @@
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
items-center
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex items-center flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="!doc ? selectRequest() : {}"
|
||||
>
|
||||
<span class="truncate"> {{ request.name }} </span>
|
||||
@@ -53,7 +36,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
svg="rotate-ccw"
|
||||
:title="$t('action.restore')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="!doc ? selectRequest() : {}"
|
||||
/>
|
||||
<span>
|
||||
|
||||
@@ -52,9 +52,7 @@ export default defineComponent({
|
||||
methods: {
|
||||
addNewEnvironment() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(`${this.$t("environment.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("environment.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
createEnvironment(this.name)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
>
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div class="flex relative">
|
||||
<div class="relative flex">
|
||||
<input
|
||||
id="selectLabelEnvEdit"
|
||||
v-model="name"
|
||||
@@ -22,7 +22,7 @@
|
||||
{{ $t("action.label") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex flex-1 justify-between items-center">
|
||||
<div class="flex items-center justify-between flex-1">
|
||||
<label for="variableList" class="p-4">
|
||||
{{ $t("environment.variable_list") }}
|
||||
</label>
|
||||
@@ -43,21 +43,21 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divide-y divide-dividerLight border-divider border rounded">
|
||||
<div class="divide-dividerLight border-divider border divide-y rounded">
|
||||
<div
|
||||
v-for="(variable, index) in vars"
|
||||
:key="`variable-${index}`"
|
||||
class="divide-x divide-dividerLight flex"
|
||||
class="divide-dividerLight flex divide-x"
|
||||
>
|
||||
<input
|
||||
v-model="variable.key"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
:placeholder="`${$t('count.variable', { count: index + 1 })}`"
|
||||
:name="'param' + index"
|
||||
/>
|
||||
<input
|
||||
v-model="variable.value"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||
:name="'value' + index"
|
||||
/>
|
||||
@@ -74,28 +74,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="vars.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.environments')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.environments") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
@@ -177,9 +164,7 @@ export default defineComponent({
|
||||
clearContent() {
|
||||
this.vars = []
|
||||
this.clearIcon = "check"
|
||||
this.$toast.success(`${this.$t("state.cleared")}`, {
|
||||
icon: "clear_all",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.cleared")}`)
|
||||
setTimeout(() => (this.clearIcon = "trash-2"), 1000)
|
||||
},
|
||||
addEnvironmentVariable() {
|
||||
@@ -193,9 +178,7 @@ export default defineComponent({
|
||||
},
|
||||
saveEnvironment() {
|
||||
if (!this.name) {
|
||||
this.$toast.error(`${this.$t("environment.invalid_name")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("environment.invalid_name")}`)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
<template>
|
||||
<div class="flex items-center group">
|
||||
<div class="group flex items-center">
|
||||
<span
|
||||
class="cursor-pointer flex px-4 justify-center items-center"
|
||||
class="flex items-center justify-center px-4 cursor-pointer"
|
||||
@click="$emit('edit-environment')"
|
||||
>
|
||||
<SmartIcon class="svg-icons" name="layers" />
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
@click="$emit('edit-environment')"
|
||||
>
|
||||
<span class="truncate">
|
||||
@@ -102,9 +94,7 @@ export default defineComponent({
|
||||
removeEnvironment() {
|
||||
if (this.environmentIndex !== "Global")
|
||||
deleteEnvironment(this.environmentIndex)
|
||||
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
||||
},
|
||||
duplicateEnvironment() {
|
||||
if (this.environmentIndex === "Global") {
|
||||
|
||||
@@ -140,15 +140,11 @@ export default defineComponent({
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
this.$toast.success(this.$t("export.gist_created"), {
|
||||
icon: "done",
|
||||
})
|
||||
this.$toast.success(this.$t("export.gist_created"))
|
||||
window.open(res.html_url)
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
console.error(e)
|
||||
})
|
||||
},
|
||||
@@ -230,18 +226,14 @@ export default defineComponent({
|
||||
a.download = `${url.split("/").pop().split("#")[0].split("?")[0]}.json`
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
this.$toast.success(this.$t("state.download_started"), {
|
||||
icon: "downloading",
|
||||
})
|
||||
this.$toast.success(this.$t("state.download_started"))
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
}, 1000)
|
||||
},
|
||||
fileImported() {
|
||||
this.$toast.success(this.$t("state.file_imported"), {
|
||||
icon: "folder_shared",
|
||||
})
|
||||
this.$toast.success(this.$t("state.file_imported"))
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,27 +1,22 @@
|
||||
<template>
|
||||
<AppSection :label="`${$t('environment.title')}`">
|
||||
<div class="bg-primary rounded-t flex flex-col top-0 z-10 sticky">
|
||||
<div class="bg-primary sticky top-0 z-10 flex flex-col rounded-t">
|
||||
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
||||
<template #trigger>
|
||||
<span
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="`${$t('environment.select')}`"
|
||||
class="
|
||||
bg-transparent
|
||||
border-b border-dividerLight
|
||||
flex-1
|
||||
select-wrapper
|
||||
"
|
||||
class="border-dividerLight select-wrapper flex-1 bg-transparent border-b"
|
||||
>
|
||||
<ButtonSecondary
|
||||
v-if="selectedEnvironmentIndex !== -1"
|
||||
:label="environments[selectedEnvironmentIndex].name"
|
||||
class="rounded-none flex-1 pr-8"
|
||||
class="flex-1 pr-8 rounded-none"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-else
|
||||
:label="`${$t('environment.no_environment')}`"
|
||||
class="rounded-none flex-1 pr-8"
|
||||
class="flex-1 pr-8 rounded-none"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
@@ -50,7 +45,7 @@
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
<div class="border-b border-dividerLight flex flex-1 justify-between">
|
||||
<div class="border-dividerLight flex justify-between flex-1 border-b">
|
||||
<ButtonSecondary
|
||||
svg="plus"
|
||||
:label="`${$t('action.new')}`"
|
||||
@@ -91,7 +86,7 @@
|
||||
<EnvironmentsEnvironment
|
||||
environment-index="Global"
|
||||
:environment="globalEnvironment"
|
||||
class="border-b border-dashed border-dividerLight"
|
||||
class="border-dividerLight border-b border-dashed"
|
||||
@edit-environment="editEnvironment('Global')"
|
||||
/>
|
||||
<EnvironmentsEnvironment
|
||||
@@ -104,15 +99,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="environments.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.environments')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.environments") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@close="hideModal"
|
||||
>
|
||||
<template #body>
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col space-y-2 px-2">
|
||||
<div v-if="mode === 'sign-in'" class="flex flex-col px-2 space-y-2">
|
||||
<SmartItem
|
||||
:loading="signingInWithGitHub"
|
||||
svg="auth/github"
|
||||
@@ -56,9 +56,9 @@
|
||||
/>
|
||||
</form>
|
||||
<div v-if="mode === 'email-sent'" class="flex flex-col px-4">
|
||||
<div class="flex flex-col max-w-md justify-center items-center">
|
||||
<SmartIcon class="h-6 text-accent w-6" name="inbox" />
|
||||
<h3 class="my-2 text-center text-lg">
|
||||
<div class="flex flex-col items-center justify-center max-w-md">
|
||||
<SmartIcon class="text-accent w-6 h-6" name="inbox" />
|
||||
<h3 class="my-2 text-lg text-center">
|
||||
{{ $t("auth.we_sent_magic_link") }}
|
||||
</h3>
|
||||
<p class="text-center">
|
||||
@@ -95,7 +95,7 @@
|
||||
</p>
|
||||
<p
|
||||
v-if="mode === 'email-sent'"
|
||||
class="flex flex-1 text-secondaryLight justify-between"
|
||||
class="text-secondaryLight flex justify-between flex-1"
|
||||
>
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
@@ -155,9 +155,7 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
showLoginSuccess() {
|
||||
this.$toast.success(`${this.$t("auth.login_success")}`, {
|
||||
icon: "vpn_key",
|
||||
})
|
||||
this.$toast.success(`${this.$t("auth.login_success")}`)
|
||||
},
|
||||
async signInWithGoogle() {
|
||||
this.signingInWithGoogle = true
|
||||
@@ -174,7 +172,6 @@ export default defineComponent({
|
||||
// The pending Google credential.
|
||||
const pendingCred = e.credential
|
||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||
icon: "vpn_key",
|
||||
duration: 0,
|
||||
closeOnSwipe: false,
|
||||
action: {
|
||||
@@ -190,9 +187,7 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +213,6 @@ export default defineComponent({
|
||||
// The pending Google credential.
|
||||
const pendingCred = e.credential
|
||||
this.$toast.info(`${this.$t("auth.account_exists")}`, {
|
||||
icon: "vpn_key",
|
||||
duration: 0,
|
||||
closeOnSwipe: false,
|
||||
action: {
|
||||
@@ -234,9 +228,7 @@ export default defineComponent({
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,9 +248,7 @@ export default defineComponent({
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
this.$toast.error(e.message, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(e.message)
|
||||
this.signingInWithEmail = false
|
||||
})
|
||||
.finally(() => {
|
||||
|
||||
@@ -40,14 +40,10 @@ export default defineComponent({
|
||||
async logout() {
|
||||
try {
|
||||
await signOutUser()
|
||||
this.$toast.success(`${this.$t("auth.logged_out")}`, {
|
||||
icon: "vpn_key",
|
||||
})
|
||||
this.$toast.success(`${this.$t("auth.logged_out")}`)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(`${this.$t("error.something_went_wrong")}`)
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -21,28 +21,19 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="gqlField.description"
|
||||
class="text-secondaryLight py-2 field-desc"
|
||||
class="text-secondaryLight field-desc py-2"
|
||||
>
|
||||
{{ gqlField.description }}
|
||||
</div>
|
||||
<div
|
||||
v-if="gqlField.isDeprecated"
|
||||
class="
|
||||
rounded
|
||||
bg-yellow-200
|
||||
my-1
|
||||
text-black
|
||||
py-1
|
||||
px-2
|
||||
inline-block
|
||||
field-deprecated
|
||||
"
|
||||
class="field-deprecated inline-block px-2 py-1 my-1 text-black bg-yellow-200 rounded"
|
||||
>
|
||||
{{ $t("state.deprecated") }}
|
||||
</div>
|
||||
<div v-if="fieldArgs.length > 0">
|
||||
<h5 class="my-2">Arguments:</h5>
|
||||
<div class="border-divider border-l-2 pl-4">
|
||||
<div class="border-divider pl-4 border-l-2">
|
||||
<div v-for="(field, index) in fieldArgs" :key="`field-${index}`">
|
||||
<span>
|
||||
{{ field.name }}:
|
||||
@@ -53,7 +44,7 @@
|
||||
</span>
|
||||
<div
|
||||
v-if="field.description"
|
||||
class="text-secondaryLight py-2 field-desc"
|
||||
class="text-secondaryLight field-desc py-2"
|
||||
>
|
||||
{{ field.description }}
|
||||
</div>
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
<template>
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
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('request.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"
|
||||
:placeholder="`${t('request.url')}`"
|
||||
:disabled="connected"
|
||||
@keyup.enter="onConnectClick"
|
||||
/>
|
||||
<ButtonPrimary
|
||||
id="get"
|
||||
name="get"
|
||||
:label="!connected ? $t('action.connect') : $t('action.disconnect')"
|
||||
:label="!connected ? t('action.connect') : t('action.disconnect')"
|
||||
class="w-32"
|
||||
@click.native="onConnectClick"
|
||||
/>
|
||||
@@ -37,9 +27,15 @@
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||
import { getCurrentStrategyID } from "~/helpers/network"
|
||||
import { useReadonlyStream, useStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useStream,
|
||||
useI18n,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { gqlHeaders$, gqlURL$, setGQLURL } from "~/newstore/GQLSession"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
conn: GQLConnection
|
||||
}>()
|
||||
|
||||
@@ -3,55 +3,44 @@
|
||||
<SmartTabs styles="sticky bg-primary top-upperPrimaryStickyFold z-10">
|
||||
<template #actions>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('request.run')}`"
|
||||
:label="`${t('request.run')}`"
|
||||
svg="play"
|
||||
class="rounded-none !text-accent"
|
||||
@click.native="runQuery()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="saveRequest"
|
||||
:label="`${$t('request.save')}`"
|
||||
:label="`${t('request.save')}`"
|
||||
class="rounded-none"
|
||||
@click.native="saveRequest"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<SmartTab :id="'query'" :label="`${$t('tab.query')}`" :selected="true">
|
||||
<SmartTab :id="'query'" :label="`${t('tab.query')}`" :selected="true">
|
||||
<AppSection label="query">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
gqlRunQuery
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold gqlRunQuery sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.query") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.query") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io"
|
||||
to="https://docs.hoppscotch.io/graphql/#queries"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.prettify')"
|
||||
:title="t('action.prettify')"
|
||||
:svg="`${prettifyQueryIcon}`"
|
||||
@click.native="prettifyQuery"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyQueryIcon}`"
|
||||
@click.native="copyQuery"
|
||||
/>
|
||||
@@ -61,35 +50,25 @@
|
||||
</AppSection>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'variables'" :label="`${$t('tab.variables')}`">
|
||||
<SmartTab :id="'variables'" :label="`${t('tab.variables')}`">
|
||||
<AppSection label="variables">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.variables") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.variables") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io"
|
||||
to="https://docs.hoppscotch.io/graphql/#queries"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="`${copyVariablesIcon}`"
|
||||
@click.native="copyVariables"
|
||||
/>
|
||||
@@ -99,48 +78,38 @@
|
||||
</AppSection>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'headers'" :label="`${$t('tab.headers')}`">
|
||||
<SmartTab :id="'headers'" :label="`${t('tab.headers')}`">
|
||||
<AppSection label="headers">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("tab.headers") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("tab.headers") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io"
|
||||
to="https://docs.hoppscotch.io/graphql/#headers"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.bulk_mode')"
|
||||
:title="t('state.bulk_mode')"
|
||||
svg="edit"
|
||||
:class="{ '!text-accent': bulkMode }"
|
||||
@click.native="bulkMode = !bulkMode"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
:title="t('add.new')"
|
||||
svg="plus"
|
||||
:disabled="bulkMode"
|
||||
@click.native="addRequestHeader"
|
||||
@@ -152,14 +121,10 @@
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${String(index)}`"
|
||||
class="
|
||||
divide-x divide-dividerLight
|
||||
border-b border-dividerLight
|
||||
flex
|
||||
"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${$t('count.header', { count: index + 1 })}`"
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
:spellcheck="false"
|
||||
:value="header.key"
|
||||
@@ -182,8 +147,8 @@
|
||||
"
|
||||
/>
|
||||
<input
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
:name="`value ${String(index)}`"
|
||||
:value="header.value"
|
||||
autofocus
|
||||
@@ -201,9 +166,9 @@
|
||||
:title="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? $t('action.turn_off')
|
||||
: $t('action.turn_on')
|
||||
: $t('action.turn_off')
|
||||
? t('action.turn_off')
|
||||
: t('action.turn_on')
|
||||
: t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
header.hasOwnProperty('active')
|
||||
@@ -225,7 +190,7 @@
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
:title="t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="removeRequestHeader(index)"
|
||||
@@ -234,32 +199,19 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="headers.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.headers')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.headers") }}
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('add.new')}`"
|
||||
:label="`${t('add.new')}`"
|
||||
filled
|
||||
svg="plus"
|
||||
class="mb-4"
|
||||
@@ -280,7 +232,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||
import { onMounted, ref, watch } from "@nuxtjs/composition-api"
|
||||
import clone from "lodash/clone"
|
||||
import * as gql from "graphql"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
@@ -288,6 +240,8 @@ import {
|
||||
useNuxt,
|
||||
useReadonlyStream,
|
||||
useStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import {
|
||||
addGQLHeader,
|
||||
@@ -314,15 +268,14 @@ import jsonLinter from "~/helpers/editor/linting/json"
|
||||
import { createGQLQueryLinter } from "~/helpers/editor/linting/gqlQuery"
|
||||
import queryCompleter from "~/helpers/editor/completion/gqlQuery"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
conn: GQLConnection
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const nuxt = useNuxt()
|
||||
|
||||
const bulkMode = ref(false)
|
||||
@@ -335,11 +288,9 @@ watch(bulkHeaders, () => {
|
||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||
active: !item.trim().startsWith("//"),
|
||||
}))
|
||||
setGQLHeaders(transformation)
|
||||
setGQLHeaders(transformation as GQLHeader[])
|
||||
} catch (e) {
|
||||
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.something_went_wrong")}`)
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
@@ -392,12 +343,13 @@ const showSaveRequestModal = ref(false)
|
||||
watch(
|
||||
headers,
|
||||
() => {
|
||||
if (
|
||||
(headers.value[headers.value.length - 1]?.key !== "" ||
|
||||
headers.value[headers.value.length - 1]?.value !== "") &&
|
||||
headers.value.length
|
||||
)
|
||||
addRequestHeader()
|
||||
if (!bulkMode.value)
|
||||
if (
|
||||
(headers.value[headers.value.length - 1]?.key !== "" ||
|
||||
headers.value[headers.value.length - 1]?.value !== "") &&
|
||||
headers.value.length
|
||||
)
|
||||
addRequestHeader()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
@@ -427,6 +379,7 @@ onMounted(() => {
|
||||
const copyQuery = () => {
|
||||
copyToClipboard(gqlQueryString.value)
|
||||
copyQueryIcon.value = "check"
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyQueryIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
@@ -470,18 +423,14 @@ const runQuery = async () => {
|
||||
})
|
||||
)
|
||||
|
||||
$toast.success(`${t("state.finished_in", { duration })}`, {
|
||||
icon: "done",
|
||||
})
|
||||
toast.success(`${t("state.finished_in", { duration })}`)
|
||||
} catch (e: any) {
|
||||
response.value = `${e}`
|
||||
nuxt.value.$loading.finish()
|
||||
|
||||
$toast.error(
|
||||
toast.error(
|
||||
`${t("error.something_went_wrong")}. ${t("error.check_console_details")}`,
|
||||
{
|
||||
icon: "error_outline",
|
||||
}
|
||||
{}
|
||||
)
|
||||
console.error(e)
|
||||
}
|
||||
@@ -499,12 +448,11 @@ const hideRequestModal = () => {
|
||||
const prettifyQuery = () => {
|
||||
try {
|
||||
gqlQueryString.value = gql.print(gql.parse(gqlQueryString.value))
|
||||
prettifyQueryIcon.value = "check"
|
||||
} catch (e) {
|
||||
$toast.error(`${t("error.gql_prettify_invalid_query")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.gql_prettify_invalid_query")}`)
|
||||
prettifyQueryIcon.value = "info"
|
||||
}
|
||||
prettifyQueryIcon.value = "check"
|
||||
setTimeout(() => (prettifyQueryIcon.value = "wand"), 1000)
|
||||
}
|
||||
|
||||
@@ -515,6 +463,7 @@ const saveRequest = () => {
|
||||
const copyVariables = () => {
|
||||
copyToClipboard(variableString.value)
|
||||
copyVariablesIcon.value = "check"
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyVariablesIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
@@ -542,11 +491,10 @@ const removeRequestHeader = (index: number) => {
|
||||
|
||||
const deletedItem = headersBeforeDeletion[index]
|
||||
if (deletedItem.key || deletedItem.value) {
|
||||
$toast.success(t("state.deleted").toString(), {
|
||||
icon: "delete",
|
||||
toast.success(`${t("state.deleted")}`, {
|
||||
action: [
|
||||
{
|
||||
text: t("action.undo").toString(),
|
||||
text: `${t("action.undo")}`,
|
||||
onClick: (_, toastObject) => {
|
||||
setGQLHeaders(headersBeforeDeletion as GQLHeader[])
|
||||
editBulkHeadersLine(index, deletedItem)
|
||||
|
||||
@@ -2,32 +2,22 @@
|
||||
<AppSection ref="response" label="response">
|
||||
<div
|
||||
v-if="responseString === 'loading'"
|
||||
class="flex flex-col p-4 items-center justify-center"
|
||||
class="flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<SmartSpinner class="my-4" />
|
||||
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
|
||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
||||
</div>
|
||||
<div v-else-if="responseString">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
pl-4
|
||||
top-0
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("response.title") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("response.title") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -35,14 +25,14 @@
|
||||
<ButtonSecondary
|
||||
ref="downloadResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadResponseIcon"
|
||||
@click.native="downloadResponse"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="copyResponseButton"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyResponseIcon"
|
||||
@click.native="copyResponse"
|
||||
/>
|
||||
@@ -52,21 +42,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="
|
||||
flex flex-col flex-1
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1 p-4"
|
||||
>
|
||||
<div class="flex space-x-2 pb-4 my-4">
|
||||
<div class="flex flex-col space-y-4 text-right items-end">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.general.command_menu") }}
|
||||
<div class="flex pb-4 my-4 space-x-2">
|
||||
<div class="flex flex-col items-end space-y-4 text-right">
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.general.command_menu") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.general.help_menu") }}
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.general.help_menu") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
@@ -79,8 +63,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('app.documentation')}`"
|
||||
to="https://docs.hoppscotch.io"
|
||||
:label="`${t('app.documentation')}`"
|
||||
to="https://docs.hoppscotch.io/features/response"
|
||||
svg="external-link"
|
||||
blank
|
||||
outline
|
||||
@@ -91,17 +75,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { gqlResponse$ } from "~/newstore/GQLSession"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const responseString = useReadonlyStream(gqlResponse$, "")
|
||||
|
||||
@@ -128,6 +114,7 @@ const copyResponseIcon = ref("copy")
|
||||
const copyResponse = () => {
|
||||
copyToClipboard(responseString.value!)
|
||||
copyResponseIcon.value = "check"
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyResponseIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
@@ -141,9 +128,7 @@ const downloadResponse = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadResponseIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<SmartTab
|
||||
:id="'history'"
|
||||
icon="clock"
|
||||
:label="`${$t('tab.history')}`"
|
||||
:label="`${t('tab.history')}`"
|
||||
:selected="true"
|
||||
>
|
||||
<History
|
||||
@@ -16,7 +16,7 @@
|
||||
<SmartTab
|
||||
:id="'collections'"
|
||||
icon="folder"
|
||||
:label="`${$t('tab.collections')}`"
|
||||
:label="`${t('tab.collections')}`"
|
||||
>
|
||||
<CollectionsGraphql />
|
||||
</SmartTab>
|
||||
@@ -24,7 +24,7 @@
|
||||
<SmartTab
|
||||
:id="'docs'"
|
||||
icon="book-open"
|
||||
:label="`${$t('tab.documentation')}`"
|
||||
:label="`${t('tab.documentation')}`"
|
||||
>
|
||||
<AppSection label="docs">
|
||||
<div
|
||||
@@ -34,46 +34,33 @@
|
||||
subscriptionFields.length === 0 &&
|
||||
graphqlTypes.length === 0
|
||||
"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_comment.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.documentation')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.documentation')}`"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.documentation") }}
|
||||
<span class="mb-4 text-center">
|
||||
{{ t("empty.documentation") }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="bg-primary flex top-0 z-10 sticky">
|
||||
<div class="bg-primary sticky top-0 z-10 flex">
|
||||
<input
|
||||
v-model="graphqlFieldsFilterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
:placeholder="`${$t('action.search')}`"
|
||||
class="bg-transparent flex w-full p-4 py-2"
|
||||
:placeholder="`${t('action.search')}`"
|
||||
class="flex w-full p-4 py-2 bg-transparent"
|
||||
/>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/quickstart/graphql"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
</div>
|
||||
@@ -86,9 +73,9 @@
|
||||
<SmartTab
|
||||
v-if="queryFields.length > 0"
|
||||
:id="'queries'"
|
||||
:label="`${$t('tab.queries')}`"
|
||||
:label="`${t('tab.queries')}`"
|
||||
:selected="true"
|
||||
class="divide-y divide-dividerLight"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredQueryFields"
|
||||
@@ -101,8 +88,8 @@
|
||||
<SmartTab
|
||||
v-if="mutationFields.length > 0"
|
||||
:id="'mutations'"
|
||||
:label="`${$t('graphql.mutations')}`"
|
||||
class="divide-y divide-dividerLight"
|
||||
:label="`${t('graphql.mutations')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredMutationFields"
|
||||
@@ -115,8 +102,8 @@
|
||||
<SmartTab
|
||||
v-if="subscriptionFields.length > 0"
|
||||
:id="'subscriptions'"
|
||||
:label="`${$t('graphql.subscriptions')}`"
|
||||
class="divide-y divide-dividerLight"
|
||||
:label="`${t('graphql.subscriptions')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlField
|
||||
v-for="(field, index) in filteredSubscriptionFields"
|
||||
@@ -130,8 +117,8 @@
|
||||
v-if="graphqlTypes.length > 0"
|
||||
:id="'types'"
|
||||
ref="typesTab"
|
||||
:label="`${$t('tab.types')}`"
|
||||
class="divide-y divide-dividerLight"
|
||||
:label="`${t('tab.types')}`"
|
||||
class="divide-dividerLight divide-y"
|
||||
>
|
||||
<GraphqlType
|
||||
v-for="(type, index) in filteredGraphqlTypes"
|
||||
@@ -149,36 +136,26 @@
|
||||
</AppSection>
|
||||
</SmartTab>
|
||||
|
||||
<SmartTab :id="'schema'" icon="box" :label="`${$t('tab.schema')}`">
|
||||
<SmartTab :id="'schema'" icon="box" :label="`${t('tab.schema')}`">
|
||||
<AppSection ref="schema" label="schema">
|
||||
<div
|
||||
v-if="schemaString"
|
||||
class="
|
||||
bg-primary
|
||||
flex flex-1
|
||||
top-0
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
border-b border-dividerLight
|
||||
"
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("graphql.schema") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("graphql.schema") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/quickstart/graphql"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -186,14 +163,14 @@
|
||||
<ButtonSecondary
|
||||
ref="downloadSchema"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadSchemaIcon"
|
||||
@click.native="downloadSchema"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
ref="copySchemaCode"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copySchemaIcon"
|
||||
@click.native="copySchema"
|
||||
/>
|
||||
@@ -202,29 +179,16 @@
|
||||
<div v-if="schemaString" ref="schemaEditor"></div>
|
||||
<div
|
||||
v-else
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/blockchain.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.schema')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.schema')}`"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
{{ $t("empty.schema") }}
|
||||
<span class="mb-4 text-center">
|
||||
{{ t("empty.schema") }}
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
@@ -233,20 +197,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
reactive,
|
||||
ref,
|
||||
useContext,
|
||||
} from "@nuxtjs/composition-api"
|
||||
import { computed, nextTick, reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { GraphQLField, GraphQLType } from "graphql"
|
||||
import { map } from "rxjs/operators"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { GQLConnection } from "~/helpers/GQLConnection"
|
||||
import { GQLHeader } from "~/helpers/types/HoppGQLRequest"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import {
|
||||
setGQLHeaders,
|
||||
setGQLQuery,
|
||||
@@ -255,6 +217,8 @@ import {
|
||||
setGQLVariables,
|
||||
} from "~/newstore/GQLSession"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
function isTextFoundInGraphqlFieldObject(
|
||||
text: string,
|
||||
field: GraphQLField<any, any>
|
||||
@@ -321,11 +285,7 @@ const props = defineProps<{
|
||||
conn: GQLConnection
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const queryFields = useReadonlyStream(
|
||||
props.conn.queryFields$.pipe(map((x) => x ?? [])),
|
||||
@@ -408,12 +368,25 @@ const handleJumpToType = async (type: GraphQLType) => {
|
||||
await nextTick()
|
||||
|
||||
const rootTypeName = resolveRootType(type).name
|
||||
|
||||
const target = document.getElementById(`type_${rootTypeName}`)
|
||||
if (target) {
|
||||
gqlTabs.value.$el
|
||||
.querySelector(".gqlTabs")
|
||||
.scrollTo({ top: target.offsetTop, behavior: "smooth" })
|
||||
target.scrollIntoView({ block: "center", behavior: "smooth" })
|
||||
target.classList.add(
|
||||
"transition-all",
|
||||
"ring-inset",
|
||||
"ring-accentLight",
|
||||
"ring-4"
|
||||
)
|
||||
setTimeout(
|
||||
() =>
|
||||
target.classList.remove(
|
||||
"ring-inset",
|
||||
"ring-accentLight",
|
||||
"ring-4",
|
||||
"transition-all"
|
||||
),
|
||||
2000
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,9 +422,7 @@ const downloadSchema = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadSchemaIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<span v-else-if="isEnum" class="text-accent">enum </span>
|
||||
{{ gqlType.name }}
|
||||
</div>
|
||||
<div v-if="gqlType.description" class="text-secondaryLight py-2 type-desc">
|
||||
<div v-if="gqlType.description" class="py-2 text-secondaryLight type-desc">
|
||||
{{ gqlType.description }}
|
||||
</div>
|
||||
<div v-if="interfaces.length > 0">
|
||||
@@ -18,7 +18,7 @@
|
||||
<GraphqlTypeLink
|
||||
:gql-type="gqlInterface"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@
|
||||
:key="`child-${index}`"
|
||||
:gql-type="child"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="gqlType.getFields">
|
||||
@@ -37,7 +37,7 @@
|
||||
<GraphqlField
|
||||
v-for="(field, index) in gqlType.getFields()"
|
||||
:key="`field-${index}`"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
:gql-field="field"
|
||||
:is-highlighted="isFieldHighlighted({ field })"
|
||||
:jump-type-callback="jumpTypeCallback"
|
||||
@@ -48,7 +48,7 @@
|
||||
<div
|
||||
v-for="(value, index) in gqlType.getValues()"
|
||||
:key="`value-${index}`"
|
||||
class="border-divider border-l-2 pl-4"
|
||||
class="pl-4 border-l-2 border-divider"
|
||||
v-text="value.name"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
<template>
|
||||
<div class="flex flex-col group">
|
||||
<div class="group flex flex-col">
|
||||
<div class="flex items-center">
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
pl-4
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pl-4 pr-2 transition cursor-pointer"
|
||||
data-testid="restore_history_entry"
|
||||
@click="useEntry"
|
||||
>
|
||||
@@ -24,7 +15,7 @@
|
||||
svg="trash"
|
||||
color="red"
|
||||
:title="$t('action.remove')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
data-testid="delete_history_entry"
|
||||
@click.native="$emit('delete-entry')"
|
||||
/>
|
||||
@@ -32,7 +23,7 @@
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="expand ? $t('hide.more') : $t('show.more')"
|
||||
:svg="expand ? 'minimize-2' : 'maximize-2'"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
@click.native="expand = !expand"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
@@ -49,7 +40,7 @@
|
||||
<span
|
||||
v-for="(line, index) in query"
|
||||
:key="`line-${index}`"
|
||||
class="cursor-pointer text-secondaryLight px-4 whitespace-pre truncate"
|
||||
class="text-secondaryLight px-4 truncate whitespace-pre cursor-pointer"
|
||||
data-testid="restore_history_entry"
|
||||
@click="useEntry"
|
||||
>{{ line }}</span
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<AppSection label="history">
|
||||
<div class="bg-primary border-b border-dividerLight flex top-0 z-10 sticky">
|
||||
<div class="sticky top-0 z-10 flex border-b bg-primary border-dividerLight">
|
||||
<input
|
||||
v-model="filterText"
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
class="bg-transparent flex w-full p-4 py-2"
|
||||
class="flex w-full p-4 py-2 bg-transparent"
|
||||
:placeholder="`${$t('action.search')}`"
|
||||
/>
|
||||
<div class="flex">
|
||||
@@ -49,24 +49,24 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="!(filteredHistory.length !== 0 || history.length === 0)"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<i class="opacity-75 pb-2 material-icons">manage_search</i>
|
||||
<i class="pb-2 opacity-75 material-icons">manage_search</i>
|
||||
<span class="text-center">
|
||||
{{ $t("state.nothing_found") }} "{{ filterText }}"
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="history.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/history.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.history')"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
<span class="mb-4 text-center">
|
||||
{{ $t("empty.history") }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -140,9 +140,7 @@ export default defineComponent({
|
||||
clearHistory() {
|
||||
if (this.page === "rest") clearRESTHistory()
|
||||
else clearGraphqlHistory()
|
||||
this.$toast.success(`${this.$t("state.history_deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.history_deleted")}`)
|
||||
},
|
||||
useHistory(entry: any) {
|
||||
if (this.page === "rest") setRESTRequest(entry.request)
|
||||
@@ -150,9 +148,7 @@ export default defineComponent({
|
||||
deleteHistory(entry: any) {
|
||||
if (this.page === "rest") deleteRESTHistoryEntry(entry)
|
||||
else deleteGraphqlHistoryEntry(entry)
|
||||
this.$toast.success(`${this.$t("state.deleted")}`, {
|
||||
icon: "delete",
|
||||
})
|
||||
this.$toast.success(`${this.$t("state.deleted")}`)
|
||||
},
|
||||
toggleStar(entry: any) {
|
||||
if (this.page === "rest") toggleRESTHistoryEntryStar(entry)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="flex items-center group">
|
||||
<div class="group flex items-center">
|
||||
<span
|
||||
class="cursor-pointer flex px-2 w-16 justify-center items-center truncate"
|
||||
class="flex items-center justify-center w-16 px-2 truncate cursor-pointer"
|
||||
:class="entryStatus.className"
|
||||
data-testid="restore_history_entry"
|
||||
:title="`${duration}`"
|
||||
@@ -10,15 +10,7 @@
|
||||
{{ entry.request.method }}
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
cursor-pointer
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
pr-2
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 py-2 pr-2 transition cursor-pointer"
|
||||
data-testid="restore_history_entry"
|
||||
:title="`${duration}`"
|
||||
@click="$emit('use-entry')"
|
||||
@@ -32,7 +24,7 @@
|
||||
svg="trash"
|
||||
color="red"
|
||||
:title="$t('action.remove')"
|
||||
class="hidden group-hover:inline-flex"
|
||||
class="group-hover:inline-flex hidden"
|
||||
data-testid="delete_history_entry"
|
||||
@click.native="$emit('delete-entry')"
|
||||
/>
|
||||
@@ -49,13 +41,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
computed,
|
||||
defineComponent,
|
||||
PropType,
|
||||
useContext,
|
||||
} from "@nuxtjs/composition-api"
|
||||
import { computed, defineComponent, PropType } from "@nuxtjs/composition-api"
|
||||
import findStatusGroup from "~/helpers/findStatusGroup"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
import { RESTHistoryEntry } from "~/newstore/history"
|
||||
|
||||
export default defineComponent({
|
||||
@@ -64,10 +52,7 @@ export default defineComponent({
|
||||
showMore: Boolean,
|
||||
},
|
||||
setup(props) {
|
||||
const {
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const $t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const duration = computed(() => {
|
||||
if (props.entry.responseMeta.duration) {
|
||||
@@ -75,9 +60,9 @@ export default defineComponent({
|
||||
if (!responseDuration) return ""
|
||||
|
||||
return responseDuration > 0
|
||||
? `${$t("request.duration")}: ${responseDuration}ms`
|
||||
: $t("error.no_duration")
|
||||
} else return $t("error.no_duration")
|
||||
? `${t("request.duration")}: ${responseDuration}ms`
|
||||
: t("error.no_duration")
|
||||
} else return t("error.no_duration")
|
||||
})
|
||||
|
||||
const entryStatus = computed(() => {
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("authorization.type") }}
|
||||
</label>
|
||||
<tippy
|
||||
@@ -27,7 +17,7 @@
|
||||
<template #trigger>
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
class="rounded-none ml-2 pr-8"
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
:label="authName"
|
||||
/>
|
||||
</span>
|
||||
@@ -93,37 +83,37 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'none'"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/login.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.authorization')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.authorization") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
outline
|
||||
:label="$t('app.documentation')"
|
||||
to="https://docs.hoppscotch.io"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
svg="external-link"
|
||||
reverse
|
||||
class="mb-4"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="authType === 'basic'" class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div v-if="authType === 'basic'" class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<SmartEnvInput
|
||||
v-model="basicUsername"
|
||||
:placeholder="$t('authorization.username')"
|
||||
styles="bg-transparent flex flex-1 py-1 px-4"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<SmartEnvInput
|
||||
v-model="basicPassword"
|
||||
:placeholder="$t('authorization.password')"
|
||||
@@ -132,17 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
h-full
|
||||
top-upperTertiaryStickyFold
|
||||
min-w-46
|
||||
max-w-1/3
|
||||
p-4
|
||||
z-9
|
||||
sticky
|
||||
overflow-auto
|
||||
"
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -151,15 +131,15 @@
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||
to="https://docs.hoppscotch.io/"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="authType === 'bearer'" class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div v-if="authType === 'bearer'" class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<SmartEnvInput
|
||||
v-model="bearerToken"
|
||||
placeholder="Token"
|
||||
@@ -168,17 +148,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
h-full
|
||||
top-upperTertiaryStickyFold
|
||||
min-w-46
|
||||
max-w-1/3
|
||||
p-4
|
||||
z-9
|
||||
sticky
|
||||
overflow-auto
|
||||
"
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -187,7 +157,7 @@
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||
to="https://docs.hoppscotch.io/"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
/>
|
||||
</div>
|
||||
@@ -195,10 +165,10 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="authType === 'oauth-2'"
|
||||
class="border-b border-dividerLight flex"
|
||||
class="border-dividerLight flex border-b"
|
||||
>
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<SmartEnvInput
|
||||
v-model="oauth2Token"
|
||||
placeholder="Token"
|
||||
@@ -208,17 +178,7 @@
|
||||
<HttpOAuth2Authorization />
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
h-full
|
||||
top-upperTertiaryStickyFold
|
||||
min-w-46
|
||||
max-w-1/3
|
||||
p-4
|
||||
z-9
|
||||
sticky
|
||||
overflow-auto
|
||||
"
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
>
|
||||
<div class="p-2">
|
||||
<div class="text-secondaryLight pb-2">
|
||||
@@ -227,7 +187,7 @@
|
||||
<SmartAnchor
|
||||
class="link"
|
||||
:label="`${$t('authorization.learn')} \xA0 →`"
|
||||
to="https://docs.hoppscotch.io/"
|
||||
to="https://docs.hoppscotch.io/features/authorization"
|
||||
blank
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<span class="flex items-center">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("request.content_type") }}
|
||||
</label>
|
||||
<tippy
|
||||
@@ -28,7 +18,7 @@
|
||||
<span class="select-wrapper">
|
||||
<ButtonSecondary
|
||||
:label="contentType || $t('state.none').toLowerCase()"
|
||||
class="rounded-none ml-2 pr-8"
|
||||
class="pr-8 ml-2 rounded-none"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
||||
@@ -63,21 +53,21 @@
|
||||
<HttpRawBody v-else-if="contentType !== null" :content-type="contentType" />
|
||||
<div
|
||||
v-if="contentType == null"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.body')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.body") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
outline
|
||||
:label="`${$t('app.documentation')}`"
|
||||
to="https://docs.hoppscotch.io"
|
||||
to="https://docs.hoppscotch.io/features/body"
|
||||
blank
|
||||
svg="external-link"
|
||||
reverse
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<template>
|
||||
<AppSection label="bodyParameters">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperTertiaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("request.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -41,7 +31,7 @@
|
||||
<div
|
||||
v-for="(param, index) in bodyParams"
|
||||
:key="`param-${index}`"
|
||||
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
@@ -63,7 +53,7 @@
|
||||
"
|
||||
/>
|
||||
<div v-if="param.isFile" class="file-chips-container hide-scrollbar">
|
||||
<div class="space-x-2 file-chips-wrapper">
|
||||
<div class="file-chips-wrapper space-x-2">
|
||||
<SmartDeletableChip
|
||||
v-for="(file, fileIndex) in param.value"
|
||||
:key="`param-${index}-file-${fileIndex}`"
|
||||
@@ -151,15 +141,15 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="bodyParams.length === 0"
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/upload_single_file.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.body')"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
<span class="pb-4 text-center">
|
||||
{{ $t("empty.body") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<label for="requestType" class="px-4 pb-4">
|
||||
{{ $t("request.choose_language") }}
|
||||
{{ t("request.choose_language") }}
|
||||
</label>
|
||||
<tippy ref="options" interactive trigger="click" theme="popover" arrow>
|
||||
<template #trigger>
|
||||
@@ -33,7 +33,7 @@
|
||||
"
|
||||
/>
|
||||
</tippy>
|
||||
<div class="flex flex-1 justify-between">
|
||||
<div class="flex justify-between flex-1">
|
||||
<label for="generatedCode" class="p-4">
|
||||
{{ t("request.generated_code") }}
|
||||
</label>
|
||||
@@ -41,7 +41,7 @@
|
||||
<div
|
||||
v-if="codegenType"
|
||||
ref="generatedCode"
|
||||
class="border border-dividerLight rounded"
|
||||
class="border rounded border-dividerLight"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -62,13 +62,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL"
|
||||
import { getCurrentEnvironment } from "~/newstore/environments"
|
||||
import { getRESTRequest } from "~/newstore/RESTSession"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
@@ -78,11 +81,7 @@ const emit = defineEmits<{
|
||||
(e: "hide-modal"): void
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const options = ref<any | null>(null)
|
||||
|
||||
@@ -126,9 +125,7 @@ const hideModal = () => emit("hide-modal")
|
||||
const copyRequestCode = () => {
|
||||
copyToClipboard(requestCode.value)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,45 +1,35 @@
|
||||
<template>
|
||||
<AppSection label="headers">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.header_list") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.header_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/headers"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.bulk_mode')"
|
||||
:title="t('state.bulk_mode')"
|
||||
svg="edit"
|
||||
:class="{ '!text-accent': bulkMode }"
|
||||
@click.native="bulkMode = !bulkMode"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
:title="t('add.new')"
|
||||
svg="plus"
|
||||
:disabled="bulkMode"
|
||||
@click.native="addHeader"
|
||||
@@ -51,10 +41,10 @@
|
||||
<div
|
||||
v-for="(header, index) in headers$"
|
||||
:key="`header-${index}`"
|
||||
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${$t('count.header', { count: index + 1 })}`"
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
:spellcheck="false"
|
||||
:value="header.key"
|
||||
@@ -78,7 +68,7 @@
|
||||
/>
|
||||
<SmartEnvInput
|
||||
v-model="header.value"
|
||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
styles="
|
||||
bg-transparent
|
||||
flex
|
||||
@@ -100,9 +90,9 @@
|
||||
:title="
|
||||
header.hasOwnProperty('active')
|
||||
? header.active
|
||||
? $t('action.turn_off')
|
||||
: $t('action.turn_on')
|
||||
: $t('action.turn_off')
|
||||
? t('action.turn_off')
|
||||
: t('action.turn_on')
|
||||
: t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
header.hasOwnProperty('active')
|
||||
@@ -126,7 +116,7 @@
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
:title="t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="deleteHeader(index)"
|
||||
@@ -135,33 +125,20 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="headers$.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.headers')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.headers')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.headers") }}
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("empty.headers") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
filled
|
||||
:label="`${$t('add.new')}`"
|
||||
:label="`${t('add.new')}`"
|
||||
svg="plus"
|
||||
class="mb-4"
|
||||
@click.native="addHeader"
|
||||
@@ -172,7 +149,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUpdate, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||
import { onBeforeUpdate, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import {
|
||||
addRESTHeader,
|
||||
@@ -183,14 +160,16 @@ import {
|
||||
updateRESTHeader,
|
||||
} from "~/newstore/RESTSession"
|
||||
import { commonHeaders } from "~/helpers/headers"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const bulkMode = ref(false)
|
||||
const bulkHeaders = ref("")
|
||||
@@ -212,11 +191,9 @@ watch(bulkHeaders, () => {
|
||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||
active: !item.trim().startsWith("//"),
|
||||
}))
|
||||
setRESTHeaders(transformation)
|
||||
setRESTHeaders(transformation as HoppRESTHeader[])
|
||||
} catch (e) {
|
||||
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.something_went_wrong")}`)
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
@@ -226,12 +203,13 @@ const headers$ = useReadonlyStream(restHeaders$, [])
|
||||
watch(
|
||||
headers$,
|
||||
(newValue) => {
|
||||
if (
|
||||
(newValue[newValue.length - 1]?.key !== "" ||
|
||||
newValue[newValue.length - 1]?.value !== "") &&
|
||||
newValue.length
|
||||
)
|
||||
addHeader()
|
||||
if (!bulkMode.value)
|
||||
if (
|
||||
(newValue[newValue.length - 1]?.key !== "" ||
|
||||
newValue[newValue.length - 1]?.value !== "") &&
|
||||
newValue.length
|
||||
)
|
||||
addHeader()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
@@ -277,11 +255,10 @@ const deleteHeader = (index: number) => {
|
||||
|
||||
const deletedItem = headersBeforeDeletion[index]
|
||||
if (deletedItem.key || deletedItem.value) {
|
||||
$toast.success(t("state.deleted").toString(), {
|
||||
icon: "delete",
|
||||
toast.success(`${t("state.deleted")}`, {
|
||||
action: [
|
||||
{
|
||||
text: t("action.undo").toString(),
|
||||
text: `${t("action.undo")}`,
|
||||
onClick: (_, toastObject) => {
|
||||
setRESTHeaders(headersBeforeDeletion as HoppRESTHeader[])
|
||||
editBulkHeadersLine(index, deletedItem)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<SmartModal v-if="show" :title="`${$t('import.curl')}`" @close="hideModal">
|
||||
<SmartModal v-if="show" :title="`${t('import.curl')}`" @close="hideModal">
|
||||
<template #body>
|
||||
<div class="flex flex-col px-2">
|
||||
<div ref="curlEditor" class="border border-dividerLight rounded"></div>
|
||||
<div ref="curlEditor" class="border rounded border-dividerLight"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<span class="flex">
|
||||
<ButtonPrimary
|
||||
:label="`${$t('import.title')}`"
|
||||
:label="`${t('import.title')}`"
|
||||
@click.native="handleImport"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('action.cancel')}`"
|
||||
:label="`${t('action.cancel')}`"
|
||||
@click.native="hideModal"
|
||||
/>
|
||||
</span>
|
||||
@@ -21,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { ref } from "@nuxtjs/composition-api"
|
||||
import parseCurlCommand from "~/helpers/curlparser"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import {
|
||||
@@ -30,12 +30,11 @@ import {
|
||||
makeRESTRequest,
|
||||
} from "~/helpers/types/HoppRESTRequest"
|
||||
import { setRESTRequest } from "~/newstore/RESTSession"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const curl = ref("")
|
||||
|
||||
@@ -123,9 +122,7 @@ const handleImport = () => {
|
||||
)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
$toast.error(`${t("error.curl_invalid_format")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.curl_invalid_format")}`)
|
||||
}
|
||||
hideModal()
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<input
|
||||
id="oidcDiscoveryURL"
|
||||
v-model="oidcDiscoveryURL"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
placeholder="OpenID Connect Discovery URL"
|
||||
name="oidcDiscoveryURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<input
|
||||
id="authURL"
|
||||
v-model="authURL"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
placeholder="Authentication URL"
|
||||
name="authURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<input
|
||||
id="accessTokenURL"
|
||||
v-model="accessTokenURL"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
placeholder="Access Token URL"
|
||||
name="accessTokenURL"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<input
|
||||
id="clientID"
|
||||
v-model="clientID"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
placeholder="Client ID"
|
||||
name="clientID"
|
||||
/>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="flex border-b border-dividerLight">
|
||||
<input
|
||||
id="scope"
|
||||
v-model="scope"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
placeholder="Scope"
|
||||
name="scope"
|
||||
/>
|
||||
@@ -48,7 +48,7 @@
|
||||
<div class="p-2">
|
||||
<ButtonSecondary
|
||||
filled
|
||||
:label="`${$t('authorization.generate_token')}`"
|
||||
:label="`${t('authorization.generate_token')}`"
|
||||
@click.native="handleAccessTokenRequest()"
|
||||
/>
|
||||
</div>
|
||||
@@ -56,19 +56,21 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { pluckRef, useStream } from "~/helpers/utils/composables"
|
||||
import { Ref } from "@nuxtjs/composition-api"
|
||||
import {
|
||||
pluckRef,
|
||||
useI18n,
|
||||
useStream,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { HoppRESTAuthOAuth2 } from "~/helpers/types/HoppRESTAuth"
|
||||
import { restAuth$, setRESTAuth } from "~/newstore/RESTSession"
|
||||
import { tokenRequest } from "~/helpers/oauth"
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const $t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
const toast = useToast()
|
||||
|
||||
const auth = useStream(
|
||||
restAuth$,
|
||||
@@ -97,9 +99,7 @@ export default {
|
||||
oidcDiscoveryURL.value === "" &&
|
||||
(authURL.value === "" || accessTokenURL.value === "")
|
||||
) {
|
||||
$toast.error(`${$t("complete_config_urls")}`, {
|
||||
icon: "error",
|
||||
})
|
||||
toast.error(`${t("complete_config_urls")}`)
|
||||
return
|
||||
}
|
||||
try {
|
||||
@@ -113,9 +113,7 @@ export default {
|
||||
}
|
||||
await tokenRequest(tokenReqParams)
|
||||
} catch (e) {
|
||||
$toast.error(`${e}`, {
|
||||
icon: "code",
|
||||
})
|
||||
toast.error(`${e}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,45 +1,35 @@
|
||||
<template>
|
||||
<AppSection label="parameters">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.parameter_list") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.parameter_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/parameters"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear_all')"
|
||||
:title="t('action.clear_all')"
|
||||
svg="trash-2"
|
||||
@click.native="bulkMode ? clearBulkEditor() : clearContent()"
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.bulk_mode')"
|
||||
:title="t('state.bulk_mode')"
|
||||
svg="edit"
|
||||
:class="{ '!text-accent': bulkMode }"
|
||||
@click.native="bulkMode = !bulkMode"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('add.new')"
|
||||
:title="t('add.new')"
|
||||
svg="plus"
|
||||
:disabled="bulkMode"
|
||||
@click.native="addParam"
|
||||
@@ -51,11 +41,11 @@
|
||||
<div
|
||||
v-for="(param, index) in params$"
|
||||
:key="`param-${index}`"
|
||||
class="divide-x divide-dividerLight border-b border-dividerLight flex"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
:placeholder="`${$t('count.parameter', { count: index + 1 })}`"
|
||||
:placeholder="`${t('count.parameter', { count: index + 1 })}`"
|
||||
styles="
|
||||
bg-transparent
|
||||
flex
|
||||
@@ -73,7 +63,7 @@
|
||||
/>
|
||||
<SmartEnvInput
|
||||
v-model="param.value"
|
||||
:placeholder="`${$t('count.value', { count: index + 1 })}`"
|
||||
:placeholder="`${t('count.value', { count: index + 1 })}`"
|
||||
styles="
|
||||
bg-transparent
|
||||
flex
|
||||
@@ -95,9 +85,9 @@
|
||||
:title="
|
||||
param.hasOwnProperty('active')
|
||||
? param.active
|
||||
? $t('action.turn_off')
|
||||
: $t('action.turn_on')
|
||||
: $t('action.turn_off')
|
||||
? t('action.turn_off')
|
||||
: t('action.turn_on')
|
||||
: t('action.turn_off')
|
||||
"
|
||||
:svg="
|
||||
param.hasOwnProperty('active')
|
||||
@@ -119,7 +109,7 @@
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.remove')"
|
||||
:title="t('action.remove')"
|
||||
svg="trash"
|
||||
color="red"
|
||||
@click.native="deleteParam(index)"
|
||||
@@ -128,32 +118,19 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="params$.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_files.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.parameters')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.parameters')}`"
|
||||
/>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("empty.parameters") }}
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("empty.parameters") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
:label="`${$t('add.new')}`"
|
||||
:label="`${t('add.new')}`"
|
||||
svg="plus"
|
||||
filled
|
||||
class="mb-4"
|
||||
@@ -165,10 +142,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, useContext, watch, onBeforeUpdate } from "@nuxtjs/composition-api"
|
||||
import { ref, watch, onBeforeUpdate } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { HoppRESTParam } from "~/helpers/types/HoppRESTRequest"
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import {
|
||||
useReadonlyStream,
|
||||
useI18n,
|
||||
useToast,
|
||||
} from "~/helpers/utils/composables"
|
||||
import {
|
||||
restParams$,
|
||||
addRESTParam,
|
||||
@@ -178,11 +159,9 @@ import {
|
||||
setRESTParams,
|
||||
} from "~/newstore/RESTSession"
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const bulkMode = ref(false)
|
||||
const bulkParams = ref("")
|
||||
@@ -194,11 +173,9 @@ watch(bulkParams, () => {
|
||||
value: item.substring(item.indexOf(":") + 1).trim(),
|
||||
active: !item.trim().startsWith("//"),
|
||||
}))
|
||||
setRESTParams(transformation)
|
||||
setRESTParams(transformation as HoppRESTParam[])
|
||||
} catch (e) {
|
||||
$toast.error(`${t("error.something_went_wrong")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.something_went_wrong")}`)
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
@@ -219,12 +196,13 @@ const params$ = useReadonlyStream(restParams$, [])
|
||||
watch(
|
||||
params$,
|
||||
(newValue) => {
|
||||
if (
|
||||
(newValue[newValue.length - 1]?.key !== "" ||
|
||||
newValue[newValue.length - 1]?.value !== "") &&
|
||||
newValue.length
|
||||
)
|
||||
addParam()
|
||||
if (!bulkMode.value)
|
||||
if (
|
||||
(newValue[newValue.length - 1]?.key !== "" ||
|
||||
newValue[newValue.length - 1]?.value !== "") &&
|
||||
newValue.length
|
||||
)
|
||||
addParam()
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
@@ -270,11 +248,10 @@ const deleteParam = (index: number) => {
|
||||
|
||||
const deletedItem = parametersBeforeDeletion[index]
|
||||
if (deletedItem.key || deletedItem.value) {
|
||||
$toast.success(t("state.deleted").toString(), {
|
||||
icon: "delete",
|
||||
toast.success(`${t("state.deleted")}`, {
|
||||
action: [
|
||||
{
|
||||
text: t("action.undo").toString(),
|
||||
text: `${t("action.undo")}`,
|
||||
onClick: (_, toastObject) => {
|
||||
setRESTParams(parametersBeforeDeletion as HoppRESTParam[])
|
||||
editBulkParamsLine(index, deletedItem)
|
||||
|
||||
@@ -1,71 +1,51 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${$t('preRequest.script')}`">
|
||||
<AppSection id="script" :label="`${t('preRequest.script')}`">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("preRequest.javascript_code") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("preRequest.javascript_code") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/pre-request-script"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
:title="t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div ref="preRrequestEditor"></div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
h-full
|
||||
top-upperTertiaryStickyFold
|
||||
min-w-46
|
||||
max-w-1/3
|
||||
p-4
|
||||
z-9
|
||||
sticky
|
||||
overflow-auto
|
||||
"
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
>
|
||||
<div class="text-secondaryLight pb-2">
|
||||
{{ $t("helpers.pre_request_script") }}
|
||||
{{ t("helpers.pre_request_script") }}
|
||||
</div>
|
||||
<SmartAnchor
|
||||
:label="`${$t('preRequest.learn')}`"
|
||||
:label="`${t('preRequest.learn')}`"
|
||||
to="https://docs.hoppscotch.io/features/pre-request-script"
|
||||
blank
|
||||
/>
|
||||
<h4 class="font-bold text-secondaryLight pt-6">
|
||||
{{ $t("preRequest.snippets") }}
|
||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
||||
{{ t("preRequest.snippets") }}
|
||||
</h4>
|
||||
<div class="flex flex-col pt-4">
|
||||
<TabSecondary
|
||||
@@ -82,17 +62,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { usePreRequestScript } from "~/newstore/RESTSession"
|
||||
import snippets from "~/helpers/preRequestScriptSnippets"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import linter from "~/helpers/editor/linting/preRequest"
|
||||
import completer from "~/helpers/editor/completion/preRequest"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const {
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const preRequestScript = usePreRequestScript()
|
||||
|
||||
|
||||
@@ -1,39 +1,29 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperTertiaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperTertiaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.raw_body") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.raw_body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/body"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
:title="t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
@@ -41,14 +31,14 @@
|
||||
v-if="contentType && contentType.endsWith('json')"
|
||||
ref="prettifyRequest"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.prettify')"
|
||||
:title="t('action.prettify')"
|
||||
:svg="prettifyIcon"
|
||||
@click.native="prettifyRequestBody"
|
||||
/>
|
||||
<label for="payload">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('import.json')"
|
||||
:title="t('import.json')"
|
||||
svg="file-plus"
|
||||
@click.native="$refs.payload.click()"
|
||||
/>
|
||||
@@ -67,21 +57,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { computed, reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { getEditorLangForMimeType } from "~/helpers/editorutils"
|
||||
import { pluckRef } from "~/helpers/utils/composables"
|
||||
import { pluckRef, useI18n, useToast } from "~/helpers/utils/composables"
|
||||
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
contentType: string
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const rawParamsBody = pluckRef(useRESTRequestBody(), "body")
|
||||
const prettifyIcon = ref("wand")
|
||||
@@ -118,13 +106,9 @@ const uploadPayload = (e: InputEvent) => {
|
||||
rawParamsBody.value = target?.result
|
||||
}
|
||||
reader.readAsText(file)
|
||||
$toast.success(`${t("state.file_imported")}`, {
|
||||
icon: "attach_file",
|
||||
})
|
||||
toast.success(`${t("state.file_imported")}`)
|
||||
} else {
|
||||
$toast.error(`${t("action.choose_file")}`, {
|
||||
icon: "attach_file",
|
||||
})
|
||||
toast.error(`${t("action.choose_file")}`)
|
||||
}
|
||||
}
|
||||
const prettifyRequestBody = () => {
|
||||
@@ -135,9 +119,7 @@ const prettifyRequestBody = () => {
|
||||
setTimeout(() => (prettifyIcon.value = "wand"), 1000)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
$toast.error(`${t("error.json_prettify_invalid_body")}`, {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.json_prettify_invalid_body")}`)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
flex
|
||||
space-x-2
|
||||
p-4
|
||||
top-0
|
||||
z-10
|
||||
sticky
|
||||
overflow-x-auto
|
||||
hide-scrollbar
|
||||
"
|
||||
class="bg-primary hide-scrollbar sticky top-0 z-10 flex p-4 space-x-2 overflow-x-auto"
|
||||
>
|
||||
<div class="flex flex-1">
|
||||
<div class="flex relative">
|
||||
<div class="relative flex">
|
||||
<label for="method">
|
||||
<tippy
|
||||
ref="methodOptions"
|
||||
@@ -26,24 +16,10 @@
|
||||
<span class="select-wrapper">
|
||||
<input
|
||||
id="method"
|
||||
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
|
||||
"
|
||||
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"
|
||||
:value="newMethod"
|
||||
:readonly="!isCustomMethod"
|
||||
:placeholder="`${$t('request.method')}`"
|
||||
:placeholder="`${t('request.method')}`"
|
||||
@input="onSelectMethod($event.target.value)"
|
||||
/>
|
||||
</span>
|
||||
@@ -60,7 +36,7 @@
|
||||
<div class="flex flex-1">
|
||||
<SmartEnvInput
|
||||
v-model="newEndpoint"
|
||||
:placeholder="`${$t('request.url')}`"
|
||||
:placeholder="`${t('request.url')}`"
|
||||
styles="
|
||||
bg-primaryLight
|
||||
border border-divider
|
||||
@@ -82,8 +58,8 @@
|
||||
<div class="flex">
|
||||
<ButtonPrimary
|
||||
id="send"
|
||||
class="rounded-r-none flex-1 min-w-20"
|
||||
:label="`${!loading ? $t('action.send') : $t('action.cancel')}`"
|
||||
class="min-w-20 flex-1 rounded-r-none"
|
||||
:label="`${!loading ? t('action.send') : t('action.cancel')}`"
|
||||
@click.native="!loading ? newSendRequest() : cancelRequest()"
|
||||
/>
|
||||
<span class="flex">
|
||||
@@ -98,7 +74,7 @@
|
||||
<ButtonPrimary class="rounded-l-none" filled svg="chevron-down" />
|
||||
</template>
|
||||
<SmartItem
|
||||
:label="`${$t('import.curl')}`"
|
||||
:label="`${t('import.curl')}`"
|
||||
svg="file-code"
|
||||
@click.native="
|
||||
() => {
|
||||
@@ -108,7 +84,7 @@
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
:label="`${$t('show.code')}`"
|
||||
:label="`${t('show.code')}`"
|
||||
svg="code-2"
|
||||
@click.native="
|
||||
() => {
|
||||
@@ -119,7 +95,7 @@
|
||||
/>
|
||||
<SmartItem
|
||||
ref="clearAll"
|
||||
:label="`${$t('action.clear_all')}`"
|
||||
:label="`${t('action.clear_all')}`"
|
||||
svg="rotate-ccw"
|
||||
@click.native="
|
||||
() => {
|
||||
@@ -131,10 +107,10 @@
|
||||
</tippy>
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
class="rounded rounded-r-none ml-2"
|
||||
class="ml-2 rounded rounded-r-none"
|
||||
:label="
|
||||
windowInnerWidth.x.value >= 768 && COLUMN_LAYOUT
|
||||
? `${$t('request.save')}`
|
||||
? `${t('request.save')}`
|
||||
: ''
|
||||
"
|
||||
filled
|
||||
@@ -159,27 +135,27 @@
|
||||
<input
|
||||
id="request-name"
|
||||
v-model="requestName"
|
||||
:placeholder="`${$t('request.name')}`"
|
||||
:placeholder="`${t('request.name')}`"
|
||||
name="request-name"
|
||||
type="text"
|
||||
autocomplete="off"
|
||||
class="mb-2 input"
|
||||
class="input mb-2"
|
||||
@keyup.enter="saveOptions.tippy().hide()"
|
||||
/>
|
||||
<SmartItem
|
||||
ref="copyRequest"
|
||||
:label="`${$t('request.copy_link')}`"
|
||||
:svg="hasNavigatorShare ? 'share-2' : 'copy'"
|
||||
:label="shareButtonText"
|
||||
:svg="copyLinkIcon"
|
||||
:loading="fetchingShareLink"
|
||||
@click.native="
|
||||
() => {
|
||||
copyRequest()
|
||||
saveOptions.tippy().hide()
|
||||
}
|
||||
"
|
||||
/>
|
||||
<SmartItem
|
||||
ref="saveRequest"
|
||||
:label="`${$t('request.save_as')}`"
|
||||
:label="`${t('request.save_as')}`"
|
||||
svg="folder-plus"
|
||||
@click.native="
|
||||
() => {
|
||||
@@ -208,8 +184,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, watch } from "@nuxtjs/composition-api"
|
||||
import { computed, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { isRight } from "fp-ts/lib/Either"
|
||||
import * as E from "fp-ts/Either"
|
||||
import {
|
||||
updateRESTResponse,
|
||||
restEndpoint$,
|
||||
@@ -220,6 +197,7 @@ import {
|
||||
useRESTRequestName,
|
||||
getRESTSaveContext,
|
||||
getRESTRequest,
|
||||
restRequest$,
|
||||
} from "~/newstore/RESTSession"
|
||||
import { editRESTRequest } from "~/newstore/collections"
|
||||
import { runRESTRequest$ } from "~/helpers/RequestRunner"
|
||||
@@ -227,6 +205,9 @@ import {
|
||||
useStreamSubscriber,
|
||||
useStream,
|
||||
useNuxt,
|
||||
useI18n,
|
||||
useToast,
|
||||
useReadonlyStream,
|
||||
} from "~/helpers/utils/composables"
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
@@ -234,6 +215,9 @@ import { useSetting } from "~/newstore/settings"
|
||||
import { overwriteRequestTeams } from "~/helpers/teams/utils"
|
||||
import { apolloClient } from "~/helpers/apollo"
|
||||
import useWindowSize from "~/helpers/utils/useWindowSize"
|
||||
import { createShortcode } from "~/helpers/backend/mutations/Shortcode"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const methods = [
|
||||
"GET",
|
||||
@@ -248,12 +232,9 @@ const methods = [
|
||||
"CUSTOM",
|
||||
]
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const toast = useToast()
|
||||
const nuxt = useNuxt()
|
||||
const t = i18n.t.bind(i18n)
|
||||
|
||||
const { subscribeToStream } = useStreamSubscriber()
|
||||
|
||||
const newEndpoint = useStream(restEndpoint$, "", setRESTEndpoint)
|
||||
@@ -282,6 +263,11 @@ watch(loading, () => {
|
||||
})
|
||||
|
||||
const newSendRequest = async () => {
|
||||
if (newEndpoint.value === "" || /^\s+$/.test(newEndpoint.value)) {
|
||||
toast.error(`${t("empty.endpoint")}`)
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
|
||||
// Double calling is because the function returns a TaskEither than should be executed
|
||||
@@ -327,7 +313,46 @@ const clearContent = () => {
|
||||
resetRESTRequest()
|
||||
}
|
||||
|
||||
const copyRequest = () => {
|
||||
const copyLinkIcon = hasNavigatorShare ? ref("share-2") : ref("copy")
|
||||
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) {
|
||||
const time = new Date().toLocaleTimeString()
|
||||
const date = new Date().toLocaleDateString()
|
||||
@@ -335,15 +360,15 @@ const copyRequest = () => {
|
||||
.share({
|
||||
title: "Hoppscotch",
|
||||
text: `Hoppscotch • Open source API development ecosystem at ${time} on ${date}`,
|
||||
url: window.location.href,
|
||||
url: `https://hopp.sh/r${shareLink}`,
|
||||
})
|
||||
.then(() => {})
|
||||
.catch(() => {})
|
||||
} else {
|
||||
copyToClipboard(window.location.href)
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
copyLinkIcon.value = "check"
|
||||
copyToClipboard(`https://hopp.sh/r${shareLink}`)
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyLinkIcon.value = "copy"), 2000)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,9 +407,7 @@ const saveRequest = () => {
|
||||
|
||||
if (saveCtx.originLocation === "user-collection") {
|
||||
editRESTRequest(saveCtx.folderPath, saveCtx.requestIndex, getRESTRequest())
|
||||
$toast.success(`${t("request.saved")}`, {
|
||||
icon: "playlist_add_check",
|
||||
})
|
||||
toast.success(`${t("request.saved")}`)
|
||||
} else if (saveCtx.originLocation === "team-collection") {
|
||||
const req = getRESTRequest()
|
||||
|
||||
@@ -397,20 +420,14 @@ const saveRequest = () => {
|
||||
saveCtx.requestID
|
||||
)
|
||||
.then(() => {
|
||||
$toast.success(`${t("request.saved")}`, {
|
||||
icon: "playlist_add_check",
|
||||
})
|
||||
toast.success(`${t("request.saved")}`)
|
||||
})
|
||||
.catch(() => {
|
||||
$toast.error(t("profile.no_permission").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("profile.no_permission")}`)
|
||||
})
|
||||
} catch (error) {
|
||||
showSaveRequestModal.value = true
|
||||
$toast.error(t("error.something_went_wrong").toString(), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
toast.error(`${t("error.something_went_wrong")}`)
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
<template>
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky items-center">
|
||||
<div
|
||||
class="bg-primary hide-scrollbar whitespace-nowrap sticky top-0 z-10 flex items-center p-4 overflow-auto"
|
||||
>
|
||||
<div
|
||||
v-if="response == null"
|
||||
class="
|
||||
flex flex-col flex-1
|
||||
text-secondaryLight
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center flex-1"
|
||||
>
|
||||
<div class="flex space-x-2 pb-4 my-4">
|
||||
<div class="flex flex-col space-y-4 text-right items-end">
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.request.send_request") }}
|
||||
<div class="flex pb-4 my-4 space-x-2">
|
||||
<div class="flex flex-col items-end space-y-4 text-right">
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.request.send_request") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.general.show_all") }}
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.general.show_all") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.general.command_menu") }}
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.general.command_menu") }}
|
||||
</span>
|
||||
<span class="flex flex-1 items-center">
|
||||
{{ $t("shortcut.general.help_menu") }}
|
||||
<span class="flex items-center flex-1">
|
||||
{{ t("shortcut.general.help_menu") }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-4">
|
||||
@@ -42,8 +39,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<ButtonSecondary
|
||||
:label="$t('app.documentation')"
|
||||
to="https://docs.hoppscotch.io"
|
||||
:label="t('app.documentation')"
|
||||
to="https://docs.hoppscotch.io/features/response"
|
||||
svg="external-link"
|
||||
blank
|
||||
outline
|
||||
@@ -56,48 +53,41 @@
|
||||
class="flex flex-col items-center justify-center"
|
||||
>
|
||||
<SmartSpinner class="my-4" />
|
||||
<span class="text-secondaryLight">{{ $t("state.loading") }}</span>
|
||||
<span class="text-secondaryLight">{{ t("state.loading") }}</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="response.type === 'network_fail'"
|
||||
class="flex flex-col flex-1 p-4 items-center justify-center"
|
||||
class="flex flex-col items-center justify-center flex-1 p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/youre_lost.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-32
|
||||
w-32
|
||||
inline-flex
|
||||
"
|
||||
:alt="$t('empty.network_fail')"
|
||||
class="inline-flex flex-col object-contain object-center w-32 h-32 my-4"
|
||||
:alt="`${t('error.network_fail')}`"
|
||||
/>
|
||||
<span class="text-center font-semibold mb-2">
|
||||
{{ $t("error.network_fail") }}
|
||||
<span class="mb-2 font-semibold text-center">
|
||||
{{ t("error.network_fail") }}
|
||||
</span>
|
||||
<span class="text-center text-secondaryLight mb-4 max-w-sm">
|
||||
{{ $t("helpers.network_fail") }}
|
||||
<span class="text-secondaryLight max-w-sm mb-4 text-center">
|
||||
{{ t("helpers.network_fail") }}
|
||||
</span>
|
||||
<AppInterceptor />
|
||||
</div>
|
||||
<div
|
||||
v-if="response.type === 'success' || 'fail'"
|
||||
:class="statusCategory.className"
|
||||
class="font-semibold space-x-4"
|
||||
class="space-x-4 font-semibold"
|
||||
>
|
||||
<span v-if="response.statusCode">
|
||||
<span class="text-secondary"> {{ $t("response.status") }}: </span>
|
||||
{{ response.statusCode || $t("state.waiting_send_request") }}
|
||||
<span class="text-secondary"> {{ t("response.status") }}: </span>
|
||||
{{ response.statusCode || t("state.waiting_send_request") }}
|
||||
</span>
|
||||
<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` }}
|
||||
</span>
|
||||
<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` }}
|
||||
</span>
|
||||
</div>
|
||||
@@ -110,6 +100,9 @@ import { computed } from "@nuxtjs/composition-api"
|
||||
import findStatusGroup from "~/helpers/findStatusGroup"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
response: HoppRESTResponse
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<AppSection :label="`${$t('test.results')}`">
|
||||
<AppSection :label="`${t('test.results')}`">
|
||||
<div
|
||||
v-if="
|
||||
testResults &&
|
||||
@@ -7,24 +7,14 @@
|
||||
"
|
||||
>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-dividerLight border-b
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("test.report") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("test.report") }}
|
||||
</label>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
:title="t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent()"
|
||||
/>
|
||||
@@ -48,10 +38,10 @@
|
||||
<div
|
||||
v-for="(result, index) in testResults.expectResults"
|
||||
:key="`result-${index}`"
|
||||
class="flex py-2 px-4 items-center"
|
||||
class="flex items-center px-4 py-2"
|
||||
>
|
||||
<i
|
||||
class="mr-4 material-icons"
|
||||
class="material-icons mr-4"
|
||||
:class="
|
||||
result.status === 'pass' ? 'text-green-500' : 'text-red-500'
|
||||
"
|
||||
@@ -64,9 +54,7 @@
|
||||
<span class="text-secondaryLight">
|
||||
{{
|
||||
` \xA0 — \xA0 ${
|
||||
result.status === "pass"
|
||||
? $t("test.passed")
|
||||
: $t("test.failed")
|
||||
result.status === "pass" ? t("test.passed") : t("test.failed")
|
||||
}`
|
||||
}}
|
||||
</span>
|
||||
@@ -76,24 +64,24 @@
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="flex flex-col text-secondaryLight p-4 items-center justify-center"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/validation.svg`"
|
||||
loading="lazy"
|
||||
class="flex-col my-4 object-contain object-center h-16 w-16 inline-flex"
|
||||
:alt="$t('empty.tests')"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="`${t('empty.tests')}`"
|
||||
/>
|
||||
<span class="text-center pb-2">
|
||||
{{ $t("empty.tests") }}
|
||||
<span class="pb-2 text-center">
|
||||
{{ t("empty.tests") }}
|
||||
</span>
|
||||
<span class="text-center pb-4">
|
||||
{{ $t("helpers.tests") }}
|
||||
<span class="pb-4 text-center">
|
||||
{{ t("helpers.tests") }}
|
||||
</span>
|
||||
<ButtonSecondary
|
||||
outline
|
||||
:label="`${$t('action.learn_more')}`"
|
||||
to="https://docs.hoppscotch.io"
|
||||
:label="`${t('action.learn_more')}`"
|
||||
to="https://docs.hoppscotch.io/features/tests"
|
||||
blank
|
||||
svg="external-link"
|
||||
reverse
|
||||
@@ -104,9 +92,11 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useReadonlyStream } from "~/helpers/utils/composables"
|
||||
import { useReadonlyStream, useI18n } from "~/helpers/utils/composables"
|
||||
import { restTestResults$, setRESTTestResults } from "~/newstore/RESTSession"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const testResults = useReadonlyStream(restTestResults$, null)
|
||||
|
||||
const clearContent = () => setRESTTestResults(null)
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
<div>
|
||||
<span
|
||||
v-if="testResults.description"
|
||||
class="flex font-bold text-secondaryDark py-2 px-4 items-center"
|
||||
class="flex items-center px-4 py-2 font-bold text-secondaryDark"
|
||||
>
|
||||
{{ testResults.description }}
|
||||
</span>
|
||||
<div v-if="testResults.expectResults" class="divide-y divide-dividerLight">
|
||||
<div v-if="testResults.expectResults" class="divide-dividerLight divide-y">
|
||||
<HttpTestResultReport
|
||||
v-if="testResults.expectResults.length"
|
||||
:test-results="testResults"
|
||||
@@ -14,7 +14,7 @@
|
||||
<div
|
||||
v-for="(result, index) in testResults.expectResults"
|
||||
:key="`result-${index}`"
|
||||
class="flex py-2 px-4 items-center"
|
||||
class="flex items-center px-4 py-2"
|
||||
>
|
||||
<i
|
||||
class="mr-4 material-icons"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex p-2 items-center">
|
||||
<div class="flex items-center p-2">
|
||||
<SmartProgressRing
|
||||
class="text-red-500"
|
||||
:radius="16"
|
||||
|
||||
@@ -1,71 +1,51 @@
|
||||
<template>
|
||||
<AppSection id="script" :label="`${$t('test.script')}`">
|
||||
<AppSection id="script" :label="`${t('test.script')}`">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("test.javascript_code") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("test.javascript_code") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
to="https://docs.hoppscotch.io/features/tests"
|
||||
blank
|
||||
:title="$t('app.wiki')"
|
||||
:title="t('app.wiki')"
|
||||
svg="help-circle"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
/>
|
||||
<ButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.clear')"
|
||||
:title="t('action.clear')"
|
||||
svg="trash-2"
|
||||
@click.native="clearContent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-b border-dividerLight flex">
|
||||
<div class="border-r border-dividerLight w-2/3">
|
||||
<div class="border-dividerLight flex border-b">
|
||||
<div class="border-dividerLight w-2/3 border-r">
|
||||
<div ref="testScriptEditor"></div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
h-full
|
||||
top-upperTertiaryStickyFold
|
||||
min-w-46
|
||||
max-w-1/3
|
||||
p-4
|
||||
z-9
|
||||
sticky
|
||||
overflow-auto
|
||||
"
|
||||
class="bg-primary top-upperTertiaryStickyFold min-w-46 max-w-1/3 z-9 sticky h-full p-4 overflow-auto"
|
||||
>
|
||||
<div class="text-secondaryLight pb-2">
|
||||
{{ $t("helpers.post_request_tests") }}
|
||||
{{ t("helpers.post_request_tests") }}
|
||||
</div>
|
||||
<SmartAnchor
|
||||
:label="`${$t('test.learn')}`"
|
||||
:label="`${t('test.learn')}`"
|
||||
to="https://docs.hoppscotch.io/features/tests"
|
||||
blank
|
||||
/>
|
||||
<h4 class="font-bold text-secondaryLight pt-6">
|
||||
{{ $t("test.snippets") }}
|
||||
<h4 class="text-secondaryLight pt-6 font-bold">
|
||||
{{ t("test.snippets") }}
|
||||
</h4>
|
||||
<div class="flex flex-col pt-4">
|
||||
<TabSecondary
|
||||
@@ -82,17 +62,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref, useContext } from "@nuxtjs/composition-api"
|
||||
import { reactive, ref } from "@nuxtjs/composition-api"
|
||||
import { useTestScript } from "~/newstore/RESTSession"
|
||||
import testSnippets from "~/helpers/testSnippets"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import linter from "~/helpers/editor/linting/testScript"
|
||||
import completer from "~/helpers/editor/completion/testScript"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const {
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const t = useI18n()
|
||||
|
||||
const testScript = useTestScript()
|
||||
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("request.header_list") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("request.header_list") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-if="headers"
|
||||
ref="copyHeaders"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyIcon"
|
||||
@click.native="copyHeaders"
|
||||
/>
|
||||
@@ -30,38 +20,19 @@
|
||||
<div
|
||||
v-for="(header, index) in headers"
|
||||
:key="`header-${index}`"
|
||||
class="
|
||||
divide-x divide-dividerLight
|
||||
border-b border-dividerLight
|
||||
flex
|
||||
group
|
||||
"
|
||||
class="divide-dividerLight border-dividerLight group flex border-b divide-x"
|
||||
>
|
||||
<span
|
||||
class="
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
px-4
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
||||
>
|
||||
<span class="rounded-sm select-all truncate">
|
||||
<span class="truncate rounded-sm select-all">
|
||||
{{ header.key }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
class="
|
||||
flex flex-1
|
||||
min-w-0
|
||||
py-2
|
||||
px-4
|
||||
transition
|
||||
group-hover:text-secondaryDark
|
||||
"
|
||||
class="group-hover:text-secondaryDark flex flex-1 min-w-0 px-4 py-2 transition"
|
||||
>
|
||||
<span class="rounded-sm select-all truncate">
|
||||
<span class="truncate rounded-sm select-all">
|
||||
{{ header.value }}
|
||||
</span>
|
||||
</span>
|
||||
@@ -69,28 +40,26 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
<script setup lang="ts">
|
||||
import { ref } from "@nuxtjs/composition-api"
|
||||
import { HoppRESTHeader } from "~/helpers/types/HoppRESTRequest"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
headers: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
copyIcon: "copy",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
copyHeaders() {
|
||||
copyToClipboard(JSON.stringify(this.headers))
|
||||
this.copyIcon = "check"
|
||||
this.$toast.success(this.$t("state.copied_to_clipboard"), {
|
||||
icon: "content_paste",
|
||||
})
|
||||
setTimeout(() => (this.copyIcon = "copy"), 1000)
|
||||
},
|
||||
},
|
||||
})
|
||||
const t = useI18n()
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const props = defineProps<{
|
||||
headers: Array<HoppRESTHeader>
|
||||
}>()
|
||||
|
||||
const copyIcon = ref("copy")
|
||||
|
||||
const copyHeaders = () => {
|
||||
copyToClipboard(JSON.stringify(props.headers))
|
||||
copyIcon.value = "check"
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
<template>
|
||||
<div class="flex flex-col flex-1">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("response.body") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-if="response.body"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -29,7 +19,7 @@
|
||||
v-if="response.body"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="
|
||||
previewEnabled ? $t('hide.preview') : $t('response.preview_html')
|
||||
previewEnabled ? t('hide.preview') : t('response.preview_html')
|
||||
"
|
||||
:svg="!previewEnabled ? 'eye' : 'eye-off'"
|
||||
@click.native.prevent="togglePreview"
|
||||
@@ -38,7 +28,7 @@
|
||||
v-if="response.body"
|
||||
ref="downloadResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadIcon"
|
||||
@click.native="downloadResponse"
|
||||
/>
|
||||
@@ -46,7 +36,7 @@
|
||||
v-if="response.body"
|
||||
ref="copyResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyIcon"
|
||||
@click.native="copyResponse"
|
||||
/>
|
||||
@@ -64,20 +54,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
response: HoppRESTResponse
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const responseBodyText = computed(() => {
|
||||
if (
|
||||
@@ -127,9 +116,7 @@ const downloadResponse = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
@@ -140,9 +127,7 @@ const downloadResponse = () => {
|
||||
const copyResponse = () => {
|
||||
copyToClipboard(responseBodyText.value)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -28,7 +18,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
class="border-b border-dividerLight flex max-w-full flex-1"
|
||||
class="border-dividerLight flex flex-1 max-w-full border-b"
|
||||
:src="imageSource"
|
||||
loading="lazy"
|
||||
:alt="imageSource"
|
||||
@@ -103,9 +93,7 @@ export default defineComponent({
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
this.downloadIcon = "check"
|
||||
this.$toast.success(this.$t("state.download_started"), {
|
||||
icon: "downloading",
|
||||
})
|
||||
this.$toast.success(this.$t("state.download_started"))
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">{{
|
||||
$t("response.body")
|
||||
<label class="text-secondaryLight font-semibold">{{
|
||||
t("response.body")
|
||||
}}</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-if="response.body"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -29,7 +19,7 @@
|
||||
v-if="response.body"
|
||||
ref="downloadResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadIcon"
|
||||
@click.native="downloadResponse"
|
||||
/>
|
||||
@@ -37,7 +27,7 @@
|
||||
v-if="response.body"
|
||||
ref="copyResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyIcon"
|
||||
@click.native="copyResponse"
|
||||
/>
|
||||
@@ -46,17 +36,7 @@
|
||||
<div ref="jsonResponse"></div>
|
||||
<div
|
||||
v-if="outlinePath"
|
||||
class="
|
||||
bg-primaryLight
|
||||
border-t border-dividerLight
|
||||
flex flex-nowrap flex-1
|
||||
px-2
|
||||
bottom-0
|
||||
z-10
|
||||
sticky
|
||||
overflow-auto
|
||||
hide-scrollbar
|
||||
"
|
||||
class="bg-primaryLight border-dividerLight flex-nowrap hide-scrollbar sticky bottom-0 z-10 flex flex-1 px-2 overflow-auto border-t"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in outlinePath"
|
||||
@@ -135,7 +115,7 @@
|
||||
</tippy>
|
||||
<i
|
||||
v-if="index + 1 !== outlinePath.length"
|
||||
class="text-secondaryLight opacity-50 material-icons"
|
||||
class="text-secondaryLight material-icons opacity-50"
|
||||
>chevron_right</i
|
||||
>
|
||||
</div>
|
||||
@@ -144,7 +124,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
@@ -154,16 +134,15 @@ import {
|
||||
convertIndexToLineCh,
|
||||
convertLineChToIndex,
|
||||
} from "~/helpers/editor/utils"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
response: HoppRESTResponse
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const responseBodyText = computed(() => {
|
||||
if (
|
||||
@@ -234,9 +213,7 @@ const downloadResponse = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
@@ -256,9 +233,7 @@ const outlinePath = computed(() => {
|
||||
const copyResponse = () => {
|
||||
copyToClipboard(responseBodyText.value)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("response.body") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-if="response.body"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -29,7 +19,7 @@
|
||||
v-if="response.body"
|
||||
ref="downloadResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadIcon"
|
||||
@click.native="downloadResponse"
|
||||
/>
|
||||
@@ -37,7 +27,7 @@
|
||||
v-if="response.body"
|
||||
ref="copyResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyIcon"
|
||||
@click.native="copyResponse"
|
||||
/>
|
||||
@@ -48,20 +38,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, useContext, computed, reactive } from "@nuxtjs/composition-api"
|
||||
import { ref, computed, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
response: HoppRESTResponse
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const responseBodyText = computed(() => {
|
||||
if (
|
||||
@@ -117,9 +106,7 @@ const downloadResponse = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
@@ -130,9 +117,7 @@ const downloadResponse = () => {
|
||||
const copyResponse = () => {
|
||||
copyToClipboard(responseBodyText.value)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-lowerSecondaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-lowerSecondaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
{{ $t("response.body") }}
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ t("response.body") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
<ButtonSecondary
|
||||
v-if="response.body"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('state.linewrap')"
|
||||
:title="t('state.linewrap')"
|
||||
:class="{ '!text-accent': linewrapEnabled }"
|
||||
svg="corner-down-left"
|
||||
@click.native.prevent="linewrapEnabled = !linewrapEnabled"
|
||||
@@ -29,7 +19,7 @@
|
||||
v-if="response.body"
|
||||
ref="downloadResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.download_file')"
|
||||
:title="t('action.download_file')"
|
||||
:svg="downloadIcon"
|
||||
@click.native="downloadResponse"
|
||||
/>
|
||||
@@ -37,7 +27,7 @@
|
||||
v-if="response.body"
|
||||
ref="copyResponse"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t('action.copy')"
|
||||
:title="t('action.copy')"
|
||||
:svg="copyIcon"
|
||||
@click.native="copyResponse"
|
||||
/>
|
||||
@@ -48,20 +38,19 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref, useContext, reactive } from "@nuxtjs/composition-api"
|
||||
import { computed, ref, reactive } from "@nuxtjs/composition-api"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
import { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
|
||||
import { useI18n, useToast } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
response: HoppRESTResponse
|
||||
}>()
|
||||
|
||||
const {
|
||||
$toast,
|
||||
app: { i18n },
|
||||
} = useContext()
|
||||
const t = i18n.t.bind(i18n)
|
||||
const toast = useToast()
|
||||
|
||||
const responseBodyText = computed(() => {
|
||||
if (
|
||||
@@ -117,9 +106,7 @@ const downloadResponse = () => {
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
downloadIcon.value = "check"
|
||||
$toast.success(`${t("state.download_started")}`, {
|
||||
icon: "downloading",
|
||||
})
|
||||
toast.success(`${t("state.download_started")}`)
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(a)
|
||||
URL.revokeObjectURL(url)
|
||||
@@ -130,9 +117,7 @@ const downloadResponse = () => {
|
||||
const copyResponse = () => {
|
||||
copyToClipboard(responseBodyText.value)
|
||||
copyIcon.value = "check"
|
||||
$toast.success(`${t("state.copied_to_clipboard")}`, {
|
||||
icon: "content_paste",
|
||||
})
|
||||
toast.success(`${t("state.copied_to_clipboard")}`)
|
||||
setTimeout(() => (copyIcon.value = "copy"), 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,32 +1,15 @@
|
||||
<template>
|
||||
<div class="cursor-pointer flex h-5 w-5 relative items-center justify-center">
|
||||
<div class="relative flex items-center justify-center w-5 h-5 cursor-pointer">
|
||||
<img
|
||||
class="
|
||||
bg-primaryDark bg-primaryLight
|
||||
rounded-full
|
||||
object-cover object-center
|
||||
h-5
|
||||
transition
|
||||
w-5
|
||||
absolute
|
||||
"
|
||||
class="bg-primaryDark absolute object-cover object-center w-5 h-5 transition rounded-full"
|
||||
:src="url"
|
||||
:alt="alt"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="rounded-full shadow-inner inset-0 absolute"></div>
|
||||
<div class="absolute inset-0 rounded-full shadow-inner"></div>
|
||||
<span
|
||||
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"
|
||||
></span>
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,9 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
pl-4
|
||||
top-0
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight sticky top-0 z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label for="log" class="font-semibold text-secondaryLight py-2">
|
||||
<label for="log" class="text-secondaryLight py-2 font-semibold">
|
||||
{{ title }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -26,7 +16,7 @@
|
||||
>{{ entry.ts }}{{ source(entry.source) }}{{ entry.payload }}</span
|
||||
>
|
||||
</span>
|
||||
<span v-else>{{ $t("response.waiting_for_connection") }}</span>
|
||||
<span v-else>{{ t("response.waiting_for_connection") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -34,6 +24,9 @@
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref, watch } from "@nuxtjs/composition-api"
|
||||
import { getSourcePrefix as source } from "~/helpers/utils/string"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
log: { type: Array, default: () => [] },
|
||||
|
||||
@@ -9,30 +9,22 @@
|
||||
>
|
||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div
|
||||
class="bg-primary flex flex-col space-y-4 p-4 top-0 z-10 sticky"
|
||||
class="bg-primary sticky top-0 z-10 flex flex-col p-4 space-y-4"
|
||||
>
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="mqtt-url"
|
||||
v-model="url"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
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
|
||||
"
|
||||
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"
|
||||
:placeholder="$t('mqtt.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="validUrl ? toggleConnection() : null"
|
||||
@@ -71,7 +63,10 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
</Pane>
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('mqtt.log')" :log="log" />
|
||||
</AppSection>
|
||||
@@ -85,8 +80,8 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="pub_topic" class="font-semibold text-secondaryLight">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<label for="pub_topic" class="text-secondaryLight font-semibold">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -101,12 +96,12 @@
|
||||
spellcheck="false"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label for="mqtt-message" class="font-semibold text-secondaryLight">
|
||||
<div class="flex items-center justify-between flex-1 p-4">
|
||||
<label for="mqtt-message" class="text-secondaryLight font-semibold">
|
||||
{{ $t("mqtt.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<div class="flex px-4 space-x-2">
|
||||
<input
|
||||
id="mqtt-message"
|
||||
v-model="msg"
|
||||
@@ -125,19 +120,13 @@
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
border-t border-dividerLight
|
||||
flex flex-col flex-1
|
||||
mt-4
|
||||
p-4
|
||||
inline-flex
|
||||
"
|
||||
class="border-dividerLight flex inline-flex flex-col flex-1 p-4 mt-4 border-t"
|
||||
>
|
||||
<label for="sub_topic" class="font-semibold text-secondaryLight">
|
||||
<label for="sub_topic" class="text-secondaryLight font-semibold">
|
||||
{{ $t("mqtt.topic") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<div class="flex px-4 space-x-2">
|
||||
<input
|
||||
id="sub_topic"
|
||||
v-model="sub_topic"
|
||||
@@ -288,9 +277,7 @@ export default defineComponent({
|
||||
color: "var(--accent-color)",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
this.$toast.success(this.$t("state.connected"), {
|
||||
icon: "sync",
|
||||
})
|
||||
this.$toast.success(this.$t("state.connected"))
|
||||
},
|
||||
onMessageArrived({ payloadString, destinationName }) {
|
||||
this.log.push({
|
||||
@@ -321,13 +308,9 @@ export default defineComponent({
|
||||
this.connectingState = false
|
||||
this.connectionState = false
|
||||
if (this.manualDisconnect) {
|
||||
this.$toast.error(this.$t("state.disconnected"), {
|
||||
icon: "sync_disabled",
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
} else {
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
}
|
||||
this.manualDisconnect = false
|
||||
this.subscriptionState = false
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
>
|
||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<label for="client-version">
|
||||
<tippy
|
||||
@@ -28,21 +31,7 @@
|
||||
id="client-version"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
title="socket.io-client version"
|
||||
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
|
||||
"
|
||||
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"
|
||||
:value="`Client ${clientVersion}`"
|
||||
readonly
|
||||
:disabled="connectionState"
|
||||
@@ -64,18 +53,7 @@
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
:class="{ error: !urlValid }"
|
||||
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
|
||||
"
|
||||
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"
|
||||
:placeholder="$t('socketio.url')"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
@@ -83,19 +61,7 @@
|
||||
<input
|
||||
id="socketio-path"
|
||||
v-model="path"
|
||||
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
|
||||
"
|
||||
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"
|
||||
spellcheck="false"
|
||||
:disabled="connectionState"
|
||||
@keyup.enter="urlValid ? toggleConnection() : null"
|
||||
@@ -118,7 +84,10 @@
|
||||
</div>
|
||||
</AppSection>
|
||||
</Pane>
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog :title="$t('socketio.log')" :log="communication.log" />
|
||||
</AppSection>
|
||||
@@ -132,8 +101,8 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<label for="events" class="font-semibold text-secondaryLight">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<label for="events" class="text-secondaryLight font-semibold">
|
||||
{{ $t("socketio.events") }}
|
||||
</label>
|
||||
</div>
|
||||
@@ -149,8 +118,8 @@
|
||||
:disabled="!connectionState"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-1 p-4 items-center justify-between">
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<div class="flex items-center justify-between flex-1 p-4">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("socketio.communication") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -163,7 +132,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col space-y-2 px-4 pb-4">
|
||||
<div class="flex flex-col px-4 pb-4 space-y-2">
|
||||
<div
|
||||
v-for="(input, index) of communication.inputs"
|
||||
:key="`input-${index}`"
|
||||
@@ -325,9 +294,7 @@ export default defineComponent({
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
},
|
||||
]
|
||||
this.$toast.success(this.$t("state.connected"), {
|
||||
icon: "sync",
|
||||
})
|
||||
this.$toast.success(this.$t("state.connected"))
|
||||
})
|
||||
this.io.on("*", ({ data }) => {
|
||||
const [eventName, message] = data
|
||||
@@ -355,15 +322,11 @@ export default defineComponent({
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"), {
|
||||
icon: "sync_disabled",
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleError(e)
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
}
|
||||
|
||||
logHoppRequestRunToAnalytics({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<Pane :size="COLUMN_LAYOUT ? 45 : 50" class="hide-scrollbar !overflow-auto">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<div class="flex flex-1">
|
||||
<input
|
||||
id="server"
|
||||
@@ -10,51 +10,21 @@
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
:class="{ error: !serverValid }"
|
||||
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
|
||||
"
|
||||
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"
|
||||
:placeholder="$t('sse.url')"
|
||||
:disabled="connectionSSEState"
|
||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||
/>
|
||||
<label
|
||||
for="event-type"
|
||||
class="
|
||||
bg-primaryLight
|
||||
border-t border-b border-divider
|
||||
font-semibold
|
||||
text-secondaryLight
|
||||
py-2
|
||||
px-4
|
||||
truncate
|
||||
"
|
||||
class="bg-primaryLight border-divider text-secondaryLight px-4 py-2 font-semibold truncate border-t border-b"
|
||||
>
|
||||
{{ $t("sse.event_type") }}
|
||||
</label>
|
||||
<input
|
||||
id="event-type"
|
||||
v-model="eventType"
|
||||
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
|
||||
"
|
||||
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"
|
||||
spellcheck="false"
|
||||
:disabled="connectionSSEState"
|
||||
@keyup.enter="serverValid ? toggleSSEConnection() : null"
|
||||
@@ -74,7 +44,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane :size="COLUMN_LAYOUT ? 65 : 50" class="hide-scrollbar !overflow-auto">
|
||||
<AppSection label="response">
|
||||
<ul>
|
||||
<li>
|
||||
@@ -171,9 +141,7 @@ export default defineComponent({
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
},
|
||||
]
|
||||
this.$toast.success(this.$t("state.connected"), {
|
||||
icon: "sync",
|
||||
})
|
||||
this.$toast.success(this.$t("state.connected"))
|
||||
}
|
||||
this.sse.onerror = () => {
|
||||
this.handleSSEError()
|
||||
@@ -188,9 +156,7 @@ export default defineComponent({
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"), {
|
||||
icon: "sync_disabled",
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
}
|
||||
this.sse.addEventListener(this.eventType, ({ data }) => {
|
||||
this.events.log.push({
|
||||
@@ -201,9 +167,7 @@ export default defineComponent({
|
||||
})
|
||||
} catch (e) {
|
||||
this.handleSSEError(e)
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
}
|
||||
} else {
|
||||
this.events.log = [
|
||||
|
||||
@@ -9,25 +9,17 @@
|
||||
>
|
||||
<Pane size="75" min-size="65" class="hide-scrollbar !overflow-auto">
|
||||
<Splitpanes class="smart-splitter" :horizontal="COLUMN_LAYOUT">
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 45 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="request">
|
||||
<div class="bg-primary flex p-4 top-0 z-10 sticky">
|
||||
<div class="space-x-2 flex-1 inline-flex">
|
||||
<div class="bg-primary sticky top-0 z-10 flex p-4">
|
||||
<div class="inline-flex flex-1 space-x-2">
|
||||
<input
|
||||
id="websocket-url"
|
||||
v-model="url"
|
||||
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
|
||||
"
|
||||
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"
|
||||
type="url"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
@@ -52,19 +44,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="
|
||||
bg-primary
|
||||
border-b border-dividerLight
|
||||
flex flex-1
|
||||
top-upperPrimaryStickyFold
|
||||
pl-4
|
||||
z-10
|
||||
sticky
|
||||
items-center
|
||||
justify-between
|
||||
"
|
||||
class="bg-primary border-dividerLight top-upperPrimaryStickyFold sticky z-10 flex items-center justify-between flex-1 pl-4 border-b"
|
||||
>
|
||||
<label class="font-semibold text-secondaryLight">
|
||||
<label class="text-secondaryLight font-semibold">
|
||||
{{ $t("websocket.protocols") }}
|
||||
</label>
|
||||
<div class="flex">
|
||||
@@ -85,15 +67,11 @@
|
||||
<div
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
class="
|
||||
divide-x divide-dividerLight
|
||||
border-b border-dividerLight
|
||||
flex
|
||||
"
|
||||
class="divide-dividerLight border-dividerLight flex border-b divide-x"
|
||||
>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="bg-transparent flex flex-1 py-2 px-4"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
:placeholder="$t('count.protocol', { count: index + 1 })"
|
||||
name="message"
|
||||
type="text"
|
||||
@@ -136,34 +114,24 @@
|
||||
</div>
|
||||
<div
|
||||
v-if="protocols.length === 0"
|
||||
class="
|
||||
flex flex-col
|
||||
text-secondaryLight
|
||||
p-4
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
class="text-secondaryLight flex flex-col items-center justify-center p-4"
|
||||
>
|
||||
<img
|
||||
:src="`/images/states/${$colorMode.value}/add_category.svg`"
|
||||
loading="lazy"
|
||||
class="
|
||||
flex-col
|
||||
my-4
|
||||
object-contain object-center
|
||||
h-16
|
||||
w-16
|
||||
inline-flex
|
||||
"
|
||||
class="inline-flex flex-col object-contain object-center w-16 h-16 my-4"
|
||||
:alt="$t('empty.protocols')"
|
||||
/>
|
||||
<span class="text-center mb-4">
|
||||
<span class="mb-4 text-center">
|
||||
{{ $t("empty.protocols") }}
|
||||
</span>
|
||||
</div>
|
||||
</AppSection>
|
||||
</Pane>
|
||||
<Pane class="hide-scrollbar !overflow-auto">
|
||||
<Pane
|
||||
:size="COLUMN_LAYOUT ? 65 : 50"
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="response">
|
||||
<RealtimeLog
|
||||
:title="$t('websocket.log')"
|
||||
@@ -180,15 +148,15 @@
|
||||
class="hide-scrollbar !overflow-auto"
|
||||
>
|
||||
<AppSection label="messages">
|
||||
<div class="flex flex-col flex-1 p-4 inline-flex">
|
||||
<div class="flex inline-flex flex-col flex-1 p-4">
|
||||
<label
|
||||
for="websocket-message"
|
||||
class="font-semibold text-secondaryLight"
|
||||
class="text-secondaryLight font-semibold"
|
||||
>
|
||||
{{ $t("websocket.communication") }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex space-x-2 px-4">
|
||||
<div class="flex px-4 space-x-2">
|
||||
<input
|
||||
id="websocket-message"
|
||||
v-model="communication.input"
|
||||
@@ -319,9 +287,7 @@ export default defineComponent({
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
},
|
||||
]
|
||||
this.$toast.success(this.$t("state.connected"), {
|
||||
icon: "sync",
|
||||
})
|
||||
this.$toast.success(this.$t("state.connected"))
|
||||
}
|
||||
this.socket.onerror = () => {
|
||||
this.handleError()
|
||||
@@ -334,9 +300,7 @@ export default defineComponent({
|
||||
color: "#ff5555",
|
||||
ts: new Date().toLocaleTimeString(),
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"), {
|
||||
icon: "sync_disabled",
|
||||
})
|
||||
this.$toast.error(this.$t("state.disconnected"))
|
||||
}
|
||||
this.socket.onmessage = ({ data }) => {
|
||||
this.communication.log.push({
|
||||
@@ -347,9 +311,7 @@ export default defineComponent({
|
||||
}
|
||||
} catch (e) {
|
||||
this.handleError(e)
|
||||
this.$toast.error(this.$t("error.something_went_wrong"), {
|
||||
icon: "error_outline",
|
||||
})
|
||||
this.$toast.error(this.$t("error.something_went_wrong"))
|
||||
}
|
||||
|
||||
logHoppRequestRunToAnalytics({
|
||||
@@ -433,7 +395,6 @@ export default defineComponent({
|
||||
const oldProtocols = this.protocols.slice()
|
||||
this.$delete(this.protocols, index)
|
||||
this.$toast.success(this.$t("state.deleted"), {
|
||||
icon: "delete",
|
||||
action: {
|
||||
text: this.$t("action.undo"),
|
||||
duration: 4000,
|
||||
|
||||
@@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="
|
||||
cursor-pointer
|
||||
flex-nowrap
|
||||
group
|
||||
inline-flex
|
||||
items-center
|
||||
justify-center
|
||||
transition
|
||||
hover:text-secondaryDark
|
||||
"
|
||||
class="flex-nowrap group hover:text-secondaryDark inline-flex items-center justify-center transition cursor-pointer"
|
||||
@click="$emit('change')"
|
||||
>
|
||||
<input
|
||||
@@ -21,7 +12,7 @@
|
||||
/>
|
||||
<label
|
||||
for="checkbox"
|
||||
class="cursor-pointer pl-0 align-middle font-semibold"
|
||||
class="pl-0 font-semibold align-middle cursor-pointer"
|
||||
>
|
||||
<slot></slot>
|
||||
</label>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-for="(color, index) of colors"
|
||||
:key="`color-${index}`"
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="$t(getColorModeName(color))"
|
||||
:title="t(getColorModeName(color))"
|
||||
:class="{
|
||||
'bg-primaryLight !text-accent hover:text-accent': color === active,
|
||||
}"
|
||||
@@ -22,6 +22,9 @@ import {
|
||||
HoppBgColors,
|
||||
useSetting,
|
||||
} from "~/newstore/settings"
|
||||
import { useI18n } from "~/helpers/utils/composables"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const colors = HoppBgColors
|
||||
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