initial upload

This commit is contained in:
Kai Waggeling 2025-05-17 16:23:48 +02:00
parent ac114da487
commit 7c1cfdff51
63 changed files with 6883 additions and 0 deletions

45
assets/api.js Normal file
View file

@ -0,0 +1,45 @@
const LabelApi = {
async GET(Endpoint)
{
const Response = await fetch(`/api/${Endpoint}`, {
method: "GET"
});
return Response.json();
},
async POST(Endpoint, BodyData = {})
{
const Response = await fetch(`/api/${Endpoint}`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(BodyData)
});
return Response.json();
},
async PUT(Endpoint, BodyData = {})
{
const Response = await fetch(`/api/${Endpoint}`, {
method: "PUT",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(BodyData)
});
return Response.json();
},
async DELETE(Endpoint, BodyData = {})
{
const Response = await fetch(`/api/${Endpoint}`, {
method: "DELETE",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(BodyData)
});
}
}

76
assets/app.media.js Normal file
View file

@ -0,0 +1,76 @@
var App = Vue.createApp({
data() {
return {
mediaList: [],
mediaIndex: null
}
},
methods: {
EditMedium(mediaIndex, showModal = true)
{
this.mediaIndex = mediaIndex;
if (showModal) {
$('#addMediaModal').modal('show');
}
},
CreateMedium()
{
this.mediaList.push({
id: null,
name: 'new medium',
columns: 1,
spacing: 0,
width: 32
})
this.mediaIndex = this.mediaList.length - 1;
$('#addMediaModal').modal('show');
},
async SaveMedium(mediaIndex)
{
if (this.mediaList[mediaIndex].id == null) {
await LabelApi.POST('medium', {
name: this.mediaList[mediaIndex].name,
columns: this.mediaList[mediaIndex].columns,
spacing: this.mediaList[mediaIndex].spacing,
width: this.mediaList[mediaIndex].width
});
} else {
await LabelApi.PUT('medium', {
mediumId: this.mediaList[mediaIndex].id,
name: this.mediaList[mediaIndex].name,
columns: this.mediaList[mediaIndex].columns,
spacing: this.mediaList[mediaIndex].spacing,
width: this.mediaList[mediaIndex].width
});
}
$('#addMediaModal').modal('hide');
await GetMediaList();
},
async DeleteMedium(mediaIndex, finaly = false)
{
if (finaly) {
$('#deleteMediaModal').modal('hide');
await LabelApi.DELETE('medium', {
mediumId: this.mediaList[mediaIndex].id
});
this.mediaIndex = null;
await GetMediaList();
} else {
this.mediaIndex = mediaIndex;
$('#deleteMediaModal').modal('show');
}
}
}
}).mount('main');
async function GetMediaList()
{
let mediaList = await LabelApi.GET(`media`);
App.mediaList = mediaList;
}
GetMediaList();

102
assets/app.printers.js Normal file
View file

@ -0,0 +1,102 @@
var App = Vue.createApp({
data() {
return {
printerList: [],
printerEditor: {
id: null,
name: "",
density: 203,
socket_addr: "",
socket_port: 6101,
type: "zdl"
}
}
},
methods: {
EditPrinter(PrinterID, ShowModal = true)
{
let Printer = this.printerList.find((_Printer) => {
return _Printer.id == PrinterID;
});
this.printerEditor.id = Printer.id;
this.printerEditor.name = Printer.name;
this.printerEditor.density = Printer.density;
this.printerEditor.socket_addr = Printer.socket_addr;
this.printerEditor.socket_port = Printer.socket_port;
if (ShowModal) {
$('#printerSettingsModal').modal('show');
}
},
CreatePrinter()
{
this.printerEditor.id = null;
this.printerEditor.name = "";
this.printerEditor.density = 203;
this.printerEditor.type = "zdl";
this.printerEditor.socket_addr = "";
this.printerEditor.socket_port = 6101;
$('#printerSettingsModal').modal('show');
},
SavePrinter()
{
if (this.printerEditor.id == null)
{
$.ajax({
type: 'POST',
url: `/api/printer`,
data: JSON.stringify(this.printerEditor),
contentType: "application/json"
}).done(function () {
$('#printerSettingsModal').modal('hide');
GetPrinterList();
});
}
else
{
$.ajax({
type: 'PUT',
url: `/api/printer`,
data: JSON.stringify(this.printerEditor),
contentType: "application/json"
}).done(function () {
$('#printerSettingsModal').modal('hide');
GetPrinterList();
});
}
},
DeletePrinter(PrinterID, Confirm = false)
{
this.EditPrinter(PrinterID, false);
if (Confirm) {
$('#printerDeleteModal').modal('hide');
$.ajax({
type: 'DELETE',
url: `/api/printer/${PrinterID}`
}).done(function () {
GetPrinterList();
});
} else {
$('#printerDeleteModal').modal('show');
}
}
}
}).mount('main');
function GetPrinterList() {
$.ajax({
url: `/api/printers`,
type: 'GET',
success: function (Printer) {
App.printerList = Printer;
}
});
}
GetPrinterList();

