Save collapsed sections to state

When you refresh or navigate to a new page and back, your collapsed sections will be as you set them.
This commit is contained in:
Dmitry Yankowski
2020-02-24 23:34:06 -05:00
parent 6b675d5def
commit 2d5b70ab85
4 changed files with 101 additions and 82 deletions

View File

@@ -3,10 +3,13 @@
<legend @click.prevent="collapse"> <legend @click.prevent="collapse">
<span>{{ label }}</span> <span>{{ label }}</span>
<i class="material-icons"> <i class="material-icons">
{{ isCollapsed ? "expand_more" : "expand_less" }} {{ isCollapsed(label) ? "expand_more" : "expand_less" }}
</i> </i>
</legend> </legend>
<div class="collapsible" :class="{ hidden: collapsed }"> <div
class="collapsible"
:class="{ hidden: isCollapsed(label.toLowerCase()) }"
>
<slot /> <slot />
</div> </div>
</fieldset> </fieldset>
@@ -22,13 +25,10 @@ fieldset.no-colored-frames legend {
export default { export default {
computed: { computed: {
frameColorsEnabled() { frameColorsEnabled() {
return this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false return this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false;
}, },
}, sectionString() {
return `${this.$route.path}/${this.label}`;
data() {
return {
isCollapsed: false,
} }
}, },
@@ -44,10 +44,18 @@ export default {
methods: { methods: {
collapse({ target }) { collapse({ target }) {
const parent = target.parentNode.parentNode const parent = target.parentNode.parentNode;
parent.querySelector(".collapsible").classList.toggle("hidden") parent.querySelector(".collapsible").classList.toggle("hidden");
this.isCollapsed = !this.isCollapsed // Save collapsed section to local state
this.$store.commit("setCollapsedSection", this.sectionString);
}, },
}, isCollapsed(label) {
} return (
this.$store.state.theme.collapsedSections.includes(
this.sectionString
) || false
);
}
}
};
</script> </script>

View File

@@ -144,10 +144,10 @@
</pw-section> </pw-section>
<pw-section class="cyan" :label="$t('query')" ref="query"> <pw-section class="cyan" :label="$t('query')" ref="query">
<div class="flex-wrap"> <div class="flex-wrap gqlRunQuery">
<label for="gqlQuery">{{ $t("query") }}</label> <label for="gqlQuery">{{ $t("query") }}</label>
<div> <div>
<button class="icon" @click="runQuery()" v-tooltip.bottom="$t('run_query')"> <button @click="runQuery()" v-tooltip.bottom="$t('run_query')">
<i class="material-icons">play_arrow</i> <i class="material-icons">play_arrow</i>
</button> </button>
<button <button
@@ -308,6 +308,9 @@
max-height: calc(100vh - 186px); max-height: calc(100vh - 186px);
overflow: auto; overflow: auto;
} }
.gqlRunQuery {
margin-bottom: 12px;
}
</style> </style>
<script> <script>
@@ -373,19 +376,19 @@ export default {
}, },
response: { response: {
get() { get() {
return this.$store.state.gql.response; return this.$store.state.gql.response
}, },
set(value) { set(value) {
this.$store.commit("setGQLState", { value, attribute: "response" }); this.$store.commit("setGQLState", { value, attribute: "response" })
} },
}, },
schema: { schema: {
get() { get() {
return this.$store.state.gql.schema; return this.$store.state.gql.schema
}, },
set(value) { set(value) {
this.$store.commit("setGQLState", { value, attribute: "schema" }); this.$store.commit("setGQLState", { value, attribute: "schema" })
} },
}, },
variableString: { variableString: {
get() { get() {
@@ -426,13 +429,13 @@ export default {
return t return t
}, },
copySchema() { copySchema() {
this.$refs.copySchemaCode.innerHTML = this.doneButton; this.$refs.copySchemaCode.innerHTML = this.doneButton
const aux = document.createElement("textarea"); const aux = document.createElement("textarea")
aux.innerText = this.schema; aux.innerText = this.schema
document.body.appendChild(aux); document.body.appendChild(aux)
aux.select(); aux.select()
document.execCommand("copy"); document.execCommand("copy")
document.body.removeChild(aux); document.body.removeChild(aux)
this.$toast.success(this.$t("copied_to_clipboard"), { this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done", icon: "done",
}) })
@@ -452,13 +455,13 @@ export default {
setTimeout(() => (this.$refs.copyQueryButton.innerHTML = this.copyButton), 1000) setTimeout(() => (this.$refs.copyQueryButton.innerHTML = this.copyButton), 1000)
}, },
copyResponse() { copyResponse() {
this.$refs.copyResponseButton.innerHTML = this.doneButton; this.$refs.copyResponseButton.innerHTML = this.doneButton
const aux = document.createElement("textarea"); const aux = document.createElement("textarea")
aux.innerText = this.response; aux.innerText = this.response
document.body.appendChild(aux); document.body.appendChild(aux)
aux.select(); aux.select()
document.execCommand("copy"); document.execCommand("copy")
document.body.removeChild(aux); document.body.removeChild(aux)
this.$toast.success(this.$t("copied_to_clipboard"), { this.$toast.success(this.$t("copied_to_clipboard"), {
icon: "done", icon: "done",
}) })
@@ -492,7 +495,7 @@ export default {
const data = await sendNetworkRequest(reqOptions, this.$store) const data = await sendNetworkRequest(reqOptions, this.$store)
this.response = JSON.stringify(data.data, null, 2); this.response = JSON.stringify(data.data, null, 2)
this.$nuxt.$loading.finish() this.$nuxt.$loading.finish()
const duration = Date.now() - startTime const duration = Date.now() - startTime
@@ -509,10 +512,9 @@ export default {
} }
}, },
async getSchema() { async getSchema() {
const startTime = Date.now(); const startTime = Date.now()
this.schema = this.$t("loading"); this.schema = this.$t("loading")
this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.$store.state.postwoman.settings.SCROLL_INTO_ENABLED && this.scrollInto("schema")
this.scrollInto("schema");
// Start showing the loading bar as soon as possible. // Start showing the loading bar as soon as possible.
// The nuxt axios module will hide it when the request is made. // The nuxt axios module will hide it when the request is made.
@@ -551,15 +553,15 @@ export default {
const data = this.$store.state.postwoman.settings.PROXY_ENABLED ? res.data : res const data = this.$store.state.postwoman.settings.PROXY_ENABLED ? res.data : res
const schema = gql.buildClientSchema(data.data.data); const schema = gql.buildClientSchema(data.data.data)
this.schema = gql.printSchema(schema, { this.schema = gql.printSchema(schema, {
commentDescriptions: true commentDescriptions: true,
}); })
console.log( console.log(
gql.printSchema(schema, { gql.printSchema(schema, {
commentDescriptions: true commentDescriptions: true,
}) })
); )
if (schema.getQueryType()) { if (schema.getQueryType()) {
const fields = schema.getQueryType().getFields() const fields = schema.getQueryType().getFields()
@@ -614,8 +616,8 @@ export default {
icon: "done", icon: "done",
}) })
} catch (error) { } catch (error) {
this.$nuxt.$loading.finish(); this.$nuxt.$loading.finish()
this.schema = `${error}. ${this.$t("check_console_details")}`; this.schema = `${error}. ${this.$t("check_console_details")}`
this.$toast.error(`${error} ${this.$t("f12_details")}`, { this.$toast.error(`${error} ${this.$t("f12_details")}`, {
icon: "error", icon: "error",
}) })
@@ -627,15 +629,15 @@ export default {
this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity this.responseBodyMaxLines = this.responseBodyMaxLines == Infinity ? 16 : Infinity
}, },
downloadResponse() { downloadResponse() {
const dataToWrite = JSON.stringify(this.schema, null, 2); const dataToWrite = JSON.stringify(this.schema, null, 2)
const file = new Blob([dataToWrite], { type: "application/json" }); const file = new Blob([dataToWrite], { type: "application/json" })
const a = document.createElement("a"); const a = document.createElement("a")
const url = URL.createObjectURL(file); const url = URL.createObjectURL(file)
a.href = url; a.href = url
a.download = `${this.url} on ${Date()}.graphql`.replace(/\./g, "[dot]"); a.download = `${this.url} on ${Date()}.graphql`.replace(/\./g, "[dot]")
document.body.appendChild(a); document.body.appendChild(a)
a.click(); a.click()
this.$refs.downloadResponse.innerHTML = this.doneButton; this.$refs.downloadResponse.innerHTML = this.doneButton
this.$toast.success(this.$t("download_started"), { this.$toast.success(this.$t("download_started"), {
icon: "done", icon: "done",
}) })

View File

@@ -7,6 +7,12 @@ export default {
gql[attribute] = value gql[attribute] = value
}, },
setCollapsedSection({ theme }, value) {
theme.collapsedSections.includes(value)
? (theme.collapsedSections = theme.collapsedSections.filter(section => section !== value))
: theme.collapsedSections.push(value)
},
addGQLHeader({ gql }, object) { addGQLHeader({ gql }, object) {
gql.headers.push(object) gql.headers.push(object)
}, },

View File

@@ -1,40 +1,43 @@
export default () => ({ export default () => ({
request: { request: {
method: 'GET', method: "GET",
url: 'https://httpbin.org', url: "https://httpbin.org",
path: '/get', path: "/get",
label: '', label: "",
auth: 'None', auth: "None",
httpUser: '', httpUser: "",
httpPassword: '', httpPassword: "",
passwordFieldType: 'password', passwordFieldType: "password",
bearerToken: '', bearerToken: "",
headers: [], headers: [],
params: [], params: [],
bodyParams: [], bodyParams: [],
rawParams: '', rawParams: "",
rawInput: false, rawInput: false,
requestType: '', requestType: "",
contentType: '', contentType: "",
}, },
gql: { gql: {
url: 'https://rickandmortyapi.com/graphql', url: "https://rickandmortyapi.com/graphql",
headers: [], headers: [],
schema: '', schema: "",
variablesJSONString: '{}', variablesJSONString: "{}",
query: '', query: "",
response: '' response: "",
},
theme: {
collapsedSections: [],
}, },
oauth2: { oauth2: {
tokens: [], tokens: [],
tokenReqs: [], tokenReqs: [],
tokenReqSelect: '', tokenReqSelect: "",
tokenReqName: '', tokenReqName: "",
accessTokenName: '', accessTokenName: "",
oidcDiscoveryUrl: '', oidcDiscoveryUrl: "",
authUrl: '', authUrl: "",
accessTokenUrl: '', accessTokenUrl: "",
clientId: '', clientId: "",
scope: '', scope: "",
}, },
}) })