Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions bin/build-static.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

#------------------------------------------------------------------------------
#- build-static.sh
#- Copies all necessary x0 JavaScript source files and static web assets
#- from /www into the /static directory, preparing it for static deployment.
#-
#- Usage:
#- bin/build-static.sh [OUTPUT_DIR]
#-
#- OUTPUT_DIR defaults to <repo-root>/static when not specified.
#------------------------------------------------------------------------------

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"

WWW_DIR="${REPO_ROOT}/www"
OUTPUT_DIR="${1:-${REPO_ROOT}/static}"

echo "x0 static build"
echo " source : ${WWW_DIR}"
echo " output : ${OUTPUT_DIR}"

mkdir -p "${OUTPUT_DIR}"

#- JavaScript source files
echo " copying JS files ..."
cp -a "${WWW_DIR}"/*.js "${OUTPUT_DIR}/"

#- CSS and font assets (bootstrap, globalstyles, fontawesome)
echo " copying static assets ..."
cp -ra "${WWW_DIR}/static/." "${OUTPUT_DIR}/static/"

#- Favicon and image assets
echo " copying image assets ..."
mkdir -p "${OUTPUT_DIR}/image"
cp -ra "${WWW_DIR}/image/." "${OUTPUT_DIR}/image/"

echo " done."
echo ""
echo " Place your metadata files in ${OUTPUT_DIR}/data/:"
echo " object.json - x0 object definitions"
echo " skeleton.json - x0 screen skeleton"
echo " menu.json - x0 menu definition"
echo " text-data.json - x0 UI text strings"
22 changes: 22 additions & 0 deletions conf/vhost-x0-static.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<VirtualHost *:80>
ServerName x0-static.x0.localnet
ServerAdmin admin@x0.localnet
DocumentRoot /var/www/vhosts/x0-static
LogLevel warn

<Directory /var/www/vhosts/x0-static>
Options -Indexes +FollowSymLinks
AllowOverride None
Require all granted
# Allow POST requests so the x0 JS loader can fetch static JSON data files
AllowMethods GET POST HEAD OPTIONS
</Directory>

# Serve JSON metadata files with correct content type
<FilesMatch "\.json$">
Header set Content-Type "application/json; charset=UTF-8"
</FilesMatch>

ErrorLog /var/log/apache2/x0-static.error.log
CustomLog /var/log/apache2/x0-static.access.log vhost_combined
</VirtualHost>
7 changes: 7 additions & 0 deletions docker/build-x0-static.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

workdir="$(echo $PWD)"

cd ../../
docker build --progress=plain -t x0-static --file ./x0/docker/x0-static.dockerfile . &> x0-build-static.log
cd ${workdir}
10 changes: 10 additions & 0 deletions docker/x0-start-static.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

docker stop x0-static
docker container rm x0-static

docker run -i \
--log-driver=none \
-a stdin -a stdout -a stderr \
--name x0-static \
-p 8080:80 x0-static
39 changes: 39 additions & 0 deletions docker/x0-static.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM ubuntu:24.04
MAINTAINER Claus Prüfer

ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get -qq update -y && \
apt-get -qq install -y apache2

# Copy x0 JS source and static assets for the build step
COPY www/ /build/www/

# Copy static deployment directory (contains index.html and data/ templates)
COPY static/ /build/static/

# Copy the build script
COPY bin/build-static.sh /build/bin/build-static.sh

# Run build: populate /build/static with JS files and web assets from /build/www
RUN chmod +x /build/bin/build-static.sh && \
/build/bin/build-static.sh /build/static

# Deploy static files to the Apache document root
RUN mkdir -p /var/www/vhosts/x0-static && \
cp -ra /build/static/. /var/www/vhosts/x0-static/

# Configure Apache virtual host
COPY conf/vhost-x0-static.conf /etc/apache2/sites-available/x0-static.conf

RUN a2dissite 000-default.conf && \
a2ensite x0-static.conf && \
a2enmod headers allowmethods

CMD ["apache2ctl", "-D", "FOREGROUND"]

EXPOSE 80

LABEL org.opencontainers.image.source=https://github.com/clauspruefer/x0
LABEL org.opencontainers.image.description="x0 docker container image - static variant"
LABEL org.opencontainers.image.licenses=AGPL-3.0-or-later
8 changes: 8 additions & 0 deletions static/data/menu.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"MenuEntry1":
{
"RefID": "sysMenu"
}
}
]
11 changes: 11 additions & 0 deletions static/data/object.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Header1":
{
"Type": "Div",
"Attributes": {
"DOMType": "h1",
"Value": "x0 Static",
"Style": "border rounded p-3 fw-bold"
}
}
}
11 changes: 11 additions & 0 deletions static/data/skeleton.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"Screen1":
[
{
"Header1":
{
"RefID": "Screen1"
}
}
]
}
7 changes: 7 additions & 0 deletions static/data/text-data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"TXT.SYS.OBJECT.DEFAULT.TEXT":
{
"value_de": "Standard Text",
"value_en": "Default Text"
}
}
79 changes: 79 additions & 0 deletions static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<title>x0 Static</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="icon" href="image/favicon-32x32.png" type="image/png">
<link rel="shortcut icon" href="image/favicon-32x32.png" type="image/png">
<link href="static/bootstrap.css" rel="stylesheet">
<link href="static/globalstyles.css" rel="stylesheet">
<link href="static/fontawesome/css/all.min.css" rel="stylesheet">
<script type="text/javascript" src="/userFunctions.js"></script>
<script type="text/javascript" src="/sysHelper.js"></script>
<script type="text/javascript" src="/sysSourceObjectHandler.js"></script>
<script type="text/javascript" src="/sysRequestDataHandler.js"></script>
<script type="text/javascript" src="/sysReactor.js"></script>
<script type="text/javascript" src="/sysRandomNr.js"></script>
<script type="text/javascript" src="/sysBase64.js"></script>
<script type="text/javascript" src="/sysBaseDOMElement.js"></script>
<script type="text/javascript" src="/sysBaseObject.js"></script>
<script type="text/javascript" src="/sysXMLRPCRequest.js"></script>
<script type="text/javascript" src="/sysXMLRPCBaseSyncLoader.js"></script>
<script type="text/javascript" src="/sysJSONData.js"></script>
<script type="text/javascript" src="/sysText.js"></script>
<script type="text/javascript" src="/sysServiceConnector.js"></script>
<script type="text/javascript" src="/sysRTPagination.js"></script>
<script type="text/javascript" src="/sysRTFormSectionHeader.js"></script>
<script type="text/javascript" src="/sysObjLink.js"></script>
<script type="text/javascript" src="/sysObjLinkExternal.js"></script>
<script type="text/javascript" src="/sysObjSQLText.js"></script>
<script type="text/javascript" src="/sysObjDiv.js"></script>
<script type="text/javascript" src="/sysObjContextMenu.js"></script>
<script type="text/javascript" src="/sysScreenOverlay.js"></script>
<script type="text/javascript" src="/sysObjButton.js"></script>
<script type="text/javascript" src="/sysObjButtonInternal.js"></script>
<script type="text/javascript" src="/sysObjButtonCallback.js"></script>
<script type="text/javascript" src="/sysObjFileUpload.js"></script>
<script type="text/javascript" src="/sysObjErrorContainer.js"></script>
<script type="text/javascript" src="/sysFormfieldOnChangeHandler.js"></script>
<script type="text/javascript" src="/sysIntervalHandler.js"></script>
<script type="text/javascript" src="/sysFormfieldValidate.js"></script>
<script type="text/javascript" src="/sysObjFormfieldItem.js"></script>
<script type="text/javascript" src="/sysGlobalData.js"></script>
<script type="text/javascript" src="/sysScreen.js"></script>
<script type="text/javascript" src="/sysObjectLoader.js"></script>
<script type="text/javascript" src="/sysObjList.js"></script>
<script type="text/javascript" src="/sysObjTabContainer.js"></script>
<script type="text/javascript" src="/sysObjFormfieldList.js"></script>
<script type="text/javascript" src="/sysObjDynRadioList.js"></script>
<script type="text/javascript" src="/sysObjOpenCloseContainer.js"></script>
<script type="text/javascript" src="/sysObjTreeSimple.js"></script>
<script type="text/javascript" src="/sysGridGenerator.js"></script>
<script type="text/javascript" src="/sysFactory.js"></script>
<script type="text/javascript" src="/sysAsyncNotify.js"></script>
<script type="text/javascript" src="/sysAsyncNotifyIndicator.js"></script>
<script type="text/javascript" src="/sysAsyncNotifyIndicatorItem.js"></script>
<script type="text/javascript" src="/sysAsyncNotifyMsgHandler.js"></script>
<script>
var sysVarUserSetupClasses = new Object();
var sysVarGlobalData = new Object();
var sysVarUserFunctions = new Array();
var sysVarPreLoadVars = new Object();
var sysVarPreLoadScript = undefined;
var sysVarAppSubdir = "data";
var sysVarConfigMenuFile = "menu.json";
var sysVarConfigObjectFile = "object.json";
var sysVarConfigSkeletonFile = "skeleton.json";
var sysVarTextDataFile = "/data/text-data.json";
var sysVarDisplayDefaultScreen = "Screen1";
var sysVarDebugLevel = 0;
var sysVarParentWindowURL = undefined;
var sysVarDisplayLanguage = "en";
var sysVarScreenConfig = undefined;
var sysVarMessageHandling = false;
</script>
<script type="text/javascript" src="/sysInitOnLoad.js"></script>
</head>
<body onload="Init();">
</body>
</html>
3 changes: 2 additions & 1 deletion www/sysInitOnLoad.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ function InitOk(XHR) {
sysFactory.DataObject.setLoaderObj(sysObjLoader);
sysFactory.DataSkeleton.setLoaderObj(sysObjLoader);

sysFactory.ObjText.requestXMLRPCData('/python/getText.py');
const TextDataURL = (typeof sysVarTextDataFile !== 'undefined') ? sysVarTextDataFile : '/python/getText.py';
sysFactory.ObjText.requestXMLRPCData(TextDataURL);
sysFactory.DataMenu.requestXMLRPCData(sysVarAppSubdir + '/' + sysVarConfigMenuFile);
sysFactory.DataObject.requestXMLRPCData(sysVarAppSubdir + '/' + sysVarConfigObjectFile);
sysFactory.DataSkeleton.requestXMLRPCData(sysVarAppSubdir + '/' + sysVarConfigSkeletonFile);
Expand Down