citrascope 0.8.0__py3-none-any.whl → 0.9.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.
- citrascope/hardware/abstract_astro_hardware_adapter.py +17 -0
- citrascope/hardware/adapter_registry.py +5 -0
- citrascope/hardware/devices/camera/abstract_camera.py +12 -0
- citrascope/hardware/devices/camera/usb_camera.py +20 -15
- citrascope/hardware/devices/camera/ximea_camera.py +22 -10
- citrascope/hardware/direct_hardware_adapter.py +21 -3
- citrascope/hardware/dummy_adapter.py +202 -0
- citrascope/time/__init__.py +2 -1
- citrascope/time/time_health.py +8 -1
- citrascope/time/time_monitor.py +27 -5
- citrascope/time/time_sources.py +199 -0
- citrascope/web/app.py +31 -9
- citrascope/web/static/app.js +118 -988
- citrascope/web/static/components.js +136 -0
- citrascope/web/static/config.js +209 -505
- citrascope/web/static/formatters.js +129 -0
- citrascope/web/static/store-init.js +204 -0
- citrascope/web/static/style.css +5 -0
- citrascope/web/templates/_config.html +175 -0
- citrascope/web/templates/_config_hardware.html +208 -0
- citrascope/web/templates/_monitoring.html +242 -0
- citrascope/web/templates/dashboard.html +69 -442
- {citrascope-0.8.0.dist-info → citrascope-0.9.0.dist-info}/METADATA +2 -1
- {citrascope-0.8.0.dist-info → citrascope-0.9.0.dist-info}/RECORD +27 -20
- {citrascope-0.8.0.dist-info → citrascope-0.9.0.dist-info}/WHEEL +0 -0
- {citrascope-0.8.0.dist-info → citrascope-0.9.0.dist-info}/entry_points.txt +0 -0
- {citrascope-0.8.0.dist-info → citrascope-0.9.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Alpine.js Component Definitions for CitraScope Dashboard
|
|
3
|
+
*
|
|
4
|
+
* Reusable component functions for common UI patterns.
|
|
5
|
+
* These components reduce template complexity and improve maintainability.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Adapter field component - handles rendering different field types
|
|
10
|
+
* (boolean, select, number, text) with appropriate validation and styling
|
|
11
|
+
* @param {Object} field - The field object from adapterFields
|
|
12
|
+
*/
|
|
13
|
+
export function adapterField(field) {
|
|
14
|
+
return {
|
|
15
|
+
field: field,
|
|
16
|
+
|
|
17
|
+
get inputId() {
|
|
18
|
+
if (!this.field || !this.field.name) return '';
|
|
19
|
+
return 'adapter_' + this.field.name;
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
get isBoolean() {
|
|
23
|
+
if (!this.field) return false;
|
|
24
|
+
return this.field.type === 'bool';
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
get isSelect() {
|
|
28
|
+
if (!this.field) return false;
|
|
29
|
+
return this.field.type !== 'bool' &&
|
|
30
|
+
this.field.options &&
|
|
31
|
+
Array.isArray(this.field.options) &&
|
|
32
|
+
this.field.options.length > 0;
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
get isNumber() {
|
|
36
|
+
if (!this.field) return false;
|
|
37
|
+
return this.field.type !== 'bool' &&
|
|
38
|
+
(!this.field.options || this.field.options.length === 0) &&
|
|
39
|
+
(this.field.type === 'int' || this.field.type === 'float');
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
get isText() {
|
|
43
|
+
return !this.isBoolean && !this.isSelect && !this.isNumber;
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
handleChange(event) {
|
|
47
|
+
if (!this.field) return;
|
|
48
|
+
|
|
49
|
+
if (this.field.type === 'int') {
|
|
50
|
+
this.field.value = parseInt(event.target.value, 10);
|
|
51
|
+
} else if (this.field.type === 'float') {
|
|
52
|
+
this.field.value = parseFloat(event.target.value);
|
|
53
|
+
} else {
|
|
54
|
+
this.field.value = event.target.value;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Reload schema if device type changed
|
|
58
|
+
if (this.field.name && ['camera_type', 'mount_type', 'filter_wheel_type', 'focuser_type'].includes(this.field.name)) {
|
|
59
|
+
this.$store.citrascope.reloadAdapterSchema?.();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Task row component - displays a single task in the queue table
|
|
67
|
+
* with active/inactive status styling
|
|
68
|
+
* @param {Object} task - The task object
|
|
69
|
+
*/
|
|
70
|
+
export function taskRow(task) {
|
|
71
|
+
return {
|
|
72
|
+
task: task,
|
|
73
|
+
|
|
74
|
+
get isActive() {
|
|
75
|
+
if (!this.task || !this.task.id) return false;
|
|
76
|
+
return this.task.id === this.$store.citrascope.currentTaskId;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
get statusBadgeClass() {
|
|
80
|
+
return this.isActive ? 'bg-success' : 'bg-info';
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
get statusText() {
|
|
84
|
+
if (!this.task) return '';
|
|
85
|
+
return this.isActive ? 'Active' : (this.task.status || '');
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
get rowClass() {
|
|
89
|
+
return this.isActive ? 'table-active' : '';
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Filter row component - displays a single filter configuration row
|
|
96
|
+
* with colored badge styling
|
|
97
|
+
* @param {Object} filter - The filter object
|
|
98
|
+
* @param {string} filterId - The filter ID
|
|
99
|
+
*/
|
|
100
|
+
export function filterRow(filter, filterId) {
|
|
101
|
+
return {
|
|
102
|
+
filter: filter,
|
|
103
|
+
filterId: filterId,
|
|
104
|
+
|
|
105
|
+
get badgeStyle() {
|
|
106
|
+
if (!this.filter || !this.filter.color) return 'background-color: gray; color: white;';
|
|
107
|
+
return `background-color: ${this.filter.color}; color: white;`;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Log entry component - displays a single log message
|
|
114
|
+
* with formatted timestamp and stripped ANSI codes
|
|
115
|
+
* @param {Object} log - The log entry object
|
|
116
|
+
*/
|
|
117
|
+
export function logEntry(log) {
|
|
118
|
+
return {
|
|
119
|
+
log: log,
|
|
120
|
+
|
|
121
|
+
get timestamp() {
|
|
122
|
+
if (!this.log || !this.log.timestamp) return '';
|
|
123
|
+
return new Date(this.log.timestamp).toLocaleTimeString();
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
get levelClass() {
|
|
127
|
+
if (!this.log || !this.log.level) return '';
|
|
128
|
+
return 'log-level-' + this.log.level;
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
get strippedMessage() {
|
|
132
|
+
if (!this.log || !this.log.message) return '';
|
|
133
|
+
return this.$store.citrascope.stripAnsiCodes(this.log.message);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|