flock-core 0.4.0b34__py3-none-any.whl → 0.4.0b35__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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

Files changed (47) hide show
  1. flock/__init__.py +27 -5
  2. flock/core/api/main.py +138 -39
  3. flock/webapp/__init__.py +1 -0
  4. flock/webapp/app/__init__.py +0 -0
  5. flock/webapp/app/api/__init__.py +0 -0
  6. flock/webapp/app/api/agent_management.py +270 -0
  7. flock/webapp/app/api/execution.py +173 -0
  8. flock/webapp/app/api/flock_management.py +102 -0
  9. flock/webapp/app/api/registry_viewer.py +30 -0
  10. flock/webapp/app/config.py +9 -0
  11. flock/webapp/app/main.py +571 -0
  12. flock/webapp/app/models_ui.py +7 -0
  13. flock/webapp/app/services/__init__.py +0 -0
  14. flock/webapp/app/services/flock_service.py +291 -0
  15. flock/webapp/app/utils.py +85 -0
  16. flock/webapp/run.py +30 -0
  17. flock/webapp/static/css/custom.css +527 -0
  18. flock/webapp/templates/base.html +98 -0
  19. flock/webapp/templates/flock_editor.html +17 -0
  20. flock/webapp/templates/index.html +12 -0
  21. flock/webapp/templates/partials/_agent_detail_form.html +97 -0
  22. flock/webapp/templates/partials/_agent_list.html +24 -0
  23. flock/webapp/templates/partials/_agent_manager_view.html +15 -0
  24. flock/webapp/templates/partials/_agent_tools_checklist.html +14 -0
  25. flock/webapp/templates/partials/_create_flock_form.html +52 -0
  26. flock/webapp/templates/partials/_dashboard_flock_detail.html +18 -0
  27. flock/webapp/templates/partials/_dashboard_flock_file_list.html +17 -0
  28. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +29 -0
  29. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +17 -0
  30. flock/webapp/templates/partials/_dynamic_input_form_content.html +22 -0
  31. flock/webapp/templates/partials/_execution_form.html +48 -0
  32. flock/webapp/templates/partials/_execution_view_container.html +19 -0
  33. flock/webapp/templates/partials/_flock_file_list.html +24 -0
  34. flock/webapp/templates/partials/_flock_properties_form.html +51 -0
  35. flock/webapp/templates/partials/_flock_upload_form.html +17 -0
  36. flock/webapp/templates/partials/_load_manage_view.html +88 -0
  37. flock/webapp/templates/partials/_registry_table.html +25 -0
  38. flock/webapp/templates/partials/_registry_viewer_content.html +47 -0
  39. flock/webapp/templates/partials/_results_display.html +35 -0
  40. flock/webapp/templates/partials/_sidebar.html +63 -0
  41. flock/webapp/templates/partials/_structured_data_view.html +40 -0
  42. flock/webapp/templates/registry_viewer.html +84 -0
  43. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b35.dist-info}/METADATA +1 -1
  44. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b35.dist-info}/RECORD +47 -7
  45. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b35.dist-info}/WHEEL +0 -0
  46. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b35.dist-info}/entry_points.txt +0 -0
  47. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b35.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,527 @@