138
assets/app.queue.js Normal file
View file

@ -0,0 +1,138 @@
var queueApp = Vue.createApp({
data() {
return {
queueData,
templates,
printers,
// SelectedPrinter: null,
LabelData: {
Auftragsnummer: null,
Bezeichnung: null
},
LabelQueue: [],
Settings: {
AutoPrint: false
},
CurrentTemplate: templates[0].id
}
},
methods: {
ContinueFieldInput()
{
console.log("ContinueFieldInput");
let Fields = Object.entries(this.LabelData).map((Field) => {
return {
Key: Field[0],
Value: Field[1]
};
});
Fields = Fields.filter((Field) => {
return Field.Value == null || Field.Value == "";
});
if (Fields.length > 0) {
$(`input[placeholder='${Fields[0].Key}']`).focus();
} else {
this.SaveLabelData()
}
},
SaveLabelData()
{
this.LabelQueue.push({
Fields: {
...this.LabelData
}
});
Object.keys(this.LabelData).forEach((FieldName) => {
this.LabelData[FieldName] = null;
});
$(`input[placeholder='${Object.keys(this.LabelData)[0]}']`).focus();
this.SavePersistent();
},
DeleteLabel(LabelIndex) {
console.log(LabelIndex);
this.LabelQueue.splice(LabelIndex, 1);
this.SavePersistent();
},
SavePersistent()
{
localStorage.setItem('LabelQueue', JSON.stringify(this.LabelQueue));
localStorage.setItem('Settings', JSON.stringify(this.Settings));
},
LoadPersistent()
{
if (localStorage.getItem('LabelQueue') != null) {
this.LabelQueue = JSON.parse(localStorage.getItem('LabelQueue'));
}
if (localStorage.getItem('Settings') != null) {
this.Settings = {
...this.Settings,
...JSON.parse(localStorage.getItem('Settings'))
}
}
},
// Settings
ToggleAutoPrint() {
this.Settings.AutoPrint = !this.Settings.AutoPrint;
this.SavePersistent();
}
}
}).mount('main');
queueApp.LoadPersistent();
async function GetTemplateList() {
let templates = await LabelApi.GET('templates');
queueApp.templates = templates;
}
async function GetPrinterList() {
let printers = await LabelApi.GET('printers');
queueApp.printers = printers;
}
async function GetQueueSettings() {
let queueData = await LabelApi.GET('queue/' + queueApp.queueData.id);
queueApp.queueData = queueData;
}
function GetSelectedPrinter() {
if (localStorage.getItem('SelectedPrinter') == null) {
SetSelectedPrinter([])
}
queueApp.SelectedPrinter = JSON.parse(
localStorage.getItem('SelectedPrinter')
);
}
function SetSelectedPrinter(SelectedPrinter) {
localStorage.setItem('SelectedPrinter', JSON.stringify(SelectedPrinter));
}
function GetLabelQueue() {
if (localStorage.getItem('LabelQueue') == null) {
SetLabelQueue([])
}
queueApp.LabelQueue = JSON.parse(
localStorage.getItem('LabelQueue')
);
}
function SetLabelQueue(LabelQueue) {
localStorage.setItem('LabelQueue', JSON.stringify(LabelQueue));
}
GetPrinterList();
GetLabelQueue();

100
assets/app.queues.js Normal file
View file

