ecmind-blue-studio 1.0.0a1__tar.gz
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.
- ecmind_blue_studio-1.0.0a1/LICENSE +21 -0
- ecmind_blue_studio-1.0.0a1/PKG-INFO +233 -0
- ecmind_blue_studio-1.0.0a1/README.md +213 -0
- ecmind_blue_studio-1.0.0a1/pyproject.toml +61 -0
- ecmind_blue_studio-1.0.0a1/pyproject.toml.orig +51 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/__init__.py +3 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/__main__.py +18 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/compat.py +132 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/config.py +60 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/deps.py +62 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/errors.py +95 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/i18n.py +72 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/locales/de.json +417 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/locales/en.json +417 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/main.py +222 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/__init__.py +167 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/ast.py +411 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/bindings.py +236 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/completion.py +1381 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/errors.py +177 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/executor.py +364 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/formatter.py +278 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/formatting.py +51 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/keywords.py +181 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/lexer.py +408 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/parser.py +1366 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/planner.py +327 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/resolver.py +1449 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/security.py +792 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/snapshot.py +348 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/span.py +20 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/sql_completion.py +247 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/statement_templates.py +162 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/tokens.py +43 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/querylang/variables.py +140 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/rendering.py +53 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/__init__.py +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/auth.py +81 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/definition.py +83 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/files.py +124 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/health.py +47 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/icons.py +19 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/jobcalls.py +71 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/objects.py +318 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/pages.py +78 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/query.py +472 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/routers/settings.py +55 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/__init__.py +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/auth.py +84 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/commands.py +629 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/db_schema.py +79 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/definition_view.py +467 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/definitions.py +100 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/exports.py +211 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/groups.py +34 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/jobcalls.py +430 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/parent_hints.py +126 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/queries.py +1029 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/roles.py +51 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/security_admin.py +681 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/security_names.py +65 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/startup_checks.py +50 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/user_settings.py +84 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/services/visible_types.py +117 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/sessions.py +149 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/app.css +918 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/icons/favicon-blue.svg +1 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/icons/favicon-green.svg +1 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/icons/favicon-yellow.svg +1 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/app.js +322 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/attachments.js +70 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/definition.js +243 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/ecmql.js +206 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/editor.js +481 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/i18n.js +14 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/jobcalls.js +688 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/output.js +170 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/saved.js +124 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/settings.js +58 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/splitter.js +86 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/js/tabs.js +334 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/bootstrap/bootstrap.bundle.min.js +7 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-500-italic-Cljvy9n8.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-500-italic-Cxw8XFib.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-700-normal-BWTpRfYl.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-cyrillic-700-normal-CEoEElIJ.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-500-italic-BOoFGiPg.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-500-italic-DNb4joLt.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-700-normal-C6CZE3T8.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-greek-700-normal-DEigVDxa.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-500-italic-BAmfUVTg.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-500-italic-DMxVtl1n.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-700-normal-BYuf6tUa.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-700-normal-D3wTyLJW.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-500-italic-BfTxQ-NC.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-500-italic-gNibIUfK.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-700-normal-CZipNAKV.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-latin-ext-700-normal-CxPITLHs.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-vietnamese-500-italic-BPh13p40.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-vietnamese-500-italic-BkKfFY3r.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/jetbrains-mono-vietnamese-700-normal-BDLVIk2r.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-400-italic-BUPR0S1h.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-400-italic-DGpcSWlQ.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-400-normal-DvjyhnTk.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-400-normal-XMp_Qeuo.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-600-normal-BuMhxFId.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-600-normal-C5LXWJm_.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-700-normal-Db4W_Rwa.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-700-normal-FWckWEfO.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-400-italic-DTxbCGjE.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-400-italic-j4MbU4yU.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-400-normal-B28g4zcY.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-400-normal-CtkCLoLZ.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-600-normal-CivhzOCV.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-600-normal-DX5V8c14.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-700-normal-BWp9aGB1.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-cyrillic-ext-700-normal-hbT5P32v.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-400-italic-BuH7C3yF.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-400-italic-CilYwb5U.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-400-normal-BKm6CSmU.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-400-normal-yVf9KAAO.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-600-normal-CkCBI2Km.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-600-normal-Xt_394w2.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-700-normal-YcFp24oM.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-greek-700-normal-bcfTBw-h.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-400-italic-CXPP0jOX.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-400-italic-D5O-QnBO.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-400-normal-C3uFZKNA.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-400-normal-Cowz_U6T.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-600-normal-CQztwT7q.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-600-normal-D7z6DfF6.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-700-normal-CZc_Q6SQ.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-hebrew-700-normal-DnAL3HC_.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-400-italic-BEURUQpT.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-400-italic-oaOkCnEp.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-400-normal-Bk63H6sG.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-400-normal-DKniycaP.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-600-normal-C3dWW5mx.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-600-normal-Cp4N6AwT.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-700-normal-CZCQA30i.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-700-normal-CceUhp2e.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-400-italic-7zHzNkY4.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-400-italic-BF0ugEcP.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-400-normal-BfzJ9CTS.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-400-normal-URAvo6nN.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-600-normal-CXDaa6Q7.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-600-normal-YZ6Vktkr.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-700-normal-DatbY7Hl.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-latin-ext-700-normal-IE4yTLg1.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-400-italic-BsO0csMs.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-400-italic-CAApjVH7.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-400-normal-C76BUjK0.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-400-normal-Cs0GbA_j.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-600-normal-CWMKYWAo.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-600-normal-DQ8cZjrd.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-700-normal-B7X9EnEK.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-math-700-normal-EYnC2qGX.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-400-italic-0Ch9q1R9.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-400-italic-DdEf8Kfy.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-400-normal-B5VgOMNH.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-400-normal-OZvd8qMe.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-600-normal-BiWokiHG.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-600-normal-DgwZOEXg.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-700-normal-DNvDgxgv.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-symbols-700-normal-DfXrtqu8.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-400-italic-B-vHoAQ6.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-400-italic-BLoWRDoa.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-400-normal-DCU23d-J.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-400-normal-Dqpvjuft.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-600-normal-CVI-Ycr6.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-600-normal-cWHhjaNO.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-700-normal-BwQSBZ9d.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/assets/open-sans-vietnamese-700-normal-C0rmKuKj.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/ecmind-css/ecmind.css +2 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/htmx/htmx.min.js +1 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/base/worker/workerMain.js +31 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/editor/editor.main.css +8 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/editor/editor.main.js +798 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/loader.js +11 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/monaco/vs/nls.messages.de.js +21 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/fill/Phosphor-Fill.ttf +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/fill/Phosphor-Fill.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/fill/Phosphor-Fill.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/fill/style.css +4627 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/regular/Phosphor.ttf +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/regular/Phosphor.woff +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/regular/Phosphor.woff2 +0 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/static/vendor/phosphor/regular/style.css +4627 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/app.html +286 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/base.html +50 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/login.html +32 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/batch_result.html +38 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/batch_row.html +42 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/batch_shell.html +18 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/count_result.html +20 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/definition.html +167 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/definition_field.html +101 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/details.html +133 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/dml_result.html +54 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/history.html +25 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/jobcalls.html +94 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/result_error.html +15 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/result_section.html +116 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/result_tabs.html +33 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/result_text.html +22 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/security_dml_result.html +42 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/security_result.html +74 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/settings_dialog.html +69 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/sql_result.html +33 -0
- ecmind_blue_studio-1.0.0a1/src/ecmind_blue_studio/templates/partials/table_field.html +29 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ECMind GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ecmind-blue-studio
|
|
3
|
+
Version: 1.0.0a1
|
|
4
|
+
Summary: ECMind blue Studio, admin interface for the ecmind-blue-client
|
|
5
|
+
Author: ECMind GmbH
|
|
6
|
+
Author-email: ECMind GmbH <info@ecmind.ch>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: fastapi
|
|
10
|
+
Requires-Dist: uvicorn
|
|
11
|
+
Requires-Dist: jinja2
|
|
12
|
+
Requires-Dist: pydantic-settings
|
|
13
|
+
Requires-Dist: itsdangerous
|
|
14
|
+
Requires-Dist: python-multipart
|
|
15
|
+
Requires-Dist: ecmind-blue-client==1.0.0
|
|
16
|
+
Requires-Python: >=3.13
|
|
17
|
+
Project-URL: Homepage, https://ecmind.ch/
|
|
18
|
+
Project-URL: Repository, https://gitlab.ecmind.ch/open/ecmind_blue_studio
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# ECMind blue Studio
|
|
22
|
+
|
|
23
|
+
A admin interface for the DMS enaio(r) (OPTIMAL SYSTEMS GmbH), exposing the
|
|
24
|
+
ecmind-blue-client features.
|
|
25
|
+
Query folders, registers and documents with a simple query language in a Monaco
|
|
26
|
+
editor, inspect results and download files. Works fully offline against your
|
|
27
|
+
DMS infrastructure; all frontend assets are vendored.
|
|
28
|
+
|
|
29
|
+
## Features (work in progress)
|
|
30
|
+
|
|
31
|
+
- Browser-like vertical tabs, each with a query editor and a result view
|
|
32
|
+
- Object definition explorer: every cabinet, type and index field with its full
|
|
33
|
+
configuration, a filter over all of it, prefilled statements per object type
|
|
34
|
+
and the native asobjdef.xml as download
|
|
35
|
+
- Job call monitor: the live server job stream with filters per server, job,
|
|
36
|
+
computer, application and user, and the full parameters of a single call with
|
|
37
|
+
base64 payloads decoded
|
|
38
|
+
- Simple query language for folders, registers and documents with subqueries,
|
|
39
|
+
Klausel-style conditions, code completion and diagnostics
|
|
40
|
+
- Security statements for users, groups, roles, membership and the rights export
|
|
41
|
+
- Result tables per object type with file download
|
|
42
|
+
- ECMind theme with Green/Yellow/Blue brands, automatic light/dark mode
|
|
43
|
+
- English/German localization with automatic detection
|
|
44
|
+
|
|
45
|
+
## Requirements
|
|
46
|
+
|
|
47
|
+
- Python >= 3.13 and [uv](https://docs.astral.sh/uv/)
|
|
48
|
+
- A DMS application server (default: 127.0.0.1:4000)
|
|
49
|
+
- A technical account with the system role "Kontextwechsel" (switch context)
|
|
50
|
+
|
|
51
|
+
## Setup
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
uv sync
|
|
55
|
+
copy .env.example .env
|
|
56
|
+
# edit .env: servers, technical account, session secret
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Run
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
uv run uvicorn ecmind_blue_studio.main:app --reload --host 127.0.0.1 --port 8099
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then open http://127.0.0.1:8099 and log in with a DMS user.
|
|
66
|
+
|
|
67
|
+
## Object definition
|
|
68
|
+
|
|
69
|
+
The first tab cannot be closed and shows what the DMS server knows about its
|
|
70
|
+
own data model: cabinets with their folders, registers and documents, the index
|
|
71
|
+
mask fields of every type with data type, database column and names in the
|
|
72
|
+
configured languages, and the complete configuration of a single field. The
|
|
73
|
+
filter box searches all of it at once, six buttons per object type open a
|
|
74
|
+
prefilled `select`, `count`, `insert`, `update`, `upsert` or `delete` statement
|
|
75
|
+
in a new tab, and the download button hands out the native `asobjdef.xml`.
|
|
76
|
+
|
|
77
|
+
It needs the system role "DMS: Supervisor" (18) or "Editor: Starten" (11);
|
|
78
|
+
without one of them the tab is not shown.
|
|
79
|
+
|
|
80
|
+
## Job calls
|
|
81
|
+
|
|
82
|
+
The second fixed tab shows the live job stream of the configured servers, the
|
|
83
|
+
same feed the Enterprise Manager displays. Press Listen and every finished job
|
|
84
|
+
appears as one line with its timestamp, computer, user, job name, application
|
|
85
|
+
and file counts; a green check for success, a red warning for a failure, and
|
|
86
|
+
optionally a blue play line when the job starts. Filter by server, by job (a
|
|
87
|
+
popup over every namespace the server offers), by computer, application or user,
|
|
88
|
+
or reduce the stream to failures only. Clicking a line shows the call the way
|
|
89
|
+
the Enterprise Manager prints it, with base64 payloads decoded and XML indented.
|
|
90
|
+
|
|
91
|
+
It needs the system role "DMS: Supervisor" (18) or "Administrator: Starten" (1).
|
|
92
|
+
The monitor runs on the technical connection, which is why the roles are checked
|
|
93
|
+
on the server and not only in the browser. Job parameters are shown unmasked.
|
|
94
|
+
|
|
95
|
+
## Query language
|
|
96
|
+
|
|
97
|
+
Each tab has a Monaco editor with completion, hover and live diagnostics for a
|
|
98
|
+
simple query language (see [SPECS.md](SPECS.md) section 4). Ctrl+Enter runs the
|
|
99
|
+
query, Shift+Alt+F formats it, Alt+N opens a tab and Alt+W closes it. Internal
|
|
100
|
+
field names work without brackets:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
select document Invoice, DeliveryNote where Status = 'open' order by InvoiceDate desc limit 100
|
|
104
|
+
select document Invoice in (register Correspondence where Subject = 'Dunning*') where InvoiceNo != ''
|
|
105
|
+
select document Invoice where Clerk = #USER# and InvoiceDate >= #DATE#-1y6m
|
|
106
|
+
select document Invoice columns InvoiceNo, Amount, folder.CompanyName
|
|
107
|
+
select document Invoice columns InvoiceNo, {OBJECT_FILESIZE}, {OBJECT_MODIFYTIME}, {OBJECT_DOCPAGECOUNT}
|
|
108
|
+
count document Invoice where Status = 'open'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
System fields (`OBJECT_ID`, `OBJECT_LINKS`, `OBJECT_FILESIZE`, `OBJECT_COUNT`,
|
|
112
|
+
`OBJECT_MODIFYUSER` and more, see SPECS.md) work in `where`, `order by` and
|
|
113
|
+
`columns`; document-only fields are rejected on folder and register queries
|
|
114
|
+
with a live editor marker.
|
|
115
|
+
|
|
116
|
+
The editor also flags object types the signed-in user cannot see, and completion
|
|
117
|
+
notes them in its list. The DMS answers a query on such a type with an empty result
|
|
118
|
+
and no error at all, so the hint is shown before the run. It stays a warning and
|
|
119
|
+
never blocks the query: a type you can see may return no rows as well.
|
|
120
|
+
|
|
121
|
+
Data statements update, create and delete objects, always with the rights of the
|
|
122
|
+
signed-in user:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
update document Invoice 4711 set Status = 'paid'
|
|
126
|
+
update document Invoice 4711, 4712 set Status = 'paid'
|
|
127
|
+
delete document Invoice 6524, 6522 purge
|
|
128
|
+
insert document Invoice into 55 set InvoiceNo = 'R-9' file 'scan.pdf'
|
|
129
|
+
upsert document Invoice into 55 set InvoiceNo = 'R-9', Amount = 12.5 search InvoiceNo
|
|
130
|
+
variant 4711 set Status = 'draft' file 'v2.pdf'
|
|
131
|
+
delete document Invoice where Status = 'void' purge
|
|
132
|
+
insert document Invoice into 55 set InvoiceNo = 'R-9', Positions = (Article = 'A-100', Qty = 5), (Article = 'B-200', Qty = 3)
|
|
133
|
+
update document Invoice 4711 set Positions = (Article = 'A-100', Qty = 7) replacetables
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
A single `insert`, `update` or `variant` shows what it wrote: the objects are
|
|
137
|
+
read back from the server and rendered as a result table below the
|
|
138
|
+
confirmation, with the usual row actions. A large `update` (more objects than
|
|
139
|
+
one result page) and statement batches keep the plain confirmation, because
|
|
140
|
+
reading every object back costs a roundtrip each.
|
|
141
|
+
|
|
142
|
+
Table fields take a comma separated list of rows, each row a list of
|
|
143
|
+
`Column = value` pairs. On update and upsert the statement has to say whether
|
|
144
|
+
the rows replace the table (`replacetables`) or extend it (`appendtables`) -
|
|
145
|
+
the mode belongs to the whole statement, so replacing one table and appending
|
|
146
|
+
to another needs two statements. The table popup in a result row carries an
|
|
147
|
+
"Edit table" button that opens a new tab with exactly such a statement, filled
|
|
148
|
+
with the rows currently stored.
|
|
149
|
+
|
|
150
|
+
Files referenced by `file '...'` are attached to the tab with the paperclip
|
|
151
|
+
button; `file #BROWSE#` instead opens the file dialog every time the statement
|
|
152
|
+
`update` and `delete` also take a list of object ids, and every listed object
|
|
153
|
+
gets its own copy of the file; a failing object does not stop the others, and
|
|
154
|
+
the result lists what was written and what failed. On an id based update the
|
|
155
|
+
`set` clause is optional, so
|
|
156
|
+
`update document Invoice 6523 file 'scan.pdf'` replaces only the file and
|
|
157
|
+
`update document Invoice 6523 file #NULL#` only removes it. Prefilled
|
|
158
|
+
document statements (edit button, object definition page) end with
|
|
159
|
+
`file #BROWSE#` as a reminder; delete the line for metadata-only changes.
|
|
160
|
+
File content can also be written inline, with an optional extension
|
|
161
|
+
after the closing quotes so the DMS knows the file type: `file '''<data>
|
|
162
|
+
</data>'''.xml` stores the text, `file b64'''iVBOR...'''.png` decodes base64
|
|
163
|
+
(line breaks and spaces are ignored), and `file #NULL#` removes the document
|
|
164
|
+
file on an update. Without an extension, text becomes a txt and base64 a bin
|
|
165
|
+
file:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
insert document Invoice into 5693
|
|
169
|
+
set InvoiceNo = 'R-9'
|
|
170
|
+
file b64'''
|
|
171
|
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzE...
|
|
172
|
+
'''.png;
|
|
173
|
+
select document Invoice
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Security statements administer the DMS users, groups and roles in the same
|
|
177
|
+
language, again with the rights of the signed-in user, so the server enforces
|
|
178
|
+
the role for configuring the security system:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
select user where locked = false order by username limit 100
|
|
182
|
+
select user where group = 'Sales'
|
|
183
|
+
select group where user = #USER#
|
|
184
|
+
insert user KOL set display_name = 'Roland Koller', password = 'Start.2026', change_pwd = true
|
|
185
|
+
add user KOL to group Sales
|
|
186
|
+
export security group Sales, Marketing
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`select user KOL` shows one account with every attribute, `count group` the
|
|
190
|
+
number alone, and `delete user KOL forward to MEY` hands the portfolios and
|
|
191
|
+
mails over before the account goes. User and group rows carry the same edit
|
|
192
|
+
button as DMS rows: it opens a new tab with an `update user` or `update group`
|
|
193
|
+
statement holding the current values. The password is never part of it, and
|
|
194
|
+
never part of a result or a log.
|
|
195
|
+
|
|
196
|
+
Results render as a table by default or as JSON, JSONL, XML, CSV, TSV or TSV
|
|
197
|
+
quoted, `sql` results included. Every text format opens in an editable editor, so
|
|
198
|
+
the output can be trimmed before copy or download hands it to the next step.
|
|
199
|
+
TSV sanitizes tabs and line breaks inside values to keep one record per line,
|
|
200
|
+
TSV quoted keeps them and quotes like CSV instead. Every result
|
|
201
|
+
row offers details (metadata, variants and versions), an edit button that opens
|
|
202
|
+
a prefilled update statement, and file download.
|
|
203
|
+
|
|
204
|
+
Statement batches (separated by `;`) stream their results statement by
|
|
205
|
+
statement, report the executed command and the upsert action per row, and can
|
|
206
|
+
be cancelled mid run; the stop button in the toolbar also aborts long running
|
|
207
|
+
queries. A query starting with a comment line names its tab, the question
|
|
208
|
+
button in the toolbar lists all keyboard shortcuts, the info button next to it
|
|
209
|
+
opens the about dialog, and the tab rail shows the connected DMS servers
|
|
210
|
+
above the user menu.
|
|
211
|
+
|
|
212
|
+
## Tests
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
uv run pytest # unit and endpoint tests
|
|
216
|
+
$env:EBS_LIVE_TESTS = "1"; uv run pytest -m live # against a local DMS (PowerShell)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Documentation
|
|
220
|
+
|
|
221
|
+
- [SPECS.md](SPECS.md) - full specification and decision log
|
|
222
|
+
- [TODO.md](TODO.md) - backlog
|
|
223
|
+
- [CHANGELOG.md](CHANGELOG.md) - notable changes
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
MIT, see [LICENSE](LICENSE). Bundled third-party libraries, fonts, icons and tools are
|
|
228
|
+
acknowledged in [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
|
|
229
|
+
|
|
230
|
+
The MIT license covers this software only and grants no rights to the DMS itself. Operators must
|
|
231
|
+
make sure their use of the DMS is covered by their own license agreement with the DMS vendor or
|
|
232
|
+
reseller. See the DMS licensing section of
|
|
233
|
+
[THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
# ECMind blue Studio
|
|
2
|
+
|
|
3
|
+
A admin interface for the DMS enaio(r) (OPTIMAL SYSTEMS GmbH), exposing the
|
|
4
|
+
ecmind-blue-client features.
|
|
5
|
+
Query folders, registers and documents with a simple query language in a Monaco
|
|
6
|
+
editor, inspect results and download files. Works fully offline against your
|
|
7
|
+
DMS infrastructure; all frontend assets are vendored.
|
|
8
|
+
|
|
9
|
+
## Features (work in progress)
|
|
10
|
+
|
|
11
|
+
- Browser-like vertical tabs, each with a query editor and a result view
|
|
12
|
+
- Object definition explorer: every cabinet, type and index field with its full
|
|
13
|
+
configuration, a filter over all of it, prefilled statements per object type
|
|
14
|
+
and the native asobjdef.xml as download
|
|
15
|
+
- Job call monitor: the live server job stream with filters per server, job,
|
|
16
|
+
computer, application and user, and the full parameters of a single call with
|
|
17
|
+
base64 payloads decoded
|
|
18
|
+
- Simple query language for folders, registers and documents with subqueries,
|
|
19
|
+
Klausel-style conditions, code completion and diagnostics
|
|
20
|
+
- Security statements for users, groups, roles, membership and the rights export
|
|
21
|
+
- Result tables per object type with file download
|
|
22
|
+
- ECMind theme with Green/Yellow/Blue brands, automatic light/dark mode
|
|
23
|
+
- English/German localization with automatic detection
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Python >= 3.13 and [uv](https://docs.astral.sh/uv/)
|
|
28
|
+
- A DMS application server (default: 127.0.0.1:4000)
|
|
29
|
+
- A technical account with the system role "Kontextwechsel" (switch context)
|
|
30
|
+
|
|
31
|
+
## Setup
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
uv sync
|
|
35
|
+
copy .env.example .env
|
|
36
|
+
# edit .env: servers, technical account, session secret
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Run
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
uv run uvicorn ecmind_blue_studio.main:app --reload --host 127.0.0.1 --port 8099
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then open http://127.0.0.1:8099 and log in with a DMS user.
|
|
46
|
+
|
|
47
|
+
## Object definition
|
|
48
|
+
|
|
49
|
+
The first tab cannot be closed and shows what the DMS server knows about its
|
|
50
|
+
own data model: cabinets with their folders, registers and documents, the index
|
|
51
|
+
mask fields of every type with data type, database column and names in the
|
|
52
|
+
configured languages, and the complete configuration of a single field. The
|
|
53
|
+
filter box searches all of it at once, six buttons per object type open a
|
|
54
|
+
prefilled `select`, `count`, `insert`, `update`, `upsert` or `delete` statement
|
|
55
|
+
in a new tab, and the download button hands out the native `asobjdef.xml`.
|
|
56
|
+
|
|
57
|
+
It needs the system role "DMS: Supervisor" (18) or "Editor: Starten" (11);
|
|
58
|
+
without one of them the tab is not shown.
|
|
59
|
+
|
|
60
|
+
## Job calls
|
|
61
|
+
|
|
62
|
+
The second fixed tab shows the live job stream of the configured servers, the
|
|
63
|
+
same feed the Enterprise Manager displays. Press Listen and every finished job
|
|
64
|
+
appears as one line with its timestamp, computer, user, job name, application
|
|
65
|
+
and file counts; a green check for success, a red warning for a failure, and
|
|
66
|
+
optionally a blue play line when the job starts. Filter by server, by job (a
|
|
67
|
+
popup over every namespace the server offers), by computer, application or user,
|
|
68
|
+
or reduce the stream to failures only. Clicking a line shows the call the way
|
|
69
|
+
the Enterprise Manager prints it, with base64 payloads decoded and XML indented.
|
|
70
|
+
|
|
71
|
+
It needs the system role "DMS: Supervisor" (18) or "Administrator: Starten" (1).
|
|
72
|
+
The monitor runs on the technical connection, which is why the roles are checked
|
|
73
|
+
on the server and not only in the browser. Job parameters are shown unmasked.
|
|
74
|
+
|
|
75
|
+
## Query language
|
|
76
|
+
|
|
77
|
+
Each tab has a Monaco editor with completion, hover and live diagnostics for a
|
|
78
|
+
simple query language (see [SPECS.md](SPECS.md) section 4). Ctrl+Enter runs the
|
|
79
|
+
query, Shift+Alt+F formats it, Alt+N opens a tab and Alt+W closes it. Internal
|
|
80
|
+
field names work without brackets:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
select document Invoice, DeliveryNote where Status = 'open' order by InvoiceDate desc limit 100
|
|
84
|
+
select document Invoice in (register Correspondence where Subject = 'Dunning*') where InvoiceNo != ''
|
|
85
|
+
select document Invoice where Clerk = #USER# and InvoiceDate >= #DATE#-1y6m
|
|
86
|
+
select document Invoice columns InvoiceNo, Amount, folder.CompanyName
|
|
87
|
+
select document Invoice columns InvoiceNo, {OBJECT_FILESIZE}, {OBJECT_MODIFYTIME}, {OBJECT_DOCPAGECOUNT}
|
|
88
|
+
count document Invoice where Status = 'open'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
System fields (`OBJECT_ID`, `OBJECT_LINKS`, `OBJECT_FILESIZE`, `OBJECT_COUNT`,
|
|
92
|
+
`OBJECT_MODIFYUSER` and more, see SPECS.md) work in `where`, `order by` and
|
|
93
|
+
`columns`; document-only fields are rejected on folder and register queries
|
|
94
|
+
with a live editor marker.
|
|
95
|
+
|
|
96
|
+
The editor also flags object types the signed-in user cannot see, and completion
|
|
97
|
+
notes them in its list. The DMS answers a query on such a type with an empty result
|
|
98
|
+
and no error at all, so the hint is shown before the run. It stays a warning and
|
|
99
|
+
never blocks the query: a type you can see may return no rows as well.
|
|
100
|
+
|
|
101
|
+
Data statements update, create and delete objects, always with the rights of the
|
|
102
|
+
signed-in user:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
update document Invoice 4711 set Status = 'paid'
|
|
106
|
+
update document Invoice 4711, 4712 set Status = 'paid'
|
|
107
|
+
delete document Invoice 6524, 6522 purge
|
|
108
|
+
insert document Invoice into 55 set InvoiceNo = 'R-9' file 'scan.pdf'
|
|
109
|
+
upsert document Invoice into 55 set InvoiceNo = 'R-9', Amount = 12.5 search InvoiceNo
|
|
110
|
+
variant 4711 set Status = 'draft' file 'v2.pdf'
|
|
111
|
+
delete document Invoice where Status = 'void' purge
|
|
112
|
+
insert document Invoice into 55 set InvoiceNo = 'R-9', Positions = (Article = 'A-100', Qty = 5), (Article = 'B-200', Qty = 3)
|
|
113
|
+
update document Invoice 4711 set Positions = (Article = 'A-100', Qty = 7) replacetables
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
A single `insert`, `update` or `variant` shows what it wrote: the objects are
|
|
117
|
+
read back from the server and rendered as a result table below the
|
|
118
|
+
confirmation, with the usual row actions. A large `update` (more objects than
|
|
119
|
+
one result page) and statement batches keep the plain confirmation, because
|
|
120
|
+
reading every object back costs a roundtrip each.
|
|
121
|
+
|
|
122
|
+
Table fields take a comma separated list of rows, each row a list of
|
|
123
|
+
`Column = value` pairs. On update and upsert the statement has to say whether
|
|
124
|
+
the rows replace the table (`replacetables`) or extend it (`appendtables`) -
|
|
125
|
+
the mode belongs to the whole statement, so replacing one table and appending
|
|
126
|
+
to another needs two statements. The table popup in a result row carries an
|
|
127
|
+
"Edit table" button that opens a new tab with exactly such a statement, filled
|
|
128
|
+
with the rows currently stored.
|
|
129
|
+
|
|
130
|
+
Files referenced by `file '...'` are attached to the tab with the paperclip
|
|
131
|
+
button; `file #BROWSE#` instead opens the file dialog every time the statement
|
|
132
|
+
`update` and `delete` also take a list of object ids, and every listed object
|
|
133
|
+
gets its own copy of the file; a failing object does not stop the others, and
|
|
134
|
+
the result lists what was written and what failed. On an id based update the
|
|
135
|
+
`set` clause is optional, so
|
|
136
|
+
`update document Invoice 6523 file 'scan.pdf'` replaces only the file and
|
|
137
|
+
`update document Invoice 6523 file #NULL#` only removes it. Prefilled
|
|
138
|
+
document statements (edit button, object definition page) end with
|
|
139
|
+
`file #BROWSE#` as a reminder; delete the line for metadata-only changes.
|
|
140
|
+
File content can also be written inline, with an optional extension
|
|
141
|
+
after the closing quotes so the DMS knows the file type: `file '''<data>
|
|
142
|
+
</data>'''.xml` stores the text, `file b64'''iVBOR...'''.png` decodes base64
|
|
143
|
+
(line breaks and spaces are ignored), and `file #NULL#` removes the document
|
|
144
|
+
file on an update. Without an extension, text becomes a txt and base64 a bin
|
|
145
|
+
file:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
insert document Invoice into 5693
|
|
149
|
+
set InvoiceNo = 'R-9'
|
|
150
|
+
file b64'''
|
|
151
|
+
iVBORw0KGgoAAAANSUhEUgAAABAAAAARCAYAAADUryzE...
|
|
152
|
+
'''.png;
|
|
153
|
+
select document Invoice
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Security statements administer the DMS users, groups and roles in the same
|
|
157
|
+
language, again with the rights of the signed-in user, so the server enforces
|
|
158
|
+
the role for configuring the security system:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
select user where locked = false order by username limit 100
|
|
162
|
+
select user where group = 'Sales'
|
|
163
|
+
select group where user = #USER#
|
|
164
|
+
insert user KOL set display_name = 'Roland Koller', password = 'Start.2026', change_pwd = true
|
|
165
|
+
add user KOL to group Sales
|
|
166
|
+
export security group Sales, Marketing
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`select user KOL` shows one account with every attribute, `count group` the
|
|
170
|
+
number alone, and `delete user KOL forward to MEY` hands the portfolios and
|
|
171
|
+
mails over before the account goes. User and group rows carry the same edit
|
|
172
|
+
button as DMS rows: it opens a new tab with an `update user` or `update group`
|
|
173
|
+
statement holding the current values. The password is never part of it, and
|
|
174
|
+
never part of a result or a log.
|
|
175
|
+
|
|
176
|
+
Results render as a table by default or as JSON, JSONL, XML, CSV, TSV or TSV
|
|
177
|
+
quoted, `sql` results included. Every text format opens in an editable editor, so
|
|
178
|
+
the output can be trimmed before copy or download hands it to the next step.
|
|
179
|
+
TSV sanitizes tabs and line breaks inside values to keep one record per line,
|
|
180
|
+
TSV quoted keeps them and quotes like CSV instead. Every result
|
|
181
|
+
row offers details (metadata, variants and versions), an edit button that opens
|
|
182
|
+
a prefilled update statement, and file download.
|
|
183
|
+
|
|
184
|
+
Statement batches (separated by `;`) stream their results statement by
|
|
185
|
+
statement, report the executed command and the upsert action per row, and can
|
|
186
|
+
be cancelled mid run; the stop button in the toolbar also aborts long running
|
|
187
|
+
queries. A query starting with a comment line names its tab, the question
|
|
188
|
+
button in the toolbar lists all keyboard shortcuts, the info button next to it
|
|
189
|
+
opens the about dialog, and the tab rail shows the connected DMS servers
|
|
190
|
+
above the user menu.
|
|
191
|
+
|
|
192
|
+
## Tests
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
uv run pytest # unit and endpoint tests
|
|
196
|
+
$env:EBS_LIVE_TESTS = "1"; uv run pytest -m live # against a local DMS (PowerShell)
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Documentation
|
|
200
|
+
|
|
201
|
+
- [SPECS.md](SPECS.md) - full specification and decision log
|
|
202
|
+
- [TODO.md](TODO.md) - backlog
|
|
203
|
+
- [CHANGELOG.md](CHANGELOG.md) - notable changes
|
|
204
|
+
|
|
205
|
+
## License
|
|
206
|
+
|
|
207
|
+
MIT, see [LICENSE](LICENSE). Bundled third-party libraries, fonts, icons and tools are
|
|
208
|
+
acknowledged in [THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
|
|
209
|
+
|
|
210
|
+
The MIT license covers this software only and grants no rights to the DMS itself. Operators must
|
|
211
|
+
make sure their use of the DMS is covered by their own license agreement with the DMS vendor or
|
|
212
|
+
reseller. See the DMS licensing section of
|
|
213
|
+
[THIRD-PARTY-NOTICES.md](THIRD-PARTY-NOTICES.md).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ecmind-blue-studio"
|
|
3
|
+
version = "1.0.0a1"
|
|
4
|
+
description = "ECMind blue Studio, admin interface for the ecmind-blue-client"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
dependencies = [
|
|
10
|
+
"fastapi",
|
|
11
|
+
"uvicorn",
|
|
12
|
+
"jinja2",
|
|
13
|
+
"pydantic-settings",
|
|
14
|
+
"itsdangerous",
|
|
15
|
+
"python-multipart",
|
|
16
|
+
"ecmind-blue-client==1.0.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[[project.authors]]
|
|
20
|
+
name = "ECMind GmbH"
|
|
21
|
+
email = "info@ecmind.ch"
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://ecmind.ch/"
|
|
25
|
+
Repository = "https://gitlab.ecmind.ch/open/ecmind_blue_studio"
|
|
26
|
+
|
|
27
|
+
[project.scripts]
|
|
28
|
+
ecmind-blue-studio = "ecmind_blue_studio.__main__:main"
|
|
29
|
+
|
|
30
|
+
[dependency-groups]
|
|
31
|
+
dev = [
|
|
32
|
+
"pytest",
|
|
33
|
+
"pytest-asyncio",
|
|
34
|
+
"pytest-cov",
|
|
35
|
+
"httpx",
|
|
36
|
+
"ruff",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[build-system]
|
|
40
|
+
requires = ["uv_build>=0.11,<0.13"]
|
|
41
|
+
build-backend = "uv_build"
|
|
42
|
+
|
|
43
|
+
[tool.pytest.ini_options]
|
|
44
|
+
markers = ["live: needs a local DMS instance"]
|
|
45
|
+
addopts = "-m 'not live'"
|
|
46
|
+
asyncio_mode = "auto"
|
|
47
|
+
|
|
48
|
+
[tool.ruff]
|
|
49
|
+
line-length = 120
|
|
50
|
+
src = [
|
|
51
|
+
"src",
|
|
52
|
+
"tests",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
ignore = [
|
|
57
|
+
"DTZ001",
|
|
58
|
+
"DTZ005",
|
|
59
|
+
"DTZ006",
|
|
60
|
+
"DTZ011",
|
|
61
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ecmind-blue-studio"
|
|
3
|
+
version = "1.0.0a1"
|
|
4
|
+
description = "ECMind blue Studio, admin interface for the ecmind-blue-client"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "ECMind GmbH", email = "info@ecmind.ch" }]
|
|
10
|
+
dependencies = [
|
|
11
|
+
"fastapi",
|
|
12
|
+
"uvicorn",
|
|
13
|
+
"jinja2",
|
|
14
|
+
"pydantic-settings",
|
|
15
|
+
"itsdangerous",
|
|
16
|
+
"python-multipart",
|
|
17
|
+
"ecmind-blue-client==1.0.0",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[dependency-groups]
|
|
21
|
+
dev = [
|
|
22
|
+
"pytest",
|
|
23
|
+
"pytest-asyncio",
|
|
24
|
+
"pytest-cov",
|
|
25
|
+
"httpx",
|
|
26
|
+
"ruff",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://ecmind.ch/"
|
|
31
|
+
Repository = "https://gitlab.ecmind.ch/open/ecmind_blue_studio"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
ecmind-blue-studio = "ecmind_blue_studio.__main__:main"
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["uv_build>=0.11,<0.13"]
|
|
38
|
+
build-backend = "uv_build"
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
markers = ["live: needs a local DMS instance"]
|
|
42
|
+
addopts = "-m 'not live'"
|
|
43
|
+
asyncio_mode = "auto"
|
|
44
|
+
|
|
45
|
+
[tool.ruff]
|
|
46
|
+
line-length = 120
|
|
47
|
+
src = ["src", "tests"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff.lint]
|
|
50
|
+
# DMS index data and query variables use naive server-local datetimes.
|
|
51
|
+
ignore = ["DTZ001", "DTZ005", "DTZ006", "DTZ011"]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Entry point: run the web client with uvicorn."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def main() -> None:
|
|
5
|
+
import uvicorn
|
|
6
|
+
|
|
7
|
+
from ecmind_blue_studio.config import get_settings
|
|
8
|
+
|
|
9
|
+
settings = get_settings()
|
|
10
|
+
uvicorn.run(
|
|
11
|
+
"ecmind_blue_studio.main:app",
|
|
12
|
+
host=settings.host,
|
|
13
|
+
port=settings.port,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
main()
|