Skip to content

Commit

Permalink
gluon web2 "5 minute edition"
Browse files Browse the repository at this point in the history
  • Loading branch information
mkg20001 committed Jul 17, 2023
1 parent ff2a5d2 commit 3eb5964
Show file tree
Hide file tree
Showing 10 changed files with 1,273 additions and 22 deletions.
7 changes: 6 additions & 1 deletion package/gluon-web2/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
node_modules
/node_modules
/.parcel-cache
/dist
.DS_Store
yarn-debug.log*
yarn-error.log*
44 changes: 44 additions & 0 deletions package/gluon-web2/dump-network.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
local interfaces = {}
local uci = require('simple-uci').cursor()
local json = require 'jsonc'
local ethernet = require 'gluon.ethernet'

uci:foreach('gluon', 'interface', function(interface)
table.insert(interfaces, interface)
end)

local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' -- You will need this for encoding/decoding
-- encoding
function enc(data)
return ((data:gsub('.', function(x)
local r,b='',x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return b:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end

-- decoding
function dec(data)
data = string.gsub(data, '[^'..b..'=]', '')
return (data:gsub('.', function(x)
if (x == '=') then return '' end
local r,f='',(b:find(x)-1)
for i=6,1,-1 do r=r..(f%2^i-f%2^(i-1)>0 and '1' or '0') end
return r;
end):gsub('%d%d%d?%d?%d?%d?%d?%d?', function(x)
if (#x ~= 8) then return '' end
local c=0
for i=1,8 do c=c+(x:sub(i,i)=='1' and 2^(8-i) or 0) end
return string.char(c)
end))
end

print(enc(json.stringify({
phy_interfaces = ethernet.interfaces(),
uci = interfaces
})))
21 changes: 19 additions & 2 deletions package/gluon-web2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,33 @@
"name": "gluon-web2",
"version": "1.0.0",
"description": "Gluon Web rewritten with Preact and Parcel",
"main": "index.js",
"author": "Gluon Contributors",
"license": "MIT",
"dependencies": {
"preact": "^10.15.1"
},
"scripts": {
"start": "parcel serve --target dev",
"build": "parcel build"
},
"targets": {
"default": {
"source": "src/index.tsx",
"distDir": "bundle"
},
"dev": {
"source": "src/index.html"
}
},
"eslintConfig": {
"extends": "ipfs"
},
"devDependencies": {
"parcel": "^2.9.2",
"@parcel/transformer-sass": "2.9.2",
"@types/jest": "^29.5.2",
"eslint-config-ipfs": "^4.0.3",
"jest": "^29.5.0",
"parcel": "^2.9.2",
"ts-jest": "^29.1.0",
"typescript": "^5.1.3"
}
Expand Down
22 changes: 22 additions & 0 deletions package/gluon-web2/src/GluonWeb2.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Fragment, h } from "preact";
import { useState } from 'preact/hooks';

import Components from "./components"

const GluonWeb2 = ({ id, component, data: initialData }: { id: string, component: string, data: any }) => {
const { data, setData } = useState<any>(initialData)

return (
<Fragment>
<input type="text" style="display: none" name={id} value={JSON.stringify(data)} />,
{
h(Components[component], {
data,
setData
})
}
</Fragment>
)
}

export default GluonWeb2;
4 changes: 4 additions & 0 deletions package/gluon-web2/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import VlanUI from "./vlan-ui"
export default {
"vlan-ui": VlanUI
}
47 changes: 47 additions & 0 deletions package/gluon-web2/src/components/vlan-ui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { h } from "preact";

const ROLES = {
'uplink': 'Uplink',
'mesh': 'Mesh',
'client': 'Client'
}

const VlanUI = ({ data, setData }: { data: any, setData: (data: any) => void }) => {
/* return data.uci.map(intf => {
(
<div>
<label class="gluon-value-title" for="id.1.4.iface_wan_vlan11">{intf.name}</label>
<div class="gluon-value-field">
<div>
<label data-index="1">
{(intf.roles ?? [])}
<input data-update="click change" type="checkbox" id="id.1.4.iface_wan_vlan11.uplink" name="id.1.4.iface_wan_vlan11" value="uplink" data-exclusive-with="[&#34;client&#34;]" data-update="change">
<label for="id.1.4.iface_wan_vlan11.uplink"></label>
<span class="gluon-multi-list-option-descr">Uplink</span>
</label>
&#160;&#160;&#160;
<label data-index="2">
<input data-update="click change" type="checkbox" id="id.1.4.iface_wan_vlan11.mesh" name="id.1.4.iface_wan_vlan11" value="mesh" checked="checked" data-exclusive-with="[&#34;client&#34;]" data-update="change">
<label for="id.1.4.iface_wan_vlan11.mesh"></label>
<span class="gluon-multi-list-option-descr">Mesh</span>
</label>
&#160;&#160;&#160;
<label data-index="3">
<input data-update="click change" type="checkbox" id="id.1.4.iface_wan_vlan11.client" name="id.1.4.iface_wan_vlan11" value="client" data-exclusive-with="[&#34;uplink&#34;,&#34;mesh&#34;]" data-update="change">
<label for="id.1.4.iface_wan_vlan11.client"></label>
<span class="gluon-multi-list-option-descr">Client</span>
</label>
</div>
)
}) */

return <h1>VLANUI {JSON.stringify(data)}</h1>
};

export default VlanUI;
8 changes: 5 additions & 3 deletions package/gluon-web2/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>Parcel Preact Typescript</title>
<link rel="stylesheet" href="../../gluon-config-mode-theme/sass/gluon.scss">
<link rel="stylesheet" href="./main.scss">
<title>Gluon Web v2 Development Render</title>
</head>
<body>
<div id="root"></div>
<script src="./index.tsx"></script>
<gluon-web2 data-component="vlan-ui" data-component-data="eyJwaHlfaW50ZXJmYWNlcyI6WyJ3YW4iLCJsYW40IiwibGFuMiIsImxhbjMiLCJsYW4xIl0sInVjaSI6W3siLm5hbWUiOiJpZmFjZV93YW4iLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJcL3dhbiIsInJvbGUiOlsibm90aGluZyJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoxfSx7Ii5uYW1lIjoiaWZhY2VfbGFuIiwiLnR5cGUiOiJpbnRlcmZhY2UiLCJuYW1lIjoiXC9sYW4iLCJyb2xlIjpbInVwbGluayJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoyfSx7Ii5uYW1lIjoiaWZhY2Vfd2FuX3ZsYW4xMSIsIi50eXBlIjoiaW50ZXJmYWNlIiwibmFtZSI6Indhbi4xMSIsInJvbGUiOlsibWVzaCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4Ijo1fSx7Ii5uYW1lIjoiaWZhY2VfbGFuMV92bGFuMjU1IiwiLnR5cGUiOiJpbnRlcmZhY2UiLCJuYW1lIjoibGFuMS4yNTUiLCJyb2xlIjpbIm1lc2giXSwiLmFub255bW91cyI6ZmFsc2UsIi5pbmRleCI6Nn0seyIubmFtZSI6ImlmYWNlX2xhbjJfdmxhbjI1NSIsIi50eXBlIjoiaW50ZXJmYWNlIiwibmFtZSI6ImxhbjIuMjU1Iiwicm9sZSI6WyJtZXNoIl0sIi5hbm9ueW1vdXMiOmZhbHNlLCIuaW5kZXgiOjd9LHsiLm5hbWUiOiJpZmFjZV9sYW4zX3ZsYW4yNTUiLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJsYW4zLjI1NSIsInJvbGUiOlsibWVzaCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4Ijo4fSx7Ii5uYW1lIjoiaWZhY2VfbGFuNF92bGFuMjU1IiwiLnR5cGUiOiJpbnRlcmZhY2UiLCJuYW1lIjoibGFuNC4yNTUiLCJyb2xlIjpbIm1lc2giXSwiLmFub255bW91cyI6ZmFsc2UsIi5pbmRleCI6OX0seyIubmFtZSI6ImlmYWNlX2xhbjFfdmxhbjMiLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJsYW4xLjMiLCJyb2xlIjpbImNsaWVudCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoxMH0seyIubmFtZSI6ImlmYWNlX2xhbjJfdmxhbjMiLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJsYW4yLjMiLCJyb2xlIjpbImNsaWVudCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoxMX0seyIubmFtZSI6ImlmYWNlX2xhbjNfdmxhbjMiLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJsYW4zLjMiLCJyb2xlIjpbImNsaWVudCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoxMn0seyIubmFtZSI6ImlmYWNlX2xhbjRfdmxhbjMiLCIudHlwZSI6ImludGVyZmFjZSIsIm5hbWUiOiJsYW40LjMiLCJyb2xlIjpbImNsaWVudCJdLCIuYW5vbnltb3VzIjpmYWxzZSwiLmluZGV4IjoxM31dfQ=="></gluon-web2>
<script type="module" src="./index.tsx"></script>
</body>
</html>
65 changes: 63 additions & 2 deletions package/gluon-web2/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,65 @@
import { h, render } from "preact";
import App from "./App";
/* import App from "./App";
render(<App />, document.getElementById("root")!);
render(<App />, document.getElementById("root")!); */

import GluonWeb2 from "./GluonWeb2";

const INSTANCES: Record<string, GluonWeb2Instance> = {}

class GluonWeb2Instance {
readonly el: HTMLElement;
readonly rendered: any;

constructor(el: HTMLElement) {
this.el = el;
const dataset = this.el.dataset

try {
let parsedData = JSON.parse(atob(dataset.componentData))

this.rendered = render(<GluonWeb2
id={dataset.gluonWeb2}
component={dataset.component}
data={parsedData}
/>, this.el)
} catch (error) {
const errEl = document.createElement('p')
errEl.classList.add('web2-error')
el.appendChild(errEl)
errEl.appendChild(document.createTextNode(
JSON.stringify(dataset, null, 2) + ' ' + String(error)
))
}
}

teardown() {

}
}

function findGluonWeb2() {
const nodes = document.querySelectorAll('gluon-web2')

let seen: Record<string, boolean> = {}

for (let i = 0; i < nodes.length; i++) {
let node = nodes[i] as HTMLElement

if (!node.dataset.gluonWeb2) {
node.dataset.gluonWeb2 = String(Math.random())
INSTANCES[node.dataset.gluonWeb2] = new GluonWeb2Instance(node)
}

seen[node.dataset.gluonWeb2] = true
}

for (const key of Object.keys(INSTANCES).filter(k => !seen[k])) {
INSTANCES[key].teardown()
delete INSTANCES[key]
}
}

window.GluonWeb2Refresh = findGluonWeb2

findGluonWeb2()
5 changes: 5 additions & 0 deletions package/gluon-web2/src/main.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.web2-error {
background: #ff000080;
color: black;
padding: 1em;
}
Loading

0 comments on commit 3eb5964

Please sign in to comment.