@ -0,0 +1,100 @@
var App = Vue.createApp({
data() {
return {
queueList: [],
printerList: [],
queueEditor: {
id: null,
name: "",
printerId: null
}
}
},
methods: {
EditQueue(QueueID, ShowModal = true)
{
let QueueData = this.queueList.find((_Queue) => {
return _Queue.id == QueueID;
});
this.queueEditor.id = QueueData.id;
this.queueEditor.name = QueueData.name;
this.queueEditor.printerId = QueueData.printerId;
if (ShowModal) {
$('#QueueSettingsModal').modal('show');
}
},
CreateQueue()
{
this.queueEditor.id = null;
this.queueEditor.name = "";
this.queueEditor.printerId = null;
$('#QueueSettingsModal').modal('show');
},
async SaveQueue()
{
if (this.queueEditor.id == null)
{
await LabelApi.POST('queue', {
name: this.queueEditor.name,
printerId: this.queueEditor.printerId,
});
GetQueueList();
}
else
{
await LabelApi.PUT('queue', {
id: this.queueEditor.id,
name: this.queueEditor.name,
printerId: this.queueEditor.printerId,
});
GetQueueList();
}
$('#QueueSettingsModal').modal('hide');
},
async DeleteQueue(QueueID, Confirm = false)
{
this.EditQueue(QueueID, false);
if (Confirm) {
$('#QueueDeleteModal').modal('hide');
await LabelApi.DELETE('queue', {
id: QueueID
});
GetQueueList();
} else {
$('#QueueDeleteModal').modal('show');
}
},
GetPrinterById(PrinterID) {
if (PrinterID != null) {
return this.printerList.find((Printer) => {
return Printer.id == PrinterID;
}).name;
} else {
return "Kein Drucker";
}
}
}
}).mount('main');
async function GetQueueList() {
let QueueList = await LabelApi.GET('queues');
App.queueList = QueueList;
}
async function GetPrinterList() {
let PrinterList = await LabelApi.GET('printers');
App.printerList = PrinterList;
}
GetPrinterList();
GetQueueList();

222
assets/app.template.js Normal file
View file

@ -0,0 +1,222 @@
var App = Vue.createApp({
data() {
return {
// LabelEditor: {
// ...LabelData
// },
template,
variableIndex: null,
elementIndex: null
}
},
methods: {
async SaveTemplate() {
await LabelApi.PUT('template', {
templateId: this.template.id,
name: this.template.name,
width: this.template.width,
height: this.template.height
});
let toast = bootstrap.Toast.getOrCreateInstance(toastTemplateSaved)
toast.show()
await GetLabelData();
},
async AddVariable() {
this.template.variables.push({
id: null,
name: 'new variable',
label: 'unknown variable',
regex: '^.*$',
example: '',
default: ''
});
this.variableIndex = this.template.variables.length - 1;
$('#VariableSettingsModal').modal('show');
},
async EditVariable(Index) {
this.variableIndex = Index;
$('#VariableSettingsModal').modal('show');
},
async SaveVariable(Index) {
if (this.template.variables[Index].id == null) {
await LabelApi.POST('variable', {
templateId: this.template.id,
name: this.template.variables[Index].name,
label: this.template.variables[Index].label,
regex: this.template.variables[Index].regex,
example: this.template.variables[Index].example,
default: this.template.variables[Index].default
});
} else {
await LabelApi.PUT('variable', {
variableId: this.template.variables[Index].id,
name: this.template.variables[Index].name,
label: this.template.variables[Index].label,
regex: this.template.variables[Index].regex,
example: this.template.variables[Index].example,
default: this.template.variables[Index].default
});
}
$('#VariableSettingsModal').modal('hide');
await GetLabelData();
},
async DeleteVariable(Index, finaly = false) {
if (finaly) {
$('#DeleteVariableModal').modal('hide');
await LabelApi.DELETE('variable', {
variableId: this.template.variables[Index].id
});
this.variableIndex = null;
await GetLabelData();
} else {
this.variableIndex = Index;
$('#DeleteVariableModal').modal('show');
}
},
async AddElement(ElementType) {
let elementConfig = {};
if (ElementType == 'text') {
elementConfig = {
...elementConfig,
fontType: '0',
fontHeight: 10,
content: '<%- VarName %> or Plain Text'
}
}
if (ElementType == 'box') {
elementConfig = {
...elementConfig,
width: 20,
height: 10,
borderWidth: 1,
borderColor: 'B',
borderRadius: 0
}
}
if (ElementType == 'ellipse') {
elementConfig = {
...elementConfig,
width: 20,
height: 10,
borderWidth: 1,
borderColor: 'B'
}
}
if (ElementType == 'code39') {
elementConfig = {
...elementConfig,
codeHeight: 30,
codeWidth: 2,
widthRatio: 3.0,
content: '<%- VarName %> or Plain Text'
}
}
if (ElementType == 'code128') {
elementConfig = {
...elementConfig,
codeHeight: 30,
codeWidth: 2,
widthRatio: 3.0,
content: '<%- VarName %> or Plain Text'
}
}
this.template.elements.push({
name: 'new ' + ElementType,
type: ElementType,
config: {
originX: 0,
originY: 0,
originAlign: 0,
...elementConfig
}
});
this.elementIndex = this.template.elements.length - 1;
$('#ElementSettingsModal').modal('show');
},
async EditElement(Index) {
this.elementIndex = Index;
$('#ElementSettingsModal').modal('show');
},
async SaveElement(Index) {
if (this.template.elements[Index].id == null) {
await LabelApi.POST('element', {
templateId: this.template.id,
name: this.template.elements[Index].name,
type: this.template.elements[Index].type,
config: this.template.elements[Index].config,
comment: this.template.elements[Index].comment
});
} else {
await LabelApi.PUT('element', {
elementId: this.template.elements[Index].id,
name: this.template.elements[Index].name,
type: this.template.elements[Index].type,
config: this.template.elements[Index].config,
comment: this.template.elements[Index].comment
});
}
$('#ElementSettingsModal').modal('hide');
await GetLabelData();
},
async DeleteElement(Index, finaly = false) {
if (finaly) {
$('#DeleteElementModal').modal('hide');
await LabelApi.DELETE('element', {
elementId: this.template.elements[Index].id
});
this.elementIndex = null;
await GetLabelData();
} else {
this.elementIndex = Index;
$('#DeleteElementModal').modal('show');
}
},
GetElementTypeName(ElementType) {
switch (ElementType) {
case 'text':
return 'Text';
break;
case 'box':
return 'Graphical Box';
break;
case 'ellipse':
return 'Graphical Ellipse';
break;
case 'code39':
return 'Code 39';
break;
case 'code128':
return 'Code 128';
break;
default:
return 'Unknown';
break;
}
}
}
}).mount('main');
async function GetLabelData() {
App.variableIndex = null;
App.elementIndex = null;
let template = await LabelApi.GET(`template/${App.template.id}`);
App.template = template;
}
const toastTemplateSaved = document.getElementById('toast-template-saved')

