Many improvements for the `execute` panel.

This commit is contained in:
Fabio Manganiello 2023-05-21 03:04:52 +02:00
parent edf1dbee1d
commit 229b8f2985
Signed by: blacklight
GPG Key ID: D90FBA7F76362774
2 changed files with 142 additions and 49 deletions

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="row plugin execute-container"> <div class="row plugin execute-container">
<Loading v-if="loading" /> <Loading v-if="loading" />
<div class="command-container"> <div class="section command-container">
<div class="title">Execute Action</div> <div class="section-title">Execute Action</div>
<form class="action-form" ref="actionForm" autocomplete="off" @submit.prevent="executeAction"> <form class="action-form" ref="actionForm" autocomplete="off" @submit.prevent="executeAction">
<div class="request-type-container"> <div class="request-type-container">
<input type="radio" id="action-structured-input" <input type="radio" id="action-structured-input"
@ -14,17 +14,21 @@
</div> </div>
<div class="request structured-request" :class="structuredInput ? '' : 'hidden'"> <div class="request structured-request" :class="structuredInput ? '' : 'hidden'">
<div class="autocomplete"> <div class="request-header">
<label> <div class="autocomplete">
<input ref="actionName" type="text" class="action-name" <label>
placeholder="Action Name" :disabled="running" v-model="action.name" <input ref="actionName" type="text" class="action-name"
@change="actionChanged=true" @blur="updateAction"> placeholder="Action Name" :disabled="running" v-model="action.name"
</label> @change="actionChanged=true" @blur="updateAction">
</label>
</div>
<div class="buttons">
<button type="submit" class="run-btn btn-primary"
:disabled="running || !action?.name?.length" title="Run">
<i class="fas fa-play" />
</button>
</div>
</div> </div>
<button type="submit" class="run-btn btn-primary"
:disabled="running || !action?.name?.length" title="Run">
<i class="fas fa-play" />
</button>
<div class="doc-container" v-if="selectedDoc"> <div class="doc-container" v-if="selectedDoc">
<div class="title"> <div class="title">
@ -100,7 +104,14 @@
</div> </div>
<div class="output-container"> <div class="output-container">
<div class="title" v-text="error != null ? 'Error' : 'Output'" v-if="error != null || response != null" /> <div class="header" v-if="error != null || response != null">
<div class="title" v-text="error != null ? 'Error' : 'Output'" />
<div class="buttons">
<button type="button" title="Copy to clipboard" @click="copyToClipboard">
<i class="fas fa-clipboard" />
</button>
</div>
</div>
<div class="response" v-html="response" v-if="response != null" /> <div class="response" v-html="response" v-if="response != null" />
<div class="error" v-html="error" v-else-if="error != null" /> <div class="error" v-html="error" v-else-if="error != null" />
</div> </div>
@ -117,7 +128,14 @@
</div> </div>
<div class="output-container" v-if="response != null || error != null"> <div class="output-container" v-if="response != null || error != null">
<div class="title" v-text="error != null ? 'Error' : 'Output'" /> <div class="header" v-if="error != null || response != null">
<div class="title" v-text="error != null ? 'Error' : 'Output'" />
<div class="buttons">
<button type="button" title="Copy to clipboard" @click="copyToClipboard">
<i class="fas fa-clipboard" />
</button>
</div>
</div>
<div class="error" v-html="error" v-if="error != null" /> <div class="error" v-html="error" v-if="error != null" />
<div class="response" v-html="response" v-else-if="response != null" /> <div class="response" v-html="response" v-else-if="response != null" />
</div> </div>
@ -125,8 +143,8 @@
</form> </form>
</div> </div>
<div class="procedures-container"> <div class="section procedures-container">
<div class="title">Execute Procedure</div> <div class="section-title">Execute Procedure</div>
<div class="procedure" :class="selectedProcedure.name === name ? 'selected' : ''" <div class="procedure" :class="selectedProcedure.name === name ? 'selected' : ''"
v-for="name in Object.keys(procedures).sort()" :key="name" @click="updateProcedure(name, $event)"> v-for="name in Object.keys(procedures).sort()" :key="name" @click="updateProcedure(name, $event)">
<form ref="procedureForm" autocomplete="off" @submit.prevent="executeProcedure"> <form ref="procedureForm" autocomplete="off" @submit.prevent="executeProcedure">
@ -323,8 +341,6 @@ export default {
}, },
resetAttrDoc() { resetAttrDoc() {
this.response = undefined
this.error = undefined
this.selectedAttr = undefined this.selectedAttr = undefined
this.selectedAttrDoc = undefined this.selectedAttrDoc = undefined
}, },
@ -356,6 +372,14 @@ export default {
this.running = false this.running = false
}, },
async copyToClipboard() {
const output = (
this.error != null ? this.error : this.response
).replace(/^\s*<pre>/g, '').replace(/<\/pre>\s*/g, '')
await navigator.clipboard.writeText(output)
},
executeAction() { executeAction() {
if (!this.action.name && !this.rawRequest || this.running) if (!this.action.name && !this.rawRequest || this.running)
return return
@ -451,6 +475,19 @@ export default {
$params-desktop-width: 30em; $params-desktop-width: 30em;
$params-tablet-width: 20em; $params-tablet-width: 20em;
$request-headers-btn-width: 7.5em;
@mixin header {
background: $default-bg-5;
display: flex;
align-items: center;
padding: 0.5em;
border: $title-border;
border-radius: 1em;
box-shadow: $title-shadow;
font-weight: normal;
font-size: 1em;
}
.execute-container { .execute-container {
width: 100%; width: 100%;
@ -459,6 +496,22 @@ $params-tablet-width: 20em;
font-weight: 400; font-weight: 400;
border-bottom: $default-border-2; border-bottom: $default-border-2;
border-radius: 0 0 1em 1em; border-radius: 0 0 1em 1em;
display: flex;
flex-direction: column;
align-items: center;
.section {
width: 100%;
max-width: 1000px;
display: flex;
flex-direction: column;
box-shadow: $section-shadow;
@include from($desktop) {
margin: 1em;
border-radius: 1em 1em 0 0;
}
}
form { form {
padding: 0; padding: 0;
@ -472,13 +525,34 @@ $params-tablet-width: 20em;
padding: 1em .5em; padding: 1em .5em;
} }
.title { .request-header {
width: 100%;
display: flex;
align-items: center;
.autocomplete {
width: calc(100% - $request-headers-btn-width);
flex-grow: 1;
}
.buttons {
width: $request-headers-btn-width;
display: inline-flex;
justify-content: flex-end;
margin-right: 0.5em;
}
}
.section-title {
background: $header-bg; background: $header-bg;
padding: .5em; padding: .75em .5em;
border: $title-border;
box-shadow: $title-shadow; box-shadow: $title-shadow;
font-size: 1.1em; font-size: 1.1em;
margin-bottom: 0 !important; margin-bottom: 0 !important;
@include from($desktop) {
border-radius: 0.5em 0.5em 0 0;
}
} }
.request-type-container { .request-type-container {
@ -492,26 +566,19 @@ $params-tablet-width: 20em;
} }
.request { .request {
display: flex;
flex-direction: column;
margin: 0 .5em; margin: 0 .5em;
form { form {
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
.autocomplete {
width: 80%;
max-width: 60em;
}
.action-name { .action-name {
box-shadow: $action-name-shadow; box-shadow: $action-name-shadow;
width: 100%; width: 100%;
} }
[type=submit] {
margin-left: 2em;
}
.options { .options {
display: flex; display: flex;
margin-top: .5em; margin-top: .5em;
@ -604,6 +671,22 @@ $params-tablet-width: 20em;
margin-top: .5em; margin-top: .5em;
} }
.doc-container,
.attr-doc-container {
.title {
@include header;
}
}
.attr-doc-container {
.title {
.attr-name {
font-weight: bold;
margin-left: 0.25em;
}
}
}
.output-container { .output-container {
flex-grow: 1; flex-grow: 1;
} }
@ -648,12 +731,22 @@ $params-tablet-width: 20em;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.title { .header {
font-weight: normal; @include header;
font-size: 1em;
padding: .5em; .title {
background: $section-title-bg; flex-grow: 1;
border-radius: .5em; }
button {
background: none;
border: none;
box-shadow: none;
&:hover {
color: $default-hover-fg;
}
}
.attr-name { .attr-name {
display: inline-block; display: inline-block;
@ -666,23 +759,25 @@ $params-tablet-width: 20em;
.doc { .doc {
height: 100%; height: 100%;
padding: .5em .5em 0 .5em; padding: .5em .5em 0 .5em;
border-radius: 0 0 1em 1em; border-radius: 1em;
overflow: auto; overflow: auto;
margin-top: 0.1em;
} }
.response { .response {
background: $response-bg; background: $response-bg;
border: $response-border; box-shadow: $response-shadow;
} }
.error { .error {
background: $error-bg; background: $error-bg;
border: $error-border; padding: 1em;
box-shadow: $error-shadow;
} }
.doc { .doc {
background: $doc-bg; background: $doc-bg;
border: $doc-border; box-shadow: $doc-shadow;
} }
} }
@ -791,9 +886,6 @@ $params-tablet-width: 20em;
box-shadow: none; box-shadow: none;
} }
} }
&:not(disabled) {
}
} }
} }
</style> </style>

View File

@ -1,13 +1,14 @@
$section-shadow: 0 3px 3px 0 rgba(187,187,187,0.75), 0 3px 3px 0 rgba(187,187,187,0.75);
$title-bg: #eee; $title-bg: #eee;
$title-border: 1px solid #ddd; $title-border: 1px solid #ddd;
$title-shadow: 0 3px 3px 0 rgba(187,187,187,0.75); $title-shadow: 0 3px 3px 0 rgba(187,187,187,0.75);
$action-name-shadow: 1px 1px 1px 1px #ddd; $action-name-shadow: 1px 1px 1px 1px #ddd;
$extra-params-btn-bg: #eee; $extra-params-btn-bg: #eee;
$response-bg: #edfff2; $response-bg: linear-gradient(#dbffe5, #d5ecdc);
$response-border: 1px dashed #98ff98; $error-bg: linear-gradient(#ffd9d9, #e6cbcb);
$error-bg: #ffbcbc; $error-shadow: 0 1px 3px 1px #d7c0c0, inset 0 1px 1px 0 #d7c9c9;
$error-border: 1px dashed #ff5353; $doc-bg: linear-gradient(#effbe3, #e0ecdb);
$doc-bg: $background-color; $doc-shadow: 0 1px 3px 1px #d7d3c0, inset 0 1px 1px 0 #d7d3c9;
$doc-border: 1px dashed $border-color-2; $response-shadow: $doc-shadow;
$procedure-submit-btn-bg: #ebffeb; $procedure-submit-btn-bg: #ebffeb;
$section-title-bg: rgba(0, 0, 0, .04); $section-title-bg: rgba(0, 0, 0, .04);