Skip to content

Commit

Permalink
Merge branch 'aas-error-handling' of https://github.com/SergioCasCeb/…
Browse files Browse the repository at this point in the history
…playground into aas-error-handling
  • Loading branch information
SergioCasCeb committed Oct 13, 2023
2 parents 6c8ae58 + 1ad78b0 commit 2224de1
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 84 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# W3C Web of Things - Thing Description Playground

Try it online at [http://plugfest.thingweb.io/playground/](http://plugfest.thingweb.io/playground/)
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eclipse-thingweb/website/master/misc/thingweb_logo_for_dark_bg.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/eclipse-thingweb/website/master/misc/thingweb_logo.svg">
<img title="ThingWeb" alt="Thingweb logo" src="" width="300px">
</picture>

## Playground
> The place where you can create and play with Thing Descriptions. Try it online at [http://plugfest.thingweb.io/playground/](http://plugfest.thingweb.io/playground/)
[![Default CI & CD Pipeline](https://github.com/thingweb/thingweb-playground/actions/workflows/ci-cd.yaml/badge.svg)](https://github.com/thingweb/thingweb-playground/actions/workflows/ci-cd.yaml)
[![CodeQL](https://github.com/thingweb/thingweb-playground/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/thingweb/thingweb-playground/actions/workflows/codeql-analysis.yml)
Expand Down
2 changes: 1 addition & 1 deletion packages/web-new/src/scripts/console.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import { openApiTab, openApiJsonBtn, openApiYamlBtn, openApiView } from './open-api'
import { asyncApiTab, asyncApiJsonBtn, asyncApiYamlBtn, asyncApiView } from './async-api'
import { AASView, AASTab } from './aas'
import { AASTab, AASView } from './aas'
import { defaultsView, defaultsJsonBtn, defaultsYamlBtn, defaultsAddBtn } from './defaults'
import { visualize } from './visualize'
import { validationView } from './validation'
Expand Down
104 changes: 68 additions & 36 deletions packages/web-new/src/scripts/editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,81 @@ function createTab(tabNumber, exampleName, thingType) {
closeIcon.classList.add("fa-solid", "fa-xmark")

closeBtn.appendChild(closeIcon)

//Create the close confirmation btns
const confirmBtns = document.createElement("div")
confirmBtns.classList.add("confirm-btns", "hidden")

const confirmTabClose = document.createElement("button")
confirmTabClose.classList.add("confirm-tab-close")
confirmTabClose.textContent = "Close"
const confirmTabIcon = document.createElement("i")
confirmTabIcon.classList.add("fa-solid", "fa-check")
confirmTabClose.appendChild(confirmTabIcon)

const cancelTabClose = document.createElement("button")
cancelTabClose.classList.add("cancel-tab-close")
cancelTabClose.textContent = "Cancel"
const cancelTabIcon = document.createElement("i")
cancelTabIcon.classList.add("fa-solid", "fa-xmark")
cancelTabClose.appendChild(cancelTabIcon)

cancelTabClose.addEventListener("click", () => {
cancelTabClose.parentElement.classList.add("hidden")
})

confirmBtns.appendChild(confirmTabClose)
confirmBtns.appendChild(cancelTabClose)

newTab.appendChild(tabIcon)
newTab.appendChild(tabContent)
newTab.appendChild(closeBtn)
newTab.appendChild(confirmBtns)

//Insert the newly created list at the end of the tab container but before the add new tab button
tabsLeftContainer.insertBefore(newTab, tabsLeftContainer.children[(tabsLeftContainer.children.length) - 1])
tabsLeft = document.querySelectorAll(".ide__tabs__left li:not(:last-child)")

//Once the new tab is created remove "active class from all other tab" as well as the
//contenteditable attribute and give the class "active to the new tab"
//Once the new tab is created remove "active class from all other tab"
//and give the class "active to the new tab"
tabsLeft.forEach(tab => {
tab.classList.remove("active")
tab.children[0].removeAttribute("contenteditable")
})
newTab.classList.add("active")

confirmTabClose.addEventListener("click", () => {
//If there is only one tab and its closed create a completely editor and tab and restart the counter
//If not the last one adjust the styling accordingly and update the amount of tabs
if (tabsLeft.length == 1) {
ideCount.ideNumber = 0
editorList.forEach(ide => {
if (confirmTabClose.parentElement.parentElement.dataset.tabId === ide["_domElement"].dataset.ideId) {
//remove the editor from the editor list array and from the DOM
const index = editorList.indexOf(ide)
editorList.splice(index, 1)
ide["_domElement"].remove()
}
})
//remove tab
confirmTabClose.parentElement.parentElement.remove()
//create new tab
createIde(++ideCount.ideNumber)
jsonBtn.checked = true
}
else {
editorList.forEach(ide => {
if (confirmTabClose.parentElement.parentElement.dataset.tabId === ide["_domElement"].dataset.ideId) {
const index = editorList.indexOf(ide)
editorList.splice(index, 1)
ide["_domElement"].remove()
}
})
confirmTabClose.parentElement.parentElement.remove()
tabsLeft = document.querySelectorAll(".ide__tabs__left li:not(:last-child)")
tabsLeft[0].classList.add("active")
editorList[0]["_domElement"].classList.add("active")
}
})
}

/**
Expand Down Expand Up @@ -333,14 +393,16 @@ tabsLeftContainer.addEventListener("click", (e) => {
//getting the initial target
const selectedElement = e.target
clearConsole()
tabsLeft.forEach(tab => {
tab.children[3].classList.add("hidden")
})

//Add the active styling when tab is clicked
if (selectedElement.id == "tab" || selectedElement.parentElement.id == "tab") {

//Removing the active style from all tabs and contenteditable attribute
//Removing the active style from all tabs
tabsLeft.forEach(tab => {
tab.classList.remove("active")
tab.children[0].removeAttribute("contenteditable")
})
//removing the active style from all editors
editorList.forEach(ide => {
Expand Down Expand Up @@ -375,37 +437,7 @@ tabsLeftContainer.addEventListener("click", (e) => {

//Closing tabs only when the click event happens on the close icon of the tab
if (selectedElement.className == "close-tab" && tabsLeft.length >= 1) {
//If there is only one tab and its closed create a completely editor and tab and restart the counter
//If not the last one adjust the styling accordingly and update the amount of tabs
if (tabsLeft.length == 1) {
ideCount.ideNumber = 0
editorList.forEach(ide => {
if (selectedElement.parentElement.dataset.tabId === ide["_domElement"].dataset.ideId) {
//remove the editor from the editor list array and from the DOM
const index = editorList.indexOf(ide)
editorList.splice(index, 1)
ide["_domElement"].remove()
}
})
//remove tab
selectedElement.parentElement.remove()
//create new tab
createIde(++ideCount.ideNumber)
jsonBtn.checked = true
}
else {
editorList.forEach(ide => {
if (selectedElement.parentElement.dataset.tabId === ide["_domElement"].dataset.ideId) {
const index = editorList.indexOf(ide)
editorList.splice(index, 1)
ide["_domElement"].remove()
}
})
selectedElement.parentElement.remove()
tabsLeft = document.querySelectorAll(".ide__tabs__left li:not(:last-child)")
tabsLeft[0].classList.add("active")
editorList[0]["_domElement"].classList.add("active")
}
selectedElement.nextElementSibling.classList.remove("hidden")
}

findFileType()
Expand Down
9 changes: 9 additions & 0 deletions packages/web-new/src/scripts/json-yaml.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const jsonBtn = document.querySelector("#file-type-json")
const yamlWarning = document.querySelector('.json-yaml-warning')
const yamlConfirmBtn = document.querySelector("#yaml-confirm-btn")
const yamlCancelBtn = document.querySelector("#yaml-cancel-btn")
const yamlWarningContainer = document.querySelector(".json-yaml-warning__container")
jsonBtn.checked = true


Expand All @@ -57,6 +58,14 @@ yamlCancelBtn.addEventListener("click", () => {
jsonBtn.checked = true
})

//Handle click outside the warning pop up
document.addEventListener('click', (e) => {
if(!yamlBtn.contains(e.target) && !yamlWarningContainer.contains(e.target) && !yamlWarning.classList.contains("closed")){
yamlWarning.classList.add("closed")
jsonBtn.checked = true
}
})

//Confirm the json to yaml convertion
yamlConfirmBtn.addEventListener("click", () => {
yamlWarning.classList.add('closed')
Expand Down
49 changes: 30 additions & 19 deletions packages/web-new/src/scripts/save-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,23 @@ import { editorList, getEditorData } from "./editor"
const saveMenu = document.querySelector(".save-menu")
const saveMenuBtn = document.querySelector("#save-btn")
const closeSaveMenu = document.querySelector(".save-menu-close i")
const shareUrlContainer = document.querySelector("#share-url-input")
const openUrlTab = document.querySelector("#open-url-tab")
const shareUrlContainer = document.querySelector("#share-url-input")
const openUrlTab = document.querySelector("#open-url-tab")
const thingTypeText = document.querySelector('#thing-type-text')
const shareUrlBtn = document.querySelector("#share-url-btn")
const openEditdorBtn = document.querySelector('#open-editdor-btn')
const downloadBtn = document.querySelector("#download-btn")
const saveAsBtn = document.querySelector("#save-as-btn")
const saveAsWarning = document.querySelector(".save-warning")
const saveMenuContainer = document.querySelector(".save-menu__container")
let fileHandle;
openUrlTab.disabled = true
shareUrlContainer.value = ""

//Open the save menu and change the text depending on the Thing type (TD or TM)
saveMenuBtn.addEventListener("click", () => {
editorList.forEach(editorInstance => {
if(editorInstance["_domElement"].classList.contains("active")){
if (editorInstance["_domElement"].classList.contains("active")) {
const editorValues = getEditorData(editorInstance)
thingTypeText.innerText = editorValues[1].toUpperCase()
}
Expand All @@ -59,14 +60,23 @@ closeSaveMenu.addEventListener("click", () => {
openUrlTab.disabled = true
})

//Handle click outside the save menu
document.addEventListener('click', (e) => {
if (!saveMenuBtn.contains(e.target) && !saveMenuContainer.contains(e.target) && !saveMenu.classList.contains("closed")) {
saveMenu.classList.add("closed")
shareUrlContainer.value = ""
openUrlTab.disabled = true
}
})

/**
* Get the active editor, the format type, doc type and editor
* and call the saveAsURL function
*/
shareUrlBtn.addEventListener("click", () => {
try {
editorList.forEach(editorInstance => {
if(editorInstance["_domElement"].classList.contains("active")){
if (editorInstance["_domElement"].classList.contains("active")) {
const editorValues = getEditorData(editorInstance)

saveAsURL(editorValues[0], editorValues[1], editorValues[2])
Expand All @@ -90,9 +100,9 @@ shareUrlBtn.addEventListener("click", () => {
* @param { String } format - json or yaml
* @param { Object } editor - the editor reference object
*/
async function saveAsURL(formatType, thingType, editorContent){
async function saveAsURL(formatType, thingType, editorContent) {
const URL = await save(formatType, thingType, editorContent)
if(URL !== undefined){
if (URL !== undefined) {
shareUrlContainer.value = URL
openUrlTab.disabled = false
}
Expand All @@ -105,7 +115,7 @@ async function saveAsURL(formatType, thingType, editorContent){
openEditdorBtn.addEventListener("click", () => {
try {
editorList.forEach(editorInstance => {
if(editorInstance["_domElement"].classList.contains("active")){
if (editorInstance["_domElement"].classList.contains("active")) {
const editorValues = getEditorData(editorInstance)

openEditdor(editorValues[0], editorValues[1], editorInstance)
Expand All @@ -126,7 +136,7 @@ openEditdorBtn.addEventListener("click", () => {
* Open the generated sharable link in a new playground tab
*/
openUrlTab.addEventListener("click", () => {
if(shareUrlContainer.value !== "" || shareUrlContainer.value !== "Invalid JSON Object"){
if (shareUrlContainer.value !== "" || shareUrlContainer.value !== "Invalid JSON Object") {
window.open(shareUrlContainer.value, '_blank');
}
})
Expand All @@ -137,7 +147,7 @@ openUrlTab.addEventListener("click", () => {
*/
downloadBtn.addEventListener("click", () => {
editorList.forEach(editorInstance => {
if(editorInstance["_domElement"].classList.contains("active")){
if (editorInstance["_domElement"].classList.contains("active")) {
const editorValues = getEditorData(editorInstance)
let tabName = editorValues[2]["title"].replaceAll(' ', '-')
const contentType = `application/${editorValues[0]};charset=utf-8;`
Expand All @@ -146,6 +156,8 @@ downloadBtn.addEventListener("click", () => {
}
})
saveMenu.classList.add("closed")
shareUrlContainer.value = ""
openUrlTab.disabled = true
})

/* Save as btn functionality */
Expand All @@ -157,7 +169,7 @@ saveAsBtn.addEventListener("click", () => {
* Saves the td as a file in the file system
* @param {*} content
*/
async function saveFileInSystem(content){
async function saveFileInSystem(content) {
let stream = await fileHandle.createWritable()
await stream.write(content)
await stream.close()
Expand All @@ -168,14 +180,14 @@ async function saveFileInSystem(content){
* name and save it as json , jsonld or yaml
* This function only works for chrome, edge and oper as of now (26.05.2023)
*/
async function saveAsFile(){
try{
async function saveAsFile() {
try {
let fileName = ""
let editorContent = ""
let acceptOpts = {}
let acceptDesc = ""
editorList.forEach(editorInstance => {
if(editorInstance["_domElement"].classList.contains("active")){
if (editorInstance["_domElement"].classList.contains("active")) {
const editorValues = getEditorData(editorInstance)
fileName = `${editorValues[2]["title"]}.${editorValues[0]}`
editorContent = editorInstance.getValue()
Expand All @@ -186,7 +198,7 @@ async function saveAsFile(){


const opts = {
suggestedName : fileName,
suggestedName: fileName,
types: [
{
description: acceptDesc,
Expand All @@ -200,17 +212,16 @@ async function saveAsFile(){

saveFileInSystem(editorContent)

}catch(err){
} catch (err) {
const errTxt = `${err}`
if(errTxt === "AbortError: The user aborted a request.")
{
if (errTxt === "AbortError: The user aborted a request.") {
console.error(err)
}
else{
else {
saveAsWarning.classList.add("active")
setTimeout(() => {
saveAsWarning.classList.remove("active")
},1500)
}, 1500)
}
}
}
Expand Down
Loading

0 comments on commit 2224de1

Please sign in to comment.