48
assets/app.templates.js Normal file
View file

@ -0,0 +1,48 @@
var App = Vue.createApp({
data() {
return {
templateList: [],
templateIndex: null
}
},
methods: {
EditTemplate(templateIndex)
{
document.location.href = `/template/${this.templateList[templateIndex].id}`;
},
async CreateTemplate()
{
await LabelApi.POST('medium', {
name: "new template",
width: 10,
height: 10
});
await GetTemplateList();
},
async DeleteTemplate(templateIndex, finaly = false)
{
if (finaly) {
$('#DeleteTemplateModal').modal('hide');
await LabelApi.DELETE('template', {
templateId: this.templateList[templateIndex].id
});
this.templateIndex = null;
await GetTemplateList();
} else {
this.templateIndex = templateIndex;
$('#DeleteTemplateModal').modal('show');
}
}
}
}).mount('main');
async function GetTemplateList() {
let templateList = await LabelApi.GET(`templates`);
App.templateList = templateList;
console.log(templateList);
}
GetTemplateList();

6
assets/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

4
assets/css/tabler-icons.min.css vendored Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

1
assets/img/AO-Logo.svg Normal file
View file

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" viewBox="0 0 75 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><path d="M24.688,21.364c-1.064,3.285 -3.866,9.611 -9.69,9.611c-6.412,-0.285 -8.018,-7.536 -8.018,-11.317c0,-4.197 1.064,-11.878 8.15,-12.09c5.374,-0.165 8.203,5.883 9.393,9.407l8.282,20.814l7.443,0l-11.871,-28.581c-2.783,-6.009 -6.894,-9.208 -12.216,-9.208c-4.765,-0 -8.652,1.745 -11.653,5.242c-3.008,3.496 -4.508,8.196 -4.508,14.112c0,5.354 1.415,9.889 4.23,13.617c2.823,3.728 6.458,5.592 10.907,5.592c5.182,-0 9.644,-2.479 13.154,-8.15l-3.596,-9.036l-0.007,-0.013Z" style="fill:#00b4e5;fill-rule:nonzero;"/><path d="M33.44,17.53l5.764,-16.77l-7.906,0l-2.188,6.326l4.33,10.444Z" style="fill:#00b4e5;fill-rule:nonzero;"/><path d="M52.966,30.512c-2.664,-2.631 -4.832,-7.291 -4.832,-12.764c0,-4.045 0.833,-6.009 2.505,-8.097c1.673,-2.089 3.854,-3.134 6.557,-3.134c2.704,0 5.004,1.085 6.63,3.253c1.626,2.168 2.439,4.091 2.439,7.971c0,5.592 -2.505,10.021 -5.129,12.764l7.489,0c1.877,-2.174 4.885,-6.729 4.885,-13.61c-0,-5.228 -1.553,-9.346 -4.667,-12.361c-3.113,-3.014 -6.993,-4.521 -11.633,-4.521c-4.641,0 -8.501,1.501 -11.621,4.508c-3.12,3.001 -4.68,7.152 -4.68,12.454c0,6.854 3.061,11.369 4.984,13.53l7.093,0l-0.02,0.007Z" style="fill:#33b5b3;fill-rule:nonzero;"/><path d="M59.51,31.755l-0,5.995l12.923,-0l2.511,-5.995l-15.434,-0Z" style="fill:#33b5b3;fill-rule:nonzero;"/><path d="M39.429,31.755l2.399,5.995l13.055,-0l-0,-5.995l-15.454,-0Z" style="fill:#33b5b3;fill-rule:nonzero;"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
assets/img/Favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

