feat: persist line wrap setting (#3647)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Muhammed Ajmal M
2024-02-09 14:05:09 +05:30
committed by GitHub
parent 6a0e73fdec
commit 47226be6d0
21 changed files with 273 additions and 72 deletions

View File

@@ -22,9 +22,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'cookie')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }" v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -102,6 +102,8 @@ import {
useCopyResponse, useCopyResponse,
useDownloadResponse, useDownloadResponse,
} from "~/composables/lens-actions" } from "~/composables/lens-actions"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
// TODO: Build Managed Mode! // TODO: Build Managed Mode!
@@ -122,7 +124,7 @@ const toast = useToast()
const cookieEditor = ref<HTMLElement>() const cookieEditor = ref<HTMLElement>()
const rawCookieString = ref("") const rawCookieString = ref("")
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "cookie")
useCodemirror( useCodemirror(
cookieEditor, cookieEditor,
@@ -131,7 +133,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/plain", mode: "text/plain",
placeholder: `${t("cookies.modal.enter_cookie_string")}`, placeholder: `${t("cookies.modal.enter_cookie_string")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -27,9 +27,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlHeaders')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -315,6 +315,8 @@ import { commonHeaders } from "~/helpers/headers"
import { useCodemirror } from "@composables/codemirror" import { useCodemirror } from "@composables/codemirror"
import { objRemoveKey } from "~/helpers/functional/object" import { objRemoveKey } from "~/helpers/functional/object"
import { useVModel } from "@vueuse/core" import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import { HoppGQLHeader } from "~/helpers/graphql" import { HoppGQLHeader } from "~/helpers/graphql"
import { throwError } from "~/helpers/functional/error" import { throwError } from "~/helpers/functional/error"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties" import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
@@ -338,7 +340,7 @@ const request = useVModel(props, "modelValue", emit)
const idTicker = ref(0) const idTicker = ref(0)
const linewrapEnabled = ref(false) const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlHeaders")
const bulkMode = ref(false) const bulkMode = ref(false)
const bulkHeaders = ref("") const bulkHeaders = ref("")
@@ -353,7 +355,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/x-yaml", mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`, placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -61,9 +61,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlQuery')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -112,6 +112,8 @@ import {
socketDisconnect, socketDisconnect,
subscriptionState, subscriptionState,
} from "~/helpers/graphql/connection" } from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
// Template refs // Template refs
const queryEditor = ref<any | null>(null) const queryEditor = ref<any | null>(null)
@@ -137,7 +139,7 @@ const prettifyQueryIcon = refAutoReset<
typeof IconWand | typeof IconCheck | typeof IconInfo typeof IconWand | typeof IconCheck | typeof IconInfo
>(IconWand, 1000) >(IconWand, 1000)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlQuery")
const selectedOperation = ref<gql.OperationDefinitionNode | null>(null) const selectedOperation = ref<gql.OperationDefinitionNode | null>(null)
@@ -184,7 +186,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "graphql", mode: "graphql",
placeholder: `${t("request.query")}`, placeholder: `${t("request.query")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: createGQLQueryLinter(schema), linter: createGQLQueryLinter(schema),
completer: queryCompleter(schema), completer: queryCompleter(schema),

View File

@@ -16,9 +16,11 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="
toggleNestedSetting('WRAP_LINES', 'graphqlResponseBody')
"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }" v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -99,6 +101,8 @@ import { useI18n } from "@composables/i18n"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils" import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { GQLResponseEvent } from "~/helpers/graphql/connection" import { GQLResponseEvent } from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import interfaceLanguages from "~/helpers/utils/interfaceLanguages" import interfaceLanguages from "~/helpers/utils/interfaceLanguages"
import { import {
useCopyInterface, useCopyInterface,
@@ -133,8 +137,8 @@ const responseString = computed(() => {
}) })
const schemaEditor = ref<any | null>(null) const schemaEditor = ref<any | null>(null)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlResponseBody")
const copyInterfaceTippyActions = ref<any | null>(null) const copyInterfaceTippyActions = ref<any | null>(null)
const linewrapEnabled = ref(true)
useCodemirror( useCodemirror(
schemaEditor, schemaEditor,
@@ -143,7 +147,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/ld+json", mode: "application/ld+json",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -127,9 +127,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlSchema')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -202,6 +202,8 @@ import {
subscriptionFields, subscriptionFields,
} from "~/helpers/graphql/connection" } from "~/helpers/graphql/connection"
import { platform } from "~/platform" import { platform } from "~/platform"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type NavigationTabs = "history" | "collection" | "docs" | "schema" type NavigationTabs = "history" | "collection" | "docs" | "schema"
type GqlTabs = "queries" | "mutations" | "subscriptions" | "types" type GqlTabs = "queries" | "mutations" | "subscriptions" | "types"
@@ -349,7 +351,7 @@ const handleJumpToType = async (type: GraphQLType) => {
} }
const schemaEditor = ref<any | null>(null) const schemaEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlSchema")
useCodemirror( useCodemirror(
schemaEditor, schemaEditor,
@@ -358,7 +360,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "graphql", mode: "graphql",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -49,9 +49,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'graphqlVariables')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -93,6 +93,8 @@ import {
socketDisconnect, socketDisconnect,
subscriptionState, subscriptionState,
} from "~/helpers/graphql/connection" } from "~/helpers/graphql/connection"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
const toast = useToast() const toast = useToast()
@@ -114,7 +116,7 @@ const variableString = useVModel(props, "modelValue", emit)
const variableEditor = ref<any | null>(null) const variableEditor = ref<any | null>(null)
const linewrapEnabled = ref(false) const WRAP_LINES = useNestedSetting("WRAP_LINES", "graphqlVariables")
const copyVariablesIcon = refAutoReset<typeof IconCopy | typeof IconCheck>( const copyVariablesIcon = refAutoReset<typeof IconCopy | typeof IconCheck>(
IconCopy, IconCopy,
@@ -131,7 +133,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/ld+json", mode: "application/ld+json",
placeholder: `${t("request.variables")}`, placeholder: `${t("request.variables")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: computed(() => linter: computed(() =>
variableString.value.length > 0 ? jsonLinter : null variableString.value.length > 0 ? jsonLinter : null

View File

@@ -86,9 +86,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'codeGen')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }" v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -161,6 +161,8 @@ import cloneDeep from "lodash-es/cloneDeep"
import { platform } from "~/platform" import { platform } from "~/platform"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -224,7 +226,7 @@ const requestCode = computed(() => {
// Template refs // Template refs
const tippyActions = ref<any | null>(null) const tippyActions = ref<any | null>(null)
const generatedCode = ref<any | null>(null) const generatedCode = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "codeGen")
useCodemirror( useCodemirror(
generatedCode, generatedCode,
@@ -233,7 +235,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/plain", mode: "text/plain",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -29,9 +29,9 @@
v-if="bulkMode" v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpHeaders')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -332,6 +332,9 @@ import { useVModel } from "@vueuse/core"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { InspectionService, InspectorResult } from "~/services/inspection" import { InspectionService, InspectorResult } from "~/services/inspection"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { toggleSetting } from "~/newstore/settings"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties" import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
const t = useI18n() const t = useI18n()
@@ -346,7 +349,7 @@ const idTicker = ref(0)
const bulkMode = ref(false) const bulkMode = ref(false)
const bulkHeaders = ref("") const bulkHeaders = ref("")
const bulkEditor = ref<any | null>(null) const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpHeaders")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null) const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -371,7 +374,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/x-yaml", mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`, placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter, linter,
completer: null, completer: null,

View File

@@ -22,9 +22,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'importCurl')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip', allowHTML: true }" v-tippy="{ theme: 'tooltip', allowHTML: true }"
@@ -96,6 +96,8 @@ import IconTrash2 from "~icons/lucide/trash-2"
import { platform } from "~/platform" import { platform } from "~/platform"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -106,7 +108,7 @@ const tabs = useService(RESTTabService)
const curl = ref("") const curl = ref("")
const curlEditor = ref<any | null>(null) const curlEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "importCurl")
const props = defineProps<{ show: boolean; text: string }>() const props = defineProps<{ show: boolean; text: string }>()
@@ -117,7 +119,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/x-sh", mode: "application/x-sh",
placeholder: `${t("request.enter_curl")}`, placeholder: `${t("request.enter_curl")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -24,9 +24,9 @@
v-if="bulkMode" v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpParams')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -205,6 +205,8 @@ import { useVModel } from "@vueuse/core"
import { useService } from "dioc/vue" import { useService } from "dioc/vue"
import { InspectionService, InspectorResult } from "~/services/inspection" import { InspectionService, InspectorResult } from "~/services/inspection"
import { RESTTabService } from "~/services/tab/rest" import { RESTTabService } from "~/services/tab/rest"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const colorMode = useColorMode() const colorMode = useColorMode()
@@ -217,7 +219,7 @@ const idTicker = ref(0)
const bulkMode = ref(false) const bulkMode = ref(false)
const bulkParams = ref("") const bulkParams = ref("")
const bulkEditor = ref<any | null>(null) const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpParams")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null) const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -228,7 +230,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/x-yaml", mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`, placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter, linter,
completer: null, completer: null,

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpPreRequest')"
/> />
</div> </div>
</div> </div>
@@ -72,6 +72,8 @@ import linter from "~/helpers/editor/linting/preRequest"
import completer from "~/helpers/editor/completion/preRequest" import completer from "~/helpers/editor/completion/preRequest"
import { useI18n } from "@composables/i18n" import { useI18n } from "@composables/i18n"
import { useVModel } from "@vueuse/core" import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -85,7 +87,7 @@ const emit = defineEmits<{
const preRequestScript = useVModel(props, "modelValue", emit) const preRequestScript = useVModel(props, "modelValue", emit)
const preRequestEditor = ref<any | null>(null) const preRequestEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpPreRequest")
useCodemirror( useCodemirror(
preRequestEditor, preRequestEditor,
@@ -93,7 +95,7 @@ useCodemirror(
reactive({ reactive({
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/javascript", mode: "application/javascript",
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
placeholder: `${t("preRequest.javascript_code")}`, placeholder: `${t("preRequest.javascript_code")}`,
}, },
linter, linter,

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpRequestBody')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-if=" v-if="
@@ -85,6 +85,8 @@ import { isJSONContentType } from "~/helpers/utils/contenttypes"
import jsonLinter from "~/helpers/editor/linting/json" import jsonLinter from "~/helpers/editor/linting/json"
import { readFileAsText } from "~/helpers/functional/files" import { readFileAsText } from "~/helpers/functional/files"
import xmlFormat from "xml-formatter" import xmlFormat from "xml-formatter"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type PossibleContentTypes = Exclude< type PossibleContentTypes = Exclude<
ValidContentTypes, ValidContentTypes,
@@ -122,7 +124,7 @@ const langLinter = computed(() =>
isJSONContentType(body.value.contentType) ? jsonLinter : null isJSONContentType(body.value.contentType) ? jsonLinter : null
) )
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpRequestBody")
const rawBodyParameters = ref<any | null>(null) const rawBodyParameters = ref<any | null>(null)
const codemirrorValue: Ref<string | undefined> = const codemirrorValue: Ref<string | undefined> =
@@ -148,7 +150,7 @@ useCodemirror(
codemirrorValue, codemirrorValue,
reactive({ reactive({
extendedEditorConfig: { extendedEditorConfig: {
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
mode: rawInputEditorLang, mode: rawInputEditorLang,
placeholder: t("request.raw_body").toString(), placeholder: t("request.raw_body").toString(),
}, },

View File

@@ -23,9 +23,9 @@
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpTest')"
/> />
</div> </div>
</div> </div>
@@ -72,6 +72,8 @@ import linter from "~/helpers/editor/linting/testScript"
import completer from "~/helpers/editor/completion/testScript" import completer from "~/helpers/editor/completion/testScript"
import { useI18n } from "@composables/i18n" import { useI18n } from "@composables/i18n"
import { useVModel } from "@vueuse/core" import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -81,7 +83,7 @@ const props = defineProps<{
const emit = defineEmits(["update:modelValue"]) const emit = defineEmits(["update:modelValue"])
const testScript = useVModel(props, "modelValue", emit) const testScript = useVModel(props, "modelValue", emit)
const testScriptEditor = ref<any | null>(null) const testScriptEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpTest")
useCodemirror( useCodemirror(
testScriptEditor, testScriptEditor,
@@ -89,7 +91,7 @@ useCodemirror(
reactive({ reactive({
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/javascript", mode: "application/javascript",
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
placeholder: `${t("test.javascript_code")}`, placeholder: `${t("test.javascript_code")}`,
}, },
linter, linter,

View File

@@ -24,9 +24,9 @@
v-if="bulkMode" v-if="bulkMode"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpUrlEncoded')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
@@ -196,6 +196,8 @@ import { useColorMode } from "@composables/theming"
import { objRemoveKey } from "~/helpers/functional/object" import { objRemoveKey } from "~/helpers/functional/object"
import { throwError } from "~/helpers/functional/error" import { throwError } from "~/helpers/functional/error"
import { useVModel } from "@vueuse/core" import { useVModel } from "@vueuse/core"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
type Body = HoppRESTReqBody & { type Body = HoppRESTReqBody & {
contentType: "application/x-www-form-urlencoded" contentType: "application/x-www-form-urlencoded"
@@ -220,7 +222,7 @@ const idTicker = ref(0)
const bulkMode = ref(false) const bulkMode = ref(false)
const bulkUrlEncodedParams = ref("") const bulkUrlEncodedParams = ref("")
const bulkEditor = ref<any | null>(null) const bulkEditor = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpUrlEncoded")
const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null) const deletionToast = ref<{ goAway: (delay: number) => void } | null>(null)
@@ -231,7 +233,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/x-yaml", mode: "text/x-yaml",
placeholder: `${t("state.bulk_mode_placeholder")}`, placeholder: `${t("state.bulk_mode_placeholder")}`,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter, linter,
completer: null, completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body" v-if="response.body"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-if="response.body" v-if="response.body"
@@ -76,6 +76,8 @@ import { useI18n } from "@composables/i18n"
import type { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse" import type { HoppRESTResponse } from "~/helpers/types/HoppRESTResponse"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils" import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -84,7 +86,7 @@ const props = defineProps<{
}>() }>()
const htmlResponse = ref<any | null>(null) const htmlResponse = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
const { responseBodyText } = useResponseBody(props.response) const { responseBodyText } = useResponseBody(props.response)
const { downloadIcon, downloadResponse } = useDownloadResponse( const { downloadIcon, downloadResponse } = useDownloadResponse(
@@ -104,7 +106,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "htmlmixed", mode: "htmlmixed",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -14,9 +14,9 @@
v-if="response.body" v-if="response.body"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-if="response.body" v-if="response.body"
@@ -260,6 +260,8 @@ import {
} from "@composables/lens-actions" } from "@composables/lens-actions"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils" import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
import interfaceLanguages from "~/helpers/utils/interfaceLanguages" import interfaceLanguages from "~/helpers/utils/interfaceLanguages"
const t = useI18n() const t = useI18n()
@@ -371,8 +373,8 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
// Template refs // Template refs
const tippyActions = ref<any | null>(null) const tippyActions = ref<any | null>(null)
const jsonResponse = ref<any | null>(null) const jsonResponse = ref<any | null>(null)
const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
const copyInterfaceTippyActions = ref<any | null>(null) const copyInterfaceTippyActions = ref<any | null>(null)
const linewrapEnabled = ref(true)
const { cursor } = useCodemirror( const { cursor } = useCodemirror(
jsonResponse, jsonResponse,
@@ -381,7 +383,7 @@ const { cursor } = useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/ld+json", mode: "application/ld+json",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body" v-if="response.body"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-if="response.body" v-if="response.body"
@@ -58,6 +58,8 @@ import {
import { objFieldMatches } from "~/helpers/functional/object" import { objFieldMatches } from "~/helpers/functional/object"
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils" import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -97,7 +99,7 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
const { copyIcon, copyResponse } = useCopyResponse(responseBodyText) const { copyIcon, copyResponse } = useCopyResponse(responseBodyText)
const rawResponse = ref<any | null>(null) const rawResponse = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
useCodemirror( useCodemirror(
rawResponse, rawResponse,
@@ -106,7 +108,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "text/plain", mode: "text/plain",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -11,9 +11,9 @@
v-if="response.body" v-if="response.body"
v-tippy="{ theme: 'tooltip' }" v-tippy="{ theme: 'tooltip' }"
:title="t('state.linewrap')" :title="t('state.linewrap')"
:class="{ '!text-accent': linewrapEnabled }" :class="{ '!text-accent': WRAP_LINES }"
:icon="IconWrapText" :icon="IconWrapText"
@click.prevent="linewrapEnabled = !linewrapEnabled" @click.prevent="toggleNestedSetting('WRAP_LINES', 'httpResponseBody')"
/> />
<HoppButtonSecondary <HoppButtonSecondary
v-if="response.body" v-if="response.body"
@@ -58,6 +58,8 @@ import {
import { defineActionHandler } from "~/helpers/actions" import { defineActionHandler } from "~/helpers/actions"
import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils" import { getPlatformSpecialKey as getSpecialKey } from "~/helpers/platformutils"
import { objFieldMatches } from "~/helpers/functional/object" import { objFieldMatches } from "~/helpers/functional/object"
import { useNestedSetting } from "~/composables/settings"
import { toggleNestedSetting } from "~/newstore/settings"
const t = useI18n() const t = useI18n()
@@ -91,7 +93,7 @@ const { downloadIcon, downloadResponse } = useDownloadResponse(
const { copyIcon, copyResponse } = useCopyResponse(responseBodyText) const { copyIcon, copyResponse } = useCopyResponse(responseBodyText)
const xmlResponse = ref<any | null>(null) const xmlResponse = ref<any | null>(null)
const linewrapEnabled = ref(true) const WRAP_LINES = useNestedSetting("WRAP_LINES", "httpResponseBody")
useCodemirror( useCodemirror(
xmlResponse, xmlResponse,
@@ -100,7 +102,7 @@ useCodemirror(
extendedEditorConfig: { extendedEditorConfig: {
mode: "application/xml", mode: "application/xml",
readOnly: true, readOnly: true,
lineWrapping: linewrapEnabled, lineWrapping: WRAP_LINES,
}, },
linter: null, linter: null,
completer: null, completer: null,

View File

@@ -13,7 +13,36 @@ export function useSetting<K extends keyof SettingsDef>(
settingsStore.dispatch({ settingsStore.dispatch({
dispatcher: "applySetting", dispatcher: "applySetting",
payload: { payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey, settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
value,
},
})
}
)
}
export function useNestedSetting<
K extends keyof SettingsDef,
P extends keyof SettingsDef[K],
>(settingKey: K, property: P): Ref<SettingsDef[K][P]> {
return useStream(
settingsStore.subject$.pipe(
pluck(settingKey),
pluck(property),
distinctUntilChanged()
),
settingsStore.value[settingKey][property],
(value: SettingsDef[K][P]) => {
settingsStore.dispatch({
dispatcher: "applyNestedSetting",
payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
// @ts-expect-error TS is not able to understand the type semantics here
value, value,
}, },
}) })
@@ -35,7 +64,9 @@ export function useSettingStatic<K extends keyof SettingsDef>(
settingsStore.dispatch({ settingsStore.dispatch({
dispatcher: "applySetting", dispatcher: "applySetting",
payload: { payload: {
// @ts-expect-error TS is not able to understand the type semantics here
settingKey, settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
value, value,
}, },
}) })

View File

@@ -30,6 +30,24 @@ export type SettingsDef = {
PROXY_URL: string PROXY_URL: string
WRAP_LINES: {
httpRequestBody: boolean
httpResponseBody: boolean
httpHeaders: boolean
httpParams: boolean
httpUrlEncoded: boolean
httpPreRequest: boolean
httpTest: boolean
graphqlQuery: boolean
graphqlResponseBody: boolean
graphqlHeaders: boolean
graphqlVariables: boolean
graphqlSchema: boolean
importCurl: boolean
codeGen: boolean
cookie: boolean
}
CURRENT_INTERCEPTOR_ID: string CURRENT_INTERCEPTOR_ID: string
URL_EXCLUDES: { URL_EXCLUDES: {
@@ -53,6 +71,24 @@ export const getDefaultSettings = (): SettingsDef => ({
syncHistory: true, syncHistory: true,
syncEnvironments: true, syncEnvironments: true,
WRAP_LINES: {
httpRequestBody: true,
httpResponseBody: true,
httpHeaders: true,
httpParams: true,
httpUrlEncoded: true,
httpPreRequest: true,
httpTest: true,
graphqlQuery: true,
graphqlResponseBody: true,
graphqlHeaders: false,
graphqlVariables: false,
graphqlSchema: true,
importCurl: true,
codeGen: true,
cookie: true,
},
CURRENT_INTERCEPTOR_ID: "browser", // TODO: Allow the platform definition to take this place CURRENT_INTERCEPTOR_ID: "browser", // TODO: Allow the platform definition to take this place
// TODO: Interceptor related settings should move under the interceptor systems // TODO: Interceptor related settings should move under the interceptor systems
@@ -80,6 +116,16 @@ type ApplySettingPayload = {
} }
}[keyof SettingsDef] }[keyof SettingsDef]
type ApplyNestedSettingPayload = {
[K in KeysMatching<SettingsDef, Record<string, any>>]: {
[P in keyof SettingsDef[K]]: {
settingKey: K
property: P
value: SettingsDef[K][P]
}
}[keyof SettingsDef[K]]
}[KeysMatching<SettingsDef, Record<string, any>>]
const dispatchers = defineDispatchers({ const dispatchers = defineDispatchers({
bulkApplySettings(_currentState: SettingsDef, payload: Partial<SettingsDef>) { bulkApplySettings(_currentState: SettingsDef, payload: Partial<SettingsDef>) {
return payload return payload
@@ -100,6 +146,29 @@ const dispatchers = defineDispatchers({
return result return result
}, },
toggleNestedSetting(
currentState: SettingsDef,
{
settingKey,
property,
}: {
settingKey: KeysMatching<SettingsDef, Record<string, boolean>>
property: KeysMatching<SettingsDef[typeof settingKey], boolean>
}
) {
if (!has(currentState, [settingKey, property])) {
return {}
}
const result: Partial<SettingsDef> = {
[settingKey]: {
...currentState[settingKey],
[property]: !currentState[settingKey][property],
},
}
return result
},
applySetting( applySetting(
_currentState: SettingsDef, _currentState: SettingsDef,
{ settingKey, value }: ApplySettingPayload { settingKey, value }: ApplySettingPayload
@@ -108,6 +177,18 @@ const dispatchers = defineDispatchers({
[settingKey]: value, [settingKey]: value,
} }
return result
},
applyNestedSetting(
_currentState: SettingsDef,
{ settingKey, property, value }: ApplyNestedSettingPayload
) {
const result: Partial<SettingsDef> = {
[settingKey]: {
[property]: value,
},
}
return result return result
}, },
}) })
@@ -144,6 +225,20 @@ export function toggleSetting(settingKey: KeysMatching<SettingsDef, boolean>) {
}) })
} }
export function toggleNestedSetting<
K extends KeysMatching<SettingsDef, Record<string, boolean>>,
P extends keyof SettingsDef[K],
>(settingKey: K, property: P) {
settingsStore.dispatch({
dispatcher: "toggleNestedSetting",
payload: {
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
},
})
}
export function applySetting<K extends keyof SettingsDef>( export function applySetting<K extends keyof SettingsDef>(
settingKey: K, settingKey: K,
value: SettingsDef[K] value: SettingsDef[K]
@@ -159,6 +254,22 @@ export function applySetting<K extends keyof SettingsDef>(
}) })
} }
export function applyNestedSetting<
K extends KeysMatching<SettingsDef, Record<string, any>>,
P extends keyof SettingsDef[K],
R extends SettingsDef[K][P],
>(settingKey: K, property: P, value: R) {
settingsStore.dispatch({
dispatcher: "applyNestedSetting",
payload: {
settingKey,
// @ts-expect-error TS is not able to understand the type semantics here
property,
value,
},
})
}
export function performSettingsDataMigrations(data: any): SettingsDef { export function performSettingsDataMigrations(data: any): SettingsDef {
const source = cloneDeep(data) const source = cloneDeep(data)

View File

@@ -45,6 +45,26 @@ const SettingsDefSchema = z.object({
SIDEBAR: z.boolean(), SIDEBAR: z.boolean(),
SIDEBAR_ON_LEFT: z.boolean(), SIDEBAR_ON_LEFT: z.boolean(),
COLUMN_LAYOUT: z.boolean(), COLUMN_LAYOUT: z.boolean(),
WRAP_LINES: z.optional(
z.object({
httpRequestBody: z.boolean(),
httpResponseBody: z.boolean(),
httpHeaders: z.boolean(),
httpParams: z.boolean(),
httpUrlEncoded: z.boolean(),
httpPreRequest: z.boolean(),
httpTest: z.boolean(),
graphqlQuery: z.boolean(),
graphqlResponseBody: z.boolean(),
graphqlHeaders: z.boolean(),
graphqlVariables: z.boolean(),
graphqlSchema: z.boolean(),
importCurl: z.boolean(),
codeGen: z.boolean(),
cookie: z.boolean(),
})
),
}) })
// Common properties shared across REST & GQL collections // Common properties shared across REST & GQL collections