main
html 172 lines 6.31 KB
Raw
1 <html>
2 <head>
3 <title>Plugin Execute</title>
4 <script type="module">
5 import { store } from "/components/plugins/list/plugin-execute-store.js";
6 </script>
7 </head>
8 <body>
9 <div x-data>
10 <template x-if="$store.pluginExecuteStore">
11 <div x-destroy="$store.pluginExecuteStore.cleanup()"
12 x-create="$el.closest('.modal')?.querySelector('.modal-title') && ($el.closest('.modal').querySelector('.modal-title').textContent = 'Execute: ' + $store.pluginExecuteStore.pluginDisplayName)"
13 class="plugin-execute-root">
14
15 <div class="plugin-execute-idle"
16 x-show="!$store.pluginExecuteStore.running && $store.pluginExecuteStore.exitCode === null && !$store.pluginExecuteStore.output">
17 <x-icon class="idle-icon" name="terminal"></x-icon>
18 <div class="idle-text">
19 <span class="idle-headline">Press <strong>Run</strong> to execute <strong x-text="$store.pluginExecuteStore.pluginDisplayName"></strong></span>
20 <span class="idle-sub">This will run the plugin's <code>execute.py</code> script.</span>
21 <template x-if="$store.pluginExecuteStore.lastExecution">
22 <span class="last-exec-info">
23 Last run:
24 <span x-text="$store.pluginExecuteStore.formatTimestamp($store.pluginExecuteStore.lastExecution.executed_at)"></span>
25 &nbsp;&mdash;&nbsp;
26 <span :class="$store.pluginExecuteStore.lastExecution.exit_code === 0 ? 'exit-ok' : 'exit-err'"
27 x-text="$store.pluginExecuteStore.lastExecution.exit_code === 0 ? 'succeeded' : 'failed (exit ' + $store.pluginExecuteStore.lastExecution.exit_code + ')'">
28 </span>
29 </span>
30 </template>
31 <template x-if="!$store.pluginExecuteStore.lastExecution">
32 <span class="last-exec-info never-run">Never executed</span>
33 </template>
34 </div>
35 </div>
36
37 <div class="plugin-execute-status" x-show="$store.pluginExecuteStore.running">
38 <x-icon class="spin" name="progress_activity"></x-icon>
39 <span>Running execute.py...</span>
40 </div>
41
42 <div class="plugin-execute-exit" x-show="!$store.pluginExecuteStore.running && $store.pluginExecuteStore.exitCode !== null">
43 <x-icon
44 :class="$store.pluginExecuteStore.exitCode === 0 ? 'exit-ok' : 'exit-err'"
45 :name="$store.pluginExecuteStore.exitCode === 0 ? 'check_circle' : 'error'"></x-icon>
46 <span x-text="$store.pluginExecuteStore.exitCode === 0 ? 'Completed successfully (exit 0)' : 'Exited with code ' + $store.pluginExecuteStore.exitCode"></span>
47 </div>
48
49 <pre class="plugin-execute-output"
50 x-show="$store.pluginExecuteStore.output || $store.pluginExecuteStore.running"
51 x-text="$store.pluginExecuteStore.output || ''"></pre>
52 </div>
53 </template>
54 </div>
55
56 <div class="modal-footer" data-modal-footer>
57 <button class="btn btn-action footer-btn"
58 x-data
59 :disabled="$store.pluginExecuteStore?.running"
60 @click="$store.pluginExecuteStore?.run()">
61 <x-icon class="icon" name="play_arrow"></x-icon>
62 <span x-text="$store.pluginExecuteStore?.exitCode !== null || $store.pluginExecuteStore?.output ? 'Rerun' : 'Run'">Run</span>
63 </button>
64 <button class="btn btn-cancel footer-btn" @click="window.closeModal?.()">Close</button>
65 </div>
66
67 <style>
68 .plugin-execute-root {
69 display: flex;
70 flex-direction: column;
71 width: 100%;
72 }
73
74 .plugin-execute-idle {
75 display: flex;
76 align-items: flex-start;
77 gap: 1rem;
78 padding: 2rem 1.5rem;
79 color: var(--color-text-secondary);
80 }
81
82 .idle-icon {
83 font-size: 2.75rem;
84 opacity: 0.35;
85 flex-shrink: 0;
86 margin-top: 0.15rem;
87 }
88
89 .idle-text {
90 display: flex;
91 flex-direction: column;
92 gap: 0.4rem;
93 }
94
95 .idle-headline {
96 font-size: 1rem;
97 color: var(--color-text);
98 line-height: 1.4;
99 }
100
101 .idle-sub {
102 font-size: 0.82rem;
103 opacity: 0.65;
104 }
105
106 .last-exec-info {
107 font-size: 0.8rem;
108 opacity: 0.7;
109 margin-top: 0.25rem;
110 }
111
112 .never-run {
113 font-style: italic;
114 }
115
116 .plugin-execute-status {
117 display: flex;
118 align-items: center;
119 gap: 0.5rem;
120 padding: 0.75rem 1.5rem;
121 color: var(--color-text-secondary);
122 font-size: var(--font-size-small);
123 }
124
125 .plugin-execute-exit {
126 display: flex;
127 align-items: center;
128 gap: 0.5rem;
129 padding: 0.5rem 1.5rem;
130 font-size: var(--font-size-small);
131 }
132
133 .exit-ok {
134 color: var(--color-success, #27ae60);
135 }
136
137 .exit-err {
138 color: var(--color-error, #e74c3c);
139 }
140
141 .plugin-execute-output {
142 font-family: "Courier New", Courier, monospace;
143 font-size: 0.82rem;
144 background: var(--color-bg-secondary, #1e1e1e);
145 color: var(--color-text-primary);
146 padding: 1rem 1.5rem;
147 margin: 0;
148 overflow-y: auto;
149 max-height: 60vh;
150 white-space: pre-wrap;
151 word-break: break-word;
152 border-radius: 6px;
153 }
154
155 @keyframes spin {
156 from { transform: rotate(0deg); }
157 to { transform: rotate(360deg); }
158 }
159
160 .spin {
161 animation: spin 1s linear infinite;
162 }
163
164 .footer-btn {
165 padding: 0.5rem 1.5rem;
166 font-size: 0.875rem;
167 font-weight: 500;
168 border-radius: 0.25rem;
169 }
170 </style>
171 </body>
172 </html>