mirror of
https://github.com/luc-github/ESP3D-WEBUI.git
synced 2026-02-20 01:11:21 +01:00
Add new extension API to allow extension to load and save data in preferences.json
This commit is contained in:
BIN
dist/CNC/GRBL/index.html.gz
vendored
BIN
dist/CNC/GRBL/index.html.gz
vendored
Binary file not shown.
BIN
dist/CNC/GRBLHal/index.html.gz
vendored
BIN
dist/CNC/GRBLHal/index.html.gz
vendored
Binary file not shown.
BIN
dist/Plotter/HP-GL/index.html.gz
vendored
BIN
dist/Plotter/HP-GL/index.html.gz
vendored
Binary file not shown.
BIN
dist/Printer3D/Marlin-embedded/index.html.gz
vendored
BIN
dist/Printer3D/Marlin-embedded/index.html.gz
vendored
Binary file not shown.
BIN
dist/Printer3D/Marlin/index.html.gz
vendored
BIN
dist/Printer3D/Marlin/index.html.gz
vendored
Binary file not shown.
BIN
dist/Printer3D/Repetier/index.html.gz
vendored
BIN
dist/Printer3D/Repetier/index.html.gz
vendored
Binary file not shown.
BIN
dist/Printer3D/Smoothieware/index.html.gz
vendored
BIN
dist/Printer3D/Smoothieware/index.html.gz
vendored
Binary file not shown.
BIN
dist/SandTable/GRBL/index.html.gz
vendored
BIN
dist/SandTable/GRBL/index.html.gz
vendored
Binary file not shown.
@@ -1,45 +1,45 @@
|
||||
<script type="text/javascript">
|
||||
function sendMessage(msg){
|
||||
window.parent.postMessage(msg, '*');
|
||||
}
|
||||
|
||||
function onclickBtn(){
|
||||
const selectElement = document.getElementById('request_id');
|
||||
id_requested = selectElement.value
|
||||
sendMessage({type:'capabilities', target:'webui', id:document.getElementById('request_id').value,});
|
||||
function sendMessage(msg) {
|
||||
window.parent.postMessage(msg, '*');
|
||||
}
|
||||
|
||||
function processMessage(eventMsg){
|
||||
if (eventMsg.data.type && (!eventMsg.data.id||eventMsg.data.id==document.getElementById('request_id').value)){
|
||||
if (eventMsg.data.type=="capabilities"){
|
||||
const line = eventMsg.data.content
|
||||
const resultPanel = document.getElementById("output");
|
||||
let res = JSON.stringify(line.response," ","\n")
|
||||
while (res.includes("\n\n")) {
|
||||
res = res.replace("\n\n", "\n");
|
||||
}
|
||||
resultPanel.innerHTML = res;
|
||||
|
||||
}
|
||||
function onclickBtn() {
|
||||
const selectElement = document.getElementById('request_id');
|
||||
id_requested = selectElement.value
|
||||
sendMessage({ type: 'capabilities', target: 'webui', id: document.getElementById('request_id').value, });
|
||||
}
|
||||
|
||||
function processMessage(eventMsg) {
|
||||
if (eventMsg.data.type && (!eventMsg.data.id || eventMsg.data.id == document.getElementById('request_id').value)) {
|
||||
if (eventMsg.data.type == "capabilities") {
|
||||
const line = eventMsg.data.content
|
||||
const resultPanel = document.getElementById("output");
|
||||
let res = JSON.stringify(line.response, " ", "\n")
|
||||
while (res.includes("\n\n")) {
|
||||
res = res.replace("\n\n", "\n");
|
||||
}
|
||||
resultPanel.innerHTML = res;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
window.onload = (event) => {
|
||||
window.addEventListener("message", processMessage, false);
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<select id="request_id" class="form-select column">
|
||||
<option value="connection">connection</option>
|
||||
<option value="features">features</option>
|
||||
<option value="interface">interface</option>
|
||||
<option value="settings">settings</option>
|
||||
</select>
|
||||
<button class="btn m-1" onclick="onclickBtn();">Capabilities</button>
|
||||
<pre class="container m-2" id="output">
|
||||
<select id="request_id" class="form-select column">
|
||||
<option value="connection">connection</option>
|
||||
<option value="features">features</option>
|
||||
<option value="interface">interface</option>
|
||||
<option value="settings">settings</option>
|
||||
<option value="extensions">extensions</option>
|
||||
</select>
|
||||
<button class="btn m-1" onclick="onclickBtn();">Capabilities</button>
|
||||
<pre class="container m-2" id="output">
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
45
extensions_samples/extension_settings.html
Normal file
45
extensions_samples/extension_settings.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<script type="text/javascript">
|
||||
function sendMessage(msg) {
|
||||
window.parent.postMessage(msg, '*');
|
||||
}
|
||||
|
||||
function onclickBtn() {
|
||||
const contentTxt = "{'" + document.getElementById('value_name').value + "':'" + document.getElementById('value_data').value + "'}"
|
||||
sendMessage({ type: 'extensionsData', target: 'webui', id: document.getElementById('extension_name').value, content: contentTxt });
|
||||
}
|
||||
|
||||
function processMessage(eventMsg) {
|
||||
if (eventMsg.data.type) {
|
||||
|
||||
if (eventMsg.data.type == "extensionsData") {
|
||||
const line = eventMsg.data.content
|
||||
const resultPanel = document.getElementById("output");
|
||||
let res = JSON.stringify(line.response, " ", "\n")
|
||||
while (res.includes("\n\n")) {
|
||||
res = res.replace("\n\n", "\n");
|
||||
}
|
||||
resultPanel.innerHTML = res;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = (event) => {
|
||||
window.addEventListener("message", processMessage, false);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="extension_name">Extension Name:</label><input class="form-input" id="extension_name"
|
||||
type="text" value="myextension">
|
||||
<label class="form-label" for="value_name">Value Name:</label><input class="form-input" id="value_name" type="text"
|
||||
value="xmax">
|
||||
<label class="form-label" for="value_data">Value:</label><input class="form-input" id="value_data" type="text"
|
||||
value="100">
|
||||
<button class="btn m-1" onclick="onclickBtn();">Save</button>
|
||||
</div>
|
||||
<div id="output"></div>
|
||||
|
||||
</div>
|
||||
@@ -24,7 +24,10 @@ import { machineSettings, iconsTarget } from "../targets"
|
||||
import { ConnectionContainer } from "./connection"
|
||||
import { MainContainer } from "./main"
|
||||
import { useUiContext, useUiContextFn } from "../contexts/UiContext"
|
||||
import { useSettingsContext } from "../contexts/SettingsContext"
|
||||
import {
|
||||
useSettingsContext,
|
||||
useSettingsContextFn,
|
||||
} from "../contexts/SettingsContext"
|
||||
import { useSettings, useHttpQueue } from "../hooks"
|
||||
import { useEffect } from "preact/hooks"
|
||||
import { showLogin, showKeepConnected, showModal } from "../components/Modal"
|
||||
@@ -65,8 +68,12 @@ const ViewContainer = () => {
|
||||
const ContentContainer = () => {
|
||||
let displayIcon = {}
|
||||
const { getConnectionSettings, getInterfaceSettings } = useSettings()
|
||||
const { connectionSettings, interfaceSettings, featuresSettings } =
|
||||
useSettingsContext()
|
||||
const {
|
||||
connectionSettings,
|
||||
interfaceSettings,
|
||||
featuresSettings,
|
||||
extensionsSettings,
|
||||
} = useSettingsContext()
|
||||
const { createNewRequest } = useHttpQueue()
|
||||
const { toasts, modals } = useUiContext()
|
||||
const iconsList = { ...iconsTarget, ...iconsFeather }
|
||||
@@ -381,7 +388,6 @@ const ContentContainer = () => {
|
||||
}
|
||||
break
|
||||
case "icon":
|
||||
console.log(eventMsg.data.id)
|
||||
const iconToSend = iconsFeather[eventMsg.data.id]
|
||||
//Temporary DOM
|
||||
const tempElement = document.createElement("div")
|
||||
@@ -391,7 +397,6 @@ const ContentContainer = () => {
|
||||
const iconSvgString = tempElement.firstChild.outerHTML
|
||||
//Delete the temporary DOM
|
||||
tempElement.remove()
|
||||
console.log(iconSvgString)
|
||||
|
||||
dispatchToExtensions(
|
||||
"icon",
|
||||
@@ -401,35 +406,128 @@ const ContentContainer = () => {
|
||||
},
|
||||
eventMsg.data.id
|
||||
)
|
||||
break
|
||||
case "extensionsData":
|
||||
//Get extension name
|
||||
const section = eventMsg.data.id
|
||||
//Get extensions settings
|
||||
const data = eventMsg.data.content
|
||||
//Some sanity check
|
||||
if (!extensionsSettings.current.extensions) {
|
||||
extensionsSettings.current.extensions = {}
|
||||
}
|
||||
if (!extensionsSettings.current.extensions[section]) {
|
||||
extensionsSettings.current.extensions[section] = {}
|
||||
}
|
||||
//Update the settings
|
||||
//Note: it will overwrite the whole section
|
||||
extensionsSettings.current.extensions[section] = data
|
||||
//now stringify and save
|
||||
const preferencestosave = JSON.stringify(
|
||||
extensionsSettings.current,
|
||||
null,
|
||||
" "
|
||||
)
|
||||
//Create a blob
|
||||
const blob = new Blob([preferencestosave], {
|
||||
type: "application/json",
|
||||
})
|
||||
//Create a file
|
||||
const preferencesFileName =
|
||||
useSettingsContextFn.getValue("HostUploadPath") +
|
||||
"preferences.json"
|
||||
const formDataExtensions = new FormData()
|
||||
const file_to_save = new File([blob], preferencesFileName)
|
||||
formDataExtensions.append(
|
||||
"path",
|
||||
useSettingsContextFn.getValue("HostUploadPath")
|
||||
)
|
||||
formDataExtensions.append("creatPath", "true")
|
||||
formDataExtensions.append(
|
||||
preferencesFileName + "S",
|
||||
preferencestosave.length
|
||||
)
|
||||
formDataExtensions.append(
|
||||
"myfiles",
|
||||
file_to_save,
|
||||
preferencesFileName
|
||||
)
|
||||
//Send the file
|
||||
createNewRequest(
|
||||
espHttpURL(useSettingsContextFn.getValue("HostTarget")),
|
||||
{
|
||||
method: "POST",
|
||||
id: "preferences",
|
||||
body: formDataExtensions,
|
||||
},
|
||||
{
|
||||
onSuccess: (result) => {
|
||||
toasts.addToast({
|
||||
content: T("S62"),
|
||||
type: "success",
|
||||
})
|
||||
dispatchToExtensions(
|
||||
"extensionsData",
|
||||
{
|
||||
response: { status: "success" },
|
||||
initiator: eventMsg.data,
|
||||
},
|
||||
eventMsg.data.id
|
||||
)
|
||||
},
|
||||
onFail: (error) => {
|
||||
toasts.addToast({
|
||||
content: T("S44"),
|
||||
type: "Error",
|
||||
})
|
||||
dispatchToExtensions(
|
||||
"extensionsData",
|
||||
{
|
||||
response: { status: "error" },
|
||||
initiator: eventMsg.data,
|
||||
},
|
||||
eventMsg.data.id
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
break
|
||||
case "capabilities":
|
||||
let response = {}
|
||||
switch (eventMsg.data.id) {
|
||||
case "connection":
|
||||
console.log(connectionSettings.current)
|
||||
response = JSON.parse(
|
||||
JSON.stringify(connectionSettings.current)
|
||||
)
|
||||
break
|
||||
case "settings":
|
||||
console.log(machineSettings)
|
||||
response = JSON.parse(
|
||||
JSON.stringify(machineSettings)
|
||||
)
|
||||
break
|
||||
break
|
||||
case "interface":
|
||||
console.log(interfaceSettings.current)
|
||||
response = JSON.parse(
|
||||
JSON.stringify(interfaceSettings.current)
|
||||
)
|
||||
break
|
||||
case "features":
|
||||
console.log(featuresSettings.current)
|
||||
response = JSON.parse(
|
||||
JSON.stringify(featuresSettings.current)
|
||||
)
|
||||
break
|
||||
case "extensions":
|
||||
if (extensionsSettings.current.extensions) {
|
||||
response = JSON.parse(
|
||||
JSON.stringify(
|
||||
extensionsSettings.current.extensions
|
||||
)
|
||||
)
|
||||
} else {
|
||||
response = "{}"
|
||||
}
|
||||
break
|
||||
default:
|
||||
response = {}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
*/
|
||||
import { h } from "preact"
|
||||
import { webUIbuild } from "../../targets"
|
||||
export const webUIversion = "3.0.0-a61"
|
||||
export const webUIversion = "3.0.0-a62"
|
||||
export const Esp3dVersion = () => (
|
||||
<span>
|
||||
{webUIversion}.{webUIbuild}
|
||||
|
||||
@@ -34,6 +34,7 @@ const SettingsContextProvider = ({ children }) => {
|
||||
const interfaceValues = useRef({})
|
||||
const connectionValues = useRef({})
|
||||
const featuresValues = useRef({})
|
||||
const extensionsValues = useRef({})
|
||||
const pollingInterval = useRef([])
|
||||
useSettingsContextFn.getValue = (val) => connectionValues.current[val]
|
||||
|
||||
@@ -71,6 +72,7 @@ const SettingsContextProvider = ({ children }) => {
|
||||
interfaceSettings: interfaceValues,
|
||||
connectionSettings: connectionValues,
|
||||
featuresSettings: featuresValues,
|
||||
extensionsSettings: extensionsValues,
|
||||
activity: { startPolling, stopPolling },
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ const useSettings = () => {
|
||||
const { createNewRequest } = useHttpQueue()
|
||||
const { toasts, modals, connection, uisettings } = useUiContext()
|
||||
const { processData } = useTargetContextFn
|
||||
const { interfaceSettings, connectionSettings, activity } =
|
||||
const { interfaceSettings, connectionSettings, extensionsSettings, activity } =
|
||||
useSettingsContext()
|
||||
const { defaultRoute, setActiveRoute } = useRouterContext()
|
||||
const sendCommand = (cmd, id) => {
|
||||
@@ -379,6 +379,7 @@ const useSettings = () => {
|
||||
{
|
||||
onSuccess: (result) => {
|
||||
const jsonResult = JSON.parse(result)
|
||||
extensionsSettings.current =JSON.parse(JSON.stringify(jsonResult))
|
||||
const [preferences, haserrors] = importPreferences(
|
||||
defaultPreferences,
|
||||
jsonResult
|
||||
|
||||
@@ -47,7 +47,7 @@ const InterfaceTab = () => {
|
||||
const { toasts, modals, connection } = useUiContext()
|
||||
const { createNewRequest, abortRequest } = useHttpQueue()
|
||||
const { getInterfaceSettings } = useSettings()
|
||||
const { interfaceSettings, connectionSettings } = useSettingsContext()
|
||||
const { interfaceSettings, connectionSettings,extensionsSettings } = useSettingsContext()
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [showSave, setShowSave] = useState(true)
|
||||
const inputFile = useRef(null)
|
||||
@@ -304,8 +304,10 @@ const InterfaceTab = () => {
|
||||
}
|
||||
|
||||
const SaveSettings = () => {
|
||||
const settings_to_save = exportPreferences(interfaceSettings.current, false)
|
||||
settings_to_save.extensions=extensionsSettings.current.extensions
|
||||
const preferencestosave = JSON.stringify(
|
||||
exportPreferences(interfaceSettings.current, false),
|
||||
settings_to_save,
|
||||
null,
|
||||
" "
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user