@chengxianglibra/dsh-data-analysis 0.1.1 → 0.2.0
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.
- package/README.md +139 -53
- package/cordis.patch.yml +1 -1
- package/lib/bin/environment.js +9 -7
- package/lib/bin/presentation-lint.js +21 -0
- package/lib/bridges.js +2 -2
- package/lib/client/credentials/changes.js +74 -0
- package/lib/client/credentials/create-datasource.js +171 -0
- package/lib/client/credentials/credential-draft.js +42 -0
- package/lib/client/credentials/defaults.js +11 -0
- package/lib/client/credentials/descriptions.js +46 -0
- package/lib/client/credentials/install.js +319 -0
- package/lib/client/credentials/model.js +766 -0
- package/lib/client/credentials/report-publishing.js +96 -0
- package/lib/client/credentials/styles.js +21 -0
- package/lib/client/i18n/context.js +22 -0
- package/lib/client/i18n/copy.js +57 -0
- package/lib/client/i18n/credentials.js +475 -0
- package/lib/client/i18n/host.js +27 -0
- package/lib/client/i18n/navigation.js +41 -0
- package/lib/client/i18n/presentation.js +577 -0
- package/lib/client/i18n/python.js +36 -0
- package/lib/client/i18n/semantic.js +441 -0
- package/lib/client/input-context.js +21 -0
- package/lib/client/python-tool/card.js +35 -0
- package/lib/client/python-tool/execution-error.js +35 -0
- package/lib/client/python-tool/install.js +9 -0
- package/lib/client/python-tool/model.js +101 -0
- package/lib/client/right-tabs/install.js +535 -0
- package/lib/client/right-tabs/live-delivery.js +58 -0
- package/lib/client/right-tabs/navigation.js +47 -0
- package/lib/client/right-tabs/page.js +178 -0
- package/lib/client/right-tabs/styles.js +11 -0
- package/lib/client/rpc.js +5 -0
- package/lib/client/semantic-reference.js +10 -0
- package/lib/client/workspace-header-action.js +24 -0
- package/lib/client/workspace-shortcuts.js +26 -0
- package/lib/client.js +1250 -730
- package/lib/compatibility.js +2 -2
- package/lib/datasource/authoring.js +109 -0
- package/lib/datasource/bridge-programs.js +42 -27
- package/lib/datasource/bridge.js +144 -9
- package/lib/datasource/changes-contract.js +41 -0
- package/lib/datasource/changes.js +49 -0
- package/lib/datasource/configure.js +39 -0
- package/lib/datasource/defaults.js +25 -0
- package/lib/datasource/index.js +4 -2
- package/lib/datasource/python-options.js +21 -0
- package/lib/datasource/python.js +206 -0
- package/lib/datasource/resolver-program.js +112 -0
- package/lib/datasource/rpc.js +150 -0
- package/lib/datasource/service.js +962 -0
- package/lib/datasource/shell-env.js +2 -333
- package/lib/datasource/test.js +25 -51
- package/lib/disclosure/activation.js +19 -7
- package/lib/disclosure/execution-guidance.js +52 -0
- package/lib/disclosure/help.js +4 -1
- package/lib/environment/binding.js +54 -9
- package/lib/environment/runtime.js +120 -108
- package/lib/environment/subprocess.js +6 -1
- package/lib/environment/summary.js +3 -3
- package/lib/environment/workspace.js +23 -1
- package/lib/index.js +1 -1
- package/lib/lifecycle.js +33 -0
- package/lib/plugin-agents.js +154 -0
- package/lib/plugin.js +172 -133
- package/lib/presentation/asset.js +34 -0
- package/lib/presentation/assets/portable.js +606 -0
- package/lib/presentation/assets/static.js +1216 -0
- package/lib/presentation/build/index.js +72 -0
- package/lib/presentation/commit.js +163 -0
- package/lib/presentation/contracts/asset-path.js +9 -0
- package/lib/presentation/contracts/catalog.js +62 -0
- package/lib/presentation/contracts/charts.js +453 -0
- package/lib/presentation/contracts/editing.js +58 -0
- package/lib/presentation/contracts/index.js +663 -0
- package/lib/presentation/contracts/interaction.js +62 -0
- package/lib/presentation/contracts/types.js +15 -0
- package/lib/presentation/contracts/values.js +28 -0
- package/lib/presentation/delivery.js +71 -0
- package/lib/presentation/export-html.js +214 -0
- package/lib/presentation/files.js +82 -0
- package/lib/presentation/index.js +6 -0
- package/lib/presentation/lint.js +46 -0
- package/lib/presentation/projection/files.js +85 -0
- package/lib/presentation/projection/index.js +196 -0
- package/lib/presentation/projection/program.js +137 -0
- package/lib/presentation/projection/sql-code.js +79 -0
- package/lib/presentation/receipt.js +34 -0
- package/lib/presentation/reports.js +219 -0
- package/lib/presentation/rpc.js +186 -0
- package/lib/presentation/tool.js +118 -0
- package/lib/python-execution-contracts.js +1 -0
- package/lib/python-execution.js +232 -0
- package/lib/report-publishing/adapters.js +111 -0
- package/lib/report-publishing/config.js +69 -0
- package/lib/report-publishing/service.js +180 -0
- package/lib/rpc.js +49 -0
- package/lib/semantic-browser/contracts.js +97 -0
- package/lib/semantic-browser/definition.js +64 -0
- package/lib/semantic-browser/program.js +129 -0
- package/lib/semantic-browser/service.js +106 -0
- package/lib/semantic-reference/bridge.js +127 -0
- package/lib/semantic-reference/contracts.js +127 -0
- package/lib/semantic-reference/environment.js +56 -0
- package/lib/semantic-reference/index.js +3 -0
- package/lib/semantic-reference/labels.js +16 -0
- package/lib/semantic-reference/rpc.js +143 -0
- package/lib/semantic-reference/search.js +95 -0
- package/lib/semantic-reference/usage.js +152 -0
- package/lib/tool-lifecycle.js +22 -0
- package/lib/types/bridges.d.ts +2 -2
- package/lib/types/client/credentials/changes.d.ts +9 -0
- package/lib/types/client/credentials/create-datasource.d.ts +7 -0
- package/lib/types/client/credentials/credential-draft.d.ts +14 -0
- package/lib/types/client/credentials/defaults.d.ts +2 -0
- package/lib/types/client/credentials/descriptions.d.ts +1 -0
- package/lib/types/client/credentials/install.d.ts +19 -0
- package/lib/types/client/credentials/model.d.ts +79 -0
- package/lib/types/client/credentials/report-publishing.d.ts +5 -0
- package/lib/types/client/credentials/styles.d.ts +1 -0
- package/lib/types/client/i18n/context.d.ts +17 -0
- package/lib/types/client/i18n/copy.d.ts +806 -0
- package/lib/types/client/i18n/credentials.d.ts +475 -0
- package/lib/types/client/i18n/host.d.ts +16 -0
- package/lib/types/client/i18n/navigation.d.ts +41 -0
- package/lib/types/client/i18n/presentation.d.ts +577 -0
- package/lib/types/client/i18n/python.d.ts +19 -0
- package/lib/types/client/i18n/semantic.d.ts +441 -0
- package/lib/types/client/input-context.d.ts +19 -0
- package/lib/types/client/presentation/ask-dsh.d.ts +5 -0
- package/lib/types/client/presentation/catalog-model.d.ts +24 -0
- package/lib/types/client/presentation/catalog.d.ts +20 -0
- package/lib/types/client/presentation/chart-explorer.d.ts +12 -0
- package/lib/types/client/presentation/chart-geometry.d.ts +30 -0
- package/lib/types/client/presentation/chart-renderer.d.ts +10 -0
- package/lib/types/client/presentation/chart-specials.d.ts +10 -0
- package/lib/types/client/presentation/chart-styles.d.ts +1 -0
- package/lib/types/client/presentation/chart-tooltip.d.ts +13 -0
- package/lib/types/client/presentation/chart-view.d.ts +23 -0
- package/lib/types/client/presentation/context-reference.d.ts +12 -0
- package/lib/types/client/presentation/copy-context.d.ts +5 -0
- package/lib/types/client/presentation/delivery-model.d.ts +75 -0
- package/lib/types/client/presentation/delivery.d.ts +78 -0
- package/lib/types/client/presentation/download.d.ts +2 -0
- package/lib/types/client/presentation/editor-controls.d.ts +12 -0
- package/lib/types/client/presentation/export-menu.d.ts +26 -0
- package/lib/types/client/presentation/export-view.d.ts +63 -0
- package/lib/types/client/presentation/global-filters.d.ts +6 -0
- package/lib/types/client/presentation/host-entry.d.ts +18 -0
- package/lib/types/client/presentation/icons.d.ts +4 -0
- package/lib/types/client/presentation/markdown.d.ts +5 -0
- package/lib/types/client/presentation/model.d.ts +61 -0
- package/lib/types/client/presentation/reader.d.ts +24 -0
- package/lib/types/client/presentation/reference-source.d.ts +9 -0
- package/lib/types/client/presentation/source-code-model.d.ts +17 -0
- package/lib/types/client/presentation/source-code.d.ts +6 -0
- package/lib/types/client/presentation/source-dialog.d.ts +12 -0
- package/lib/types/client/presentation/source-facts.d.ts +20 -0
- package/lib/types/client/presentation/source-format.d.ts +5 -0
- package/lib/types/client/presentation/source-highlight.d.ts +7 -0
- package/lib/types/client/presentation/sources.d.ts +13 -0
- package/lib/types/client/presentation/styles.d.ts +1 -0
- package/lib/types/client/presentation/table.d.ts +16 -0
- package/lib/types/client/presentation/use-element-width.d.ts +5 -0
- package/lib/types/client/python-tool/card.d.ts +2 -0
- package/lib/types/client/python-tool/execution-error.d.ts +3 -0
- package/lib/types/client/python-tool/install.d.ts +2 -0
- package/lib/types/client/python-tool/model.d.ts +20 -0
- package/lib/types/client/right-tabs/install.d.ts +18 -0
- package/lib/types/client/right-tabs/live-delivery.d.ts +8 -0
- package/lib/types/client/right-tabs/navigation.d.ts +17 -0
- package/lib/types/client/right-tabs/page.d.ts +36 -0
- package/lib/types/client/right-tabs/styles.d.ts +2 -0
- package/lib/types/client/rpc.d.ts +3 -0
- package/lib/types/client/semantic-reference.d.ts +4 -0
- package/lib/types/client/workspace-header-action.d.ts +7 -0
- package/lib/types/client/workspace-shortcuts.d.ts +15 -0
- package/lib/types/client.d.ts +9 -124
- package/lib/types/compatibility.d.ts +3 -3
- package/lib/types/datasource/authoring.d.ts +35 -0
- package/lib/types/datasource/bridge.d.ts +43 -4
- package/lib/types/datasource/changes-contract.d.ts +18 -0
- package/lib/types/datasource/changes.d.ts +15 -0
- package/lib/types/datasource/configure.d.ts +7 -0
- package/lib/types/datasource/defaults.d.ts +7 -0
- package/lib/types/datasource/index.d.ts +8 -5
- package/lib/types/datasource/python-options.d.ts +9 -0
- package/lib/types/datasource/python.d.ts +19 -0
- package/lib/types/datasource/resolver-program.d.ts +6 -0
- package/lib/types/datasource/rpc.d.ts +5 -0
- package/lib/types/datasource/service.d.ts +155 -0
- package/lib/types/datasource/shell-env.d.ts +0 -29
- package/lib/types/datasource/test.d.ts +6 -29
- package/lib/types/disclosure/activation.d.ts +2 -1
- package/lib/types/disclosure/execution-guidance.d.ts +6 -0
- package/lib/types/disclosure/help.d.ts +1 -1
- package/lib/types/environment/binding.d.ts +5 -1
- package/lib/types/environment/errors.d.ts +1 -1
- package/lib/types/environment/runtime.d.ts +5 -5
- package/lib/types/environment/types.d.ts +15 -3
- package/lib/types/environment/workspace.d.ts +1 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/lifecycle.d.ts +8 -0
- package/lib/types/plugin-agents.d.ts +27 -0
- package/lib/types/plugin.d.ts +14 -24
- package/lib/types/presentation/asset.d.ts +6 -0
- package/lib/types/presentation/build/index.d.ts +16 -0
- package/lib/types/presentation/commit.d.ts +4 -0
- package/lib/types/presentation/contracts/asset-path.d.ts +2 -0
- package/lib/types/presentation/contracts/catalog.d.ts +27 -0
- package/lib/types/presentation/contracts/charts.d.ts +11 -0
- package/lib/types/presentation/contracts/editing.d.ts +8 -0
- package/lib/types/presentation/contracts/index.d.ts +11 -0
- package/lib/types/presentation/contracts/interaction.d.ts +8 -0
- package/lib/types/presentation/contracts/types.d.ts +255 -0
- package/lib/types/presentation/contracts/values.d.ts +9 -0
- package/lib/types/presentation/delivery.d.ts +3 -0
- package/lib/types/presentation/export-html.d.ts +13 -0
- package/lib/types/presentation/files.d.ts +7 -0
- package/lib/types/presentation/index.d.ts +6 -0
- package/lib/types/presentation/lint.d.ts +13 -0
- package/lib/types/presentation/projection/files.d.ts +2 -0
- package/lib/types/presentation/projection/index.d.ts +20 -0
- package/lib/types/presentation/projection/program.d.ts +2 -0
- package/lib/types/presentation/projection/sql-code.d.ts +2 -0
- package/lib/types/presentation/receipt.d.ts +14 -0
- package/lib/types/presentation/reports.d.ts +10 -0
- package/lib/types/presentation/rpc.d.ts +25 -0
- package/lib/types/presentation/tool.d.ts +12 -0
- package/lib/types/python-execution-contracts.d.ts +10 -0
- package/lib/types/python-execution.d.ts +10 -0
- package/lib/types/report-publishing/adapters.d.ts +6 -0
- package/lib/types/report-publishing/config.d.ts +22 -0
- package/lib/types/report-publishing/service.d.ts +68 -0
- package/lib/types/rpc.d.ts +3 -0
- package/lib/types/semantic-browser/contracts.d.ts +47 -0
- package/lib/types/semantic-browser/definition.d.ts +20 -0
- package/lib/types/semantic-browser/program.d.ts +2 -0
- package/lib/types/semantic-browser/service.d.ts +26 -0
- package/lib/types/semantic-reference/bridge.d.ts +12 -0
- package/lib/types/semantic-reference/contracts.d.ts +54 -0
- package/lib/types/semantic-reference/environment.d.ts +22 -0
- package/lib/types/semantic-reference/index.d.ts +3 -0
- package/lib/types/semantic-reference/labels.d.ts +16 -0
- package/lib/types/semantic-reference/rpc.d.ts +15 -0
- package/lib/types/semantic-reference/search.d.ts +10 -0
- package/lib/types/semantic-reference/usage.d.ts +43 -0
- package/lib/types/tool-lifecycle.d.ts +4 -0
- package/lib/types/workspace-identity.d.ts +6 -0
- package/lib/workspace-identity.js +9 -0
- package/package.json +99 -53
- package/python/presentation-kit/dist/dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl +0 -0
- package/skills/dsh-data-analysis-files/SKILL.md +32 -0
- package/skills/dsh-data-analysis-files/references/examples.md +93 -0
- package/skills/dsh-data-analysis-presentation/SKILL.md +28 -0
- package/skills/dsh-data-analysis-presentation/references/chart-examples.md +18 -0
- package/skills/dsh-data-analysis-presentation/references/charts.md +55 -0
- package/skills/dsh-data-analysis-presentation/references/examples/artifact.draft.json +36 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-bins.dataset.json +33 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-boxes.dataset.json +45 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-composition.dataset.json +33 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-funnel.dataset.json +27 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-precision.dataset.json +21 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-series.dataset.json +58 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-shares.dataset.json +33 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts-waterfall.dataset.json +44 -0
- package/skills/dsh-data-analysis-presentation/references/examples/charts.draft.json +393 -0
- package/skills/dsh-data-analysis-presentation/references/examples/comparison-selected.dataset.json +24 -0
- package/skills/dsh-data-analysis-presentation/references/examples/comparison-summary.dataset.json +22 -0
- package/skills/dsh-data-analysis-presentation/references/examples/comparison.dataset.json +18 -0
- package/skills/dsh-data-analysis-presentation/references/examples/comparison.draft.json +80 -0
- package/skills/dsh-data-analysis-presentation/references/examples/computed-sources.draft.json +42 -0
- package/skills/dsh-data-analysis-presentation/references/examples/computed.dataset.json +12 -0
- package/skills/dsh-data-analysis-presentation/references/examples/computed.draft.json +58 -0
- package/skills/dsh-data-analysis-presentation/references/examples/interaction-detail.dataset.json +30 -0
- package/skills/dsh-data-analysis-presentation/references/examples/interaction-summary.dataset.json +22 -0
- package/skills/dsh-data-analysis-presentation/references/examples/interaction.draft.json +279 -0
- package/skills/dsh-data-analysis-presentation/references/examples/source-only.draft.json +27 -0
- package/skills/dsh-data-analysis-presentation/references/examples/write-charts.py +73 -0
- package/skills/dsh-data-analysis-presentation/references/examples/write-comparison.py +42 -0
- package/skills/dsh-data-analysis-presentation/references/examples/write-computed.py +21 -0
- package/skills/dsh-data-analysis-presentation/references/examples/write-interaction.py +33 -0
- package/skills/dsh-data-analysis-presentation/references/examples.md +44 -0
- package/skills/dsh-data-analysis-presentation/references/export-html.md +7 -0
- package/skills/dsh-data-analysis-presentation/references/interaction.md +56 -0
- package/skills/dsh-data-analysis-presentation/references/narrative.md +37 -0
- package/skills/dsh-data-analysis-presentation/references/publishing.md +3 -0
- package/skills/dsh-data-analysis-presentation/references/schema.md +162 -0
- package/lib/datasource/access.js +0 -60
- package/lib/datasource/credentials.js +0 -24
- package/lib/evidence/bridge-program.js +0 -153
- package/lib/evidence/bridge.js +0 -166
- package/lib/evidence/index.js +0 -2
- package/lib/evidence/sources.js +0 -263
- package/lib/types/datasource/access.d.ts +0 -27
- package/lib/types/evidence/bridge.d.ts +0 -40
- package/lib/types/evidence/index.d.ts +0 -4
- package/lib/types/evidence/sources.d.ts +0 -57
- package/python/report-kit/dist/dsh_data_analysis_report_kit-3.0.0-py3-none-any.whl +0 -0
- package/skills/dsh-data-analysis-report/SKILL.md +0 -57
- package/skills/dsh-data-analysis-report/assets/marivo-artifact.js +0 -113
- package/skills/dsh-data-analysis-report/assets/marivo-session-dag.js +0 -1201
- package/skills/dsh-data-analysis-report/assets/report-data.js +0 -449
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Presentation-only translations of public Runtime descriptions, not a field schema.
|
|
2
|
+
// Match the complete source text so changed or newly added descriptions retain their meaning.
|
|
3
|
+
const descriptions = {
|
|
4
|
+
'Global datasource name; letters, digits, underscores, and hyphens only.': 'marivo.credentials.global-datasource-name-use-only-letters-numbers-underscores-and',
|
|
5
|
+
'Rare JSON-safe ibis keyword arguments not modeled by the typed class.': 'marivo.credentials.additional-connection-parameters-for-ibis-options-not-listed-in',
|
|
6
|
+
'DuckDB database path; defaults to in-memory.': 'marivo.credentials.duckdb-database-file-path-defaults-to-an-in-memory',
|
|
7
|
+
'SQLite database path; defaults to in-memory.': 'marivo.credentials.sqlite-database-file-path-defaults-to-an-in-memory',
|
|
8
|
+
'Open the DuckDB database in read-only mode.': 'marivo.credentials.open-the-duckdb-database-in-read-only-mode',
|
|
9
|
+
'Open the SQLite database in query-only mode.': 'marivo.credentials.open-the-sqlite-database-in-query-only-mode',
|
|
10
|
+
'Optional mapping from declared SQLite type names to Ibis type strings.': 'marivo.credentials.optional-mapping-from-sqlite-declared-type-names-to-ibis',
|
|
11
|
+
'Optional HTTP(S) URL prefix for scoped remote JSON auth.': 'marivo.credentials.optional-http-s-url-prefix-where-remote-json-requests',
|
|
12
|
+
'Environment variable for a scoped HTTP bearer token.': 'marivo.credentials.credential-reference-for-the-http-bearer-token-within-the',
|
|
13
|
+
'Optional custom HTTP header names mapped to secret environment variables.': 'marivo.credentials.optional-mapping-from-custom-http-header-names-to-credential',
|
|
14
|
+
'Trino coordinator host.': 'marivo.credentials.trino-coordinator-host-address',
|
|
15
|
+
'Trino catalog; mapped to ibis database at connect time.': 'marivo.credentials.trino-catalog-name-mapped-to-the-ibis-database-parameter',
|
|
16
|
+
'Required environment variable for the Trino user.': 'marivo.credentials.required-credential-reference-for-the-trino-username',
|
|
17
|
+
'Trino port; ibis default is 8080.': 'marivo.credentials.trino-port-ibis-defaults-to-8080',
|
|
18
|
+
'Optional default schema.': 'marivo.credentials.optional-default-schema-name',
|
|
19
|
+
'Optional client application/source tag.': 'marivo.credentials.optional-client-application-or-request-source-identifier',
|
|
20
|
+
'Optional engine session timezone.': 'marivo.credentials.optional-database-session-timezone',
|
|
21
|
+
"Set to 'https' for TLS.": 'marivo.credentials.enter-https-to-enable-tls-encryption',
|
|
22
|
+
'Optional Trino client tags.': 'marivo.credentials.optional-trino-client-tags-as-a-json-array',
|
|
23
|
+
'Optional Trino session properties.': 'marivo.credentials.optional-trino-session-properties-as-a-json-object',
|
|
24
|
+
'Environment variable for Trino auth token or password.': 'marivo.credentials.credential-reference-for-the-trino-token-or-password',
|
|
25
|
+
'MySQL host.': 'marivo.credentials.mysql-server-host-address',
|
|
26
|
+
'MySQL database name.': 'marivo.credentials.mysql-database-name',
|
|
27
|
+
'MySQL port; ibis default is 3306.': 'marivo.credentials.mysql-port-ibis-defaults-to-3306',
|
|
28
|
+
'Optional autocommit override.': 'marivo.credentials.optional-setting-for-automatic-transaction-commits',
|
|
29
|
+
'Environment variable for MySQL user.': 'marivo.credentials.credential-reference-for-the-mysql-username',
|
|
30
|
+
'Environment variable for MySQL password.': 'marivo.credentials.credential-reference-for-the-mysql-password',
|
|
31
|
+
'Postgres host.': 'marivo.credentials.postgresql-server-host-address',
|
|
32
|
+
'Postgres database name.': 'marivo.credentials.postgresql-database-name',
|
|
33
|
+
'Postgres port; ibis default is 5432.': 'marivo.credentials.postgresql-port-ibis-defaults-to-5432',
|
|
34
|
+
'Environment variable for Postgres user.': 'marivo.credentials.credential-reference-for-the-postgresql-username',
|
|
35
|
+
'Environment variable for Postgres password.': 'marivo.credentials.credential-reference-for-the-postgresql-password',
|
|
36
|
+
'ClickHouse host.': 'marivo.credentials.clickhouse-server-host-address',
|
|
37
|
+
'ClickHouse port; native default is 9000, secure default is 9440.': 'marivo.credentials.clickhouse-port-native-connections-default-to-9000-secure-connections',
|
|
38
|
+
"ClickHouse database; ibis default is 'default'.": 'marivo.credentials.clickhouse-database-name-ibis-defaults-to-default',
|
|
39
|
+
'Enable TLS for ClickHouse.': 'marivo.credentials.enable-tls-encryption-for-clickhouse',
|
|
40
|
+
'Optional ClickHouse settings map.': 'marivo.credentials.optional-clickhouse-settings-as-a-json-object',
|
|
41
|
+
'Environment variable for ClickHouse user.': 'marivo.credentials.credential-reference-for-the-clickhouse-username',
|
|
42
|
+
'Environment variable for ClickHouse password.': 'marivo.credentials.credential-reference-for-the-clickhouse-password',
|
|
43
|
+
};
|
|
44
|
+
export function datasourceDescription(description) {
|
|
45
|
+
return descriptions[description] ?? description;
|
|
46
|
+
}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState, useSyncExternalStore } from 'react';
|
|
3
|
+
import { useCopy } from "./../i18n/context.js";
|
|
4
|
+
import { localized } from "../i18n/host.js";
|
|
5
|
+
import { CreateDatasource } from "./create-datasource.js";
|
|
6
|
+
import { CredentialClientModel, credentialMessage } from "./model.js";
|
|
7
|
+
import { ReportPublishingCredentials } from "./report-publishing.js";
|
|
8
|
+
import { credentialStyles } from "./styles.js";
|
|
9
|
+
const statusLabels = {
|
|
10
|
+
'awaiting-input': 'marivo.credentials.awaiting-input',
|
|
11
|
+
executing: 'marivo.credentials.saving-or-validating-77',
|
|
12
|
+
'awaiting-decision': 'marivo.credentials.connection-validation-failed-action-needed',
|
|
13
|
+
succeeded: 'marivo.credentials.validated-original-call-continues',
|
|
14
|
+
'handed-off': 'marivo.credentials.handed-to-the-assistant-for-investigation',
|
|
15
|
+
'call-ended': 'marivo.credentials.original-call-ended',
|
|
16
|
+
cancelled: 'marivo.credentials.configuration-request-cancelled',
|
|
17
|
+
'context-changed': 'marivo.credentials.context-changed',
|
|
18
|
+
};
|
|
19
|
+
export function CredentialIcon({ name, size = 18 }) {
|
|
20
|
+
return (_jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [name === 'database' && (_jsxs(_Fragment, { children: [_jsx("ellipse", { cx: "12", cy: "5", rx: "8", ry: "3" }), _jsx("path", { d: "M4 5v14c0 4 16 4 16 0V5M4 12c0 4 16 4 16 0" })] })), name === 'refresh' && (_jsx("path", { d: "M20 7v5h-5M4 17v-5h5M6.1 6a8 8 0 0 1 13.4 3M4.5 15a8 8 0 0 0 13.4 3" })), name === 'add' && _jsx("path", { d: "M12 5v14M5 12h14" }), name === 'edit' && _jsx("path", { d: "m16 3 5 5L9 20l-6 1 1-6L16 3ZM13 6l5 5" }), name === 'delete' && _jsx("path", { d: "M3 6h18M9 6V3h6v3M5 6l1 15h12l1-15M10 10v7m4-7v7" }), name === 'test' && (_jsx("path", { d: "M9 3h6M10 3v6l-6 10a1.3 1.3 0 0 0 1 2h14a1.3 1.3 0 0 0 1-2L14 9V3M7 15h10" })), name === 'check' && _jsx("path", { d: "m5 12 4 4L19 6" }), name === 'info' && (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "12", r: "9" }), _jsx("path", { d: "M12 11v6m0-10v.01" })] }))] }));
|
|
21
|
+
}
|
|
22
|
+
export function TestResult({ result, stale = false }) {
|
|
23
|
+
const t = useCopy();
|
|
24
|
+
if (!result)
|
|
25
|
+
return null;
|
|
26
|
+
return (_jsxs("div", { className: "mc-result", "data-tone": t(stale ? 'stale' : result.ok ? 'success' : 'error'), role: "status", children: [_jsxs("div", { className: "mc-result-title", children: [_jsx(CredentialIcon, { name: stale || !result.ok ? 'info' : 'check', size: 16 }), stale
|
|
27
|
+
? t('marivo.credentials.configuration-changed-test-again')
|
|
28
|
+
: result.ok
|
|
29
|
+
? t('marivo.credentials.connection-test-succeeded')
|
|
30
|
+
: t('marivo.credentials.connection-test-failed')] }), !result.ok && !stale && (_jsxs(_Fragment, { children: [_jsx("p", { children: t(result.failure?.message) }), result.repair?.action && _jsx("p", { children: result.repair.action }), result.failure?.code && (_jsxs("details", { children: [_jsx("summary", { children: t('marivo.credentials.show-error-code') }), _jsx("pre", { children: result.failure.code })] }))] }))] }));
|
|
31
|
+
}
|
|
32
|
+
function OperationOutcome({ entry }) {
|
|
33
|
+
const t = useCopy();
|
|
34
|
+
if (!entry)
|
|
35
|
+
return null;
|
|
36
|
+
const operation = entry.operation;
|
|
37
|
+
const errors = operation?.errors ?? [];
|
|
38
|
+
if (operation?.action === 'delete-datasource')
|
|
39
|
+
return (_jsxs("div", { className: "mc-operation-note", "data-error": operation.status !== 'succeeded', role: "status", children: [_jsx("p", { children: operation.datasourceRemoved
|
|
40
|
+
? t('marivo.credentials.datasource-value-was-deleted', { p0: entry.name })
|
|
41
|
+
: t('marivo.credentials.deletion-of-datasource-value-is-unconfirmed-refresh-the-list', {
|
|
42
|
+
p0: entry.name,
|
|
43
|
+
}) }), operation.datasourceRemoved && !operation.deleteCredentials && (_jsx("p", { children: t('marivo.credentials.associated-saved-credentials-were-retained') })), operation.deletedCredentials?.length > 0 && (_jsxs("p", { children: [t('marivo.credentials.deleted-credentials'), operation.deletedCredentials.join('、'), "\u3002"] })), operation.credentialDeleteFailures?.length > 0 && (_jsxs("p", { children: [t('marivo.credentials.credentials-that-could-not-be-deleted'), operation.credentialDeleteFailures.join('、'), "\u3002"] })), operation.status === 'cancelled' && (_jsx("p", { children: t('marivo.credentials.operation-cancelled-completed-deletions-remain-other-credentials-may-still') })), errors.length > 0 && _jsx("p", { children: errors.map(credentialMessage).join(' ') })] }));
|
|
44
|
+
const unsuccessful = entry.error ||
|
|
45
|
+
operation?.status === 'cancelled' ||
|
|
46
|
+
operation?.status === 'failed' ||
|
|
47
|
+
operation?.result?.ok === false;
|
|
48
|
+
if (!unsuccessful && operation?.action !== 'delete')
|
|
49
|
+
return null;
|
|
50
|
+
return (_jsxs("div", { className: "mc-operation-note", "data-error": t(Boolean(entry.error || errors.length)), role: "status", children: [entry.error && _jsx("p", { children: t(entry.error) }), operation?.status === 'cancelled' && (_jsx("p", { children: t('marivo.credentials.this-operation-was-cancelled') })), operation?.status === 'succeeded' && operation.action === 'delete' && (_jsx("p", { children: t('marivo.credentials.saved-value-deleted-configuration-status-updated') })), errors.length > 0 && _jsx("p", { children: errors.map(credentialMessage).join(' ') }), operation?.status === 'failed' && errors.length === 0 && !operation.result && (_jsx("p", { children: t('marivo.credentials.operation-incomplete-please-retry') })), unsuccessful && operation?.saved.length > 0 && (_jsxs("p", { children: [t('marivo.credentials.saved'), operation.saved.join('、'), "\u3002"] }))] }));
|
|
51
|
+
}
|
|
52
|
+
export function DatasourceProperties({ context }) {
|
|
53
|
+
const t = useCopy();
|
|
54
|
+
const properties = Object.entries(context.properties ?? {});
|
|
55
|
+
return (_jsxs("section", { className: "mc-properties", "aria-label": t('marivo.credentials.datasource-properties'), children: [_jsx("h4", { className: "mc-section-heading", children: t('marivo.credentials.datasource-properties') }), _jsxs("dl", { className: "mc-property-list", children: [_jsxs("div", { className: "mc-property", children: [_jsx("dt", { children: t('marivo.credentials.engine') }), _jsx("dd", { children: context.backend || t('marivo.credentials.not-provided') })] }), properties.map(([field, value]) => (_jsxs("div", { className: "mc-property", children: [_jsx("dt", { children: field }), _jsx("dd", { children: value !== null && typeof value === 'object' ? (_jsx("section", { className: "mc-property-json",
|
|
56
|
+
// biome-ignore lint/a11y/noNoninteractiveTabindex: Keyboard users must be able to scroll long JSON values.
|
|
57
|
+
tabIndex: 0, "aria-label": t('marivo.credentials.value-configuration-value', { p0: field }), children: _jsx("pre", { children: JSON.stringify(value, null, 2) }) })) : (_jsx("span", { children: typeof value === 'string' && value !== '' ? value : JSON.stringify(value) })) })] }, field)))] })] }));
|
|
58
|
+
}
|
|
59
|
+
function CredentialForm({ context, request, state, model, workspaceId, onEdit }) {
|
|
60
|
+
const t = useCopy();
|
|
61
|
+
const [values, setValues] = useState({});
|
|
62
|
+
const [editing, setEditing] = useState({});
|
|
63
|
+
const [deleting, setDeleting] = useState('');
|
|
64
|
+
const [removingDatasource, setRemovingDatasource] = useState(false);
|
|
65
|
+
const [removeCredentials, setRemoveCredentials] = useState(false);
|
|
66
|
+
const busy = request?.status === 'executing' ||
|
|
67
|
+
state.operations.some((entry) => entry.handle.scope === context.token);
|
|
68
|
+
const ended = request?.endedAt !== undefined;
|
|
69
|
+
const configured = context.refs.filter((ref) => context.credentials[ref]?.configured).length;
|
|
70
|
+
const ready = configured === context.refs.length;
|
|
71
|
+
const outcome = state.outcomes[context.token];
|
|
72
|
+
const latestTest = !outcome?.overviewUpdated && outcome?.operation?.result
|
|
73
|
+
? { result: outcome.operation.result, at: outcome.operation.endedAt, stale: false }
|
|
74
|
+
: context.lastTest;
|
|
75
|
+
const latestResult = request?.failure ?? latestTest?.result;
|
|
76
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Identity or credential revision changes must discard unsubmitted secrets.
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
setValues({});
|
|
79
|
+
setEditing({});
|
|
80
|
+
setDeleting('');
|
|
81
|
+
setRemovingDatasource(false);
|
|
82
|
+
setRemoveCredentials(false);
|
|
83
|
+
}, [context.token, context.version]);
|
|
84
|
+
const saveReference = (ref) => {
|
|
85
|
+
const changes = { [ref]: values[ref] };
|
|
86
|
+
setValues({ ...values, [ref]: '' });
|
|
87
|
+
setEditing({ ...editing, [ref]: false });
|
|
88
|
+
void model.start(context, 'save', changes);
|
|
89
|
+
};
|
|
90
|
+
const submit = () => {
|
|
91
|
+
const changes = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== ''));
|
|
92
|
+
setValues({});
|
|
93
|
+
setEditing({});
|
|
94
|
+
void model.start(context, request ? 'submit' : 'update', changes);
|
|
95
|
+
};
|
|
96
|
+
return (_jsxs("section", { className: "mc-form", "aria-label": t('marivo.credentials.value-credential-configuration', { p0: context.name }), children: [_jsxs("div", { className: "mc-form-body", children: [_jsxs("div", { className: "mc-detail-heading mc-datasource-heading", children: [_jsx("p", { className: "mc-eyebrow", children: t('marivo.credentials.datasource-configuration') }), _jsxs("div", { className: "mc-name-row", children: [_jsx("h3", { children: context.name }), _jsxs("div", { className: "mc-heading-actions", children: [_jsxs("span", { className: "mc-badge", "data-ready": ready, children: [ready && _jsx(CredentialIcon, { name: "check", size: 13 }), context.refs.length === 0
|
|
97
|
+
? t('marivo.credentials.no-credentials-required')
|
|
98
|
+
: ready
|
|
99
|
+
? t('marivo.credentials.all-credentials-configured')
|
|
100
|
+
: t('marivo.credentials.value-value-configured', {
|
|
101
|
+
p0: configured,
|
|
102
|
+
p1: context.refs.length,
|
|
103
|
+
})] }), !ended && (_jsx("button", { className: "mc-icon-button", type: "button", title: t('marivo.credentials.edit-configuration'), "aria-label": t('marivo.credentials.edit-configuration'), disabled: busy, onClick: onEdit, children: _jsx(CredentialIcon, { name: "edit" }) })), !request && (_jsx("button", { className: "mc-icon-button mc-danger", type: "button", title: t('marivo.credentials.delete-datasource'), "aria-label": t('marivo.credentials.delete-datasource'), disabled: busy || state.loading, onClick: () => setRemovingDatasource(true), children: _jsx(CredentialIcon, { name: "delete" }) }))] })] })] }), removingDatasource && (_jsxs("fieldset", { className: "mc-confirm", "aria-label": t('marivo.credentials.confirm-datasource-deletion'), children: [_jsxs("p", { children: [t('marivo.credentials.confirm-datasource-deletion'), context.name, t('marivo.credentials.this-removes-the-datasource-definition-from-this-workspace-not')] }), context.refs.length > 0 && (_jsxs(_Fragment, { children: [_jsxs("label", { children: [_jsx("input", { type: "checkbox", checked: removeCredentials, disabled: busy, onChange: (event) => setRemoveCredentials(event.target.checked) }), ' ', t('marivo.credentials.also-delete-associated-saved-credentials')] }), _jsxs("p", { children: [t('marivo.credentials.credential-references'), context.refs.join('、'), t('marivo.credentials.other-datasources-or-workspaces-may-share-these-credentials-and')] })] })), _jsx("button", { className: "mc-danger", type: "button", disabled: busy || state.loading, onClick: () => {
|
|
104
|
+
setRemovingDatasource(false);
|
|
105
|
+
void model.start(context, 'delete-datasource', {}, undefined, removeCredentials);
|
|
106
|
+
}, children: t('marivo.credentials.confirm-datasource-deletion') }), _jsx("button", { type: "button", disabled: busy, onClick: () => {
|
|
107
|
+
setRemovingDatasource(false);
|
|
108
|
+
setRemoveCredentials(false);
|
|
109
|
+
}, children: t('marivo.credentials.cancel') })] })), request && (_jsxs("div", { className: "mc-request-status", role: "status", children: [_jsx("strong", { children: t(statusLabels[request.status]) }), !ended && (_jsx("p", { children: t('marivo.credentials.continue-the-current-task-after-successful-validation') })), (request.status === 'call-ended' || request.status === 'context-changed') && (_jsx("p", { children: t('marivo.credentials.start-the-task-again') }))] })), _jsx(DatasourceProperties, { context: context }), _jsx("h4", { className: "mc-section-heading", children: t('marivo.credentials.credentials') }), context.refs.length === 0 && (_jsx("p", { className: "mc-note", children: t('marivo.credentials.this-datasource-has-no-credential-references-you-can-test') })), context.refs.length > 0 && (_jsx("div", { className: "mc-fields", children: context.refs.map((ref) => {
|
|
110
|
+
const info = context.credentials[ref];
|
|
111
|
+
const shared = state.datasources
|
|
112
|
+
.filter((item) => item.refs.includes(ref))
|
|
113
|
+
.map((item) => item.name);
|
|
114
|
+
return (_jsxs("fieldset", { className: "mc-field", disabled: busy || ended, "aria-label": ref, children: [_jsxs("div", { className: "mc-field-header", children: [_jsxs("div", { className: "mc-field-title", children: [_jsx("h4", { children: ref }), _jsxs("p", { children: [t('marivo.credentials.field'), Object.entries(context.fields)
|
|
115
|
+
.filter(([, value]) => value === ref)
|
|
116
|
+
.map(([field]) => field)
|
|
117
|
+
.join('、'), ' ', t('marivo.credentials.source'), info?.source ?? t('marivo.credentials.none'), !info?.writable && t('marivo.credentials.read-only-source')] })] }), _jsxs("div", { className: "mc-field-actions", children: [_jsx("span", { className: "mc-badge", "data-ready": Boolean(info?.configured), children: info?.configured
|
|
118
|
+
? t('marivo.credentials.configured')
|
|
119
|
+
: t('marivo.credentials.not-configured') }), info?.writable && info.configured && !editing[ref] && (_jsx("button", { type: "button", onClick: () => setEditing({ ...editing, [ref]: true }), children: t('marivo.credentials.replace') })), info?.writable && info.configured && editing[ref] && (_jsx("button", { type: "button", onClick: () => {
|
|
120
|
+
setValues({ ...values, [ref]: '' });
|
|
121
|
+
setEditing({ ...editing, [ref]: false });
|
|
122
|
+
}, children: t('marivo.credentials.cancel-replacement') })), info?.writable && !request && info.configured && (_jsx("button", { className: "mc-danger", type: "button", onClick: () => setDeleting(ref), children: t('marivo.credentials.delete-saved-value') }))] })] }), info?.writable && (!info.configured || editing[ref]) && (_jsxs("label", { className: "mc-secret-input", children: [t('marivo.credentials.new-value'), _jsx("input", { type: "password", autoComplete: "new-password", placeholder: t('marivo.credentials.enter-credential-value-127'), value: values[ref] ?? '', onChange: (event) => setValues({ ...values, [ref]: event.target.value }) }), !request && (_jsx("button", { type: "button", className: "mc-primary", disabled: !values[ref], onClick: () => saveReference(ref), children: info.configured
|
|
123
|
+
? t('marivo.credentials.confirm-replacement')
|
|
124
|
+
: t('marivo.credentials.add-credential') }))] })), shared.length > 1 && (_jsxs("p", { className: "mc-field-note", children: [t('marivo.credentials.and'), shared.filter((name) => name !== context.name).join('、'), ' ', t('marivo.credentials.share-this-reference')] })), deleting === ref && (_jsxs("div", { className: "mc-confirm", children: [_jsxs("p", { children: [t('marivo.credentials.confirm-deletion-of'), ref, " ", t('marivo.credentials.the-saved-value')] }), _jsx("button", { className: "mc-danger", type: "button", onClick: () => {
|
|
125
|
+
setDeleting('');
|
|
126
|
+
void model.start(context, 'delete', {}, ref);
|
|
127
|
+
}, children: t('marivo.credentials.confirm-saved-value-deletion') }), _jsx("button", { type: "button", onClick: () => setDeleting(''), children: t('marivo.credentials.keep') })] }))] }, ref));
|
|
128
|
+
}) })), _jsxs("div", { className: "mc-test", children: [_jsxs("div", { className: "mc-test-heading", children: [_jsx("h4", { children: t('marivo.credentials.connection-status') }), _jsxs("div", { className: "mc-heading-actions", children: [latestTest?.at !== undefined && (_jsxs("time", { dateTime: new Date(latestTest.at).toISOString(), children: [t('marivo.credentials.last-test'), new Date(latestTest.at).toLocaleString()] })), !request && (_jsx("button", { className: "mc-icon-button", type: "button", title: t('marivo.credentials.test-connection'), "aria-label": t('marivo.credentials.test-connection'), disabled: busy, onClick: () => void model.start(context, 'test'), children: _jsx(CredentialIcon, { name: "test" }) }))] })] }), latestResult ? (_jsx(TestResult, { result: latestResult, stale: !request?.failure && latestTest?.stale })) : (_jsx("p", { className: "mc-empty-test", children: t('marivo.credentials.connection-has-not-been-tested') })), outcome?.operation?.action !== 'delete-datasource' && (_jsx(OperationOutcome, { entry: outcome }))] })] }), !ended && (request || busy) && (_jsxs("div", { className: "mc-form-footer", children: [request && (_jsx("button", { className: "mc-primary", type: "button", disabled: busy, onClick: submit, children: t('marivo.credentials.submit-credentials-and-continue') })), request && (_jsx("button", { type: "button", disabled: busy, onClick: () => void model.start(context, 'submit'), children: t('marivo.credentials.validate-existing-configuration-and-continue') })), request?.failure && (_jsx("button", { type: "button", disabled: busy, onClick: () => void model.start(context, 'diagnose'), children: t('marivo.credentials.ask-the-assistant-to-investigate') })), request ? (_jsx("button", { className: "mc-quiet mc-cancel", type: "button", onClick: () => void model.cancelRequest(request.id), children: t('marivo.credentials.cancel-this-round') })) : (busy && (_jsx("button", { className: "mc-quiet mc-cancel", type: "button", onClick: () => void model.cancelOperation(context.token), children: t('marivo.credentials.cancel-operation') })))] })), ended && (_jsx("div", { className: "mc-form-footer", children: _jsx("button", { type: "button", onClick: () => model.show(workspaceId), children: t('marivo.credentials.back-to-datasource-management') }) }))] }));
|
|
129
|
+
}
|
|
130
|
+
export function CredentialPanel({ model, workspaces, onRefresh }) {
|
|
131
|
+
const t = useCopy();
|
|
132
|
+
const state = useSyncExternalStore(model.subscribe, model.getSnapshot);
|
|
133
|
+
const columns = useRef(null);
|
|
134
|
+
const navigation = useRef(null);
|
|
135
|
+
const main = useRef(null);
|
|
136
|
+
const [creating, setCreating] = useState(false);
|
|
137
|
+
const [editingName, setEditingName] = useState('');
|
|
138
|
+
const [requestError, setRequestError] = useState('');
|
|
139
|
+
const [requestChoice, setRequestChoice] = useState('create');
|
|
140
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Switching context discards the creation form.
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
setCreating(false);
|
|
143
|
+
setEditingName('');
|
|
144
|
+
setRequestError('');
|
|
145
|
+
setRequestChoice('create');
|
|
146
|
+
}, [state.open, state.workspaceId, state.requestId]);
|
|
147
|
+
const request = state.requests.find((item) => item.id === state.requestId);
|
|
148
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Open the initial form once per request occurrence; live watch updates must preserve user navigation.
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (!request?.configuration || request.context || request.endedAt !== undefined)
|
|
151
|
+
return;
|
|
152
|
+
setCreating(true);
|
|
153
|
+
setEditingName(request.configuration.mode === 'edit' ? request.configuration.name : '');
|
|
154
|
+
}, [request?.id, state.open]);
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
if (request?.endedAt === undefined)
|
|
157
|
+
return;
|
|
158
|
+
setCreating(false);
|
|
159
|
+
setEditingName('');
|
|
160
|
+
}, [request?.endedAt]);
|
|
161
|
+
const pending = state.requests.filter((item) => item.endedAt === undefined && item.sessionId === state.sessionId);
|
|
162
|
+
const context = request
|
|
163
|
+
? request.context
|
|
164
|
+
: state.datasources.find((item) => item.token === state.selected);
|
|
165
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: A different detail or creation page starts at the top of its content.
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (main.current) {
|
|
168
|
+
main.current.scrollTop = 0;
|
|
169
|
+
const page = main.current.closest('.rt-page');
|
|
170
|
+
if (page)
|
|
171
|
+
page.scrollTop = 0;
|
|
172
|
+
}
|
|
173
|
+
if (columns.current)
|
|
174
|
+
columns.current.scrollTop = 0;
|
|
175
|
+
const list = navigation.current;
|
|
176
|
+
const selected = list?.querySelector('[aria-pressed="true"]');
|
|
177
|
+
if (selected) {
|
|
178
|
+
const bounds = selected.getBoundingClientRect();
|
|
179
|
+
const viewport = list.getBoundingClientRect();
|
|
180
|
+
if (bounds.left < viewport.left)
|
|
181
|
+
list.scrollLeft += bounds.left - viewport.left;
|
|
182
|
+
else if (bounds.right > viewport.right)
|
|
183
|
+
list.scrollLeft += bounds.right - viewport.right;
|
|
184
|
+
}
|
|
185
|
+
}, [creating, context?.token]);
|
|
186
|
+
const workspaceId = request
|
|
187
|
+
? (workspaces.find((item) => item.sessionIds.includes(request.sessionId))?.workspaceId ?? '')
|
|
188
|
+
: state.workspaceId;
|
|
189
|
+
const datasources = request ? (request.context ? [request.context] : []) : state.datasources;
|
|
190
|
+
const operations = state.operations.filter((entry) => entry.workspaceId === workspaceId);
|
|
191
|
+
const activeOperation = operations.find((entry) => entry.handle.id === state.handle?.id)?.operation;
|
|
192
|
+
if (!state.open)
|
|
193
|
+
return null;
|
|
194
|
+
return (_jsxs("section", { className: "mc-panel", "aria-label": t('marivo.credentials.datasources-and-credentials'), children: [_jsx("style", { children: credentialStyles }), _jsxs("div", { className: "rt-heading-row", children: [_jsx("h2", { className: "rt-heading", children: t('marivo.credentials.datasources-and-credentials') }), _jsxs("div", { className: "mc-heading-actions", children: [!request && (_jsx("button", { className: "mc-icon-button", type: "button", title: t('marivo.credentials.add-datasource'), "aria-label": t('marivo.credentials.add-datasource'), disabled: !workspaceId || state.loading, onClick: () => {
|
|
195
|
+
setEditingName('');
|
|
196
|
+
setCreating(true);
|
|
197
|
+
}, children: _jsx(CredentialIcon, { name: "add" }) })), _jsx("button", { className: "mc-icon-button", type: "button", title: t('marivo.credentials.refresh-datasources'), "aria-label": t('marivo.credentials.refresh-datasources'), disabled: state.loading, onClick: onRefresh ?? (() => void model.refreshDatasources()), children: _jsx(CredentialIcon, { name: "refresh" }) })] })] }), _jsx("p", { className: "rt-caption", children: workspaces.find((item) => item.workspaceId === workspaceId)?.title ?? workspaceId }), _jsxs("div", { className: "mc-shell", children: [(pending.length > 0 || request) && (_jsxs("div", { className: "mc-requests", children: [_jsx("span", { children: pending.length
|
|
198
|
+
? t('marivo.credentials.requests-in-this-session')
|
|
199
|
+
: t('marivo.credentials.configuration-result') }), pending.map((item) => (_jsxs("button", { type: "button", onClick: () => model.openRequest(item.id), children: [item.context?.name ??
|
|
200
|
+
item.configuration?.name ??
|
|
201
|
+
t('marivo.credentials.add-datasource'), ' ', "\u00B7 ", t(statusLabels[item.status])] }, item.id))), request && (_jsx("button", { className: "mc-quiet", type: "button", onClick: () => model.show(workspaceId), children: t('marivo.credentials.datasource-management') }))] })), _jsxs("div", { className: "mc-columns", ref: columns, children: [!request && (_jsx("aside", { className: "mc-nav", "aria-label": t('marivo.credentials.datasource-navigation'), children: _jsxs("div", { children: [_jsx("div", { className: "mc-nav-heading", children: _jsx("h3", { children: request
|
|
202
|
+
? t('marivo.credentials.requested-datasource')
|
|
203
|
+
: t('marivo.credentials.datasource-value', { p0: datasources.length }) }) }), _jsx("ul", { className: "mc-datasources", ref: navigation, children: datasources.map((item) => {
|
|
204
|
+
const count = item.refs.filter((ref) => item.credentials[ref]?.configured).length;
|
|
205
|
+
const ready = count === item.refs.length;
|
|
206
|
+
const running = state.operations.some((entry) => entry.handle.scope === item.token);
|
|
207
|
+
return (_jsx("li", { children: _jsxs("button", { className: "mc-datasource", type: "button", "aria-label": t('marivo.credentials.select-datasource-value', {
|
|
208
|
+
p0: item.name,
|
|
209
|
+
}), "aria-pressed": !creating && context?.token === item.token, onClick: () => {
|
|
210
|
+
if (request)
|
|
211
|
+
model.openRequest(request.id);
|
|
212
|
+
else {
|
|
213
|
+
setCreating(false);
|
|
214
|
+
model.select(item.token);
|
|
215
|
+
}
|
|
216
|
+
}, children: [_jsx(CredentialIcon, { name: "database" }), _jsxs("span", { className: "mc-datasource-copy", children: [_jsx("span", { className: "mc-datasource-name", children: item.name }), _jsxs("span", { className: "mc-datasource-status", children: [_jsx("span", { className: "mc-dot", "data-ready": ready }), running
|
|
217
|
+
? t('marivo.credentials.processing')
|
|
218
|
+
: item.refs.length === 0
|
|
219
|
+
? t('marivo.credentials.no-credentials-required')
|
|
220
|
+
: ready
|
|
221
|
+
? t('marivo.credentials.all-credentials-configured')
|
|
222
|
+
: t('marivo.credentials.value-value-configured', {
|
|
223
|
+
p0: count,
|
|
224
|
+
p1: item.refs.length,
|
|
225
|
+
})] })] })] }) }, item.token));
|
|
226
|
+
}) })] }) })), _jsxs("main", { className: "mc-main", ref: main, children: [Object.values(state.outcomes)
|
|
227
|
+
.filter((entry) => entry.workspaceId === workspaceId &&
|
|
228
|
+
entry.operation?.action === 'delete-datasource')
|
|
229
|
+
.map((entry) => (_jsxs("div", { className: "mc-request-status", children: [_jsx(OperationOutcome, { entry: entry }), _jsx("button", { type: "button", onClick: () => model.dismissOutcome(entry.handle.scope), children: t('marivo.credentials.dismiss-deletion-result') })] }, entry.handle.id))), state.error && (_jsx("p", { role: "alert", className: "mc-alert", children: t(state.error) })), state.loading && (_jsx("p", { className: "mc-loading", role: "status", children: t('marivo.credentials.loading-datasources-and-credential-status') })), !request && !creating && !state.loading && !context && !state.error && (_jsxs("div", { className: "mc-empty", children: [_jsx(CredentialIcon, { name: "database", size: 32 }), _jsx("h3", { children: !state.workspaceId
|
|
230
|
+
? t('marivo.credentials.this-session-is-not-bound-to-a-workspace')
|
|
231
|
+
: state.datasources.length === 0
|
|
232
|
+
? t('marivo.credentials.no-datasources')
|
|
233
|
+
: t('marivo.credentials.select-a-datasource') }), _jsx("p", { children: !state.workspaceId
|
|
234
|
+
? t('marivo.credentials.return-to-the-session-and-retry')
|
|
235
|
+
: state.datasources.length === 0
|
|
236
|
+
? t('marivo.credentials.this-workspace-has-no-defined-datasources')
|
|
237
|
+
: t('marivo.credentials.view-credential-configuration-and-the-latest-connection-test') })] })), request?.configuration && (_jsxs("section", { className: "mc-request-status", "aria-label": t('marivo.credentials.configuration-request'), children: [_jsxs("div", { className: "mc-request-heading", children: [_jsx("h3", { children: t('marivo.credentials.configure-a-datasource-to-continue') }), _jsx("span", { className: "mc-badge", role: "status", children: t(statusLabels[request.status]) }), request.endedAt === undefined && (_jsx("button", { className: "mc-quiet", type: "button", onClick: () => void model.cancelRequest(request.id), children: t('marivo.credentials.cancel-configuration-request') }))] }), _jsxs("details", { className: "mc-request-reason", children: [_jsx("summary", { children: t('marivo.credentials.show-assistant-request-details') }), _jsx("p", { children: t(request.configuration.reason) })] }), requestError && _jsx("p", { role: "alert", children: t(requestError) }), request.endedAt === undefined && request.status !== 'executing' && (_jsxs(_Fragment, { children: [request.configuration.mode === 'create' && !context && (_jsxs(_Fragment, { children: [_jsxs("fieldset", { className: "mc-request-choice", "aria-label": t('marivo.credentials.configuration-method'), children: [_jsx("button", { type: "button", "aria-pressed": requestChoice === 'create', onClick: () => {
|
|
238
|
+
setRequestChoice('create');
|
|
239
|
+
setCreating(true);
|
|
240
|
+
setEditingName('');
|
|
241
|
+
setRequestError('');
|
|
242
|
+
}, children: t('marivo.credentials.add-datasource') }), _jsx("button", { type: "button", "aria-pressed": requestChoice === 'existing', onClick: () => {
|
|
243
|
+
setRequestChoice('existing');
|
|
244
|
+
setCreating(false);
|
|
245
|
+
setEditingName('');
|
|
246
|
+
setRequestError('');
|
|
247
|
+
}, children: t('marivo.credentials.use-an-existing-datasource') })] }), requestChoice === 'existing' && (_jsxs("div", { className: "mc-existing-source", children: [_jsx("p", { children: t('marivo.credentials.if-an-existing-connection-can-access-the-target-table') }), _jsxs("label", { className: "mc-secret-input", children: [t('marivo.credentials.select-an-existing-datasource'), _jsxs("select", { "aria-label": t('marivo.credentials.select-an-existing-datasource'), value: "", onChange: async (event) => {
|
|
248
|
+
if (!event.target.value)
|
|
249
|
+
return;
|
|
250
|
+
try {
|
|
251
|
+
await model.selectConfiguration(workspaceId, request.id, event.target.value);
|
|
252
|
+
setCreating(false);
|
|
253
|
+
setEditingName('');
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
setRequestError(error.message);
|
|
257
|
+
}
|
|
258
|
+
}, children: [_jsx("option", { value: "", children: t('marivo.credentials.please-select') }), state.datasources.map((item) => (_jsx("option", { value: item.name, children: item.name }, item.name)))] })] }), state.datasources.length === 0 && (_jsx("p", { children: t('marivo.credentials.no-reusable-datasource-is-available-switch-to-add-datasource') }))] }))] })), !creating &&
|
|
259
|
+
!context &&
|
|
260
|
+
(request.configuration.mode === 'edit' || requestChoice === 'create') && (_jsx("button", { type: "button", onClick: () => {
|
|
261
|
+
setCreating(true);
|
|
262
|
+
setEditingName(request.configuration.name ?? '');
|
|
263
|
+
}, children: t('marivo.credentials.open-configuration-form') }))] }))] })), creating && request?.endedAt === undefined && (_jsx(CreateDatasource, { name: editingName || undefined, requestId: request?.configuration ? request.id : undefined, model: model, workspaceId: workspaceId, close: () => setCreating(false) }, `${workspaceId}/${editingName}/${request?.id ?? ''}`)), !creating && context && (_jsx(CredentialForm, { context: context, request: request, state: state, model: model, workspaceId: workspaceId, onEdit: () => {
|
|
264
|
+
setEditingName(context.name);
|
|
265
|
+
setCreating(true);
|
|
266
|
+
} }, context.token)), operations.length > 0 && (_jsxs("section", { className: "mc-activity", "aria-label": t('marivo.credentials.credential-operations-in-progress'), children: [_jsxs("p", { className: "mc-activity-heading", children: [t('marivo.credentials.in-progress'), operations.length] }), _jsx("div", { className: "mc-activity-list", children: operations.map((entry) => (_jsxs("button", { type: "button", "aria-pressed": state.handle?.id === entry.handle.id, onClick: () => model.selectOperation(entry.handle.id), children: [entry.name, " ", t('marivo.credentials.processing-177')] }, entry.handle.id))) }), activeOperation?.status === 'running' && (_jsxs("div", { className: "mc-progress", children: [_jsxs("p", { children: [state.operations.find((entry) => entry.handle.id === state.handle?.id)?.name, ' ', "\u00B7", ' ', activeOperation.phase === 'removing'
|
|
267
|
+
? t('marivo.credentials.deleting')
|
|
268
|
+
: activeOperation.phase === 'saving'
|
|
269
|
+
? t('marivo.credentials.saving')
|
|
270
|
+
: t('marivo.credentials.validating-connection')] }), _jsx("button", { type: "button", onClick: () => void model.cancelOperation(), children: t('marivo.credentials.cancel-this-operation') }), activeOperation.saved.length > 0 && (_jsxs("p", { children: [t('marivo.credentials.saved'), activeOperation.saved.join('、'), "\u3002"] }))] }))] }))] })] })] }), !request && workspaceId && (_jsx(ReportPublishingCredentials, { model: model, workspaceId: workspaceId }, workspaceId))] }));
|
|
271
|
+
}
|
|
272
|
+
export function installCredentials(ctx, rpc, changes) {
|
|
273
|
+
let storage;
|
|
274
|
+
try {
|
|
275
|
+
storage = window.sessionStorage;
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
/* optional query-handle persistence */
|
|
279
|
+
}
|
|
280
|
+
const model = new CredentialClientModel(rpc, storage, changes);
|
|
281
|
+
model.recover();
|
|
282
|
+
ctx.effect(() => () => model.dispose(), 'dsh-data-analysis: credential client lifecycle');
|
|
283
|
+
ctx.on('connection/reset', () => model.reset());
|
|
284
|
+
ctx.slots.inject('conversation.session.header.actions', () => ctx.slots.register({
|
|
285
|
+
locale: 'marivo.navigation',
|
|
286
|
+
name: 'conversation.session.header.actions',
|
|
287
|
+
id: 'marivo-credential-requests',
|
|
288
|
+
order: 120,
|
|
289
|
+
}, localized(ctx, function Pending({ sessionId }) {
|
|
290
|
+
const t = useCopy();
|
|
291
|
+
const state = useSyncExternalStore(model.subscribe, model.getSnapshot);
|
|
292
|
+
const request = state.requests.find((item) => item.sessionId === sessionId && item.endedAt === undefined);
|
|
293
|
+
return request ? (_jsx("button", { className: "mc-pending-entry", style: {
|
|
294
|
+
flex: 'none',
|
|
295
|
+
whiteSpace: 'nowrap',
|
|
296
|
+
fontSize: 12,
|
|
297
|
+
padding: '4px 6px',
|
|
298
|
+
border: '1px solid currentColor',
|
|
299
|
+
borderRadius: 7,
|
|
300
|
+
background: 'transparent',
|
|
301
|
+
color: 'inherit',
|
|
302
|
+
cursor: 'pointer',
|
|
303
|
+
}, "aria-label": request.configuration
|
|
304
|
+
? t('marivo.credentials.awaiting-datasource-configuration')
|
|
305
|
+
: t('marivo.credentials.awaiting-credentials'), title: request.configuration
|
|
306
|
+
? t('marivo.credentials.awaiting-datasource-configuration')
|
|
307
|
+
: t('marivo.credentials.awaiting-credentials'), type: "button", onClick: () => model.openRequest(request.id), children: t('marivo.credentials.configuration-needed') })) : null;
|
|
308
|
+
})));
|
|
309
|
+
ctx.slots.inject('shell.overlay', () => ctx.slots.register({ locale: 'marivo.navigation', name: 'shell.overlay', id: 'marivo-credential-observer' }, localized(ctx, function Observer({ useSessions, useWorkspaces }) {
|
|
310
|
+
const sessionId = useSessions((state) => state.current) ?? '';
|
|
311
|
+
const workspaces = useWorkspaces((state) => state.items);
|
|
312
|
+
const currentWorkspace = workspaces.find((item) => item.sessionIds.includes(sessionId))?.workspaceId ?? '';
|
|
313
|
+
useEffect(() => model.session(sessionId), [sessionId]);
|
|
314
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: Workspace reassignment must dismiss old content.
|
|
315
|
+
useEffect(() => model.close(), [currentWorkspace]);
|
|
316
|
+
return null;
|
|
317
|
+
})));
|
|
318
|
+
return model;
|
|
319
|
+
}
|