feat: reorder key-value entries (#2189)
This commit is contained in:
committed by
Andrew Bastin
parent
0edfe7b8e3
commit
29d3f3cbe3
18
packages/hoppscotch-app/assets/icons/grip-vertical.svg
Normal file
18
packages/hoppscotch-app/assets/icons/grip-vertical.svg
Normal file
@@ -0,0 +1,18 @@
|
||||
<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"
|
||||
>
|
||||
<circle cx="9" cy="12" r="1" />
|
||||
<circle cx="9" cy="5" r="1" />
|
||||
<circle cx="9" cy="19" r="1" />
|
||||
<circle cx="15" cy="12" r="1" />
|
||||
<circle cx="15" cy="5" r="1" />
|
||||
<circle cx="15" cy="19" r="1" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 413 B |
@@ -155,11 +155,31 @@
|
||||
class="flex flex-col flex-1"
|
||||
></div>
|
||||
<div v-else>
|
||||
<draggable
|
||||
v-model="workingHeaders"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(header, index) in workingHeaders"
|
||||
:key="`header-${header.id}-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== workingHeaders?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
@@ -237,6 +257,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="workingHeaders.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -288,6 +309,7 @@ import {
|
||||
parseRawKeyValueEntriesE,
|
||||
RawKeyValueEntry,
|
||||
} from "@hoppscotch/data"
|
||||
import draggable from "vuedraggable"
|
||||
import isEqual from "lodash/isEqual"
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
import { copyToClipboard } from "~/helpers/utils/clipboard"
|
||||
|
||||
@@ -28,11 +28,31 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<draggable
|
||||
v-model="workingParams"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(param, index) in workingParams"
|
||||
:key="`param-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== workingParams?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
:placeholder="`${$t('count.parameter', { count: index + 1 })}`"
|
||||
@@ -119,6 +139,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="workingParams.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -146,6 +167,7 @@ import { ref, Ref, watch } from "@nuxtjs/composition-api"
|
||||
import { FormDataKeyValue } from "@hoppscotch/data"
|
||||
import isEqual from "lodash/isEqual"
|
||||
import { clone } from "lodash"
|
||||
import draggable from "vuedraggable"
|
||||
import { pluckRef, useI18n, useToast } from "~/helpers/utils/composables"
|
||||
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
||||
|
||||
|
||||
@@ -38,11 +38,31 @@
|
||||
</div>
|
||||
<div v-if="bulkMode" ref="bulkEditor" class="flex flex-col flex-1"></div>
|
||||
<div v-else>
|
||||
<draggable
|
||||
v-model="workingHeaders"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(header, index) in workingHeaders"
|
||||
:key="`header-${header.id}-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== workingHeaders?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<SmartAutoComplete
|
||||
:placeholder="`${t('count.header', { count: index + 1 })}`"
|
||||
:source="commonHeaders"
|
||||
@@ -117,6 +137,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="workingHeaders.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -155,6 +176,7 @@ import * as E from "fp-ts/Either"
|
||||
import * as O from "fp-ts/Option"
|
||||
import * as A from "fp-ts/Array"
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
import draggable from "vuedraggable"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { restHeaders$, setRESTHeaders } from "~/newstore/RESTSession"
|
||||
import { commonHeaders } from "~/helpers/headers"
|
||||
|
||||
@@ -38,11 +38,31 @@
|
||||
</div>
|
||||
<div v-if="bulkMode" ref="bulkEditor" class="flex flex-col flex-1"></div>
|
||||
<div v-else>
|
||||
<draggable
|
||||
v-model="workingParams"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(param, index) in workingParams"
|
||||
:key="`param-${param.id}-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== workingParams?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
:placeholder="`${t('count.parameter', { count: index + 1 })}`"
|
||||
@@ -90,7 +110,9 @@
|
||||
id: param.id,
|
||||
key: param.key,
|
||||
value: param.value,
|
||||
active: param.hasOwnProperty('active') ? !param.active : false,
|
||||
active: param.hasOwnProperty('active')
|
||||
? !param.active
|
||||
: false,
|
||||
})
|
||||
"
|
||||
/>
|
||||
@@ -105,6 +127,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="workingParams.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -143,6 +166,7 @@ import {
|
||||
} from "@hoppscotch/data"
|
||||
import isEqual from "lodash/isEqual"
|
||||
import cloneDeep from "lodash/cloneDeep"
|
||||
import draggable from "vuedraggable"
|
||||
import linter from "~/helpers/editor/linting/rawKeyValue"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import { useI18n, useToast, useStream } from "~/helpers/utils/composables"
|
||||
|
||||
@@ -38,11 +38,31 @@
|
||||
</div>
|
||||
<div v-if="bulkMode" ref="bulkEditor" class="flex flex-col flex-1"></div>
|
||||
<div v-else>
|
||||
<draggable
|
||||
v-model="workingUrlEncodedParams"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(param, index) in workingUrlEncodedParams"
|
||||
:key="`param-${param.id}-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== workingUrlEncodedParams?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<SmartEnvInput
|
||||
v-model="param.key"
|
||||
:placeholder="`${t('count.parameter', { count: index + 1 })}`"
|
||||
@@ -105,6 +125,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="workingUrlEncodedParams.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -146,6 +167,7 @@ import * as O from "fp-ts/Option"
|
||||
import * as RA from "fp-ts/ReadonlyArray"
|
||||
import * as E from "fp-ts/Either"
|
||||
import { cloneDeep } from "lodash"
|
||||
import draggable from "vuedraggable"
|
||||
import { useCodemirror } from "~/helpers/editor/codemirror"
|
||||
import linter from "~/helpers/editor/linting/rawKeyValue"
|
||||
import { useRESTRequestBody } from "~/newstore/RESTSession"
|
||||
|
||||
@@ -51,11 +51,31 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<draggable
|
||||
v-model="protocols"
|
||||
animation="250"
|
||||
handle=".draggable-handle"
|
||||
draggable=".draggable-content"
|
||||
ghost-class="cursor-move"
|
||||
chosen-class="bg-primaryLight"
|
||||
drag-class="cursor-grabbing"
|
||||
>
|
||||
<div
|
||||
v-for="(protocol, index) of protocols"
|
||||
:key="`protocol-${index}`"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight"
|
||||
class="flex border-b divide-x divide-dividerLight border-dividerLight draggable-content group"
|
||||
>
|
||||
<span>
|
||||
<ButtonSecondary
|
||||
svg="grip-vertical"
|
||||
class="cursor-auto text-primary hover:text-primary"
|
||||
:class="{
|
||||
'draggable-handle group-hover:text-secondaryLight !cursor-grab':
|
||||
index !== protocols?.length - 1,
|
||||
}"
|
||||
tabindex="-1"
|
||||
/>
|
||||
</span>
|
||||
<input
|
||||
v-model="protocol.value"
|
||||
class="flex flex-1 px-4 py-2 bg-transparent"
|
||||
@@ -106,6 +126,7 @@
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</draggable>
|
||||
<div
|
||||
v-if="protocols.length === 0"
|
||||
class="flex flex-col items-center justify-center p-4 text-secondaryLight"
|
||||
@@ -162,6 +183,7 @@
|
||||
<script>
|
||||
import { defineComponent } from "@nuxtjs/composition-api"
|
||||
import debounce from "lodash/debounce"
|
||||
import draggable from "vuedraggable"
|
||||
import { logHoppRequestRunToAnalytics } from "~/helpers/fb/analytics"
|
||||
import {
|
||||
setWSEndpoint,
|
||||
@@ -185,6 +207,9 @@ import {
|
||||
import { useStream } from "~/helpers/utils/composables"
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
draggable,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
url: useStream(WSEndpoint$, "", setWSEndpoint),
|
||||
|
||||
@@ -129,6 +129,9 @@ const initView = (el: any) => {
|
||||
clipboardEv = ev
|
||||
pastedValue = ev.clipboardData?.getData("text") ?? ""
|
||||
},
|
||||
drop(ev) {
|
||||
ev.preventDefault()
|
||||
},
|
||||
}),
|
||||
ViewPlugin.fromClass(
|
||||
class {
|
||||
|
||||
@@ -111,6 +111,7 @@
|
||||
"vue-pdf-embed": "^1.1.0",
|
||||
"vue-textarea-autosize": "^1.1.1",
|
||||
"vue-tippy": "^4.13.0",
|
||||
"vuedraggable": "^2.24.3",
|
||||
"vuejs-auto-complete": "^0.9.0",
|
||||
"wonka": "^4.0.15",
|
||||
"yargs-parser": "^21.0.1"
|
||||
|
||||
@@ -55,6 +55,8 @@ export default defineConfig({
|
||||
},
|
||||
cursor: {
|
||||
nsResize: "ns-resize",
|
||||
grab: "grab",
|
||||
grabbing: "grabbing",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
735
pnpm-lock.yaml
generated
735
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user