1
+ /* Global styles */
2
+ body {
3
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
4
+ display: grid;
5
+ grid-template-columns: 300px 1fr;
6
+ /* Increased sidebar width from 280px to 300px */
7
+ grid-template-rows: auto 1fr auto;
8
+ /* Header, content, footer */
9
+ grid-template-areas:
10
+ "header header"
11
+ "sidebar main"
12
+ "footer footer";
13
+ min-height: 100vh;
14
+ margin: 0;
15
+ background-color: var(--pico-background-color);
16
+ /* Ensure body background is dark too */
17
+ }
18
+
19
+ /* --- Improved Header Styles --- */
20
+ header.top-header {
21
+ grid-area: header;
22
+ border-bottom: 1px solid var(--pico-muted-border-color);
23
+ padding: 0.7rem 1.5rem;
24
+ background-color: var(--pico-card-background-color);
25
+ display: flex;
26
+ justify-content: space-between;
27
+ align-items: center;
28
+ position: fixed;
29
+ top: 0;
30
+ left: 0;
31
+ right: 0;
32
+ z-index: 1001;
33
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
34
+ }
35
+
36
+ header.top-header strong {
37
+ color: white;
38
+ font-weight: 600;
39
+ font-size: 1.2rem;
40
+ letter-spacing: 0.02em;
41
+ }
42
+
43
+ header.top-header small {
44
+ color: rgba(255, 255, 255, 0.7);
45
+ font-size: 0.85rem;
46
+ }
47
+
48
+ header.top-header code {
49
+ background: rgba(255, 255, 255, 0.1);
50
+ color: rgba(255, 255, 255, 0.9);
51
+ padding: 0.2em 0.5em;
52
+ border-radius: 4px;
53
+ font-size: 0.85rem;
54
+ }
55
+
56
+ /* --- End Header Styles --- */
57
+
58
+ main.main-content {
59
+ grid-area: main;
60
+ padding: 1.5rem;
61
+ overflow-y: auto;
62
+ margin-top: 3.5rem;
63
+ background-color: var(--pico-background-color);
64
+ /* Main content area background */
65
+ }
66
+
67
+ footer.main-footer {
68
+ grid-area: footer;
69
+ padding: 0.5rem 1rem;
70
+ border-top: 1px solid rgba(255, 255, 255, 0.07);
71
+ font-size: 0.8em;
72
+ text-align: center;
73
+ z-index: 1;
74
+ background: var(--pico-card-background-color);
75
+ color: rgba(255, 255, 255, 0.6);
76
+ }
77
+
78
+ /* --- Improved Sidebar Styles --- */
79
+ aside.sidebar {
80
+ grid-area: sidebar;
81
+ background: var(--pico-card-background-color);
82
+ padding: 1.5rem 0;
83
+ border-right: 1px solid rgba(255, 255, 255, 0.07);
84
+ margin-top: 3.3rem;
85
+ height: calc(100vh - 3.5rem - 2.1rem);
86
+ position: fixed;
87
+ left: 0;
88
+ bottom: 2.1rem;
89
+ width: 320px;
90
+ /* Increased from 280px to 300px */
91
+ z-index: 1000;
92
+ }
93
+
94
+ .sidebar nav h5 {
95
+
96
+ margin-bottom: 0.9rem;
97
+ padding-left: 1.5rem;
98
+ color: rgba(255, 255, 255, 0.6);
99
+ font-size: 0.85em;
100
+ text-transform: uppercase;
101
+ letter-spacing: 0.08em;
102
+ font-weight: 600;
103
+ }
104
+
105
+ .sidebar nav h5:first-of-type {
106
+ margin-top: 0;
107
+ /* First heading should not have top margin */
108
+ margin-bottom: 0.9rem;
109
+ }
110
+
111
+ .sidebar nav ul {
112
+ padding-left: 0.5rem;
113
+ padding-right: 0.5rem;
114
+ list-style: none;
115
+ margin-bottom: 1.5rem;
116
+ }
117
+
118
+ .sidebar nav li {
119
+ margin-bottom: 0.2rem;
120
+ }
121
+
122
+ .sidebar hr {
123
+ margin: 1.25rem 1.5rem;
124
+ border-color: rgba(255, 255, 255, 0.1);
125
+ opacity: 0.5;
126
+ }
127
+
128
+ /* Links and buttons in sidebar */
129
+ .sidebar nav a,
130
+ .sidebar nav button {
131
+ display: block;
132
+ width: 100%;
133
+ text-align: left;
134
+ margin-bottom: 0;
135
+ padding: 0.7rem 1rem;
136
+ border: none;
137
+ background-color: transparent;
138
+ color: rgba(255, 255, 255, 0.85);
139
+ text-decoration: none;
140
+ border-radius: 8px;
141
+ font-size: 0.9em;
142
+ cursor: pointer;
143
+ transition: all 0.2s ease-in-out;
144
+ font-weight: 500;
145
+ white-space: nowrap;
146
+ /* Prevent text wrapping in menu items */
147
+ overflow: hidden;
148
+ text-overflow: ellipsis;
149
+ }
150
+
151
+ /* Icons in sidebar buttons */
152
+ .sidebar nav a i,
153
+ .sidebar nav button i {
154
+ width: 24px;
155
+ margin-right: 8px;
156
+ text-align: center;
157
+ color: rgba(255, 255, 255, 0.7);
158
+ transition: all 0.2s ease-in-out;
159
+ flex-shrink: 0;
160
+ /* Prevent icon from shrinking */
161
+ }
162
+
163
+ .sidebar nav a:hover i,
164
+ .sidebar nav button:hover i,
165
+ .sidebar nav a.active-nav i,
166
+ .sidebar nav button.active-nav i {
167
+ color: white;
168
+ transform: scale(1.1);
169
+ }
170
+
171
+ /* Remove Pico's default outline styling for buttons if class 'outline' or 'contrast' is used */
172
+ .sidebar nav button.outline,
173
+ .sidebar nav button.contrast {
174
+ border: none;
175
+ background-color: transparent;
176
+ color: rgba(255, 255, 255, 0.85);
177
+ box-shadow: none;
178
+ }
179
+
180
+ .sidebar nav button:focus {
181
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.4);
182
+ }
183
+
184
+ .sidebar nav a:hover,
185
+ .sidebar nav button:hover {
186
+ background-color: rgba(79, 70, 229, 0.15);
187
+ color: #fff;
188
+ transform: translateX(3px);
189
+ }
190
+
191
+ /* Active navigation item */
192
+ .sidebar nav a[aria-current="page"],
193
+ .sidebar nav button[aria-current="page"],
194
+ .sidebar nav a.active-nav,
195
+ .sidebar nav button.active-nav {
196
+ background-color: #4f46e5;
197
+ color: white;
198
+ font-weight: 600;
199
+ box-shadow: 0 4px 12px rgba(79, 70, 229, 0.4);
200
+ }
201
+
202
+ /* --- End Sidebar Styles --- */
203
+
204
+
205
+ /* Message container positioning */
206
+ .message-container {
207
+ position: fixed;
208
+ bottom: 3rem;
209
+ right: 1rem;
210
+ z-index: 1002;
211
+ /* Higher than sidebar */
212
+ width: auto;
213
+ max-width: 400px;
214
+ }
215
+
216
+ .message-container>div {
217
+ margin-top: 0.5rem;
218
+ box-shadow: var(--pico-card-box-shadow);
219
+ display: flex;
220
+ justify-content: space-between;
221
+ align-items: center;
222
+ padding: 0.75rem;
223
+ border-radius: var(--pico-border-radius);
224
+ font-weight: 500;
225
+ }
226
+
227
+ .message-container .success {
228
+ background-color: var(--pico-ins-color);
229
+ color: var(--pico-primary-inverse);
230
+ border: 1px solid var(--pico-ins-color);
231
+ }
232
+
233
+ .message-container .error {
234
+ background-color: var(--pico-del-color);
235
+ color: var(--pico-primary-inverse);
236
+ border: 1px solid var(--pico-del-color);
237
+ }
238
+
239
+ .message-container .close {
240
+ background: none;
241
+ border: none;
242
+ color: inherit;
243
+ font-size: 1.2rem;
244
+ cursor: pointer;
245
+ padding: 0 0.5rem;
246
+ margin-left: 1rem;
247
+ }
248
+
249
+ /* -- Progress & Loading Indicators -- */
250
+ progress {
251
+ border-radius: 10px;
252
+ height: 8px;
253
+ }
254
+
255
+ progress:indeterminate {
256
+ background: rgba(79, 70, 229, 0.2);
257
+ }
258
+
259
+ progress:indeterminate::after {
260
+ background-image: linear-gradient(90deg, rgba(79, 70, 229, 0.2) 0%, #4f46e5 50%, rgba(79, 70, 229, 0.2) 100%);
261
+ }
262
+
263
+ .sidebar progress {
264
+ width: 80%;
265
+ margin: 1rem auto;
266
+ display: block;
267
+ }
268
+
269
+ /* Editor Layout - Agent Manager View */
270
+ .editor-grid {
271
+ display: grid;
272
+ grid-template-columns: minmax(250px, 1fr) 2fr;
273
+ gap: var(--pico-spacing);
274
+ align-items: start;
275
+ }
276
+
277
+ #agent-list-panel,
278
+ #agent-detail-panel {
279
+ height: calc(80vh - var(--pico-block-spacing-vertical) * 2);
280
+ overflow-y: auto;
281
+ }
282
+
283
+ #agent-list-panel article,
284
+ #agent-detail-panel article {
285
+ background-color: var(--pico-card-background-color);
286
+ padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal);
287
+ height: 100%;
288
+ display: flex;
289
+ flex-direction: column;
290
+ }
291
+
292
+ #agent-list-panel header,
293
+ #agent-detail-panel header {
294
+ flex-shrink: 0;
295
+ }
296
+
297
+ #agent-list-panel ul {
298
+ flex-grow: 1;
299
+ overflow-y: auto;
300
+ list-style-type: none;
301
+ padding: 0;
302
+ margin-top: 1rem;
303
+ }
304
+
305
+ #agent-list-panel li {
306
+ padding: 0.75rem;
307
+ border: 1px solid var(--pico-muted-border-color);
308
+ margin-bottom: 0.5rem;
309
+ border-radius: var(--pico-border-radius);
310
+ cursor: pointer;
311
+ transition: background-color 0.2s ease-in-out;
312
+ }
313
+
314
+ #agent-list-panel li:hover,
315
+ #agent-list-panel li.htmx-settling {
316
+ background-color: var(--pico-muted-hover-background-color);
317
+ }
318
+
319
+ #agent-list-panel li.selected-agent {
320
+ background-color: var(--pico-primary-focus);
321
+ border-color: var(--pico-primary);
322
+ color: var(--pico-primary-inverse);
323
+ }
324
+
325
+ #agent-list-panel li small {
326
+ color: var(--pico-muted-color);
327
+ }
328
+
329
+ #agent-list-panel .grid {
330
+ margin-top: auto;
331
+ padding-top: 1rem;
332
+ }
333
+
334
+ /* Agent Detail Form Refinements */
335
+ #agent-detail-panel form {
336
+ flex-grow: 1;
337
+ overflow-y: auto;
338
+ padding-right: 0.5rem;
339
+ }
340
+
341
+ #agent-detail-panel fieldset {
342
+ margin-bottom: 1rem;
343
+ padding-bottom: 0.5rem;
344
+ border-bottom: 1px solid var(--pico-muted-border-color);
345
+ }
346
+
347
+ #agent-detail-panel fieldset:last-of-type {
348
+ border-bottom: none;
349
+ margin-bottom: 0;
350
+ }
351
+
352
+ #agent-detail-form-content .grid {
353
+ margin-top: 1rem;
354
+ flex-shrink: 0;
355
+ }
356
+
357
+ /* Buttons and Forms Styling */
358
+ button[type="submit"],
359
+ button.primary {
360
+ background-color: #4f46e5;
361
+ border-color: #4f46e5;
362
+ box-shadow: 0 4px 12px rgba(79, 70, 229, 0.3);
363
+ }
364
+
365
+ button[type="submit"]:hover,
366
+ button.primary:hover {
367
+ background-color: #4338ca;
368
+ border-color: #4338ca;
369
+ box-shadow: 0 6px 14px rgba(79, 70, 229, 0.4);
370
+ }
371
+
372
+ /* Tool Checklist */
373
+ .tool-checklist {
374
+ max-height: 150px;
375
+ overflow-y: auto;
376
+ border: 1px solid var(--pico-muted-border-color);
377
+ padding: 0.5rem;
378
+ margin-bottom: 0.75rem;
379
+ border-radius: var(--pico-border-radius);
380
+ background-color: var(--pico-form-element-background-color);
381
+ /* Match form input background */
382
+ }
383
+
384
+ .tool-checklist label {
385
+ display: block;
386
+ margin-bottom: 0.25rem;
387
+ font-weight: normal;
388
+ }
389
+
390
+ .tool-checklist input[type="checkbox"] {
391
+ margin-right: 0.5rem;
392
+ }
393
+
394
+ .tool-checklist label small {
395
+ color: var(--pico-muted-color);
396
+ }
397
+
398
+ /* Execution & Results Display */
399
+ #execution-panel article {
400
+ margin-bottom: 1rem;
401
+ }
402
+
403
+ #results-display-container {
404
+ margin-top: 0;
405
+ }
406
+
407
+ #results-display {
408
+ background-color: var(--pico-code-background-color);
409
+ color: var(--pico-code-color);
410
+ padding: 1rem;
411
+ border-radius: var(--pico-border-radius);
412
+ overflow-x: auto;
413
+ margin-top: 1rem;
414
+ min-height: 100px;
415
+ border: 1px solid var(--pico-muted-border-color);
416
+ }
417
+
418
+ #results-display pre {
419
+ margin: 0;
420
+ white-space: pre-wrap;
421
+ word-break: break-all;
422
+ }
423
+
424
+ #results-display .structured-table {
425
+ border: 1px solid var(--pico-muted-border-color);
426
+ font-size: 0.9em;
427
+ width: 100%;
428
+ margin-bottom: 0.75rem !important;
429
+ border-collapse: collapse;
430
+ }
431
+
432
+ #results-display .structured-table td,
433
+ #results-display .structured-table th {
434
+ padding: 0.4em 0.6em !important;
435
+ vertical-align: top;
436
+ border-bottom: 1px solid var(--pico-muted-border-color);
437
+ }
438
+
439
+ #results-display .structured-table tr:last-child td {
440
+ border-bottom: none;
441
+ }
442
+
443
+ #results-display .structured-table td[style*="font-weight: bold"] {
444
+ color: var(--pico-secondary);
445
+ min-width: 120px;
446
+ max-width: 250px;
447
+ word-break: break-word;
448
+ border-right: 1px solid var(--pico-muted-border-color);
449
+ }
450
+
451
+ #results-display .structured-table ul {
452
+ margin-left: 1em;
453
+ padding-left: 1em;
454
+ }
455
+
456
+ /* HTMX Indicators */
457
+ .htmx-indicator {
458
+ display: none;
459
+ opacity: 0;
460
+ transition: opacity 0.3s ease-in-out;
461
+ }
462
+
463
+ .htmx-request .htmx-indicator {
464
+ display: inline-block;
465
+ opacity: 1;
466
+ margin-left: 0.5em;
467
+ }
468
+
469
+ .htmx-request.htmx-indicator {
470
+ display: inline-block;
471
+ opacity: 1;
472
+ }
473
+
474
+ /* Registry Viewer Specific */
475
+ #registry-page-content nav ul[role="group"] {
476
+ margin-bottom: 1rem;
477
+ }
478
+
479
+ #registry-page-content nav ul[role="group"] li button {
480
+ width: 100%;
481
+ }
482
+
483
+ #registry-table-container table {
484
+ margin-top: 1rem;
485
+ }
486
+
487
+ /* Utility for form field errors */
488
+ .field-error {
489
+ color: var(--pico-del-color);
490
+ font-size: var(--pico-font-size-small);
491
+ margin-top: -0.5rem;
492
+ margin-bottom: 0.5rem;
493
+ }
494
+
495
+ /* Main content headings - ensure consistent vertical alignment */
496
+ main.main-content h1 {
497
+ font-size: 2rem;
498
+ margin-top: 0;
499
+ margin-bottom: 1.5rem;
500
+ color: white;
501
+ font-weight: 600;
502
+ line-height: 1.2;
503
+ }
504
+
505
+ main.main-content h2 {
506
+ font-size: 1.75rem;
507
+ margin-top: 0;
508
+ margin-bottom: 1.25rem;
509
+ color: white;
510
+ font-weight: 600;
511
+ line-height: 1.2;
512
+ }
513
+
514
+ main.main-content h3 {
515
+ font-size: 1.5rem;
516
+ margin-top: 0;
517
+ margin-bottom: 1rem;
518
+ color: white;
519
+ font-weight: 600;
520
+ line-height: 1.2;
521
+ }
522
+
523
+ /* Panel titles styling for consistency */
524
+ .panel-title {
525
+ margin-top: 0;
526
+ margin-bottom: 1.25rem;
527
+ }
@@ -0,0 +1,98 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" data-theme="dark">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>{% block title %}Flock UI{% endblock %}</title>
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
9
+ <link rel="stylesheet" href="/static/css/custom.css">
10
+ <!-- Font Awesome for icons -->
11
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
12
+ <script src="https://unpkg.com/htmx.org@1.9.10"
13
+ integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
14
+ crossorigin="anonymous"></script>
15
+ <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
16
+ <!-- Removed inline styles as they're in custom.css -->
17
+ </head>
18
+
19
+ <body>
20
+ <header class="top-header">
21
+ <span><strong>🐧 Flock UI 🐤</strong></span>
22
+ {# Use the variables passed from the route handler #}
23
+ {% if current_flock %}
24
+ <small>Current: <code>{{ current_filename or current_flock.name }}</code></small>
25
+ {% else %}
26
+ <small>No Flock Loaded</small>
27
+ {% endif %}
28
+ </header>
29
+
30
+ <aside class="sidebar" hx-get="/ui/htmx/sidebar?ui_mode={{ ui_mode }}"
31
+ hx-trigger="load, flockLoaded from:body, flockListChanged from:body" hx-swap="innerHTML">
32
+ <p>Loading navigation...</p><progress></progress>
33
+ </aside>
34
+
35
+ <main class="main-content" id="main-content-area">
36
+ {# Initial content is now loaded via HTMX based on the route #}
37
+ <div hx-get="{{ initial_content_url }}" hx-trigger="load" hx-swap="innerHTML">
38
+ <p>Loading content...</p><progress></progress>
39
+ </div>
40
+ {# Render block content if navigating directly and template extends base #}
41
+ {% block content %}{% endblock %}
42
+ </main>
43
+
44
+ <div class="message-container" x-data="messageHandler(
45
+ {{ success_message | tojson | safe if success_message else 'null' }},
46
+ {{ error_message | tojson | safe if error_message else 'null' }}
47
+ )">
48
+ <template x-if="showSuccess && successMsg">
49
+ <div class="success" role="alert" @click="showSuccess = false" style="cursor: pointer;">
50
+ <span x-text="successMsg"></span>
51
+ <button type="button" class="close" aria-label="Dismiss">×</button>
52
+ </div>
53
+ </template>
54
+ <template x-if="showError && errorMsg">
55
+ <div class="error" role="alert" @click="showError = false" style="cursor: pointer;">
56
+ <span x-text="errorMsg"></span>
57
+ <button type="button" class="close" aria-label="Dismiss">×</button>
58
+ </div>
59
+ </template>
60
+ </div>
61
+
62
+ <footer class="main-footer">
63
+ <small>Built with FastAPI, HTMX, Pico.CSS by 🤍 white duck 🦆</small>
64
+ </footer>
65
+
66
+ <script>
67
+ function messageHandler(initialSuccessMsg, initialErrorMsg) {
68
+ return {
69
+ showSuccess: !!initialSuccessMsg,
70
+ showError: !!initialErrorMsg,
71
+ successMsg: initialSuccessMsg,
72
+ errorMsg: initialErrorMsg,
73
+ init() {
74
+ if (this.successMsg) { setTimeout(() => this.showSuccess = false, 5000); }
75
+ if (this.errorMsg) { setTimeout(() => this.showError = false, 7000); }
76
+
77
+ window.addEventListener('notify', event => {
78
+ if (event.detail.type === 'success') {
79
+ this.successMsg = event.detail.message;
80
+ this.showSuccess = true; this.showError = false;
81
+ setTimeout(() => this.showSuccess = false, 5000);
82
+ }
83
+ if (event.detail.type === 'error') {
84
+ this.errorMsg = event.detail.message;
85
+ this.showError = true; this.showSuccess = false;
86
+ setTimeout(() => this.showError = false, 7000);
87
+ }
88
+ });
89
+ }
90
+ };
91
+ }
92
+ function triggerEvent(eventName, detail = {}) {
93
+ htmx.trigger(document.body, eventName, detail);
94
+ }
95
+ </script>
96
+ </body>
97
+
98
+ </html>
@@ -0,0 +1,17 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Flock Editor - {{ flock.name if flock else 'Loading...' }}{% endblock %}
4
+
5
+ {% block content %}
6
+ {# Main content area is now loaded dynamically based on sidebar clicks #}
7
+ {# We can load the properties form by default when this page is hit #}
8
+ <div id="editor-main-content"
9
+ hx-get="/api/flocks/htmx/flock-properties-form"
10
+ hx-trigger="load"
11
+ hx-swap="innerHTML">
12
+ <article>
13
+ <p>Loading editor content...</p>
14
+ <progress></progress>
15
+ </article>
16
+ </div>
17
+ {% endblock %}
@@ -0,0 +1,12 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Flock UI - Dashboard{% endblock %}
4
+
5
+ {% block content %}
6
+ {# This content will be loaded dynamically via HTMX from the sidebar #}
7
+ {# We can load the 'load/manage' view by default #}
8
+ <div id="dashboard-content" hx-get="/ui/htmx/load-flock-view" hx-trigger="load" hx-swap="innerHTML">
9
+ <p>Loading dashboard content...</p>
10
+ <progress></progress>
11
+ </div>
12
+ {% endblock %}