]> OzVa Git service - delta-velorum/commitdiff
Build updater for TS & start of admin page template
authorMax Value <greenwoodw50@gmail.com>
Mon, 30 Mar 2026 14:46:58 +0000 (15:46 +0100)
committerMax Value <greenwoodw50@gmail.com>
Mon, 30 Mar 2026 14:46:58 +0000 (15:46 +0100)
16 files changed:
.gitignore
director/__init__.py
director/src/price.ts [new file with mode: 0644]
director/src/text.ts [new file with mode: 0644]
director/src/title.ts [deleted file]
director/src/update.ts
director/static/style.css [new file with mode: 0644]
director/templates/admin.html [new file with mode: 0644]
director/templates/admin/list.html [new file with mode: 0644]
director/templates/admin/number.html [new file with mode: 0644]
director/templates/admin/select.html [new file with mode: 0644]
director/templates/admin/text.html [new file with mode: 0644]
director/templates/admin/textarea.html [new file with mode: 0644]
director/templates/index.html
requirements.txt
tsconfig.json

index 3d43339293004eaa6de63cf66c6ef986a0922141..a44e81e4f541c5eeaa34d1e34b907351fdd69c59 100644 (file)
@@ -1,2 +1,3 @@
 build/
 __pycache__/
+data/
index dd366a61b8b0ed72c540561b3992dd923077378f..58b1e7af8f7ea49f0ab43e1531252eccf0610879 100644 (file)
@@ -1,10 +1,9 @@
 from flask import Flask, render_template, send_from_directory
+from flask_socketio import SocketIO, emit
 import os
 
 app = Flask(__name__, instance_relative_config=False)
-app.config.from_mapping(
-       DATABASE=os.path.join(app.root_path, 'flaskr.sqlite')
-)
+socketio = SocketIO(app, logger=True, engineio_logger=True)
 
 @app.route("/", methods=['get'])
 def index():
@@ -13,3 +12,9 @@ def index():
 @app.route("/script/<path:filename>", methods=["get"])
 def script(filename):
        return send_from_directory(os.path.join(app.root_path, "build"), filename)
+
+@app.route("/test")
+def test():
+       #emit("update", ["data__product", {"data":{"product":{"currentPrice":100}}}], json=True, namespace="/", broadcast=True)
+
+       return ""
diff --git a/director/src/price.ts b/director/src/price.ts
new file mode 100644 (file)
index 0000000..e91bd50
--- /dev/null
@@ -0,0 +1,31 @@
+const unstablePriceChance: number = 0.7;
+
+export function renderPrice(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("price");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2));
+                       }
+               }
+       }
+}
+
+export function renderUnstablePrice(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("unstablePrice");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               if (Math.random() < unstablePriceChance) {
+                                       e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2));
+                               } else {
+                                       e.innerHTML = String(parseFloat(e.dataset.raw));
+                               }
+                       }
+               }
+       }
+}
diff --git a/director/src/text.ts b/director/src/text.ts
new file mode 100644 (file)
index 0000000..d7a6032
--- /dev/null
@@ -0,0 +1,10 @@
+export function renderText(): void {
+       const el = document.querySelectorAll(".text,.title");
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = e.dataset.raw;
+                       }
+               }
+       }
+}
diff --git a/director/src/title.ts b/director/src/title.ts
deleted file mode 100644 (file)
index 123811b..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-export default function renderTitle(): void {
-       const el: HTMLCollectionOf<Element> = document.getElementsByClassName("title");
-
-       for (let e of el) {
-               console.log(e);
-       }
-}
index fa3dfc59733f076d8c8ec72b5192a884c205d57c..275921d2fb0010a76be0d88c4ab8e621c449f847 100644 (file)
@@ -1,8 +1,37 @@
-import renderTitle from "./title.js";
-export {};
+import { renderText } from "./text.js";
+import { renderPrice, renderUnstablePrice } from "./price.js"
+import { io } from "socket.io-client";
 
