Added green shadow wan success and other things (#268)

Reviewed-on: #268
Reviewed-by: Mikolaj Widla <widlam@noreply.example.com>
Co-authored-by: Adam Bem <adam.bem@zoho.eu>
Co-committed-by: Adam Bem <adam.bem@zoho.eu>
This commit is contained in:
2023-11-16 13:24:48 +01:00
committed by Adam Bem
parent 00786bf157
commit c45d1ee83d
17 changed files with 231 additions and 240 deletions

View File

@@ -36,7 +36,7 @@ public class JsonController implements RestController {
try {
Object requestJson = this.gson.fromJson(request.body(), Object.class);
responseJson.addProperty("data", this.prettyGson.toJson(requestJson));
responseJson.addProperty("result", this.prettyGson.toJson(requestJson));
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
@@ -46,7 +46,7 @@ public class JsonController implements RestController {
response.status(400);
responseJson.addProperty("data", cause == null ? e.getMessage() : cause.getMessage());
responseJson.addProperty("result", cause == null ? e.getMessage() : cause.getMessage());
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
@@ -65,17 +65,17 @@ public class JsonController implements RestController {
response.status(200);
responseJson.addProperty("data", this.gson.toJson(requestJson));
responseJson.addProperty("result", this.gson.toJson(requestJson));
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
response.body(this.gson.toJson(responseJson));
} catch (Exception e) {
this.logger.error("Error on minimizeing Json " + e);
this.logger.error("Error on minimizing Json " + e);
Throwable cause = e.getCause();
response.status(400);
responseJson.addProperty("data", cause == null ? e.getMessage() : cause.getMessage());
responseJson.addProperty("result", cause == null ? e.getMessage() : cause.getMessage());
responseJson.addProperty("time", System.currentTimeMillis() - startProcess);
response.body(this.prettyGson.toJson(responseJson));

View File

@@ -13,6 +13,7 @@
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/theme-one-dark": "^6.1.2",
"codemirror": "^6.0.1",
"thememirror": "^2.0.1",
"vue": "^3.3.4",
"vue-codemirror": "^6.1.1",
"vue-router": "^4.2.2"
@@ -4305,6 +4306,16 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"node_modules/thememirror": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/thememirror/-/thememirror-2.0.1.tgz",
"integrity": "sha512-d5i6FVvWWPkwrm4cHLI3t9AT1OrkAt7Ig8dtdYSofgF7C/eiyNuq6zQzSTusWTde3jpW9WLvA9J/fzNKMUsd0w==",
"peerDependencies": {
"@codemirror/language": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0"
}
},
"node_modules/thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
@@ -7756,6 +7767,12 @@
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
"thememirror": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/thememirror/-/thememirror-2.0.1.tgz",
"integrity": "sha512-d5i6FVvWWPkwrm4cHLI3t9AT1OrkAt7Ig8dtdYSofgF7C/eiyNuq6zQzSTusWTde3jpW9WLvA9J/fzNKMUsd0w==",
"requires": {}
},
"thenify": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",

View File

@@ -17,6 +17,7 @@
"@codemirror/lang-xml": "^6.0.2",
"@codemirror/theme-one-dark": "^6.1.2",
"codemirror": "^6.0.1",
"thememirror": "^2.0.1",
"vue": "^3.3.4",
"vue-codemirror": "^6.1.1",
"vue-router": "^4.2.2"

View File

@@ -6,9 +6,9 @@ import SidebarComponent from '@components/sidebar/SidebarComponent.vue';
</script>
<template>
<div id="layout" class="font-sans flex h-screen bg-gradient-to-r from-white to-sky-200 dark:from-slate-800 dark:to-indigo-950">
<div id="layout" class="font-sans flex h-screen bg-gradient-to-br from-sky-200 to-indigo-200 dark:from-sky-950 dark:to-indigo-950">
<SidebarComponent />
<div class="relative p-4 w-full m-4 bg-blue-50 dark:bg-gray-700 rounded-2xl overflow-hidden shadow-lg">
<div class="relative p-4 w-full m-4 ml-0 bg-blue-50 dark:bg-gray-700 rounded-2xl overflow-hidden shadow-lg">
<RouterView></RouterView>
</div>
</div>

View File

@@ -2,60 +2,72 @@
import { computed, ref } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { oneDark } from '@codemirror/theme-one-dark'
import { espresso } from 'thememirror';
import {xml} from '@codemirror/lang-xml'
import {json} from '@codemirror/lang-json'
import {html} from '@codemirror/lang-html'
function isDarkModeSet(){
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
}
const props= defineProps({
code : {
type: String,
required: true
const props= defineProps({
code : {
type: String,
required: true
},
config: {
type: Object,
required: true
},
config: {
type: Object,
required: true
},
})
})
const emit = defineEmits(
[
'update:updatedCode'
]
)
const emit = defineEmits(
[
'update:updatedCode'
]
)
function dataUpdated(newData:String, viewUpdate : any){
emit('update:updatedCode',newData)
function dataUpdated(newData:String, viewUpdate : any){
emit('update:updatedCode',newData)
}
function selectTheme() {
if (isDarkModeSet()) {
return oneDark;
}
else {
return espresso;
}
}
const extensions = computed( ()=> {
return [
oneDark,
parseLanguage(props.config.language),
]
const extensions = computed( ()=> {
return [
selectTheme(),
parseLanguage(props.config.language),
]
} )
} )
function parseLanguage(name: String){
switch(name.toUpperCase()){
case "JSON": {
return json();
}
case "HTML": {
return html();
}
default: {
return xml();
}
function parseLanguage(name: String){
switch(name.toUpperCase()){
case "JSON": {
return json();
}
case "HTML": {
return html();
}
default: {
return xml();
}
}
}
</script>
<template>
<div class="editor w-full h-full bg-[#282C34] rounded-2xl overflow-x-auto">
<div class="editor w-full h-full rounded-2xl overflow-x-auto">
<codemirror
style="height: 100%; width: 100%; padding:1rem ; border-radius: 1rem; font-size: large;"

View File

@@ -0,0 +1,114 @@
<script setup lang="ts">
import XMLButtonFormatterComponent from '@/components/formatter/XMLButtonFormatterComponent.vue';
import JsonButtonFormatterComponent from '@/components/formatter/JsonButtonFormatterComponent.vue';
import HtmlButtonFormatterComponent from '@/components/formatter/HtmlButtonFormatterComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import CodeEditorComponent from '@/components/CodeEditorComponent.vue';
import { ref } from 'vue';
const data = ref('');
const inputFile = ref()
const errorOccurred = ref(false);
const successOccurred = ref(false);
const props = defineProps({
formatterLanguage: {
type: String,
required: true
}
})
function setTextFieldValue(newData: string) {
successOccurred.value = false;
errorOccurred.value = false;
data.value = newData;
}
function format(formatted: any) {
data.value = formatted.result;
}
function setErrorOccurred(occurred: boolean) {
errorOccurred.value = occurred;
successOccurred.value = !(occurred);
}
function setExample(data: string) {
inputFile.value.value = ''
setTextFieldValue(data)
}
function clear() {
data.value = '';
successOccurred.value = false;
errorOccurred.value = false;
inputFile.value.value = ''
}
function readFile(file : any) {
const reader = new FileReader()
reader.onloadend = () => {
var result = reader.result?.toString()
if (typeof result == "string")
setTextFieldValue(result);
}
reader.readAsText(file.target.files[0])
}
function highlightTextField() {
if (successOccurred.value)
return "text-field-success";
if (errorOccurred.value)
return "text-field-error";
return "";
}
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class= "flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100"> {{ formatterLanguage }} Formatter</span>
<!-- XML Formatter Toolbar -->
<div v-if="formatterLanguage.toLowerCase() == 'xml'" class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".xml,.xql,.xquery,.xslt,text/xml,text/plain" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="XML" @update:defaultData="(data: string) => setExample(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<XMLButtonFormatterComponent @update:error="setErrorOccurred" is-minimizer :xml="data" @update:result="format"></XMLButtonFormatterComponent>
<XMLButtonFormatterComponent @update:error="setErrorOccurred" :xml="data" @update:result="format"></XMLButtonFormatterComponent>
</div>
<!-- JSON Formatter Toolbar -->
<div v-if="formatterLanguage.toLowerCase() == 'json'" class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".json,text/xml,text/plain,text/json,application/json" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="JSON" @update:defaultData="(data: string) => setExample(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<JsonButtonFormatterComponent isMinimizer :json="data" @update:result="format" @update:error="setErrorOccurred"></JsonButtonFormatterComponent>
<JsonButtonFormatterComponent :json="data" @update:result="format" @update:error="setErrorOccurred"></JsonButtonFormatterComponent>
</div>
<!-- HTML Formatter Toolbar -->
<div v-if="formatterLanguage.toLowerCase() == 'html'" class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".xml,.html,.htm,text/xml,text/plain,text/html" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="HTML" @update:defaultData="setExample"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<HtmlButtonFormatterComponent @update:result="format" @update:error="setErrorOccurred" :code="data" format-type="Minimize" />
<HtmlButtonFormatterComponent @update:result="format" @update:error="setErrorOccurred" :code="data" format-type="Prettify" />
<HtmlButtonFormatterComponent @update:result="format" @update:error="setErrorOccurred" :code="data" format-type="HTML -> XML" />
</div>
</div>
<CodeEditorComponent :class="highlightTextField()" @update:updated-code="setTextFieldValue" :code="data" :config="{disabled:false,language:formatterLanguage.toLowerCase()}" />
</div>
</template>

View File

@@ -47,16 +47,16 @@ function createBody(){
const fetchLink = document.location.protocol + "//" + document.location.hostname + "/libxml/html/" + chooseType(props.formatType);
function processResponse(formattedCode : any){
var result = formattedCode.result;
emit("update:error", formattedCode.status == "ERR")
return result
}
function process(){
fetch(fetchLink, {body:createBody(), method: "POST"})
.then( response => response.json() )
.then( formattedCode => emit('update:result', processResponse(formattedCode) ) )
.then( formattedCode => processResponse(formattedCode) )
}
function processResponse(formattedCode : any){
emit('update:result', formattedCode )
emit("update:error", formattedCode.status == "ERR")
}
</script>

View File

@@ -41,7 +41,6 @@ async function fetchRequest(request: Request):Promise<JSON> {
return response.json()
})
.then((body) => body);
console.log(responseBody);
return responseBody;
}

View File

@@ -3,7 +3,10 @@
import ImgMan from './ImgMan.vue';
import ElementDescription from './ElementDescription.vue';
import urlSectionImg from '@assets/man/rest-mock/URL_section.png';
import statusSectionImg from '@assets/man/rest-mock/Status_section.png';
import bodySectionImg from '@assets/man/rest-mock/Body_section.png';
import headerSectionImg from '@assets/man/rest-mock/Header_section.png';
</script>
<template>
@@ -47,21 +50,21 @@ priority urgent
</pre></div>
<p>In this example we will focus on the left-hand side panel first as it contains most of the settings. On the top you see autogenerated URL link to your REST Mock service and the "Save" button that saves every setting on this page.</p>
<ImgMan imgPath="../../src/assets/man/rest-mock/URL_section.png" label="Screenshot of Rest Mock URL bar and Save button"></ImgMan>
<ImgMan :imgPath="urlSectionImg" label="Screenshot of Rest Mock URL bar and Save button"></ImgMan>
<p>Next, down from REST Mock URL are two text fields. One for content type of a response and second for the HTTP status of a response. </p>
<ImgMan imgPath="../../src/assets/man/rest-mock/Status_section.png" label='Screenshot of "Response Content Type" and "Response HTTP Status"'></ImgMan>
<ImgMan :imgPath="statusSectionImg" label='Screenshot of "Response Content Type" and "Response HTTP Status"'></ImgMan>
<p>These two fields are first things that we will set in this example. Out content type is JSON, so we will put "application/json" in "Response Content Type" field. The "Response HTTP Status" field we'll leave
unchanged for now.</p><br/>
<p>Next element of this tool is big "Response Body" text field. Here you can put data that you want your REST Mock to respond with. In this example we will put JSON from few lines above.</p>
<ImgMan imgPath="../../src/assets/man/rest-mock/Body_section.png" label='Screenshot of Response Body field filled with example JSON'></ImgMan>
<ImgMan :imgPath="bodySectionImg" label='Screenshot of Response Body field filled with example JSON'></ImgMan>
<p>Last thing that we have to set are headers. Those we can set in Headers section.</p>
<ImgMan imgPath="../../src/assets/man/rest-mock/Header_section.png" label='Screenshot of Headers Section with added custom headers.'></ImgMan>
<ImgMan :imgPath="headerSectionImg" label='Screenshot of Headers Section with added custom headers.'></ImgMan>
</div>
</div>

View File

@@ -18,10 +18,10 @@ const props = defineProps(
<template>
<div class="w-full mb-4 p-2 rounded-xl shadow-lg bg-gradient-to-r from-blue-400 to-blue-300 dark:from-sky-700 dark:to-sky-900">
<button @click="switchHiddenElement()" type="button" :class="[isActive ? 'rounded-lg' : 'rounded-lg']" class="w-full p-2 text-lg font-normal text-gray-900 transition duration-75 hover:bg-blue-100 dark:text-gray-100 dark:hover:bg-slate-600">
<button @click="switchHiddenElement()" type="button" :class="[isActive ? 'rounded-lg' : 'rounded-lg']" class="w-full p-1 text-lg font-normal text-gray-900 transition duration-75 hover:bg-blue-100 dark:text-gray-100 dark:hover:bg-slate-600">
<span class="flex-1 whitespace-nowrap">{{props.categoryName}}</span>
</button>
<div class="flex flex-col w-full py-2 bg-indigo-50 dark:bg-slate-800 rounded-xl font-light overflow-hidden" :class="[isActive ? 'active' : 'hidden']">
<div class="flex flex-col w-full mt-2 py-2 bg-indigo-50 dark:bg-slate-800 rounded-xl font-light overflow-hidden" :class="[isActive ? 'active' : 'hidden']">
<slot></slot>
</div>
</div>

View File

@@ -24,6 +24,7 @@ const engine = ref('');
const version = ref('');
const errorOccurred = ref(false);
const successOccurred = ref(false);
onMounted(() => {
@@ -119,12 +120,14 @@ async function fetchRequest(request: Request):Promise<JSON> {
function updateOutputField(data: any) {
result.value = data.result
errorOccurred.value = data.status == "ERR"
errorOccurred.value = data.status != "OK"
successOccurred.value = data.status == "OK"
}
function clear() {
result.value = ""
errorOccurred.value = false
successOccurred.value = false
}
function emitVersionChange() {
@@ -135,6 +138,16 @@ function isVersionSelectionAvailable() {
return !(props.tool == "xsd");
}
function highlightField() {
if (errorOccurred.value) {
return "text-field-error";
}
if (successOccurred.value) {
return "text-field-success";
}
return "";
}
</script>
<template>
@@ -152,7 +165,7 @@ function isVersionSelectionAvailable() {
<button class="tool-button" @click="process">Process</button>
</div>
</div>
<div class="overflow-auto h-full w-full rounded-2xl" :class="{'text-field-error' : errorOccurred}">
<div class="overflow-auto h-full w-full rounded-2xl" :class="highlightField()">
<CodeEditor :code="result" :config="{disabled:true,language:tool}"></CodeEditor>
</div>

View File

@@ -13,7 +13,7 @@ function toggleTooltips() {
</script>
<template>
<div class="flex p-2 flex-col rounded-xl shadow-lg bg-gradient-to-r from-zinc-400 to-slate-400 dark:from-slate-600 dark:to-slate-700">
<div class="flex p-2 flex-col rounded-xl shadow-lg bg-gradient-to-r from-gray-300 to-slate-300 dark:from-slate-600 dark:to-slate-700">
<button :class="{ 'mb-2' : !isCategoryHidden }" class="dark:text-slate-100 hover:font-bold" @click="toggleTooltips()">{{ props.name }}</button>
<div id="content" :class="{'hidden' : isCategoryHidden}" class="flex flex-col gap-4 w-full h-fit p-2 rounded-xl dark:text-white bg-indigo-50 dark:bg-slate-800" >
<slot></slot>

View File

@@ -62,7 +62,7 @@ function toggleTooltips() {
<button :class="{'mr-2' : !areTooltipsHidden }" class="text-xl w-6 dark:text-slate-100" @click="toggleTooltips()">
T<br/>o<br/>o<br/>l<br/>t<br/>i<br/>p<br/>s
</button>
<div id="content" :class="{'hidden' : areTooltipsHidden}" class="w-full flex flex-col gap-4 p-2 overflow-scroll rounded-xl dark:text-white bg-indigo-50 dark:bg-slate-800" >
<div id="content" :class="{'hidden' : areTooltipsHidden}" class="w-full flex flex-col gap-4 p-2 overflow-auto rounded-xl dark:text-white bg-indigo-50 dark:bg-slate-800" >
<TooltipDiffsComponent :tool-name="toolType" :tool-version="props.version"></TooltipDiffsComponent>
<div class="w-full h-2"> </div>
<tooltipCategoryComponent v-for="category in selectTooltip()" :key="category.name" :name="category.name">

View File

@@ -17,7 +17,7 @@
}
.tool-button {
@apply hover:brightness-110 py-2 px-4 h-fit min-w-fit rounded-full bg-gradient-to-r from-blue-400 to-sky-300 dark:text-white dark:from-sky-600 dark:to-sky-800 hover:bg-blue-400
@apply hover:brightness-110 py-2 px-3 h-fit min-w-fit rounded-full bg-gradient-to-r from-blue-400 to-sky-300 dark:text-white dark:from-sky-600 dark:to-sky-800 hover:bg-blue-400
}
.text-field {
@@ -25,9 +25,13 @@
}
.file-selector {
@apply block file:border-none file:font-sans file:text-base file:hover:brightness-110 file:py-2 file:px-4 file:h-full file:w-fit file:rounded-full file:bg-gradient-to-r file:from-blue-400 file:to-sky-300 file:dark:text-white file:dark:from-sky-600 file:dark:to-sky-800 file:hover:bg-blue-400 w-fit rounded-full text-sm text-gray-900 border border-gray-300 cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
@apply block file:border-none file:font-sans file:text-base file:hover:brightness-110 file:py-2 file:px-3 file:h-full file:w-fit file:rounded-full file:bg-gradient-to-r file:from-blue-400 file:to-sky-300 file:dark:text-white file:dark:from-sky-600 file:dark:to-sky-800 file:hover:bg-blue-400 w-fit rounded-full text-sm text-gray-900 border border-gray-300 cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
}
.text-field-error {
@apply shadow-[0px_0px_10px_0px_rgba(255,0,0,1)];
}
.text-field-success {
@apply shadow-[0px_0px_10px_0px_rgba(52,211,153,1)];
}

View File

@@ -1,63 +1,8 @@
<script setup lang="ts">
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import CodeEditorComponent from '@/components/CodeEditorComponent.vue';
import { ref } from 'vue';
import HtmlButtonFormatterComponent from '@/components/formatter/HtmlButtonFormatterComponent.vue';
const html = ref('');
const inputFile = ref()
const errorOccurred = ref(false);
function clear() {
html.value = '';
errorOccurred.value = false
inputFile.value.value = ''
}
function setTextFieldValue(data: string) {
html.value = data.toString()
}
function setErrorOccurred(occurred: boolean) {
errorOccurred.value = occurred
}
function setExample(data: string) {
inputFile.value.value = ''
setTextFieldValue(data)
}
function readFile(file : any) {
const reader = new FileReader()
reader.onloadend = () => {
var result = reader.result?.toString()
if (typeof result == "string")
setTextFieldValue(result);
}
reader.readAsText(file.target.files[0])
}
import FormatterComponent from '@/components/formatter/FormatterComponent.vue';
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class="flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100">HTML Formatter</span>
<div class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".xml,.html,.htm,text/xml,text/plain,text/html" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="HTML" @update:defaultData="setExample"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<HtmlButtonFormatterComponent @update:result="setTextFieldValue" @update:error="setErrorOccurred" :code="html" format-type="Minimize" />
<HtmlButtonFormatterComponent @update:result="setTextFieldValue" @update:error="setErrorOccurred" :code="html" format-type="Prettify" />
<HtmlButtonFormatterComponent @update:result="setTextFieldValue" @update:error="setErrorOccurred" :code="html" format-type="HTML -> XML" />
</div>
</div>
<CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="html" :config="{disabled:false,language:'html'}" />
</div>
<FormatterComponent formatter-language="HTML"></FormatterComponent>
</template>

View File

@@ -1,67 +1,8 @@
<script setup lang="ts">
import CodeEditorComponent from '@/components/CodeEditorComponent.vue';
import JsonButtonFormatterComponent from '@/components/formatter/JsonButtonFormatterComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import { ref } from 'vue';
const json = ref('');
const inputFile = ref()
const errorOccurred = ref(false);
function setTextFieldValue(data: string) {
json.value = data
}
function setExample(data: string) {
inputFile.value.value = ''
setTextFieldValue(data)
}
function setErrorOccurred(occurred: boolean) {
errorOccurred.value = occurred
}
function format(formattedXml: any) {
json.value = formattedXml.data;
}
function clear() {
json.value = '';
errorOccurred.value = false
inputFile.value.value = ''
}
function readFile(file : any) {
const reader = new FileReader()
reader.onloadend = () => {
var result = reader.result?.toString()
if (typeof result == "string")
setTextFieldValue(result);
}
reader.readAsText(file.target.files[0])
}
import FormatterComponent from '@/components/formatter/FormatterComponent.vue';
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class= "flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100">JSON Formatter</span>
<div class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".json,text/xml,text/plain,text/json,application/json" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="JSON" @update:defaultData="(data: string) => setExample(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<JsonButtonFormatterComponent isMinimizer :json="json" @update:result="(data: any) => format(data)" @update:error="setErrorOccurred"></JsonButtonFormatterComponent>
<JsonButtonFormatterComponent :json="json" @update:result="(data: any) => format(data)" @update:error="setErrorOccurred"></JsonButtonFormatterComponent>
</div>
</div>
<CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="json" :config="{disabled:false,language:'json'}" />
</div>
<FormatterComponent formatter-language="JSON"></FormatterComponent>
</template>

View File

@@ -1,66 +1,8 @@
<script setup lang="ts">
import XMLButtonFormatterComponent from '@/components/formatter/XMLButtonFormatterComponent.vue';
import InsertTemplateComponent from '@components/common/InsertTemplateComponent.vue';
import CodeEditorComponent from '@/components/CodeEditorComponent.vue';
import { ref } from 'vue';
const xml = ref('');
const inputFile = ref()
const errorOccurred = ref(false);
function setTextFieldValue(data: string) {
xml.value = data
}
function format(formattedXml: any) {
xml.value = formattedXml.result;
}
function setErrorOccurred(occurred: boolean) {
errorOccurred.value = occurred
}
function setExample(data: string) {
inputFile.value.value = ''
setTextFieldValue(data)
}
function clear() {
xml.value = '';
errorOccurred.value = false
inputFile.value.value = ''
}
function readFile(file : any) {
const reader = new FileReader()
reader.onloadend = () => {
var result = reader.result?.toString()
if (typeof result == "string")
setTextFieldValue(result);
}
reader.readAsText(file.target.files[0])
}
import FormatterComponent from '@/components/formatter/FormatterComponent.vue';
</script>
<template>
<div id="layout" class="flex flex-col w-full h-full gap-4">
<div id="toolbar" class= "flex flex-col gap-4 items-center lg:flex-row place-content-between">
<span class="dark:text-slate-100">XML Formatter</span>
<div class="flex flex-wrap gap-2 justify-center">
<div class="flex items-stretch w-64">
<input id="fileLoader" ref="inputFile" class="file-selector" type="file" accept=".xml,.xql,.xquery,.xslt,text/xml,text/plain" @change="readFile" />
</div>
<InsertTemplateComponent stylized-name="XML" @update:defaultData="(data: string) => setExample(data)"></InsertTemplateComponent>
<button class="tool-button" @click="clear()">Clear</button>
<XMLButtonFormatterComponent @update:error="setErrorOccurred" is-minimizer :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent>
<XMLButtonFormatterComponent @update:error="setErrorOccurred" :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent>
</div>
</div>
<CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="xml" :config="{disabled:false,language:'xml'}" />
</div>
<FormatterComponent formatter-language="XML"></FormatterComponent>
</template>