Improved legibility of REST Mock interface and various fixes #266
| @@ -1,4 +1,4 @@ | ||||
| FROM node:latest as build-stage | ||||
| FROM node:20.9.0-bullseye-slim as build-stage | ||||
| WORKDIR /app | ||||
| COPY package*.json ./ | ||||
| RUN npm install | ||||
| @@ -7,7 +7,7 @@ RUN npm run build | ||||
|  | ||||
|  | ||||
|  | ||||
| FROM nginx:stable-alpine as production-stage | ||||
| FROM nginx:stable-alpine3.17-slim as production-stage | ||||
| RUN mkdir /app | ||||
|  | ||||
| RUN apk add --no-cache tzdata | ||||
| @@ -20,7 +20,7 @@ EXPOSE 80 | ||||
| EXPOSE 443 | ||||
|  | ||||
|  | ||||
| FROM node:latest as dev | ||||
| FROM node:20.9.0-bullseye-slim as dev | ||||
| WORKDIR /app | ||||
| COPY package*.json ./ | ||||
| RUN npm install | ||||
|   | ||||
| @@ -55,7 +55,7 @@ import {html} from '@codemirror/lang-html' | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <div class="editor w-full max-w-full h-full overflow-scroll"> | ||||
|   <div class="editor w-full h-full bg-[#282C34] rounded-2xl overflow-x-auto"> | ||||
|      | ||||
|     <codemirror | ||||
|       style="height: 100%; width: 100%; padding:1rem ; border-radius: 1rem; font-size: large;" | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|  | ||||
| const props = defineProps( | ||||
|     { | ||||
|         encodeType: {type:String,required:true}, | ||||
|         operationType: {type:String,required:true}, | ||||
|         code: {type: String, required: true} | ||||
|     } | ||||
| ) | ||||
| @@ -15,16 +15,16 @@ const emit = defineEmits([ | ||||
|  | ||||
| function convert(){ | ||||
|     console.log("works") | ||||
|     switch(props.encodeType.toLowerCase()){ | ||||
|         case "base64":{ | ||||
|     switch(props.operationType.toLowerCase()){ | ||||
|         case "encode":{ | ||||
|             emit('update:result', btoa(props.code) ) | ||||
|             break; | ||||
|         } | ||||
|         case "text":{ | ||||
|         case "decode":{ | ||||
|             emit('update:result', atob(props.code) ) | ||||
|             break; | ||||
|         } | ||||
|         case "image":{ | ||||
|         case "show image":{ | ||||
|             emit('image:show', props.code ) | ||||
|             break; | ||||
|         } | ||||
| @@ -35,5 +35,5 @@ function convert(){ | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|     <button @click="convert()" class="tool-button">{{ props.encodeType }}</button> | ||||
|     <button @click="convert()" class="tool-button">{{ props.operationType }}</button> | ||||
| </template> | ||||
| @@ -1,13 +1,28 @@ | ||||
| <script setup lang="ts"> | ||||
| const props = defineProps( | ||||
|     { | ||||
|         formatType: {type:String,required:true}, | ||||
|         code: {type:String,required:true}, | ||||
|         formatType: { | ||||
|             type:String, | ||||
|             required:true | ||||
|         }, | ||||
|         code: { | ||||
|             type:String, | ||||
|             required:true | ||||
|         }, | ||||
|         isError: { | ||||
|             type:Boolean, | ||||
|             required:false | ||||
|         }, | ||||
|     } | ||||
| ) | ||||
|  | ||||
| const emit = defineEmits([ | ||||
|     'update:result', | ||||
|     'update:error' | ||||
| ]) | ||||
|  | ||||
| function chooseType(formatType: String){ | ||||
|     if (formatType == "XML Converter"){ | ||||
|     if (formatType == "HTML -> XML"){ | ||||
|         return "convert"; | ||||
|     } | ||||
|     return formatType.toLowerCase(); | ||||
| @@ -24,7 +39,7 @@ function getTypeInfo(){ | ||||
| function createBody(){ | ||||
|     return JSON.stringify({ | ||||
|         "data": props.code, | ||||
|         "process": getTypeInfo(), | ||||
|         "processorData": getTypeInfo(), | ||||
|         "processor": "libxml", | ||||
|         "version": "1.0" | ||||
|     }); | ||||
| @@ -32,12 +47,9 @@ function createBody(){ | ||||
|  | ||||
| const fetchLink = document.location.protocol + "//" + document.location.hostname + "/libxml/html/" + chooseType(props.formatType); | ||||
|  | ||||
| const emit = defineEmits([ | ||||
|     'update:result' | ||||
| ]) | ||||
|  | ||||
| function processResponse(formattedCode : any){ | ||||
|     var result = formattedCode.result; | ||||
|     emit("update:error", formattedCode.status == "ERR") | ||||
|     return result | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -5,12 +5,12 @@ const props = defineProps({ | ||||
|     isMinimizer: {type: Boolean} | ||||
| }) | ||||
|  | ||||
| const emit = defineEmits(["update:result"]) | ||||
| const emit = defineEmits(["update:result", "update:error"]) | ||||
|  | ||||
| function process() { | ||||
|     var request:Request = prepareRequest(); | ||||
|     fetchRequest(request).then((data) => { | ||||
|         sendProcessedData(data); | ||||
|         sendProcessedData(data);   | ||||
|     }) | ||||
| } | ||||
|  | ||||
| @@ -36,7 +36,10 @@ function prepareRequestBody():string { | ||||
|  | ||||
| async function fetchRequest(request: Request):Promise<JSON> { | ||||
|     var responseBody = await fetch(request) | ||||
|     .then(response => response.json()) | ||||
|     .then(response => { | ||||
|         emit('update:error', response.status != 200) | ||||
|         return response.json() | ||||
|     }) | ||||
|     .then((body) => body); | ||||
|     console.log(responseBody); | ||||
|     return responseBody; | ||||
|   | ||||
| @@ -5,7 +5,10 @@ const props = defineProps({ | ||||
|     isMinimizer: {type: Boolean} | ||||
| }) | ||||
|  | ||||
| const emit = defineEmits(["update:result"]) | ||||
| const emit = defineEmits([ | ||||
|     'update:result', | ||||
|     'update:error' | ||||
| ]) | ||||
|  | ||||
| function process() { | ||||
|     var request:Request = prepareRequest() | ||||
| @@ -42,7 +45,10 @@ function prepareRequestBody():string { | ||||
| async function fetchRequest(request: Request):Promise<JSON> { | ||||
|     var responseBody = await fetch(request) | ||||
|     .then(response => response.json()) | ||||
|     .then((body) => body) | ||||
|     .then((body) => { | ||||
|         emit("update:error", body.status == "ERR") | ||||
|         return body | ||||
|     }) | ||||
|     return responseBody | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -55,6 +55,7 @@ function addNewHeader(name : string, value : string){ | ||||
| <template> | ||||
|      | ||||
|     <div class="flex flex-col gap-4"> | ||||
|         <label>Response Headers</label> | ||||
|         <div class="flex flex-row gap-4"> | ||||
|             <div class="w-full">Header name</div> | ||||
|             <div class="w-full">Header value</div> | ||||
|   | ||||
| @@ -10,14 +10,14 @@ const props = defineProps( | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|     <div class="w-full text-center text-white mt-2 flex flex-col gap-4 "> | ||||
|     <div class="w-full text-center dark:text-white mt-2 flex flex-col gap-4 "> | ||||
|         <div class="flex flex-row gap-4">  | ||||
|             <div class="w-full font-bold">Name</div>  | ||||
|             <div class="w-full font-bold">Value</div>  | ||||
|         </div > | ||||
|         <div class="flex flex-row gap-4" v-for="(value,name) in JSON.parse(data)" :key="name"> | ||||
|             <div class="w-full overflow-hidden">{{ name }}</div> | ||||
|             <div class="w-full overflow-hidden">{{ value }}</div> | ||||
|             <div class="w-1/2 break-words">{{ name }}</div> | ||||
|             <div class="w-1/2 break-words">{{ value }}</div> | ||||
|         </div> | ||||
|     </div> | ||||
| </template> | ||||
| @@ -34,8 +34,9 @@ function showHeaders(headers: object, index: number){ | ||||
|  | ||||
|  | ||||
| <template> | ||||
|     <div class="flex flex-1 flex-col justify-items-stretch gap-y-4"> | ||||
|         <HistoryRecords class="xl:h-1/3 overflow-y-scroll" @click:show-headers="showHeaders" @click:show-body="showBody"></HistoryRecords> | ||||
|     <div class="flex flex-1 flex-col xl:w-3/12 justify-items-stretch gap-y-4"> | ||||
|         <label class="dark:text-white text-center"><span class="font-bold">Attention! </span>History doesn't refresh automatically! Use refresh button (⟳) on the right!</label> | ||||
|  | ||||
|         <HistoryRecords class="xl:h-1/3 overflow-y-auto" @click:show-headers="showHeaders" @click:show-body="showBody"></HistoryRecords> | ||||
|         <BodyDetailComponent :content-type="currentContentType" :data="currentShownData" v-if="shownDetail == 'body' "></BodyDetailComponent> | ||||
|         <HeadersDetailComponent :data="currentShownData"  v-if="shownDetail == 'headers' "></HeadersDetailComponent> | ||||
|     </div> | ||||
|   | ||||
| @@ -49,8 +49,8 @@ function refreshHistory(){ | ||||
|         <table class="w-full"> | ||||
|             <tr> | ||||
|                 <th>Time</th> | ||||
|                 <th>HTTP Method</th> | ||||
|                 <th>Headers</th> | ||||
|                 <th>Request <br>HTTP Method</th> | ||||
|                 <th>Request Headers</th> | ||||
|                 <th>Request Body</th> | ||||
|                 <th class="text-2xl"><button @click="refreshHistory()">⟳</button></th> | ||||
|             </tr> | ||||
| @@ -60,7 +60,7 @@ function refreshHistory(){ | ||||
|                 <td> <button @click="showHeaders(item.headers, index)" class="underline">Show Headers</button> </td> | ||||
|                 <td>  | ||||
|                     <button v-if="item.requestBody.length != 0" @click="showBody(item.requestBody, index, item.headers['content-type'])" class="underline">Show Body</button>  | ||||
|                     <span v-else>Empty Body</span> | ||||
|                     <span v-else>Empty</span> | ||||
|                 </td> | ||||
|             </tr> | ||||
|         </table> | ||||
|   | ||||
| @@ -44,10 +44,10 @@ function showUpdatedCode(newCode : string){ | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|   <div class="flex flex-col flex-none w-full xl:w-3/5 text-center dark:text-white gap-6 p-1"> | ||||
|   <div class="flex flex-col flex-none w-full xl:w-3/5 text-center dark:text-white gap-3 p-1"> | ||||
|     <div class="flex flex-col md:flex-row gap-4 items-center md:justify-stretch md:items-end"> | ||||
|       <div class="flex flex-col w-full"> | ||||
|         <label for="link">Link</label><br/> | ||||
|         <label for="link">REST Service URL</label><br/> | ||||
|         <div class="p-2 w-full border-slate-400 border-2 rounded-lg"> | ||||
|           <a class="underline" :href="mockMessageLink">{{ mockMessageLink }}</a> | ||||
|         </div> | ||||
| @@ -57,18 +57,18 @@ function showUpdatedCode(newCode : string){ | ||||
|     </div> | ||||
|     <div class="flex flex-col md:flex-row w-full gap-4"> | ||||
|       <div class="w-full"> | ||||
|         <label for="contentType">Content Type</label><br/> | ||||
|         <label for="contentType">Response Content Type</label><br/> | ||||
|         <input  class="text-field" id="contentType" type="text" v-model="messageData.contentType"/> | ||||
|       </div> | ||||
|        | ||||
|       <div class="w-full"> | ||||
|         <label for="httpStatus">HttpStatus</label><br/> | ||||
|         <label for="httpStatus">Response HTTP Status</label><br/> | ||||
|         <input class="text-field" id="httpStatus" type="text" v-model="messageData.httpStatus"/> | ||||
|       </div> | ||||
|        | ||||
|     </div> | ||||
|     <div class="flex text-left flex-col overflow-scroll h-3/4"> | ||||
|       <label for="messageBody text-center">Body</label> | ||||
|     <div class="flex text-left flex-col overflow-auto gap-2 h-3/4"> | ||||
|       <label class="text-center" for="messageBody text-center">Response Body</label> | ||||
|       <CodeEditorComponent | ||||
|       @update:updated-code="showUpdatedCode" | ||||
|       v-model="messageData.messageBody"  | ||||
|   | ||||
| @@ -55,10 +55,10 @@ function readFile(file : any) { | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|     <div class="flex flex-col w-full h-1/2 lg:h-1/2 flex-none pr-4 pb-2"> | ||||
|     <div class="flex flex-col w-full h-1/2 lg:h-1/2 flex-none xl:pr-2 2xl:pr-4 pb-2"> | ||||
|         <div class="flex place-content-between w-full items-center"> | ||||
|             <span class="dark:text-white mr-2">{{ stylizedName }}</span> | ||||
|             <div class="flex space-x-2 pb-2 overflow-x-scroll"> | ||||
|             <div class="flex space-x-2 pb-2 overflow-x-auto"> | ||||
|                 <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> | ||||
|   | ||||
| @@ -23,6 +23,8 @@ var versionsForCurrentEngine = ref([""]); | ||||
| const engine = ref(''); | ||||
| const version = ref(''); | ||||
|  | ||||
| const errorOccurred = ref(false); | ||||
|  | ||||
|  | ||||
| onMounted(() => { | ||||
|     changeAvailableEngines(); | ||||
| @@ -111,16 +113,18 @@ function prepareRequestBody():string { | ||||
| async function fetchRequest(request: Request):Promise<JSON> { | ||||
|     var responseBody = await fetch(request) | ||||
|     .then(response => response.json()) | ||||
|     .then((body) => body); | ||||
|     return responseBody; | ||||
|     .then((body) => body) | ||||
|     return responseBody | ||||
| } | ||||
|  | ||||
| function updateOutputField(data: any) { | ||||
|     result.value = data.result; | ||||
|     result.value = data.result | ||||
|     errorOccurred.value = data.status == "ERR" | ||||
| } | ||||
|  | ||||
| function clear() { | ||||
|     result.value = ""; | ||||
|     result.value = "" | ||||
|     errorOccurred.value = false | ||||
| } | ||||
|  | ||||
| function emitVersionChange() { | ||||
| @@ -134,10 +138,10 @@ function isVersionSelectionAvailable() { | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
|     <div class="flex flex-col flex-none w-full 2xl:w-1/2 h-1/3 2xl:h-full items-center pb-2 pr-2"> | ||||
|     <div class="flex flex-col flex-none w-full 2xl:w-1/2 h-1/3 2xl:h-full items-center pb-2 xl:pr-2"> | ||||
|         <div class="flex place-content-between w-full items-center pb-2"> | ||||
|             <span class="dark:text-white">Result:</span> | ||||
|             <div class="flex space-x-2 overflow-x-scroll"> | ||||
|             <div class="flex space-x-2 overflow-x-auto"> | ||||
|                 <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> | ||||
| @@ -148,7 +152,7 @@ function isVersionSelectionAvailable() { | ||||
|                 <button class="tool-button" @click="process">Process</button> | ||||
|             </div> | ||||
|         </div> | ||||
|         <div class="overflow-scroll h-full w-full"> | ||||
|         <div class="overflow-auto h-full w-full rounded-2xl" :class="{'text-field-error' : errorOccurred}"> | ||||
|             <CodeEditor :code="result" :config="{disabled:true,language:tool}"></CodeEditor> | ||||
|         </div> | ||||
|          | ||||
|   | ||||
| @@ -26,4 +26,8 @@ | ||||
|  | ||||
| .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 | ||||
| } | ||||
|  | ||||
| .text-field-error { | ||||
|     @apply shadow-[0px_0px_10px_0px_rgba(255,0,0,1)]; | ||||
| } | ||||
| @@ -21,8 +21,12 @@ function showImage(newImage : string){ | ||||
|  | ||||
| function convertImageToBase64(file : any){ | ||||
|     const reader = new FileReader() | ||||
|     reader.onloadend = () => (console.log(data.value = reader.result?.toString().split(',')[1])) | ||||
|     reader.onloadend = () => { | ||||
|         data.value = reader.result?.toString().split(',')[1] | ||||
|         showImage(data.value) | ||||
|     } | ||||
|     reader.readAsDataURL(file.target.files[0]) | ||||
|      | ||||
| } | ||||
|  | ||||
| function clear(){ | ||||
| @@ -38,18 +42,17 @@ function clear(){ | ||||
| <div id="layoutFull" class="w-full h-full flex flex-col xl:flex-row gap-4"> | ||||
|     <div id="layoutLeft" class="flex flex-col w-full xl:w-1/2 h-1/3 xl:h-full gap-4"> | ||||
|         <div class="w-full flex flex-row place-content-between items-center"> | ||||
|             <label class="dark:text-white text-center">Base64/Text</label> | ||||
|             <div class="flex flex-row items-center gap-2"> | ||||
|             <label class="dark:text-white text-center">Base64 Encoder</label> | ||||
|             <div class="flex flex-row items-center gap-2 overflow-x-auto"> | ||||
|                 <button class="tool-button" @click="clear()">Clear</button> | ||||
|                 <label class="text-grey-900 dark:text-white">Convert to</label> | ||||
|                 <EncoderButton @image:show="showImage" :code="data" encode-type="Image"></EncoderButton> | ||||
|                 <EncoderButton @update:result="setTextFieldValue" :code="data" encode-type="Text"></EncoderButton> | ||||
|                 <EncoderButton @update:result="setTextFieldValue" :code="data" encode-type="Base64"></EncoderButton> | ||||
|                 <EncoderButton @image:show="showImage" :code="data" operation-type="Show Image"></EncoderButton> | ||||
|                 <div class="w-2"></div> | ||||
|                 <EncoderButton @update:result="setTextFieldValue" :code="data" operation-type="Encode"></EncoderButton> | ||||
|                 <EncoderButton @update:result="setTextFieldValue" :code="data" operation-type="Decode"></EncoderButton> | ||||
|             </div> | ||||
|              | ||||
|         </div> | ||||
|         <div id="codeEditor" class="w-full h-full xl:h-1/3 flex flex-col"> | ||||
|              | ||||
|             <CodeEditorComponent @update:updated-code="setTextFieldValue" :config="{language:'base64'}" :code="data"></CodeEditorComponent> | ||||
|         </div> | ||||
|         <div class="flex flex-row justify-center w-full"> | ||||
|   | ||||
| @@ -6,15 +6,41 @@ import HtmlButtonFormatterComponent from '@/components/formatter/HtmlButtonForma | ||||
|  | ||||
|  | ||||
| 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]) | ||||
| } | ||||
|  | ||||
| </script> | ||||
|  | ||||
| <template> | ||||
| @@ -22,13 +48,16 @@ function setTextFieldValue(data: string) { | ||||
|         <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"> | ||||
|                 <InsertTemplateComponent stylized-name="HTML" @update:defaultData="setTextFieldValue"></InsertTemplateComponent> | ||||
|                 <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" :code="html" format-type="Minimize" /> | ||||
|                 <HtmlButtonFormatterComponent @update:result="setTextFieldValue" :code="html" format-type="Prettify" /> | ||||
|                 <HtmlButtonFormatterComponent @update:result="setTextFieldValue" :code="html" format-type="XML Converter" /> | ||||
|                 <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 @update:updated-code="setTextFieldValue" :code="html" :config="{disabled:false,language:'html'}" /> | ||||
|         <CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="html" :config="{disabled:false,language:'html'}" /> | ||||
|     </div> | ||||
| </template> | ||||
| @@ -6,17 +6,44 @@ 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]) | ||||
| } | ||||
|  | ||||
| </script> | ||||
| @@ -26,12 +53,15 @@ function clear() { | ||||
|         <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"> | ||||
|                 <InsertTemplateComponent stylized-name="JSON" @update:defaultData="(data: string) => setTextFieldValue(data)"></InsertTemplateComponent> | ||||
|                 <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)"></JsonButtonFormatterComponent> | ||||
|                 <JsonButtonFormatterComponent :json="json" @update:result="(data: any) => format(data)"></JsonButtonFormatterComponent> | ||||
|                 <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 @update:updated-code="setTextFieldValue" :code="json" :config="{disabled:false,language:'json'}" /> | ||||
|         <CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="json" :config="{disabled:false,language:'json'}" /> | ||||
|     </div> | ||||
| </template> | ||||
| @@ -6,7 +6,7 @@ import HistoryComponent from '@components/mock/HistoryComponent.vue' | ||||
|  | ||||
|  | ||||
| <template> | ||||
|     <div class="flex flex-col xl:flex-row gap-6 w-full overflow-y-scroll overflow-x-hidden h-full"> | ||||
|     <div class="flex flex-col xl:flex-row gap-6 w-full overflow-y-auto overflow-x-hidden h-full"> | ||||
|         <RestMockMessageComponent></RestMockMessageComponent> | ||||
|         <HistoryComponent></HistoryComponent> | ||||
|     </div> | ||||
|   | ||||
| @@ -17,7 +17,7 @@ function updateVersion(newVersion: string) { | ||||
|  | ||||
| <template> | ||||
|     <div id="layout" class="flex flex-row w-full h-full"> | ||||
|         <div class="flex flex-col 2xl:flex-row w-full 2xl:w-7/12 grow overflow-hide pr-2"> | ||||
|         <div class="flex flex-col 2xl:flex-row w-full xl:w-7/12 grow overflow-hide xl:pr-2"> | ||||
|             <div class="flex flex-col w-full 2xl:w-1/2 h-2/3 2xl:h-full flex-none items-center"> | ||||
|                 <xmlInputFieldComponent stylized-name="XML" :data="xml" @update="(data) => {xml = data}"></xmlInputFieldComponent> | ||||
|                 <xmlInputFieldComponent stylized-name="XPath" :data="query" @update="(data) => {query = data}"></xmlInputFieldComponent> | ||||
|   | ||||
| @@ -16,13 +16,13 @@ function updateVersion(newVersion: string) { | ||||
|  | ||||
| <template> | ||||
|     <div id="layout" class="flex flex-row w-full h-full"> | ||||
|         <div class="flex flex-col 2xl:flex-row w-full 2xl:w-7/12 grow overflow-hide pr-2"> | ||||
|         <div class="flex flex-col 2xl:flex-row w-full xl:w-7/12 grow overflow-hide pr-2"> | ||||
|             <div class="flex flex-col w-full 2xl:w-1/2 h-2/3 2xl:h-full flex-none items-center"> | ||||
|                 <xmlInputFieldComponent stylized-name="XML" :data="xml" @update="(data) => {xml = data}"></xmlInputFieldComponent> | ||||
|                 <xmlInputFieldComponent stylized-name="XSLT" :data="query" @update="(data) => {query = data}"></xmlInputFieldComponent> | ||||
|             </div> | ||||
|             <xmlOutputFieldComponent tool="xslt" :xml="xml" :query="query" @update="(version) => updateVersion(version)"></xmlOutputFieldComponent> | ||||
|         </div> | ||||
|         <tooltipComponent tool-type="xslt" :version="version"></tooltipComponent> | ||||
|         <TooltipComponent tool-type="xslt" :version="version"></TooltipComponent> | ||||
|     </div> | ||||
| </template> | ||||
| @@ -6,6 +6,9 @@ import { ref } from 'vue'; | ||||
|  | ||||
|  | ||||
| const xml = ref(''); | ||||
| const inputFile = ref() | ||||
|  | ||||
| const errorOccurred = ref(false); | ||||
|  | ||||
| function setTextFieldValue(data: string) { | ||||
|     xml.value = data | ||||
| @@ -15,8 +18,31 @@ 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]) | ||||
| } | ||||
|  | ||||
| </script> | ||||
| @@ -26,12 +52,15 @@ function clear() { | ||||
|         <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"> | ||||
|                 <InsertTemplateComponent stylized-name="XML" @update:defaultData="(data: string) => setTextFieldValue(data)"></InsertTemplateComponent> | ||||
|                 <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 is-minimizer :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent> | ||||
|                 <XMLButtonFormatterComponent :xml="xml" @update:result="(data: any) => format(data)"></XMLButtonFormatterComponent> | ||||
|                 <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 @update:updated-code="setTextFieldValue" :code="xml" :config="{disabled:false,language:'xml'}" /> | ||||
|         <CodeEditorComponent :class="{'text-field-error' : errorOccurred}" @update:updated-code="setTextFieldValue" :code="xml" :config="{disabled:false,language:'xml'}" /> | ||||
|     </div> | ||||
| </template> | ||||
		Reference in New Issue
	
	Block a user
	
Attention!: History doesn't refresh automatically! Use refresh button (⟳) on the right!