Implemented XML Formatter and simplified structure of XML tools (#229)

Co-authored-by: Adam Bem <adam.bem@zoho.eu>
Reviewed-on: #229
Reviewed-by: Mikolaj Widla <widlam@noreply.example.com>
This commit is contained in:
2023-06-21 14:32:00 +02:00
parent 3c79bddde3
commit f16639b45e
28 changed files with 573 additions and 329 deletions

View File

@@ -1,47 +1,49 @@
<script setup lang="ts">
import xmlInputFieldToolbarComponent from '@/components/xml/XmlInputFieldToolbarComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import XMLButtonFormatterComponent from '@components/formatter/XMLButtonFormatterComponent.vue'
import { ref } from 'vue';
const xml = ref('')
const query = ref('')
const data = ref('')
const props = defineProps(
{
prettyName: {type: String, required: true},
xmlData: {type: String},
stylizedName: {type: String, required: true},
data: {type: String},
}
)
const emit = defineEmits(['update:xml', 'update:transform'])
const emit = defineEmits(['update'])
function sendXml() {
emit('update:xml', xml.value)
function sendValue() {
emit('update', data.value)
}
function sendTransform() {
emit('update:transform', query.value)
function updateData(newData: string) {
data.value = newData;
sendValue();
}
function setToDefaultXML(data: string) {
xml.value = data;
sendXml();
function clear() {
updateData('');
}
function setToDefaultQuery(data: string) {
query.value = data;
sendTransform();
function canBeFormatted() {
return props.stylizedName.toLowerCase() == 'xml' ||
props.stylizedName.toLowerCase() == 'xsd' ||
props.stylizedName.toLowerCase() == 'xslt';
}
</script>
<template>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center gap-4">
<div class="flex flex-col w-full h-1/2">
<xmlInputFieldToolbarComponent prettyName="XML" @update:defaultData="(data) => setToDefaultXML(data)"></xmlInputFieldToolbarComponent>
<textarea id="xmlField" v-model="xml" @input="sendXml()" class="w-full h-full resize-none dark:text-slate-100 dark:bg-gray-600 border border-slate-400 p-2 rounded-md"></textarea>
</div>
<div class="flex flex-col w-full h-1/2">
<xmlInputFieldToolbarComponent :prettyName="$props.prettyName" @update:defaultData="(data) => setToDefaultQuery(data)"></xmlInputFieldToolbarComponent>
<textarea id="transformField" v-model="query" @input="sendTransform()" class="w-full h-full resize-none dark:text-slate-100 dark:bg-gray-600 border border-slate-400 p-2 rounded-md"></textarea>
<div class="flex flex-col w-full h-1/2">
<div class="flex place-content-between w-full pr-2 items-center m-2">
<span class="dark:text-white">{{ stylizedName }}</span>
<div class="flex space-x-2">
<InsertTemplateComponent :stylized-name="props.stylizedName" @update:default-data="(data: string) => updateData(data)"></InsertTemplateComponent>
<XMLButtonFormatterComponent v-if="canBeFormatted()" :xml="data" @update:result="(data:any) => updateData(data.result)"></XMLButtonFormatterComponent>
<button class="tool-button" @click="clear">Clear</button>
</div>
</div>
<textarea id="xmlField" v-model="data" @input="sendValue()" class="text-field"></textarea>
</div>
</template>

View File

@@ -1,10 +1,6 @@
<script setup lang="ts">
import sampleXML from "@/assets/sampleXml.xml?raw"
import sampleXSLT from "@/assets/sampleXslt.xml?raw"
import sampleXSD from "@/assets/sampleXsd.xml?raw"
import sampleXQuery from "@/assets/sampleXQuery.xquery?raw"
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue'
const props = defineProps(
{
@@ -14,37 +10,13 @@ const props = defineProps(
const emit = defineEmits(['update:defaultData'])
function setDefault() {
function setDefault(data: string) {
const emitName = "update:defaultData";
switch (props.prettyName.toLowerCase()) {
case "xpath":
emit(emitName, "string(/l:library/l:libraryName)")
break;
case "xsd":
emit(emitName, sampleXSD)
break;
case "xslt":
emit(emitName, sampleXSLT)
break;
case "xquery":
emit(emitName, sampleXQuery)
break;
default:
emit(emitName, sampleXML)
break;
}
emit(emitName, data)
}
</script>
<template>
<div class="flex place-content-between w-full pr-2 items-center m-2">
<span class="dark:text-white">{{ prettyName }}</span>
<div class="flex space-x-2">
<button class="tool-button" @click="setDefault()">Insert default {{ prettyName }}</button>
</div>
</div>
</template>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import xmlOutputFieldToolbarComponent from '@/components/xml/XmlOutputFieldToolbarComponent.vue';
import { ref } from 'vue';
import { onMounted, ref } from 'vue';
const props = defineProps(
@@ -13,18 +12,132 @@ const props = defineProps(
const result = ref('');
function parseResult(data: any) {
var enginesForCurrentTool = ref(["saxon", "xalan", "libxml"]);
const allVersions = ["1.0", "2.0", "3.0", "3.1"];
var versionsForCurrentEngine = ref([""]);
const engine = ref('');
const version = ref('');
onMounted(() => {
changeAvailableEngines();
changeAvailableVersions();
})
function changeAvailableEngines() {
if (props.tool == "xsd") {
enginesForCurrentTool.value = ["xalan", "libxml"]
}
else if (props.tool == "xquery") {
enginesForCurrentTool.value = ["saxon"]
}
selectDefaultEngine();
}
function changeAvailableVersions() {
if (props.tool == "xquery")
versionsForCurrentEngine.value = ["3.1"];
else if (props.tool == "xslt")
changeAvailableVersionsOfXSLT();
else if (props.tool == "xsd")
versionsForCurrentEngine.value = ["N/A"];
else if (props.tool == "xpath")
changeAvailableVersionsOfXPath();
selectDefaultVersion();
}
function changeAvailableVersionsOfXSLT() {
if(engine.value == "saxon")
versionsForCurrentEngine.value = ["3.0"];
else
versionsForCurrentEngine.value = ["1.0"];
}
function changeAvailableVersionsOfXPath() {
if(engine.value == "xalan" || engine.value == "libxml")
versionsForCurrentEngine.value = ["1.0"];
else if (engine.value == "saxon")
versionsForCurrentEngine.value = allVersions;
}
function selectDefaultEngine() {
engine.value = enginesForCurrentTool.value[0];
}
function selectDefaultVersion() {
const lastVersion = versionsForCurrentEngine.value.length - 1
version.value = versionsForCurrentEngine.value[lastVersion];
}
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
updateOutputField(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request
}
function prepareURL(): string {
const engineEndpoint = engine.value == "libxml" ? "libxml" : "java";
return document.location.protocol + "//" + document.location.hostname + "/" + engineEndpoint + "/" + props.tool;
}
function prepareRequestBody():string {
var requestBody = JSON.stringify({
"data": props.xml,
"process": props.query,
"processor": engine.value,
"version": version.value
});
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
return responseBody;
}
function updateOutputField(data: any) {
result.value = data.result;
}
function clear() {
result.value = "";
}
</script>
<template>
<div class="flex flex-col w-full lg:w-1/2 h-full items-center">
<xmlOutputFieldToolbarComponent :xml="$props.xml" :query="$props.query" :tool="$props.tool" @update:result="(data) => parseResult(data)"></xmlOutputFieldToolbarComponent>
<div class="w-full h-full p-2 overflow-scroll border border-slate-400 rounded-md text-left bg-white dark:text-slate-100 dark:bg-gray-600">
<pre class="break-words"><code>{{ result }}</code></pre>
<div class="flex flex-col w-full lg:w-1/2 h-1/2 lg:h-full items-center">
<div class="flex place-content-between w-full items-center m-2">
<span class="dark:text-white">Result:</span>
<div class="flex space-x-2">
<select v-model="engine" name="engine" @change="changeAvailableVersions()" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="engine in enginesForCurrentTool" :value="engine">{{ engine }}</option>
</select>
<select v-model="version" name="version" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="version in versionsForCurrentEngine" :value="version">{{ version }}</option>
</select>
<button class="tool-button" @click="clear">Clear</button>
<button class="tool-button" @click="process">Process</button>
</div>
</div>
<div class="text-field overflow-scroll h-full w-full">
<pre class="whitespace-pre-wrap"><code>{{ result }}</code></pre>
</div>
</div>
</template>
</template>

View File

@@ -1,112 +0,0 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
var engines = ["saxon", "xalan", "libxml"];
var versions = ["1.0", "2.0", "3.0", "3.1"];
const props = defineProps(
{
tool: {type: String, required: true},
xml: {type: String},
query: {type: String},
}
)
const emit = defineEmits(['update:result'])
const engine = ref('');
const version = ref('');
const isSaxonHidden = ref(false);
const isXalanHidden = ref(false);
const isLibXMLHidden = ref(false);
onMounted(() => {
selectAvailableEngines();
selectAvailableVersions();
selectDefaults();
})
function selectAvailableEngines() {
if (props.tool == "xsd") {
engines = ["xalan", "libxml"]
}
else if (props.tool == "xquery") {
engines = ["saxon"]
}
}
function selectAvailableVersions() {
if (props.tool == "xquery")
versions = ["3.1"];
else if (props.tool == "xsd")
versions = ["N/A"];
}
function selectDefaults() {
version.value = versions[versions.length - 1];
engine.value = engines[0];
}
function process() {
var request:Request = prepareRequest();
fetchRequest(request).then((data) => {
sendProcessedData(data);
})
}
function prepareRequest():Request {
var request = new Request(prepareURL(), {
body: prepareRequestBody(),
method: "POST"
});
return request
}
function prepareURL(): string {
const engineEndpoint = engine.value == "libxml" ? "libxml" : "java";
return document.location.protocol + "//" + document.location.hostname + "/" + engineEndpoint + "/" + props.tool;
}
function prepareRequestBody():string {
var requestBody = JSON.stringify({
"data": props.xml,
"process": props.query,
"processor": engine.value,
"version": version.value
});
return requestBody;
}
async function fetchRequest(request: Request):Promise<JSON> {
var responseBody = await fetch(request)
.then(response => response.json())
.then((body) => body);
return responseBody;
}
function sendProcessedData(data: JSON) {
emit("update:result", data);
}
</script>
<template>
<div class="flex place-content-between w-full items-center m-2">
<span class="dark:text-white">Result:</span>
<div class="flex space-x-2">
<select v-model="engine" name="engine" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="engine in engines" :value="engine">{{ engine }}</option>
</select>
<select v-model="version" name="version" class="px-3 rounded-full border border-slate-400 bg-white dark:text-slate-100 dark:bg-gray-600">
<option v-for="version in versions" :value="version">{{ version }}</option>
</select>
<button class="tool-button">Clear</button>
<button class="tool-button" @click="process">Process</button>
</div>
</div>
</template>