-function update(): void {
-       renderTitle();
+// apply a number of sequential keys to an object
+function objectPath(obj: any, path: string[]): any {
+       let key: string|undefined = path.shift();
+       if (typeof key === "undefined") {
+               return obj
+       } else {
+               return objectPath(obj[key], path)
+       }
 }
 
-update();
+export default function setupUpdate(): void {
+       const socket = io();
+       socket.on("update", ([namespace, data]) => {
+               const el = document.querySelectorAll(`.update[class*='${namespace}']`);
+
+               for (let e of el) {
+                       let c: string|undefined = Array.from(e.classList)
+                               .find((c) => c.startsWith(namespace))
+
+                       if (typeof c === "string") {
+                               let path = c.split("__");
+                               let result = objectPath(data, path);
+
+                               if (typeof result !== "undefined" && e instanceof HTMLElement) {
+                                       e.dataset.raw = result;
+                               }
+                       }
+               }
+
+               renderPrice();
+               renderUnstablePrice();
+       })
+}
diff --git a/director/static/style.css b/director/static/style.css
new file mode 100644 (file)
index 0000000..892f158
--- /dev/null
@@ -0,0 +1 @@
+title { text-transform: capitalize; }
diff --git a/director/templates/admin.html b/director/templates/admin.html
new file mode 100644 (file)
index 0000000..ab7de6b
--- /dev/null
@@ -0,0 +1,12 @@
+{#
+
+       builds the admin page
+
+#}
+<html>
+       <body>
+               <form>
+                       {% include "admin/list.html" %}
+               <form>
+       </body>
+</html>
diff --git a/director/templates/admin/list.html b/director/templates/admin/list.html
new file mode 100644 (file)
index 0000000..a5788c5
--- /dev/null
@@ -0,0 +1,18 @@
+{#
+
+       interates through the state variable and includes the relevant template for
+       each element. not tested more than double nested
+
+#}
+{% for element in state %}
+       {% if element.tag == "textarea" %}
+               {% include "admin/textarea.html" %}
+       {% elif element.tag == "select" %}
+               {% include "admin/select.html" %}
+       {% elif element.tag == "text" %}
+               {% include "admin/text.html" %}
+       {% elif element.tag == "number" %}
+               {% include "admin/number.html" %}
+       {% endif %}
+       <br>
+{% endfor %}
diff --git a/director/templates/admin/number.html b/director/templates/admin/number.html
new file mode 100644 (file)
index 0000000..6beaef2
--- /dev/null
@@ -0,0 +1,2 @@
+<label>{{ element.name }}</label><br>
+<input type="number" name="{{ element.name }}" value="{{ element.text }}" />
diff --git a/director/templates/admin/select.html b/director/templates/admin/select.html
new file mode 100644 (file)
index 0000000..0fe6770
--- /dev/null
@@ -0,0 +1,10 @@
+<details>
+    <summary>{{ element.name }}</summary>
+       <input type="radio" name="{{ element.name }}" value="soup" checked />
+       <div style="display: inline-block; vertical-align: middle;">
+               {% block list %}
+                       {% set state = element.elements %}
+                       {% include "admin/list.html" %}
+               {% endblock %}
+       </div>
+</details>
diff --git a/director/templates/admin/text.html b/director/templates/admin/text.html
new file mode 100644 (file)
index 0000000..3ea4709
--- /dev/null
@@ -0,0 +1,3 @@
+<label>{{ element.name }}</label><br>
+<input type="text" name="{{ element.name }}" value="{{ element.text }}" />
+
diff --git a/director/templates/admin/textarea.html b/director/templates/admin/textarea.html
new file mode 100644 (file)
index 0000000..f22eb50
--- /dev/null
@@ -0,0 +1,4 @@
+<label>{{ element.name }}</label><br>
+<textarea name="{{ element.name }}">
+       {{- element.default -}}
+</textarea>
index f1e077152be5911a360a7ef678c1ee3b230e63f3..5f9cbf819ebfe417d4de81ea7b40f80a722ec948 100644 (file)
@@ -1,9 +1,22 @@
 <!doctype html>
 <html>
        <head>
-               <script type="text/javascript" type="module" src="/script/update.js" defer></script>
+               <link rel="stylesheet" href="/static/style.css">
+               <script type="importmap">
+               {
+                       "imports": {
+                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
+                       }
+               }
+               </script>
+               <script type="module" defer>
+
+import setupUpdate from "/script/update.js";
+setupUpdate();
+
+               </script>
        </head>
        <body>
-               <span class="update root__product__current-price"></span>
+               <span class="update data__product__currentPrice unstablePrice">This is some text</span>
        </body>
 </html>
index 7e1060246fd6746a14204539a72e199a25469a05..34b5c1d90469217d2f016857a034a24e505c8311 100644 (file)
@@ -1 +1,2 @@
+flask_socketio
 flask
index e0bf5b80859f0207e40072d07b101b170056e4c1..3c138d242b1065b655efa0e4d021e2b7f220acd1 100644 (file)
@@ -1,45 +1,15 @@
 {
-  // Visit https://aka.ms/tsconfig to read more about this file
-  "include": ["./director/src"],
+  "include": ["./director/src","./director/static"],
+
   "compilerOptions": {
-    // File Layout
     "rootDir": "./director/src",
     "outDir": "./director/build",
 
-    // Environment Settings
-    // See also https://aka.ms/tsconfig/module
-    "module": "nodenext",
+    "module": "esnext",
     "target": "esnext",
-    "types": [],
-    // For nodejs:
-    // "lib": ["esnext"],
-    // "types": ["node"],
-    // and npm install -D @types/node
-
-    // Other Outputs
-    "sourceMap": true,
-    "declaration": true,
-    "declarationMap": true,
-
-    // Stricter Typechecking Options
-    "noUncheckedIndexedAccess": true,
-    "exactOptionalPropertyTypes": true,
-
-    // Style Options
-    // "noImplicitReturns": true,
-    // "noImplicitOverride": true,
-    // "noUnusedLocals": true,
-    // "noUnusedParameters": true,
-    // "noFallthroughCasesInSwitch": true,
-    // "noPropertyAccessFromIndexSignature": true,
 
-    // Recommended Options
-    "strict": true,
-    "jsx": "react-jsx",
-    "verbatimModuleSyntax": false,
-    "isolatedModules": true,
-    "noUncheckedSideEffectImports": true,
-    "moduleDetection": "force",
-    "skipLibCheck": true,
+    "allowJs": true,
+    "checkJs": false,
+    "resolveJsonModule": true
   }
 }