49
assets/img/Favicon.svg Normal file
View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="75"
height="75"
viewBox="0 0 75 75"
version="1.1"
xml:space="preserve"
style="clip-rule:evenodd;fill-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2"
id="svg12"
sodipodi:docname="Favicon.svg"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs16" /><sodipodi:namedview
id="namedview14"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="21.373333"
inkscape:cx="37.476606"
inkscape:cy="19.510293"
inkscape:window-width="3840"
inkscape:window-height="2066"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg12" /><path
d="m 24.688,39.364 c -1.064,3.285 -3.866,9.611 -9.69,9.611 C 8.586,48.69 6.98,41.439 6.98,37.658 c 0,-4.197 1.064,-11.878 8.15,-12.09 5.374,-0.165 8.203,5.883 9.393,9.407 l 8.282,20.814 h 7.443 L 28.377,27.208 C 25.594,21.199 21.483,18 16.161,18 11.396,18 7.509,19.745 4.508,23.242 1.5,26.738 0,31.438 0,37.354 c 0,5.354 1.415,9.889 4.23,13.617 2.823,3.728 6.458,5.592 10.907,5.592 5.182,0 9.644,-2.479 13.154,-8.15 l -3.596,-9.036 z"
style="fill:#00b4e5;fill-rule:nonzero"
id="path2" /><path
d="M 33.44,35.53 39.204,18.76 H 31.298 L 29.11,25.086 Z"
style="fill:#00b4e5;fill-rule:nonzero"
id="path4" /><path
d="m 52.966,48.512 c -2.664,-2.631 -4.832,-7.291 -4.832,-12.764 0,-4.045 0.833,-6.009 2.505,-8.097 1.673,-2.089 3.854,-3.134 6.557,-3.134 2.704,0 5.004,1.085 6.63,3.253 1.626,2.168 2.439,4.091 2.439,7.971 0,5.592 -2.505,10.021 -5.129,12.764 h 7.489 c 1.877,-2.174 4.885,-6.729 4.885,-13.61 0,-5.228 -1.553,-9.346 -4.667,-12.361 C 65.73,19.52 61.85,18.013 57.21,18.013 c -4.641,0 -8.501,1.501 -11.621,4.508 -3.12,3.001 -4.68,7.152 -4.68,12.454 0,6.854 3.061,11.369 4.984,13.53 h 7.093 z"
style="fill:#33b5b3;fill-rule:nonzero"
id="path6" /><path
d="m 59.51,49.755 v 5.995 h 12.923 l 2.511,-5.995 z"
style="fill:#33b5b3;fill-rule:nonzero"
id="path8" /><path
d="m 39.429,49.755 2.399,5.995 h 13.055 v -5.995 z"
style="fill:#33b5b3;fill-rule:nonzero"
id="path10" /></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

7
assets/js/bootstrap.bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
assets/js/jquery-3.6.4.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long