Flowfile 0.3.0__py3-none-any.whl → 0.3.0.2__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 Flowfile might be problematic. Click here for more details.
- flowfile/__init__.py +13 -6
- flowfile/__main__.py +50 -15
- flowfile/api.py +383 -0
- flowfile/readme.md +130 -0
- flowfile/web/__init__.py +155 -0
- flowfile/web/static/assets/AirbyteReader-1ac35765.css +314 -0
- flowfile/web/static/assets/AirbyteReader-cb0c1d4a.js +921 -0
- flowfile/web/static/assets/CrossJoin-41efa4cb.css +100 -0
- flowfile/web/static/assets/CrossJoin-a514fa59.js +153 -0
- flowfile/web/static/assets/DatabaseConnectionSettings-0c04b2e5.css +77 -0
- flowfile/web/static/assets/DatabaseConnectionSettings-f2cecf33.js +151 -0
- flowfile/web/static/assets/DatabaseManager-30fa27e5.css +64 -0
- flowfile/web/static/assets/DatabaseManager-83ee3c98.js +484 -0
- flowfile/web/static/assets/DatabaseReader-dc0c6881.js +426 -0
- flowfile/web/static/assets/DatabaseReader-f50c6558.css +158 -0
- flowfile/web/static/assets/DatabaseWriter-2f570e53.css +96 -0
- flowfile/web/static/assets/DatabaseWriter-5afe9f8d.js +312 -0
- flowfile/web/static/assets/ExploreData-5bdae813.css +45 -0
- flowfile/web/static/assets/ExploreData-c7ee19cf.js +118306 -0
- flowfile/web/static/assets/ExternalSource-17b23a01.js +225 -0
- flowfile/web/static/assets/ExternalSource-e37b6275.css +94 -0
- flowfile/web/static/assets/Filter-90856b4f.js +238 -0
- flowfile/web/static/assets/Filter-a9d08ba1.css +20 -0
- flowfile/web/static/assets/Formula-38b71e9e.js +197 -0
- flowfile/web/static/assets/Formula-d60a74f4.css +17 -0
- flowfile/web/static/assets/FuzzyMatch-6857de82.css +254 -0
- flowfile/web/static/assets/FuzzyMatch-d0f1fe81.js +422 -0
- flowfile/web/static/assets/GoogleSheet-854294a4.js +2616 -0
- flowfile/web/static/assets/GoogleSheet-92084da7.css +233 -0
- flowfile/web/static/assets/GraphSolver-0c86bbc6.js +382 -0
- flowfile/web/static/assets/GraphSolver-17fd26db.css +68 -0
- flowfile/web/static/assets/GroupBy-ab1ea74b.css +51 -0
- flowfile/web/static/assets/GroupBy-f2772e9f.js +413 -0
- flowfile/web/static/assets/Join-41c0f331.css +109 -0
- flowfile/web/static/assets/Join-bc3e1cf7.js +247 -0
- flowfile/web/static/assets/ManualInput-03aa0245.js +391 -0
- flowfile/web/static/assets/ManualInput-ac7b9972.css +84 -0
- flowfile/web/static/assets/Output-48f81019.css +2642 -0
- flowfile/web/static/assets/Output-5b35eee8.js +536 -0
- flowfile/web/static/assets/Pivot-7164087c.js +408 -0
- flowfile/web/static/assets/Pivot-f415e85f.css +35 -0
- flowfile/web/static/assets/PolarsCode-3abf6507.js +2863 -0
- flowfile/web/static/assets/PolarsCode-650322d1.css +35 -0
- flowfile/web/static/assets/PopOver-b37ff9be.js +577 -0
- flowfile/web/static/assets/PopOver-bccfde04.css +32 -0
- flowfile/web/static/assets/Read-65966a3e.js +701 -0
- flowfile/web/static/assets/Read-80dc1675.css +197 -0
- flowfile/web/static/assets/RecordCount-c66c6d6d.js +121 -0
- flowfile/web/static/assets/RecordId-826dc095.js +339 -0
- flowfile/web/static/assets/Sample-4ed555c8.js +184 -0
- flowfile/web/static/assets/SecretManager-eac1e97d.js +382 -0
- flowfile/web/static/assets/Select-085f05cc.js +231 -0
- flowfile/web/static/assets/SettingsSection-1f5e79c1.js +87 -0
- flowfile/web/static/assets/SettingsSection-9c836ecc.css +47 -0
- flowfile/web/static/assets/Sort-3e6cb414.js +309 -0
- flowfile/web/static/assets/Sort-7ccfa0fe.css +51 -0
- flowfile/web/static/assets/TextToRows-606349bc.js +307 -0
- flowfile/web/static/assets/TextToRows-c92d1ec2.css +48 -0
- flowfile/web/static/assets/UnavailableFields-5edd5322.css +49 -0
- flowfile/web/static/assets/UnavailableFields-b41976ed.js +36 -0
- flowfile/web/static/assets/Union-8d9ac7f9.css +30 -0
- flowfile/web/static/assets/Union-fca91665.js +145 -0
- flowfile/web/static/assets/Unique-a59f830e.js +273 -0
- flowfile/web/static/assets/Unique-b5615727.css +51 -0
- flowfile/web/static/assets/Unpivot-246e9bbd.css +77 -0
- flowfile/web/static/assets/Unpivot-c3815565.js +441 -0
- flowfile/web/static/assets/airbyte-292aa232.png +0 -0
- flowfile/web/static/assets/api-22b338bd.js +60 -0
- flowfile/web/static/assets/cross_join-d30c0290.png +0 -0
- flowfile/web/static/assets/database_reader-ce1e55f3.svg +24 -0
- flowfile/web/static/assets/database_writer-b4ad0753.svg +23 -0
- flowfile/web/static/assets/designer-2394122a.css +10697 -0
- flowfile/web/static/assets/designer-e5bbe26f.js +69712 -0
- flowfile/web/static/assets/documentation-08045cf2.js +33 -0
- flowfile/web/static/assets/documentation-12216a74.css +50 -0
- flowfile/web/static/assets/dropDown-35135ba8.css +143 -0
- flowfile/web/static/assets/dropDown-5e7e9a5a.js +319 -0
- flowfile/web/static/assets/dropDownGeneric-50a91b99.js +72 -0
- flowfile/web/static/assets/dropDownGeneric-895680d6.css +10 -0
- flowfile/web/static/assets/element-icons-9c88a535.woff +0 -0
- flowfile/web/static/assets/element-icons-de5eb258.ttf +0 -0
- flowfile/web/static/assets/explore_data-8a0a2861.png +0 -0
- flowfile/web/static/assets/fa-brands-400-808443ae.ttf +0 -0
- flowfile/web/static/assets/fa-brands-400-d7236a19.woff2 +0 -0
- flowfile/web/static/assets/fa-regular-400-54cf6086.ttf +0 -0
- flowfile/web/static/assets/fa-regular-400-e3456d12.woff2 +0 -0
- flowfile/web/static/assets/fa-solid-900-aa759986.woff2 +0 -0
- flowfile/web/static/assets/fa-solid-900-d2f05935.ttf +0 -0
- flowfile/web/static/assets/fa-v4compatibility-0ce9033c.woff2 +0 -0
- flowfile/web/static/assets/fa-v4compatibility-30f6abf6.ttf +0 -0
- flowfile/web/static/assets/filter-d7708bda.png +0 -0
- flowfile/web/static/assets/formula-eeeb1611.png +0 -0
- flowfile/web/static/assets/fullEditor-178376bb.css +256 -0
- flowfile/web/static/assets/fullEditor-705c6ccb.js +630 -0
- flowfile/web/static/assets/fuzzy_match-40c161b2.png +0 -0
- flowfile/web/static/assets/genericNodeSettings-65587f20.js +137 -0
- flowfile/web/static/assets/genericNodeSettings-924759c7.css +46 -0
- flowfile/web/static/assets/graph_solver-8b7888b8.png +0 -0
- flowfile/web/static/assets/group_by-80561fc3.png +0 -0
- flowfile/web/static/assets/index-552863fd.js +58652 -0
- flowfile/web/static/assets/index-681a3ed0.css +8843 -0
- flowfile/web/static/assets/input_data-ab2eb678.png +0 -0
- flowfile/web/static/assets/join-349043ae.png +0 -0
- flowfile/web/static/assets/manual_input-ae98f31d.png +0 -0
- flowfile/web/static/assets/nodeTitle-cf9bae3c.js +227 -0
- flowfile/web/static/assets/nodeTitle-f4b12bcb.css +134 -0
- flowfile/web/static/assets/old_join-5d0eb604.png +0 -0
- flowfile/web/static/assets/output-06ec0371.png +0 -0
- flowfile/web/static/assets/pivot-9660df51.png +0 -0
- flowfile/web/static/assets/polars_code-05ce5dc6.png +0 -0
- flowfile/web/static/assets/record_count-dab44eb5.png +0 -0
- flowfile/web/static/assets/record_id-0b15856b.png +0 -0
- flowfile/web/static/assets/sample-693a88b5.png +0 -0
- flowfile/web/static/assets/secretApi-3ad510e1.js +46 -0
- flowfile/web/static/assets/select-b0d0437a.png +0 -0
- flowfile/web/static/assets/selectDynamic-b062bc9b.css +107 -0
- flowfile/web/static/assets/selectDynamic-bd644891.js +302 -0
- flowfile/web/static/assets/sort-2aa579f0.png +0 -0
- flowfile/web/static/assets/summarize-2a099231.png +0 -0
- flowfile/web/static/assets/text_to_rows-859b29ea.png +0 -0
- flowfile/web/static/assets/union-2d8609f4.png +0 -0
- flowfile/web/static/assets/unique-1958b98a.png +0 -0
- flowfile/web/static/assets/unpivot-d3cb4b5b.png +0 -0
- flowfile/web/static/assets/view-7a0f0be1.png +0 -0
- flowfile/web/static/assets/vue-codemirror.esm-dd17b478.js +22281 -0
- flowfile/web/static/assets/vue-content-loader.es-6b36f05e.js +210 -0
- flowfile/web/static/flowfile.svg +47 -0
- flowfile/web/static/icons/flowfile.png +0 -0
- flowfile/web/static/images/airbyte.png +0 -0
- flowfile/web/static/images/flowfile.svg +47 -0
- flowfile/web/static/images/google.svg +1 -0
- flowfile/web/static/images/sheets.png +0 -0
- flowfile/web/static/index.html +22 -0
- flowfile/web/static/vite.svg +1 -0
- flowfile/web/static/vue.svg +1 -0
- flowfile-0.3.0.2.dist-info/METADATA +235 -0
- {flowfile-0.3.0.dist-info → flowfile-0.3.0.2.dist-info}/RECORD +147 -15
- {flowfile-0.3.0.dist-info → flowfile-0.3.0.2.dist-info}/entry_points.txt +1 -1
- flowfile_core/configs/settings.py +7 -32
- flowfile_core/flowfile/FlowfileFlow.py +4 -2
- flowfile_core/flowfile/analytics/analytics_processor.py +1 -1
- flowfile_core/main.py +4 -1
- flowfile_core/schemas/input_schema.py +1 -8
- flowfile_frame/__init__.py +0 -1
- flowfile_frame/utils.py +0 -139
- flowfile-0.3.0.dist-info/METADATA +0 -219
- flowfile_frame/__main__.py +0 -12
- {flowfile-0.3.0.dist-info → flowfile-0.3.0.2.dist-info}/LICENSE +0 -0
- {flowfile-0.3.0.dist-info → flowfile-0.3.0.2.dist-info}/WHEEL +0 -0
flowfile/web/__init__.py
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"""
|
|
2
|
+
flowfile/web/__init__.py
|
|
3
|
+
Web interface for Flowfile.
|
|
4
|
+
Extends the flowfile_core FastAPI app to serve the Vue.js frontend
|
|
5
|
+
and includes worker functionality.
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
import webbrowser
|
|
11
|
+
import asyncio
|
|
12
|
+
from fastapi import FastAPI, Response
|
|
13
|
+
from fastapi.staticfiles import StaticFiles
|
|
14
|
+
from fastapi.responses import FileResponse, RedirectResponse
|
|
15
|
+
|
|
16
|
+
static_dir = Path(__file__).parent / "static"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def extend_app(app: FastAPI):
|
|
20
|
+
"""
|
|
21
|
+
Extend the flowfile_core FastAPI app with routes to serve the Vue.js frontend
|
|
22
|
+
and worker functionality.
|
|
23
|
+
"""
|
|
24
|
+
# Serve static files if the directory exists
|
|
25
|
+
if static_dir.exists():
|
|
26
|
+
# Mount the assets directory
|
|
27
|
+
if (static_dir / "assets").exists():
|
|
28
|
+
app.mount("/assets", StaticFiles(directory=str(static_dir / "assets")), name="assets")
|
|
29
|
+
|
|
30
|
+
# Mount other common directories
|
|
31
|
+
for dir_name in ["css", "js", "img", "fonts", "icons", "images"]:
|
|
32
|
+
dir_path = static_dir / dir_name
|
|
33
|
+
if dir_path.exists() and dir_path.is_dir():
|
|
34
|
+
app.mount(f"/{dir_name}", StaticFiles(directory=str(dir_path)), name=dir_name)
|
|
35
|
+
|
|
36
|
+
@app.get("/favicon.ico", include_in_schema=False)
|
|
37
|
+
async def favicon():
|
|
38
|
+
"""Serve the favicon.ico file"""
|
|
39
|
+
favicon_path = static_dir / "favicon.ico"
|
|
40
|
+
if favicon_path.exists():
|
|
41
|
+
return FileResponse(favicon_path)
|
|
42
|
+
return Response(status_code=404)
|
|
43
|
+
|
|
44
|
+
@app.get("/flowfile.svg", include_in_schema=False)
|
|
45
|
+
async def svg_logo():
|
|
46
|
+
"""Serve the SVG logo file"""
|
|
47
|
+
svg_path = static_dir / "flowfile.svg"
|
|
48
|
+
if svg_path.exists():
|
|
49
|
+
return FileResponse(svg_path, media_type="image/svg+xml")
|
|
50
|
+
return Response(status_code=404)
|
|
51
|
+
|
|
52
|
+
@app.get("/test")
|
|
53
|
+
async def get_worker_host():
|
|
54
|
+
from flowfile_core.configs.settings import WORKER_URL
|
|
55
|
+
return WORKER_URL
|
|
56
|
+
|
|
57
|
+
@app.get("/ui", include_in_schema=False)
|
|
58
|
+
async def web_ui_root():
|
|
59
|
+
"""Serve the main index.html file for the web UI"""
|
|
60
|
+
index_path = static_dir / "index.html"
|
|
61
|
+
if index_path.exists():
|
|
62
|
+
return FileResponse(index_path)
|
|
63
|
+
return {"error": "Web UI not installed. Build the frontend and install it in the package."}
|
|
64
|
+
|
|
65
|
+
@app.get("/ui/{path:path}", include_in_schema=False)
|
|
66
|
+
async def serve_vue_app(path: str):
|
|
67
|
+
"""Serve static files or the index.html for client-side routing"""
|
|
68
|
+
# Try to serve the requested file
|
|
69
|
+
file_path = static_dir / path
|
|
70
|
+
if file_path.exists() and file_path.is_file():
|
|
71
|
+
return FileResponse(file_path)
|
|
72
|
+
|
|
73
|
+
# If it's a directory, redirect to add trailing slash
|
|
74
|
+
if (static_dir / path).exists() and (static_dir / path).is_dir():
|
|
75
|
+
return RedirectResponse(f"/ui/{path}/")
|
|
76
|
+
|
|
77
|
+
# For client-side routing, serve the index.html
|
|
78
|
+
index_path = static_dir / "index.html"
|
|
79
|
+
if index_path.exists():
|
|
80
|
+
return FileResponse(index_path)
|
|
81
|
+
|
|
82
|
+
return {"error": f"File not found: {path}"}
|
|
83
|
+
|
|
84
|
+
# Include worker routes if simplified mode is enabled
|
|
85
|
+
include_worker_routes(app)
|
|
86
|
+
|
|
87
|
+
return app
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def include_worker_routes(app: FastAPI):
|
|
91
|
+
"""
|
|
92
|
+
Include worker routes from flowfile_worker for simplified deployments.
|
|
93
|
+
This creates a unified API that serves both the web UI and processes the worker operations.
|
|
94
|
+
"""
|
|
95
|
+
try:
|
|
96
|
+
# Import worker modules
|
|
97
|
+
from flowfile_worker.routes import router as worker_router
|
|
98
|
+
from flowfile_worker import mp_context, CACHE_DIR
|
|
99
|
+
|
|
100
|
+
# Add lifecycle event handler for worker cleanup
|
|
101
|
+
@app.on_event("shutdown")
|
|
102
|
+
async def shutdown_worker():
|
|
103
|
+
"""Clean up worker resources on shutdown"""
|
|
104
|
+
print("Cleaning up worker resources...")
|
|
105
|
+
for p in mp_context.active_children():
|
|
106
|
+
try:
|
|
107
|
+
p.terminate()
|
|
108
|
+
p.join()
|
|
109
|
+
except Exception as e:
|
|
110
|
+
print(f"Error cleaning up process: {e}")
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
CACHE_DIR.cleanup()
|
|
114
|
+
except Exception as e:
|
|
115
|
+
print(f"Error cleaning up cache directory: {e}")
|
|
116
|
+
|
|
117
|
+
await asyncio.sleep(0.1)
|
|
118
|
+
|
|
119
|
+
# Include the worker router with a prefix
|
|
120
|
+
app.include_router(worker_router, prefix="/worker")
|
|
121
|
+
|
|
122
|
+
print("Worker functionality included in unified API")
|
|
123
|
+
|
|
124
|
+
except ImportError as e:
|
|
125
|
+
print(f"Worker module could not be imported, running without worker functionality: {e}")
|
|
126
|
+
print("This is normal for lightweight deployments that don't need data processing.")
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def start_server(host="127.0.0.1", port=63578, open_browser=True):
|
|
130
|
+
"""
|
|
131
|
+
Start the flowfile_core FastAPI app with the web UI routes and worker functionality.
|
|
132
|
+
This function is a wrapper around flowfile_core.main.run().
|
|
133
|
+
"""
|
|
134
|
+
# Set electron mode
|
|
135
|
+
os.environ["FLOWFILE_MODE"] = "electron"
|
|
136
|
+
|
|
137
|
+
# Import core app
|
|
138
|
+
from flowfile_core.main import run, app as core_app
|
|
139
|
+
|
|
140
|
+
# Extend the core app with web UI routes and worker functionality
|
|
141
|
+
extend_app(core_app)
|
|
142
|
+
|
|
143
|
+
# Open browser if requested
|
|
144
|
+
if open_browser:
|
|
145
|
+
time.sleep(2)
|
|
146
|
+
webbrowser.open_new_tab(f"http://{host}:{port}/ui")
|
|
147
|
+
|
|
148
|
+
print("\n" + "=" * 60)
|
|
149
|
+
print(" FlowFile - Visual ETL Tool (Unified Mode)")
|
|
150
|
+
print(f" Web UI: http://{host}:{port}/ui")
|
|
151
|
+
print(f" API Docs: http://{host}:{port}/docs")
|
|
152
|
+
print("=" * 60 + "\n")
|
|
153
|
+
|
|
154
|
+
# Run the core app
|
|
155
|
+
run(host=host, port=port)
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
|
|
2
|
+
/* Array input styles */
|
|
3
|
+
.array-input-section[data-v-b2f2d704] {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 8px;
|
|
7
|
+
}
|
|
8
|
+
.input-with-button[data-v-b2f2d704] {
|
|
9
|
+
display: flex;
|
|
10
|
+
gap: 8px;
|
|
11
|
+
align-items: center;
|
|
12
|
+
}
|
|
13
|
+
.items-container[data-v-b2f2d704] {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
gap: 10px; /* Space between items */
|
|
17
|
+
}
|
|
18
|
+
.item-box[data-v-b2f2d704] {
|
|
19
|
+
display: flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
padding: 5px 10px;
|
|
22
|
+
background-color: #f0f0f0;
|
|
23
|
+
border-radius: 4px;
|
|
24
|
+
font-size: 12px;
|
|
25
|
+
position: relative;
|
|
26
|
+
}
|
|
27
|
+
.remove-btn[data-v-b2f2d704] {
|
|
28
|
+
margin-left: 8px;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
color: #100f0f72;
|
|
31
|
+
font-weight: bold;
|
|
32
|
+
}
|
|
33
|
+
.add-btn[data-v-b2f2d704] {
|
|
34
|
+
padding: 4px 12px;
|
|
35
|
+
background: #7878ff5b;
|
|
36
|
+
border: none;
|
|
37
|
+
border-radius: 3px;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
font-size: 12px;
|
|
40
|
+
transition: background-color 0.2s;
|
|
41
|
+
white-space: nowrap;
|
|
42
|
+
}
|
|
43
|
+
.add-btn[data-v-b2f2d704]:hover {
|
|
44
|
+
background: #6363ff5b;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Your existing styles */
|
|
48
|
+
.form-container[data-v-b2f2d704] {
|
|
49
|
+
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
|
|
50
|
+
font-size: 13px;
|
|
51
|
+
color: #333;
|
|
52
|
+
}
|
|
53
|
+
.form-grid[data-v-b2f2d704] {
|
|
54
|
+
display: grid;
|
|
55
|
+
gap: 8px;
|
|
56
|
+
padding: 12px;
|
|
57
|
+
background: #fff;
|
|
58
|
+
border: 1px solid #eee;
|
|
59
|
+
border-radius: 4px;
|
|
60
|
+
}
|
|
61
|
+
.form-item-wrapper[data-v-b2f2d704] {
|
|
62
|
+
margin-bottom: 2px;
|
|
63
|
+
}
|
|
64
|
+
.single-item[data-v-b2f2d704] {
|
|
65
|
+
margin-bottom: 4px;
|
|
66
|
+
}
|
|
67
|
+
.compact-header[data-v-b2f2d704] {
|
|
68
|
+
font-size: 12px;
|
|
69
|
+
color: #666;
|
|
70
|
+
margin-bottom: 2px;
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
gap: 4px;
|
|
74
|
+
}
|
|
75
|
+
.minimal-header[data-v-b2f2d704] {
|
|
76
|
+
width: 100%;
|
|
77
|
+
text-align: left;
|
|
78
|
+
padding: 6px 8px;
|
|
79
|
+
background: #f5f5f5;
|
|
80
|
+
border: 1px solid #eee;
|
|
81
|
+
border-radius: 3px;
|
|
82
|
+
font-size: 12px;
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
gap: 6px;
|
|
86
|
+
cursor: pointer;
|
|
87
|
+
transition: background 0.2s;
|
|
88
|
+
}
|
|
89
|
+
.minimal-header[data-v-b2f2d704]:hover {
|
|
90
|
+
background: #f0f0f0;
|
|
91
|
+
}
|
|
92
|
+
.minimal-header.is-open[data-v-b2f2d704] {
|
|
93
|
+
border-bottom-left-radius: 0;
|
|
94
|
+
border-bottom-right-radius: 0;
|
|
95
|
+
}
|
|
96
|
+
.minimal-chevron[data-v-b2f2d704] {
|
|
97
|
+
font-size: 14px;
|
|
98
|
+
color: #999;
|
|
99
|
+
width: 12px;
|
|
100
|
+
}
|
|
101
|
+
.tag[data-v-b2f2d704] {
|
|
102
|
+
color: #ff4757;
|
|
103
|
+
font-size: 14px;
|
|
104
|
+
}
|
|
105
|
+
.type-indicator[data-v-b2f2d704] {
|
|
106
|
+
color: #999;
|
|
107
|
+
font-size: 11px;
|
|
108
|
+
}
|
|
109
|
+
.nested-content[data-v-b2f2d704] {
|
|
110
|
+
padding: 8px;
|
|
111
|
+
border: 1px solid #eee;
|
|
112
|
+
border-top: none;
|
|
113
|
+
background: #fff;
|
|
114
|
+
border-bottom-left-radius: 3px;
|
|
115
|
+
border-bottom-right-radius: 3px;
|
|
116
|
+
}
|
|
117
|
+
.nested-item[data-v-b2f2d704] {
|
|
118
|
+
margin-bottom: 6px;
|
|
119
|
+
}
|
|
120
|
+
.nested-item[data-v-b2f2d704]:last-child {
|
|
121
|
+
margin-bottom: 0;
|
|
122
|
+
}
|
|
123
|
+
.minimal-input[data-v-b2f2d704] {
|
|
124
|
+
box-sizing: border-box; /* Add this to include padding in width calculation */
|
|
125
|
+
width: 100%;
|
|
126
|
+
padding: 4px 8px;
|
|
127
|
+
border: 1px solid #ddd;
|
|
128
|
+
border-radius: 3px;
|
|
129
|
+
font-size: 12px;
|
|
130
|
+
background: #fff;
|
|
131
|
+
transition: border 0.2s;
|
|
132
|
+
}
|
|
133
|
+
.minimal-input[data-v-b2f2d704]:focus {
|
|
134
|
+
outline: none;
|
|
135
|
+
border-color: #666;
|
|
136
|
+
}
|
|
137
|
+
.minimal-input[data-v-b2f2d704]::placeholder {
|
|
138
|
+
color: #ccc;
|
|
139
|
+
}
|
|
140
|
+
.minimal-popover[data-v-b2f2d704] {
|
|
141
|
+
position: fixed;
|
|
142
|
+
background: rgba(0, 0, 0, 0.8);
|
|
143
|
+
color: #fff;
|
|
144
|
+
padding: 4px 8px;
|
|
145
|
+
border-radius: 3px;
|
|
146
|
+
font-size: 12px;
|
|
147
|
+
max-width: 250px;
|
|
148
|
+
z-index: 100;
|
|
149
|
+
pointer-events: none;
|
|
150
|
+
}
|
|
151
|
+
@media (max-width: 640px) {
|
|
152
|
+
.form-grid[data-v-b2f2d704] {
|
|
153
|
+
padding: 8px;
|
|
154
|
+
gap: 6px;
|
|
155
|
+
}
|
|
156
|
+
.minimal-header[data-v-b2f2d704] {
|
|
157
|
+
padding: 4px 6px;
|
|
158
|
+
}
|
|
159
|
+
.minimal-input[data-v-b2f2d704] {
|
|
160
|
+
padding: 3px 6px;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.to-front[data-v-9dcbd94f] {
|
|
165
|
+
z-index: 1000;
|
|
166
|
+
}
|
|
167
|
+
.config-section[data-v-9dcbd94f] {
|
|
168
|
+
margin-top: 16px;
|
|
169
|
+
}
|
|
170
|
+
.stream-section[data-v-9dcbd94f] {
|
|
171
|
+
margin-top: 16px;
|
|
172
|
+
}
|
|
173
|
+
.stream-select[data-v-9dcbd94f] {
|
|
174
|
+
width: 100%;
|
|
175
|
+
max-width: 400px;
|
|
176
|
+
}
|
|
177
|
+
.icon-button[data-v-9dcbd94f] {
|
|
178
|
+
padding: 2px;
|
|
179
|
+
border: none;
|
|
180
|
+
background: none;
|
|
181
|
+
cursor: pointer;
|
|
182
|
+
color: #666;
|
|
183
|
+
}
|
|
184
|
+
.icon-button[data-v-9dcbd94f]:hover {
|
|
185
|
+
color: #333;
|
|
186
|
+
}
|
|
187
|
+
.primary-button[data-v-9dcbd94f] {
|
|
188
|
+
display: inline-flex;
|
|
189
|
+
align-items: center;
|
|
190
|
+
justify-content: center;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
padding: 8px 16px;
|
|
193
|
+
background-color: #7878ff5b;
|
|
194
|
+
border: none;
|
|
195
|
+
border-radius: 4px;
|
|
196
|
+
font-size: 13px;
|
|
197
|
+
transition: background-color 0.3s ease;
|
|
198
|
+
}
|
|
199
|
+
.primary-button[data-v-9dcbd94f]:hover:not(:disabled) {
|
|
200
|
+
background-color: #b3b5ba;
|
|
201
|
+
}
|
|
202
|
+
.primary-button[data-v-9dcbd94f]:disabled {
|
|
203
|
+
opacity: 0.6;
|
|
204
|
+
cursor: not-allowed;
|
|
205
|
+
}
|
|
206
|
+
.secondary-button[data-v-9dcbd94f] {
|
|
207
|
+
display: inline-flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
gap: 4px;
|
|
210
|
+
padding: 4px 8px;
|
|
211
|
+
background-color: #f1f1f1;
|
|
212
|
+
border: 1px solid #ddd;
|
|
213
|
+
border-radius: 4px;
|
|
214
|
+
font-size: 12px;
|
|
215
|
+
color: #666;
|
|
216
|
+
transition: all 0.2s ease;
|
|
217
|
+
}
|
|
218
|
+
.secondary-button[data-v-9dcbd94f]:hover {
|
|
219
|
+
background-color: #e4e4e4;
|
|
220
|
+
color: #333;
|
|
221
|
+
}
|
|
222
|
+
.validation-banner[data-v-9dcbd94f] {
|
|
223
|
+
display: flex;
|
|
224
|
+
align-items: center;
|
|
225
|
+
gap: 8px;
|
|
226
|
+
padding: 12px;
|
|
227
|
+
margin-top: 12px;
|
|
228
|
+
border-radius: 4px;
|
|
229
|
+
font-size: 14px;
|
|
230
|
+
}
|
|
231
|
+
.validation-banner.success[data-v-9dcbd94f] {
|
|
232
|
+
background-color: #ecfdf5;
|
|
233
|
+
color: #047857;
|
|
234
|
+
}
|
|
235
|
+
.validation-banner.error[data-v-9dcbd94f] {
|
|
236
|
+
background-color: #fef2f2;
|
|
237
|
+
color: #dc2626;
|
|
238
|
+
}
|
|
239
|
+
.spin[data-v-9dcbd94f] {
|
|
240
|
+
animation: spin-9dcbd94f 1s linear infinite;
|
|
241
|
+
}
|
|
242
|
+
@keyframes spin-9dcbd94f {
|
|
243
|
+
from {
|
|
244
|
+
transform: rotate(0deg);
|
|
245
|
+
}
|
|
246
|
+
to {
|
|
247
|
+
transform: rotate(360deg);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
.file-upload-label[data-v-9dcbd94f] {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
justify-content: flex-start;
|
|
254
|
+
background-color: #f5f5f5;
|
|
255
|
+
border: 1px solid #ddd;
|
|
256
|
+
border-radius: 4px;
|
|
257
|
+
padding: 10px 15px;
|
|
258
|
+
color: #333;
|
|
259
|
+
font-size: 16px;
|
|
260
|
+
font-weight: 500;
|
|
261
|
+
text-align: left;
|
|
262
|
+
user-select: none;
|
|
263
|
+
cursor: pointer;
|
|
264
|
+
transition: background-color 0.3s ease;
|
|
265
|
+
}
|
|
266
|
+
.file-upload-label[data-v-9dcbd94f]:hover {
|
|
267
|
+
background-color: #e4e4e4;
|
|
268
|
+
}
|
|
269
|
+
.file-icon[data-v-9dcbd94f] {
|
|
270
|
+
margin-right: 10px;
|
|
271
|
+
font-size: 20px;
|
|
272
|
+
width: 24px;
|
|
273
|
+
height: auto;
|
|
274
|
+
}
|
|
275
|
+
.attention-notice[data-v-9dcbd94f] {
|
|
276
|
+
display: flex;
|
|
277
|
+
align-items: center;
|
|
278
|
+
gap: 6px;
|
|
279
|
+
padding: 4px 8px;
|
|
280
|
+
border-radius: 4px;
|
|
281
|
+
width: fit-content;
|
|
282
|
+
margin-top: 4px;
|
|
283
|
+
}
|
|
284
|
+
.docker-notice[data-v-9dcbd94f] {
|
|
285
|
+
font-size: 12px;
|
|
286
|
+
font-weight: 600;
|
|
287
|
+
}
|
|
288
|
+
.warning-icon[data-v-9dcbd94f] {
|
|
289
|
+
font-size: 14px;
|
|
290
|
+
animation: pulse-9dcbd94f 2s infinite;
|
|
291
|
+
}
|
|
292
|
+
.flex[data-v-9dcbd94f] {
|
|
293
|
+
display: flex;
|
|
294
|
+
}
|
|
295
|
+
.justify-between[data-v-9dcbd94f] {
|
|
296
|
+
justify-content: space-between;
|
|
297
|
+
}
|
|
298
|
+
.items-center[data-v-9dcbd94f] {
|
|
299
|
+
align-items: center;
|
|
300
|
+
}
|
|
301
|
+
.gap-2[data-v-9dcbd94f] {
|
|
302
|
+
gap: 8px;
|
|
303
|
+
}
|
|
304
|
+
@keyframes pulse-9dcbd94f {
|
|
305
|
+
0% {
|
|
306
|
+
opacity: 1;
|
|
307
|
+
}
|
|
308
|
+
50% {
|
|
309
|
+
opacity: 0.5;
|
|
310
|
+
}
|
|
311
|
+
100% {
|
|
312
|
+
opacity: 1;
|
|
313
|
+
}
|
|
314
|
+
}
|