zebra-day 0.0.37__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zebra_day/__init__.py +35 -0
- zebra_day/bin/__init__.py +0 -0
- zebra_day/cli/__init__.py +240 -0
- zebra_day/cli/cognito.py +121 -0
- zebra_day/cli/gui.py +338 -0
- zebra_day/cli/printer.py +168 -0
- zebra_day/cli/template.py +176 -0
- zebra_day/cmd_mgr.py +35 -0
- zebra_day/etc/Monoid-Regular-HalfTight-Dollar-0-1-l.ttf +0 -0
- zebra_day/etc/label_styles/blank.zpl +0 -0
- zebra_day/etc/label_styles/cornersStripOf4Squares_1inX1in.zpl +55 -0
- zebra_day/etc/label_styles/corners_1inX2in.zpl +28 -0
- zebra_day/etc/label_styles/corners_20cmX30cm.zpl +6 -0
- zebra_day/etc/label_styles/corners_smallTube.zpl +7 -0
- zebra_day/etc/label_styles/corners_unspecifiedDimensions.zpl +15 -0
- zebra_day/etc/label_styles/generic_2inX1in.zpl +21 -0
- zebra_day/etc/label_styles/plate_1inX0.25in.zpl +9 -0
- zebra_day/etc/label_styles/plate_1inX0.25inHD.zpl +9 -0
- zebra_day/etc/label_styles/smallTubeWdotHD_prod.zpl +8 -0
- zebra_day/etc/label_styles/smallTubeWdot_corners.zpl +7 -0
- zebra_day/etc/label_styles/smallTubeWdot_prod.zpl +8 -0
- zebra_day/etc/label_styles/smallTubeWdot_prodAlt1.zpl +6 -0
- zebra_day/etc/label_styles/smallTubeWdot_prodAlt1b.zpl +3 -0
- zebra_day/etc/label_styles/smallTubeWdot_prodV2.zpl +8 -0
- zebra_day/etc/label_styles/smallTubeWdot_reagent.zpl +29 -0
- zebra_day/etc/label_styles/stripOf4Squares_1inX1in.zpl +32 -0
- zebra_day/etc/label_styles/test_800dX800dCoordinateArray.zpl +1 -0
- zebra_day/etc/label_styles/tmps/.hold +0 -0
- zebra_day/etc/label_styles/tmps/tmp_zpl_templates.here +0 -0
- zebra_day/etc/label_styles/tube_20mmX30mmA.zpl +7 -0
- zebra_day/etc/label_styles/tube_2inX0.3in.zpl +15 -0
- zebra_day/etc/label_styles/tube_2inX0.5in.zpl +15 -0
- zebra_day/etc/label_styles/tube_2inX0.5inHD.zpl +15 -0
- zebra_day/etc/label_styles/tube_2inX1in.zpl +25 -0
- zebra_day/etc/label_styles/tube_2inX1inHD.zpl +22 -0
- zebra_day/etc/label_styles/tube_2inX1inHDv3.zpl +21 -0
- zebra_day/etc/old_printer_config/.hold +0 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.022846_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.033657_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.039597_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.047295_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.055804_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:50:25.061337_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.073326_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.081950_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.088251_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.096501_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.104767_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.110364_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.118239_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.125950_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.349866_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.361085_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.558323_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:24.565756_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.739070_printer_config.json +16 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.753796_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.760201_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.768747_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.775312_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.782533_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.789287_printer_config.json +1 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.794230_printer_config.json +3 -0
- zebra_day/etc/old_printer_config/2026-02-01_01:51:29.800021_printer_config.json +5 -0
- zebra_day/etc/printer_config.json +4 -0
- zebra_day/etc/printer_config.template.json +24 -0
- zebra_day/etc/tmp_printers0.json +5 -0
- zebra_day/etc/tmp_printers120.json +10 -0
- zebra_day/etc/tmp_printers145.json +10 -0
- zebra_day/etc/tmp_printers207.json +10 -0
- zebra_day/etc/tmp_printers374.json +5 -0
- zebra_day/etc/tmp_printers383.json +5 -0
- zebra_day/etc/tmp_printers450.json +5 -0
- zebra_day/etc/tmp_printers469.json +10 -0
- zebra_day/etc/tmp_printers485.json +10 -0
- zebra_day/etc/tmp_printers504.json +5 -0
- zebra_day/etc/tmp_printers531.json +10 -0
- zebra_day/etc/tmp_printers540.json +10 -0
- zebra_day/etc/tmp_printers542.json +10 -0
- zebra_day/etc/tmp_printers552.json +10 -0
- zebra_day/etc/tmp_printers608.json +5 -0
- zebra_day/etc/tmp_printers657.json +5 -0
- zebra_day/etc/tmp_printers715.json +10 -0
- zebra_day/etc/tmp_printers838.json +5 -0
- zebra_day/etc/tmp_printers839.json +5 -0
- zebra_day/etc/tmp_printers933.json +5 -0
- zebra_day/etc/tmp_printers957.json +5 -0
- zebra_day/etc/tmp_printers972.json +10 -0
- zebra_day/exceptions.py +88 -0
- zebra_day/files/.hold +0 -0
- zebra_day/files/blank_preview.png +0 -0
- zebra_day/files/corners_20cmX30cm_preview.png +0 -0
- zebra_day/files/generic_2inX1in_preview.png +0 -0
- zebra_day/files/hold +0 -0
- zebra_day/files/test_png_12020.png +0 -0
- zebra_day/files/test_png_12352.png +0 -0
- zebra_day/files/test_png_15472.png +0 -0
- zebra_day/files/test_png_17696.png +0 -0
- zebra_day/files/test_png_23477.png +0 -0
- zebra_day/files/test_png_24493.png +0 -0
- zebra_day/files/test_png_28157.png +0 -0
- zebra_day/files/test_png_30069.png +0 -0
- zebra_day/files/test_png_35832.png +0 -0
- zebra_day/files/test_png_36400.png +0 -0
- zebra_day/files/test_png_40816.png +0 -0
- zebra_day/files/test_png_47791.png +0 -0
- zebra_day/files/test_png_47799.png +0 -0
- zebra_day/files/test_png_49564.png +0 -0
- zebra_day/files/test_png_53848.png +0 -0
- zebra_day/files/test_png_55588.png +0 -0
- zebra_day/files/test_png_58809.png +0 -0
- zebra_day/files/test_png_62542.png +0 -0
- zebra_day/files/test_png_67242.png +0 -0
- zebra_day/files/test_png_89893.png +0 -0
- zebra_day/files/test_png_91597.png +0 -0
- zebra_day/files/test_png_93633.png +0 -0
- zebra_day/files/tmpbjo3k7q1.png +0 -0
- zebra_day/files/tmpigtr4pwy.png +0 -0
- zebra_day/files/tube_20mmX30mmA_preview.png +0 -0
- zebra_day/files/zpl_label_tube_2inX1in_2026-02-01_01:51:24.370964.png +0 -0
- zebra_day/logging_config.py +74 -0
- zebra_day/logs/.hold +0 -0
- zebra_day/logs/print_requests.log +2 -0
- zebra_day/paths.py +143 -0
- zebra_day/print_mgr.py +557 -117
- zebra_day/static/datschund.css +140 -0
- zebra_day/static/datschund.png +0 -0
- zebra_day/static/daylily.png +0 -0
- zebra_day/static/favicon.svg +20 -0
- zebra_day/static/general.css +99 -0
- zebra_day/static/js/zebra_modern.js +172 -0
- zebra_day/static/lsmc.css +354 -0
- zebra_day/static/moon.jpeg +0 -0
- zebra_day/static/oakland.css +197 -0
- zebra_day/static/petrichor.css +150 -0
- zebra_day/static/popday_daylily.css +140 -0
- zebra_day/static/style.css +183 -0
- zebra_day/static/triangles.css +122 -0
- zebra_day/static/tron.css +277 -0
- zebra_day/static/zebra_modern.css +771 -0
- zebra_day/static/zebras.css +176 -0
- zebra_day/templates/modern/base.html +98 -0
- zebra_day/templates/modern/config.html +141 -0
- zebra_day/templates/modern/config_backups.html +59 -0
- zebra_day/templates/modern/config_editor.html +95 -0
- zebra_day/templates/modern/config_new.html +93 -0
- zebra_day/templates/modern/dashboard.html +160 -0
- zebra_day/templates/modern/print_request.html +145 -0
- zebra_day/templates/modern/print_result.html +88 -0
- zebra_day/templates/modern/printer_detail.html +244 -0
- zebra_day/templates/modern/printers.html +144 -0
- zebra_day/templates/modern/save_result.html +46 -0
- zebra_day/templates/modern/template_editor.html +175 -0
- zebra_day/templates/modern/templates.html +122 -0
- zebra_day/web/__init__.py +9 -0
- zebra_day/web/app.py +248 -0
- zebra_day/web/auth.py +172 -0
- zebra_day/web/middleware.py +159 -0
- zebra_day/web/routers/__init__.py +2 -0
- zebra_day/web/routers/api.py +313 -0
- zebra_day/web/routers/ui.py +636 -0
- zebra_day/zpl_renderer.py +273 -0
- zebra_day-2.0.0.dist-info/METADATA +847 -0
- zebra_day-2.0.0.dist-info/RECORD +168 -0
- {zebra_day-0.0.37.dist-info → zebra_day-2.0.0.dist-info}/WHEEL +1 -1
- zebra_day-2.0.0.dist-info/entry_points.txt +4 -0
- zebra_day/bin/scan_for_networed_zebra_printers.py +0 -23
- zebra_day/bin/te.py +0 -905
- zebra_day/bin/zserve.py +0 -620
- zebra_day-0.0.37.dist-info/METADATA +0 -1177
- zebra_day-0.0.37.dist-info/RECORD +0 -10
- {zebra_day-0.0.37.dist-info → zebra_day-2.0.0.dist-info/licenses}/LICENSE +0 -0
- {zebra_day-0.0.37.dist-info → zebra_day-2.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
{% extends "modern/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Printers - Zebra Day{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<div class="page-header">
|
|
7
|
+
<h1 class="page-title">{% if lab %}{{ lab }} Printers{% else %}All Printers{% endif %}</h1>
|
|
8
|
+
<p class="page-subtitle">View and manage Zebra printers</p>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<!-- Labs Navigation -->
|
|
12
|
+
{% if not lab and labs %}
|
|
13
|
+
<div class="card mb-lg">
|
|
14
|
+
<div class="card-header">
|
|
15
|
+
<h3 class="card-title">Select a Lab</h3>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="grid grid-4">
|
|
18
|
+
{% for lab_name in labs %}
|
|
19
|
+
<a href="/printers/{{ lab_name }}" class="action-card">
|
|
20
|
+
<i class="fas fa-building"></i>
|
|
21
|
+
<div>
|
|
22
|
+
<strong>{{ lab_name }}</strong>
|
|
23
|
+
<small class="text-muted d-block">View printers</small>
|
|
24
|
+
</div>
|
|
25
|
+
</a>
|
|
26
|
+
{% endfor %}
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
|
+
{% endif %}
|
|
30
|
+
|
|
31
|
+
<!-- Printers Table -->
|
|
32
|
+
{% if printers %}
|
|
33
|
+
<div class="card">
|
|
34
|
+
<div class="card-header">
|
|
35
|
+
<h3 class="card-title">Printers{% if lab %} in {{ lab_name | default(lab) }}{% endif %}</h3>
|
|
36
|
+
<a href="/config?action=scan&lab={{ lab | default('') }}" class="btn btn-outline btn-sm">
|
|
37
|
+
<i class="fas fa-sync"></i> Rescan
|
|
38
|
+
</a>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="table-container" style="box-shadow: none;">
|
|
41
|
+
<table class="table">
|
|
42
|
+
<thead>
|
|
43
|
+
<tr>
|
|
44
|
+
<th>Printer</th>
|
|
45
|
+
<th>Location</th>
|
|
46
|
+
<th>IP Address</th>
|
|
47
|
+
<th>Status</th>
|
|
48
|
+
<th>Label Styles</th>
|
|
49
|
+
<th>Actions</th>
|
|
50
|
+
</tr>
|
|
51
|
+
</thead>
|
|
52
|
+
<tbody>
|
|
53
|
+
{% for printer in printers %}
|
|
54
|
+
<tr>
|
|
55
|
+
<td>
|
|
56
|
+
<strong>{{ printer.name }}</strong><br>
|
|
57
|
+
<small class="text-muted">{{ printer.manufacturer | default('zebra') | title }} {{ printer.model | default('Unknown model') }}</small>
|
|
58
|
+
{% if printer.id != printer.name %}
|
|
59
|
+
<br><small class="text-muted">ID: {{ printer.id }}</small>
|
|
60
|
+
{% endif %}
|
|
61
|
+
</td>
|
|
62
|
+
<td>
|
|
63
|
+
{% if printer.lab_location %}
|
|
64
|
+
<span class="badge badge-info">{{ printer.lab_location }}</span>
|
|
65
|
+
{% else %}
|
|
66
|
+
<span class="text-muted">—</span>
|
|
67
|
+
{% endif %}
|
|
68
|
+
</td>
|
|
69
|
+
<td>
|
|
70
|
+
{% if printer.ip_address != 'dl_png' %}
|
|
71
|
+
<a href="http://{{ printer.ip_address }}" target="_blank">{{ printer.ip_address }}</a>
|
|
72
|
+
{% else %}
|
|
73
|
+
<span class="text-muted">{{ printer.ip_address }}</span>
|
|
74
|
+
{% endif %}
|
|
75
|
+
</td>
|
|
76
|
+
<td>
|
|
77
|
+
{% if printer.status == 'online' %}
|
|
78
|
+
<span class="badge badge-success"><i class="fas fa-check-circle"></i> Online</span>
|
|
79
|
+
{% else %}
|
|
80
|
+
<span class="badge badge-error"><i class="fas fa-times-circle"></i> Offline</span>
|
|
81
|
+
{% endif %}
|
|
82
|
+
</td>
|
|
83
|
+
<td>
|
|
84
|
+
{% for style in printer.label_zpl_styles[:3] %}
|
|
85
|
+
<span class="badge badge-primary">{{ style }}</span>
|
|
86
|
+
{% endfor %}
|
|
87
|
+
{% if printer.label_zpl_styles | length > 3 %}
|
|
88
|
+
<span class="text-muted">+{{ printer.label_zpl_styles | length - 3 }} more</span>
|
|
89
|
+
{% endif %}
|
|
90
|
+
</td>
|
|
91
|
+
<td>
|
|
92
|
+
<a href="/printers/{{ lab }}/{{ printer.id }}" class="btn btn-sm btn-outline">
|
|
93
|
+
<i class="fas fa-info-circle"></i> Details
|
|
94
|
+
</a>
|
|
95
|
+
<a href="/print?lab={{ lab }}&printer={{ printer.id }}" class="btn btn-sm btn-primary">
|
|
96
|
+
<i class="fas fa-print"></i> Print
|
|
97
|
+
</a>
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
{% endfor %}
|
|
101
|
+
</tbody>
|
|
102
|
+
</table>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
{% elif lab %}
|
|
106
|
+
<div class="card">
|
|
107
|
+
<div class="empty-state">
|
|
108
|
+
<i class="fas fa-print"></i>
|
|
109
|
+
<p>No printers found in {{ lab }}</p>
|
|
110
|
+
<a href="/config?action=scan&lab={{ lab }}" class="btn btn-primary">
|
|
111
|
+
<i class="fas fa-wifi"></i> Scan Network
|
|
112
|
+
</a>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
{% endif %}
|
|
116
|
+
|
|
117
|
+
<!-- Scan Network Card -->
|
|
118
|
+
<div class="card mt-lg">
|
|
119
|
+
<div class="card-header">
|
|
120
|
+
<h3 class="card-title">Scan Network for Printers</h3>
|
|
121
|
+
</div>
|
|
122
|
+
<form action="/config/scan" method="get" class="grid grid-3">
|
|
123
|
+
<div class="form-group mb-0">
|
|
124
|
+
<label class="form-label">IP Range</label>
|
|
125
|
+
<input type="text" name="ip_stub" class="form-control" value="{{ ip_root | default('192.168.1') }}" placeholder="192.168.1">
|
|
126
|
+
</div>
|
|
127
|
+
<div class="form-group mb-0">
|
|
128
|
+
<label class="form-label">Lab Name</label>
|
|
129
|
+
<input type="text" name="lab" class="form-control" list="lab_names" value="{{ lab | default('') }}" placeholder="Enter lab name">
|
|
130
|
+
<datalist id="lab_names">
|
|
131
|
+
{% for lab_name in labs %}
|
|
132
|
+
<option value="{{ lab_name }}">
|
|
133
|
+
{% endfor %}
|
|
134
|
+
</datalist>
|
|
135
|
+
</div>
|
|
136
|
+
<div class="form-group mb-0" style="display: flex; align-items: flex-end;">
|
|
137
|
+
<button type="submit" class="btn btn-primary">
|
|
138
|
+
<i class="fas fa-search"></i> Scan Network
|
|
139
|
+
</button>
|
|
140
|
+
</div>
|
|
141
|
+
</form>
|
|
142
|
+
</div>
|
|
143
|
+
{% endblock %}
|
|
144
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{% extends "modern/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}{{ title }}{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<div class="page-header">
|
|
7
|
+
<h1 class="page-title">Template Saved</h1>
|
|
8
|
+
<p class="page-subtitle">Your changes have been saved to a draft file</p>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="card">
|
|
12
|
+
<div class="card-header">
|
|
13
|
+
<span class="card-icon text-success"><i class="fas fa-check-circle"></i></span>
|
|
14
|
+
<h3 class="card-title">Success</h3>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<p>Your changes have been saved to a new draft file:</p>
|
|
18
|
+
|
|
19
|
+
<div class="alert alert-info mt-md">
|
|
20
|
+
<i class="fas fa-file-code"></i>
|
|
21
|
+
<code>{{ new_filename }}</code>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<p class="text-muted mt-md">
|
|
25
|
+
Draft files are saved in the <code>tmps/</code> directory. To promote a draft to stable,
|
|
26
|
+
rename the file and move it to the main label_styles directory.
|
|
27
|
+
</p>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="card mt-lg">
|
|
31
|
+
<div class="d-flex" style="justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--spacing-md);">
|
|
32
|
+
<a href="/templates" class="btn btn-outline">
|
|
33
|
+
<i class="fas fa-arrow-left"></i> Back to Templates
|
|
34
|
+
</a>
|
|
35
|
+
<div class="d-flex gap-md">
|
|
36
|
+
<a href="/templates/edit?filename={{ new_filename }}&dtype=tmps" class="btn btn-primary">
|
|
37
|
+
<i class="fas fa-edit"></i> Continue Editing
|
|
38
|
+
</a>
|
|
39
|
+
<a href="/" class="btn btn-outline">
|
|
40
|
+
<i class="fas fa-home"></i> Dashboard
|
|
41
|
+
</a>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
{% endblock %}
|
|
46
|
+
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
{% extends "modern/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Edit: {{ filename }} - Zebra Day{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block extra_head %}
|
|
6
|
+
<style>
|
|
7
|
+
.editor-container { display: grid; grid-template-columns: 1fr 1fr; gap: var(--spacing-lg); }
|
|
8
|
+
.editor-textarea { min-height: 500px; font-family: var(--font-mono); font-size: 14px; }
|
|
9
|
+
.preview-frame { background: var(--color-white); border-radius: var(--radius-md); padding: var(--spacing-lg); min-height: 300px; }
|
|
10
|
+
@media (max-width: 1024px) { .editor-container { grid-template-columns: 1fr; } }
|
|
11
|
+
</style>
|
|
12
|
+
{% endblock %}
|
|
13
|
+
|
|
14
|
+
{% block content %}
|
|
15
|
+
<div class="page-header">
|
|
16
|
+
<h1 class="page-title">Edit: {{ filename }}</h1>
|
|
17
|
+
<p class="page-subtitle">{% if dtype %}Draft template{% else %}Stable template{% endif %}</p>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<!-- Breadcrumb -->
|
|
21
|
+
<div class="mb-lg">
|
|
22
|
+
<a href="/" class="text-muted">Dashboard</a>
|
|
23
|
+
<span class="text-muted"> / </span>
|
|
24
|
+
<a href="/templates">Templates</a>
|
|
25
|
+
<span class="text-muted"> / </span>
|
|
26
|
+
<span>{{ filename }}</span>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<form id="editor-form" action="/save" method="post">
|
|
30
|
+
<input type="hidden" name="filename" value="{{ filename }}">
|
|
31
|
+
|
|
32
|
+
<div class="editor-container">
|
|
33
|
+
<!-- Editor Panel -->
|
|
34
|
+
<div class="card">
|
|
35
|
+
<div class="card-header">
|
|
36
|
+
<h3 class="card-title"><i class="fas fa-code"></i> ZPL Code</h3>
|
|
37
|
+
<button type="button" class="btn btn-outline btn-sm" onclick="previewTemplate()">
|
|
38
|
+
<i class="fas fa-eye"></i> Preview
|
|
39
|
+
</button>
|
|
40
|
+
</div>
|
|
41
|
+
<textarea name="content" id="zpl-editor" class="form-control editor-textarea">{{ content }}</textarea>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<!-- Preview Panel -->
|
|
45
|
+
<div class="card">
|
|
46
|
+
<div class="card-header">
|
|
47
|
+
<h3 class="card-title"><i class="fas fa-image"></i> Preview</h3>
|
|
48
|
+
<span class="badge badge-info" id="preview-status">Ready</span>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="preview-frame" id="preview-container">
|
|
51
|
+
<div class="empty-state">
|
|
52
|
+
<i class="fas fa-image"></i>
|
|
53
|
+
<p>Click Preview to generate</p>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<!-- Save Options -->
|
|
60
|
+
<div class="card mt-lg">
|
|
61
|
+
<div class="card-header">
|
|
62
|
+
<h3 class="card-title">Save Options</h3>
|
|
63
|
+
</div>
|
|
64
|
+
<div class="grid grid-3">
|
|
65
|
+
<div class="form-group mb-0">
|
|
66
|
+
<label class="form-label">Draft Tag</label>
|
|
67
|
+
<input type="text" name="ftag" class="form-control" value="draft" placeholder="Tag for draft version">
|
|
68
|
+
</div>
|
|
69
|
+
<div class="form-group mb-0">
|
|
70
|
+
<label class="form-label">Test Lab</label>
|
|
71
|
+
<select name="lab" class="form-control" id="test-lab" onchange="updateTestPrinters()">
|
|
72
|
+
<option value="">Select lab...</option>
|
|
73
|
+
{% for lab in labs %}
|
|
74
|
+
<option value="{{ lab }}">{{ lab }}</option>
|
|
75
|
+
{% endfor %}
|
|
76
|
+
</select>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="form-group mb-0">
|
|
79
|
+
<label class="form-label">Test Printer</label>
|
|
80
|
+
<select name="printer" class="form-control" id="test-printer">
|
|
81
|
+
<option value="">Select printer...</option>
|
|
82
|
+
</select>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<!-- Actions -->
|
|
88
|
+
<div class="card mt-lg">
|
|
89
|
+
<div class="d-flex" style="justify-content: space-between; align-items: center; flex-wrap: wrap; gap: var(--spacing-md);">
|
|
90
|
+
<a href="/templates" class="btn btn-outline">
|
|
91
|
+
<i class="fas fa-arrow-left"></i> Cancel
|
|
92
|
+
</a>
|
|
93
|
+
<div class="d-flex gap-md">
|
|
94
|
+
<button type="button" class="btn btn-outline" onclick="testPrint()">
|
|
95
|
+
<i class="fas fa-print"></i> Test Print
|
|
96
|
+
</button>
|
|
97
|
+
<button type="submit" class="btn btn-primary">
|
|
98
|
+
<i class="fas fa-save"></i> Save as Draft
|
|
99
|
+
</button>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</form>
|
|
104
|
+
{% endblock %}
|
|
105
|
+
|
|
106
|
+
{% block extra_scripts %}
|
|
107
|
+
<script>
|
|
108
|
+
var labsDict = {{ labs_dict | safe }};
|
|
109
|
+
|
|
110
|
+
function updateTestPrinters() {
|
|
111
|
+
var labSelect = document.getElementById('test-lab');
|
|
112
|
+
var printerSelect = document.getElementById('test-printer');
|
|
113
|
+
var lab = labSelect.value;
|
|
114
|
+
|
|
115
|
+
printerSelect.innerHTML = '<option value="">Select printer...</option>';
|
|
116
|
+
if (lab && labsDict[lab] && labsDict[lab].printers) {
|
|
117
|
+
// v2 schema: printers are nested under 'printers' key
|
|
118
|
+
var printers = labsDict[lab].printers;
|
|
119
|
+
for (var printerId in printers) {
|
|
120
|
+
var printerInfo = printers[printerId];
|
|
121
|
+
var option = document.createElement('option');
|
|
122
|
+
option.value = printerId;
|
|
123
|
+
option.text = printerInfo.printer_name || printerId;
|
|
124
|
+
printerSelect.appendChild(option);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async function previewTemplate() {
|
|
130
|
+
var statusBadge = document.getElementById('preview-status');
|
|
131
|
+
var container = document.getElementById('preview-container');
|
|
132
|
+
var content = document.getElementById('zpl-editor').value;
|
|
133
|
+
|
|
134
|
+
statusBadge.textContent = 'Loading...';
|
|
135
|
+
statusBadge.className = 'badge badge-warning';
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
var response = await fetch('/api/v1/preview_zpl', {
|
|
139
|
+
method: 'POST',
|
|
140
|
+
headers: { 'Content-Type': 'application/json' },
|
|
141
|
+
body: JSON.stringify({ zpl_content: content })
|
|
142
|
+
});
|
|
143
|
+
var data = await response.json();
|
|
144
|
+
if (data.png_url) {
|
|
145
|
+
container.innerHTML = '<img src="' + data.png_url + '" alt="Preview" style="max-width: 100%;">';
|
|
146
|
+
statusBadge.textContent = 'Ready';
|
|
147
|
+
statusBadge.className = 'badge badge-success';
|
|
148
|
+
} else {
|
|
149
|
+
throw new Error(data.error || 'Preview failed');
|
|
150
|
+
}
|
|
151
|
+
} catch (err) {
|
|
152
|
+
container.innerHTML = '<div class="empty-state"><i class="fas fa-exclamation-triangle"></i><p>' + err.message + '</p></div>';
|
|
153
|
+
statusBadge.textContent = 'Error';
|
|
154
|
+
statusBadge.className = 'badge badge-error';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function testPrint() {
|
|
159
|
+
var lab = document.getElementById('test-lab').value;
|
|
160
|
+
var printer = document.getElementById('test-printer').value;
|
|
161
|
+
if (!lab || !printer) {
|
|
162
|
+
showToast('warning', 'Select Printer', 'Please select a lab and printer for test print.');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
var content = document.getElementById('zpl-editor').value;
|
|
166
|
+
var form = document.createElement('form');
|
|
167
|
+
form.method = 'POST';
|
|
168
|
+
form.action = '/api/v1/print_raw_zpl';
|
|
169
|
+
form.innerHTML = '<input name="lab" value="' + lab + '"><input name="printer" value="' + printer + '"><textarea name="zpl_content">' + content + '</textarea>';
|
|
170
|
+
document.body.appendChild(form);
|
|
171
|
+
form.submit();
|
|
172
|
+
}
|
|
173
|
+
</script>
|
|
174
|
+
{% endblock %}
|
|
175
|
+
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{% extends "modern/base.html" %}
|
|
2
|
+
|
|
3
|
+
{% block title %}Templates - Zebra Day{% endblock %}
|
|
4
|
+
|
|
5
|
+
{% block content %}
|
|
6
|
+
<div class="page-header">
|
|
7
|
+
<h1 class="page-title">ZPL Templates</h1>
|
|
8
|
+
<p class="page-subtitle">Manage label templates and styles</p>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="grid grid-2">
|
|
12
|
+
<!-- Stable Templates -->
|
|
13
|
+
<div class="card">
|
|
14
|
+
<div class="card-header">
|
|
15
|
+
<h3 class="card-title">
|
|
16
|
+
<i class="fas fa-check-circle text-success"></i> Stable Templates
|
|
17
|
+
</h3>
|
|
18
|
+
<span class="badge badge-success">{{ stable_templates | length }}</span>
|
|
19
|
+
</div>
|
|
20
|
+
{% if stable_templates %}
|
|
21
|
+
<div class="table-container" style="box-shadow: none;">
|
|
22
|
+
<table class="table">
|
|
23
|
+
<thead>
|
|
24
|
+
<tr>
|
|
25
|
+
<th>Template Name</th>
|
|
26
|
+
<th>Actions</th>
|
|
27
|
+
</tr>
|
|
28
|
+
</thead>
|
|
29
|
+
<tbody>
|
|
30
|
+
{% for template in stable_templates %}
|
|
31
|
+
<tr>
|
|
32
|
+
<td>
|
|
33
|
+
<i class="fas fa-file-code text-muted"></i>
|
|
34
|
+
<strong>{{ template }}</strong>
|
|
35
|
+
</td>
|
|
36
|
+
<td>
|
|
37
|
+
<a href="/templates/edit?filename={{ template }}" class="btn btn-sm btn-outline">
|
|
38
|
+
<i class="fas fa-edit"></i> Edit
|
|
39
|
+
</a>
|
|
40
|
+
<a href="/templates/preview?filename={{ template }}" class="btn btn-sm btn-primary">
|
|
41
|
+
<i class="fas fa-eye"></i> Preview
|
|
42
|
+
</a>
|
|
43
|
+
</td>
|
|
44
|
+
</tr>
|
|
45
|
+
{% endfor %}
|
|
46
|
+
</tbody>
|
|
47
|
+
</table>
|
|
48
|
+
</div>
|
|
49
|
+
{% else %}
|
|
50
|
+
<div class="empty-state">
|
|
51
|
+
<i class="fas fa-file-code"></i>
|
|
52
|
+
<p>No stable templates found</p>
|
|
53
|
+
</div>
|
|
54
|
+
{% endif %}
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<!-- Draft Templates -->
|
|
58
|
+
<div class="card">
|
|
59
|
+
<div class="card-header">
|
|
60
|
+
<h3 class="card-title">
|
|
61
|
+
<i class="fas fa-pencil-alt text-warning"></i> Draft Templates
|
|
62
|
+
</h3>
|
|
63
|
+
<span class="badge badge-warning">{{ draft_templates | length }}</span>
|
|
64
|
+
</div>
|
|
65
|
+
{% if draft_templates %}
|
|
66
|
+
<div class="table-container" style="box-shadow: none;">
|
|
67
|
+
<table class="table">
|
|
68
|
+
<thead>
|
|
69
|
+
<tr>
|
|
70
|
+
<th>Template Name</th>
|
|
71
|
+
<th>Actions</th>
|
|
72
|
+
</tr>
|
|
73
|
+
</thead>
|
|
74
|
+
<tbody>
|
|
75
|
+
{% for template in draft_templates %}
|
|
76
|
+
<tr>
|
|
77
|
+
<td>
|
|
78
|
+
<i class="fas fa-file-alt text-muted"></i>
|
|
79
|
+
<strong>{{ template }}</strong>
|
|
80
|
+
</td>
|
|
81
|
+
<td>
|
|
82
|
+
<a href="/templates/edit?filename={{ template }}&dtype=tmps" class="btn btn-sm btn-outline">
|
|
83
|
+
<i class="fas fa-edit"></i> Edit
|
|
84
|
+
</a>
|
|
85
|
+
<a href="/templates/preview?filename={{ template }}&dtype=tmps" class="btn btn-sm btn-primary">
|
|
86
|
+
<i class="fas fa-eye"></i> Preview
|
|
87
|
+
</a>
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
{% endfor %}
|
|
91
|
+
</tbody>
|
|
92
|
+
</table>
|
|
93
|
+
</div>
|
|
94
|
+
{% else %}
|
|
95
|
+
<div class="empty-state">
|
|
96
|
+
<i class="fas fa-pencil-alt"></i>
|
|
97
|
+
<p>No draft templates yet</p>
|
|
98
|
+
<small class="text-muted">Edit a stable template to create a draft</small>
|
|
99
|
+
</div>
|
|
100
|
+
{% endif %}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<!-- Format Keys Reference -->
|
|
105
|
+
<div class="card mt-lg">
|
|
106
|
+
<div class="card-header">
|
|
107
|
+
<h3 class="card-title">Template Format Keys</h3>
|
|
108
|
+
</div>
|
|
109
|
+
<p class="text-muted mb-lg">Use these placeholders in your ZPL templates to insert dynamic data:</p>
|
|
110
|
+
<div class="grid grid-4">
|
|
111
|
+
<div><code>{uid_barcode}</code> - Barcode value</div>
|
|
112
|
+
<div><code>{alt_a}</code> - Custom field A</div>
|
|
113
|
+
<div><code>{alt_b}</code> - Custom field B</div>
|
|
114
|
+
<div><code>{alt_c}</code> - Custom field C</div>
|
|
115
|
+
<div><code>{alt_d}</code> - Custom field D</div>
|
|
116
|
+
<div><code>{alt_e}</code> - Custom field E</div>
|
|
117
|
+
<div><code>{alt_f}</code> - Custom field F</div>
|
|
118
|
+
<div><code>{rec_date}</code> - Record date</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
{% endblock %}
|
|
122
|
+
|