Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f98cf9ced8 | ||
|
|
d2e491348d | ||
|
|
562d278f60 | ||
|
|
c6f6faf64f |
@@ -58,6 +58,17 @@ than adding custom `F1` listeners:
|
||||
headed pages. `WorkspaceLayout` owns the full-canvas workspace scope and its
|
||||
labelled primary/content panes; pages inside it use `PageLayout` in
|
||||
`workspace` mode and retain their own route-level help identity.
|
||||
- `PasswordField` passes its owner context and module through reveal/generate
|
||||
actions and the shared generator dialog. Credential consumers must supply an
|
||||
exact owner context; the generic component does not own credential policy.
|
||||
|
||||
High-risk controls use one of the source-inventory risk classes (`authority`,
|
||||
`credential`, `disclosure`, `encryption`, `external-effect`, `irreversible`,
|
||||
`policy`, or `retention`) and require exact F1 help. The extractor infers
|
||||
obvious cases conservatively; components may declare `data-help-risk`
|
||||
explicitly or mark a reviewed ordinary control with
|
||||
`data-help-risk-reviewed="standard"`. The strict workspace gate rejects new
|
||||
unresolved high-risk debt.
|
||||
|
||||
Module routes, public routes, settings sections, and administration sections
|
||||
may also declare `helpContextId` and `helpTopicId`. Each module must keep a
|
||||
|
||||
@@ -18,6 +18,27 @@ The platform inventory recognizes both inline locale objects and generated
|
||||
catalogs declared as `const de` / `const en`. Its strict mode requires both
|
||||
locales and reports `de` explicitly as the reference locale.
|
||||
|
||||
## Structured Documentation Localization
|
||||
|
||||
`DocumentationTopic.translations` continues to own localized title, summary,
|
||||
and body prose. Topics whose metadata contains rendered prose opt into the
|
||||
separate `structured_translation_version="1"` contract and provide a complete
|
||||
same-shape value for each translated metadata key in
|
||||
`structured_translations`. Version 1 covers workflow prerequisites, steps,
|
||||
outcome, result and verification; reference fields; limitations, constraints,
|
||||
consequences and consequence classes; and the other rendered explanation
|
||||
fields declared by Core.
|
||||
|
||||
The registry rejects an unversioned translation, an unsupported contract
|
||||
version, missing structured keys, changed object keys or list lengths, empty
|
||||
translated strings, and changed non-text values. Stable field IDs, routes,
|
||||
permission scopes, and other technical leaves therefore remain structurally
|
||||
bound to the source metadata. The Docs module overlays only a validated locale
|
||||
at response time and reports the selected structured locale separately from the
|
||||
title/body locale. Missing structured translations fall back to source content
|
||||
and remain visible in public coverage until the owning module adopts the
|
||||
contract.
|
||||
|
||||
## Help Resolution
|
||||
|
||||
Every focusable field and action receives a stable derived F1 identity from the
|
||||
@@ -54,6 +75,17 @@ native control nested in `FormField`. Dynamic context expressions remain
|
||||
separate evidence and generic derived fallbacks remain in the richer-help
|
||||
candidate queue.
|
||||
|
||||
The same inventory classifies controls whose labels, identities, component
|
||||
context, or explicit `data-help-risk` indicate authority, credentials,
|
||||
disclosure, encryption, external effects, irreversible changes, policy, or
|
||||
retention. These controls require an exact context rather than relying only on
|
||||
page fallback. Reviewed false positives carry
|
||||
`data-help-risk-reviewed="standard"`. Invalid risk classes and any increase
|
||||
above the versioned `tools/inventory/high-risk-help-baseline.json` ceiling fail
|
||||
strict declaration checks; the ceiling is lowered as the finite queue is
|
||||
resolved. Password fields and their generator dialog propagate the owning
|
||||
field's context so shared credential controls never invent a Core-owned topic.
|
||||
|
||||
The generated `help_review_candidates` list is therefore a content-depth queue,
|
||||
not a list of controls on which F1 cannot work. It should prioritize:
|
||||
|
||||
@@ -88,6 +120,8 @@ The check must report:
|
||||
- no duplicate stable IDs;
|
||||
- no undeclared public WebUI surface;
|
||||
- no stale runtime route or endpoint declaration.
|
||||
- no invalid high-risk help annotation or regression above the recorded
|
||||
exact-context debt ceiling.
|
||||
|
||||
Browser acceptance is part of the focused workspace gate and can be run alone:
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "govoplan-core"
|
||||
version = "0.1.35"
|
||||
version = "0.1.39"
|
||||
description = "Reusable GovOPlaN platform core, access, tenancy, and RBAC components."
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
@@ -101,6 +101,8 @@ class DatasourceGovernance:
|
||||
transfer_agreement_ref: str | None = None
|
||||
freshness_policy: Mapping[str, object] = field(default_factory=dict)
|
||||
quality_policy: Mapping[str, object] = field(default_factory=dict)
|
||||
approval_policy: Mapping[str, object] = field(default_factory=dict)
|
||||
retention_policy: Mapping[str, object] = field(default_factory=dict)
|
||||
known_limits: tuple[str, ...] = ()
|
||||
correction_procedure_ref: str | None = None
|
||||
affected_refs: tuple[str, ...] = ()
|
||||
@@ -179,6 +181,8 @@ class DatasourceGovernance:
|
||||
),
|
||||
freshness_policy=_governance_mapping(source.get("freshness_policy")),
|
||||
quality_policy=_governance_mapping(source.get("quality_policy")),
|
||||
approval_policy=_governance_mapping(source.get("approval_policy")),
|
||||
retention_policy=_governance_mapping(source.get("retention_policy")),
|
||||
known_limits=_governance_texts(source.get("known_limits")),
|
||||
correction_procedure_ref=_optional_governance_text(
|
||||
source.get("correction_procedure_ref")
|
||||
@@ -210,6 +214,8 @@ class DatasourceGovernance:
|
||||
"transfer_agreement_ref": self.transfer_agreement_ref,
|
||||
"freshness_policy": dict(self.freshness_policy),
|
||||
"quality_policy": dict(self.quality_policy),
|
||||
"approval_policy": dict(self.approval_policy),
|
||||
"retention_policy": dict(self.retention_policy),
|
||||
"known_limits": list(self.known_limits),
|
||||
"correction_procedure_ref": self.correction_procedure_ref,
|
||||
"affected_refs": list(self.affected_refs),
|
||||
@@ -289,6 +295,8 @@ class DatasourceMaterialization:
|
||||
frozen_label: str | None = None
|
||||
source_timestamp: datetime | None = None
|
||||
created_at: datetime | None = None
|
||||
disposed_at: datetime | None = None
|
||||
disposition: Mapping[str, object] = field(default_factory=dict)
|
||||
provenance: Mapping[str, object] = field(default_factory=dict)
|
||||
metadata: Mapping[str, object] = field(default_factory=dict)
|
||||
governance: DatasourceGovernance = field(default_factory=DatasourceGovernance)
|
||||
@@ -309,6 +317,7 @@ class DatasourceStage:
|
||||
row_count: int | None = None
|
||||
byte_count: int | None = None
|
||||
validation: Mapping[str, object] = field(default_factory=dict)
|
||||
approval: Mapping[str, object] = field(default_factory=dict)
|
||||
created_at: datetime | None = None
|
||||
promoted_at: datetime | None = None
|
||||
promoted_materialization_ref: str | None = None
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Iterable, Mapping, Sequence
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, replace
|
||||
from typing import Any, Literal, Protocol, TYPE_CHECKING
|
||||
|
||||
from govoplan_core.core.information_governance import ModuleInformationGovernance
|
||||
@@ -289,6 +289,30 @@ DocumentationSourceState = Literal["configured", "disabled", "unavailable"]
|
||||
CapabilityStability = Literal["experimental", "stable", "deprecated"]
|
||||
|
||||
|
||||
DOCUMENTATION_STRUCTURED_TRANSLATION_VERSION = "1"
|
||||
DOCUMENTATION_LOCALIZABLE_METADATA_KEYS = frozenset(
|
||||
{
|
||||
"admin_explanation",
|
||||
"consequence_classes",
|
||||
"consequences",
|
||||
"constraints",
|
||||
"current_configuration",
|
||||
"fields",
|
||||
"limitations",
|
||||
"operational_consequences",
|
||||
"outcome",
|
||||
"prerequisites",
|
||||
"privacy_notes",
|
||||
"purpose",
|
||||
"result",
|
||||
"steps",
|
||||
"user_explanation",
|
||||
"verification",
|
||||
"when_used",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DocumentationLink:
|
||||
label: str
|
||||
@@ -324,12 +348,142 @@ class DocumentationTopic:
|
||||
configuration_keys: tuple[str, ...] = ()
|
||||
i18n_key: str | None = None
|
||||
translations: Mapping[str, Mapping[str, str]] = field(default_factory=dict)
|
||||
structured_translation_version: str | None = None
|
||||
structured_translations: Mapping[str, Mapping[str, Any]] = field(
|
||||
default_factory=dict
|
||||
)
|
||||
source_module_id: str | None = None
|
||||
version_min: str | None = None
|
||||
version_max_exclusive: str | None = None
|
||||
metadata: Mapping[str, Any] = field(default_factory=dict)
|
||||
|
||||
|
||||
def localizable_documentation_metadata_keys(
|
||||
topic: DocumentationTopic,
|
||||
) -> tuple[str, ...]:
|
||||
"""Return structured metadata keys whose values are public prose."""
|
||||
|
||||
return tuple(
|
||||
sorted(DOCUMENTATION_LOCALIZABLE_METADATA_KEYS.intersection(topic.metadata))
|
||||
)
|
||||
|
||||
|
||||
def localized_documentation_metadata(
|
||||
topic: DocumentationTopic,
|
||||
locale: str,
|
||||
) -> dict[str, Any]:
|
||||
"""Overlay one validated structured translation onto source metadata."""
|
||||
|
||||
localized = dict(topic.metadata)
|
||||
translation = topic.structured_translations.get(locale)
|
||||
if translation:
|
||||
localized.update(translation)
|
||||
return localized
|
||||
|
||||
|
||||
def documentation_structured_translation_issues(
|
||||
topic: DocumentationTopic,
|
||||
) -> tuple[str, ...]:
|
||||
"""Validate the opt-in, versioned structured-documentation translation."""
|
||||
|
||||
version = topic.structured_translation_version
|
||||
translations = topic.structured_translations
|
||||
if version is None:
|
||||
if translations:
|
||||
return (
|
||||
"structured_translations require structured_translation_version",
|
||||
)
|
||||
return ()
|
||||
if version != DOCUMENTATION_STRUCTURED_TRANSLATION_VERSION:
|
||||
return (
|
||||
"unsupported structured_translation_version "
|
||||
f"{version!r}; expected {DOCUMENTATION_STRUCTURED_TRANSLATION_VERSION!r}",
|
||||
)
|
||||
|
||||
localizable_keys = set(localizable_documentation_metadata_keys(topic))
|
||||
issues: list[str] = []
|
||||
for locale, translation in translations.items():
|
||||
if not locale.strip():
|
||||
issues.append("structured translation locale must not be empty")
|
||||
continue
|
||||
translated_keys = set(translation)
|
||||
for key in sorted(translated_keys - localizable_keys):
|
||||
issues.append(
|
||||
f"structured translation {locale!r} contains non-localizable or missing metadata key {key!r}"
|
||||
)
|
||||
for key in sorted(localizable_keys - translated_keys):
|
||||
issues.append(
|
||||
f"structured translation {locale!r} is missing metadata key {key!r}"
|
||||
)
|
||||
for key in sorted(localizable_keys & translated_keys):
|
||||
issues.extend(
|
||||
_structured_translation_shape_issues(
|
||||
topic.metadata[key],
|
||||
translation[key],
|
||||
path=f"{locale}.{key}",
|
||||
)
|
||||
)
|
||||
return tuple(issues)
|
||||
|
||||
|
||||
def _structured_translation_shape_issues(
|
||||
source: object,
|
||||
translated: object,
|
||||
*,
|
||||
path: str,
|
||||
) -> tuple[str, ...]:
|
||||
if isinstance(source, str):
|
||||
if not isinstance(translated, str) or not translated.strip():
|
||||
return (f"structured translation {path} must be a non-empty string",)
|
||||
return ()
|
||||
if isinstance(source, Mapping):
|
||||
if not isinstance(translated, Mapping):
|
||||
return (f"structured translation {path} must preserve object shape",)
|
||||
issues: list[str] = []
|
||||
source_keys = {str(key) for key in source}
|
||||
translated_keys = {str(key) for key in translated}
|
||||
if source_keys != translated_keys:
|
||||
issues.append(
|
||||
f"structured translation {path} must preserve object keys"
|
||||
)
|
||||
return tuple(issues)
|
||||
for key, value in source.items():
|
||||
issues.extend(
|
||||
_structured_translation_shape_issues(
|
||||
value,
|
||||
translated[key],
|
||||
path=f"{path}.{key}",
|
||||
)
|
||||
)
|
||||
return tuple(issues)
|
||||
if isinstance(source, Sequence) and not isinstance(
|
||||
source, (str, bytes, bytearray)
|
||||
):
|
||||
if not isinstance(translated, Sequence) or isinstance(
|
||||
translated, (str, bytes, bytearray)
|
||||
):
|
||||
return (f"structured translation {path} must preserve list shape",)
|
||||
if len(source) != len(translated):
|
||||
return (f"structured translation {path} must preserve list length",)
|
||||
issues: list[str] = []
|
||||
for index, (source_item, translated_item) in enumerate(
|
||||
zip(source, translated, strict=True)
|
||||
):
|
||||
issues.extend(
|
||||
_structured_translation_shape_issues(
|
||||
source_item,
|
||||
translated_item,
|
||||
path=f"{path}[{index}]",
|
||||
)
|
||||
)
|
||||
return tuple(issues)
|
||||
if translated != source:
|
||||
return (
|
||||
f"structured translation {path} must preserve non-text value {source!r}",
|
||||
)
|
||||
return ()
|
||||
|
||||
|
||||
def user_workflow_scope_condition_issues(topic: DocumentationTopic) -> tuple[str, ...]:
|
||||
"""Return fail-closed authoring issues for a user-facing workflow topic.
|
||||
|
||||
@@ -533,3 +687,53 @@ class ModuleManifest:
|
||||
# runtime module ID changes.
|
||||
permission_namespace: str | None = None
|
||||
workflow_definitions: tuple["WorkflowDefinitionContribution", ...] = ()
|
||||
|
||||
|
||||
def with_documentation_structured_translations(
|
||||
manifest: ModuleManifest,
|
||||
*,
|
||||
locale: str,
|
||||
translations: Mapping[str, Mapping[str, Any]],
|
||||
) -> ModuleManifest:
|
||||
"""Merge module-owned structured documentation translations by topic id.
|
||||
|
||||
The helper keeps feature prose in its owning module while giving every
|
||||
manifest the same fail-closed merge behavior. Unknown topic ids and
|
||||
incomplete or shape-changing locale maps are rejected immediately.
|
||||
"""
|
||||
|
||||
locale = locale.strip()
|
||||
if not locale:
|
||||
raise ValueError("structured documentation locale must not be empty")
|
||||
|
||||
topics_by_id = {topic.id: topic for topic in manifest.documentation}
|
||||
unknown_topic_ids = sorted(set(translations) - set(topics_by_id))
|
||||
if unknown_topic_ids:
|
||||
raise ValueError(
|
||||
"structured documentation translations reference unknown topic ids: "
|
||||
+ ", ".join(unknown_topic_ids)
|
||||
)
|
||||
|
||||
localized_topics: list[DocumentationTopic] = []
|
||||
for topic in manifest.documentation:
|
||||
translation = translations.get(topic.id)
|
||||
if translation is None:
|
||||
localized_topics.append(topic)
|
||||
continue
|
||||
|
||||
structured_translations = dict(topic.structured_translations)
|
||||
structured_translations[locale] = translation
|
||||
localized_topic = replace(
|
||||
topic,
|
||||
structured_translation_version=DOCUMENTATION_STRUCTURED_TRANSLATION_VERSION,
|
||||
structured_translations=structured_translations,
|
||||
)
|
||||
issues = documentation_structured_translation_issues(localized_topic)
|
||||
if issues:
|
||||
raise ValueError(
|
||||
f"invalid {locale!r} structured documentation translation for "
|
||||
f"{topic.id!r}: {'; '.join(issues)}"
|
||||
)
|
||||
localized_topics.append(localized_topic)
|
||||
|
||||
return replace(manifest, documentation=tuple(localized_topics))
|
||||
|
||||
@@ -26,6 +26,7 @@ from govoplan_core.core.modules import (
|
||||
TenantSummaryBatchProvider,
|
||||
TenantSummaryProvider,
|
||||
user_workflow_scope_condition_issues,
|
||||
documentation_structured_translation_issues,
|
||||
)
|
||||
from govoplan_core.core.module_entitlements import (
|
||||
TenantModuleEntitlementResolver,
|
||||
@@ -962,6 +963,10 @@ def _validate_manifest_shape(manifest: ModuleManifest) -> None:
|
||||
raise RegistryError(
|
||||
f"Module {manifest.id!r} documentation topic {topic.id!r}: {issue}"
|
||||
)
|
||||
for issue in documentation_structured_translation_issues(topic):
|
||||
raise RegistryError(
|
||||
f"Module {manifest.id!r} documentation topic {topic.id!r}: {issue}"
|
||||
)
|
||||
_validate_documentation_extensions(manifest)
|
||||
_validate_architecture_declarations(manifest)
|
||||
_validate_workflow_definition_contributions(manifest)
|
||||
|
||||
@@ -13,6 +13,7 @@ from govoplan_core.core.datasources import (
|
||||
DatasourceArtifactBackendProvider,
|
||||
DatasourceDescriptor,
|
||||
DatasourceField,
|
||||
DatasourceGovernance,
|
||||
DatasourceLifecycleProvider,
|
||||
DatasourceMaterialization,
|
||||
DatasourceOrigin,
|
||||
@@ -212,6 +213,55 @@ class DatasourceContractTests(unittest.TestCase):
|
||||
self.assertEqual("upload", descriptor.kind)
|
||||
self.assertEqual("tabular", descriptor.shape)
|
||||
|
||||
def test_lifecycle_governance_round_trips_without_provider_specific_types(self) -> None:
|
||||
governance = DatasourceGovernance.from_mapping(
|
||||
{
|
||||
"approval_policy": {
|
||||
"version": "approval-v2",
|
||||
"required": True,
|
||||
"required_approvals": 2,
|
||||
},
|
||||
"retention_policy": {
|
||||
"version": "retention-v3",
|
||||
"enabled": True,
|
||||
"stage_days": 30,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual("approval-v2", governance.approval_policy["version"])
|
||||
self.assertEqual(30, governance.retention_policy["stage_days"])
|
||||
self.assertEqual(
|
||||
governance.approval_policy,
|
||||
governance.to_dict()["approval_policy"],
|
||||
)
|
||||
self.assertEqual(
|
||||
governance.retention_policy,
|
||||
governance.to_dict()["retention_policy"],
|
||||
)
|
||||
|
||||
stage = DatasourceStage(
|
||||
ref="stage:governed",
|
||||
name="Governed stage",
|
||||
source_name="governed",
|
||||
kind="upload",
|
||||
mode="static",
|
||||
shape="tabular",
|
||||
state="awaiting_approval",
|
||||
approval={"status": "pending", "policy_version": "approval-v2"},
|
||||
)
|
||||
materialization = DatasourceMaterialization(
|
||||
ref="materialization:disposed",
|
||||
datasource_ref="datasource:governed",
|
||||
revision=1,
|
||||
state="disposed",
|
||||
fingerprint="abc123",
|
||||
disposition={"reason": "retention_policy", "policy_version": "retention-v3"},
|
||||
)
|
||||
|
||||
self.assertEqual("pending", stage.approval["status"])
|
||||
self.assertEqual("retention_policy", materialization.disposition["reason"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -10,7 +10,9 @@ from govoplan_core.core.modules import (
|
||||
DocumentationSourceDefinition,
|
||||
DocumentationTopic,
|
||||
ModuleManifest,
|
||||
localized_documentation_metadata,
|
||||
user_workflow_scope_condition_issues,
|
||||
with_documentation_structured_translations,
|
||||
)
|
||||
from govoplan_core.core.registry import PlatformRegistry, RegistryError
|
||||
|
||||
@@ -83,6 +85,97 @@ class DocumentationTopicContractTests(unittest.TestCase):
|
||||
self.assertEqual(user_workflow_scope_condition_issues(user_reference), ())
|
||||
registry_for(scoped, admin_workflow, user_reference).validate()
|
||||
|
||||
def test_versioned_structured_translation_preserves_metadata_shape(self) -> None:
|
||||
topic = DocumentationTopic(
|
||||
id="example.workflow.localized",
|
||||
title="Run task",
|
||||
summary="Run the task.",
|
||||
metadata={
|
||||
"kind": "workflow",
|
||||
"steps": ["Review", "Execute"],
|
||||
"verification": "Confirm the result.",
|
||||
},
|
||||
structured_translation_version="1",
|
||||
structured_translations={
|
||||
"de": {
|
||||
"steps": ["Prüfen", "Ausführen"],
|
||||
"verification": "Das Ergebnis bestätigen.",
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
registry_for(topic).validate()
|
||||
self.assertEqual(
|
||||
["Prüfen", "Ausführen"],
|
||||
localized_documentation_metadata(topic, "de")["steps"],
|
||||
)
|
||||
self.assertEqual(
|
||||
"workflow", localized_documentation_metadata(topic, "de")["kind"]
|
||||
)
|
||||
|
||||
def test_structured_translation_requires_version_and_complete_shape(self) -> None:
|
||||
missing_version = DocumentationTopic(
|
||||
id="example.localized.missing-version",
|
||||
title="Localized",
|
||||
summary="Invalid contract.",
|
||||
metadata={"limitations": ["One", "Two"]},
|
||||
structured_translations={"de": {"limitations": ["Eins", "Zwei"]}},
|
||||
)
|
||||
with self.assertRaisesRegex(
|
||||
RegistryError, "require structured_translation_version"
|
||||
):
|
||||
registry_for(missing_version).validate()
|
||||
|
||||
incomplete_shape = DocumentationTopic(
|
||||
id="example.localized.incomplete",
|
||||
title="Localized",
|
||||
summary="Invalid shape.",
|
||||
metadata={"limitations": ["One", "Two"]},
|
||||
structured_translation_version="1",
|
||||
structured_translations={"de": {"limitations": ["Eins"]}},
|
||||
)
|
||||
with self.assertRaisesRegex(RegistryError, "preserve list length"):
|
||||
registry_for(incomplete_shape).validate()
|
||||
|
||||
def test_manifest_helper_merges_and_validates_owner_translations(self) -> None:
|
||||
topic = DocumentationTopic(
|
||||
id="example.workflow.localized",
|
||||
title="Run task",
|
||||
summary="Run the task.",
|
||||
metadata={"steps": ["Review", "Execute"]},
|
||||
)
|
||||
manifest = ModuleManifest(
|
||||
id="example",
|
||||
name="Example",
|
||||
version="1.0.0",
|
||||
documentation=(topic,),
|
||||
)
|
||||
|
||||
localized = with_documentation_structured_translations(
|
||||
manifest,
|
||||
locale="de",
|
||||
translations={
|
||||
topic.id: {"steps": ["Prüfen", "Ausführen"]},
|
||||
},
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
["Prüfen", "Ausführen"],
|
||||
localized.documentation[0].structured_translations["de"]["steps"],
|
||||
)
|
||||
with self.assertRaisesRegex(ValueError, "unknown topic ids"):
|
||||
with_documentation_structured_translations(
|
||||
manifest,
|
||||
locale="de",
|
||||
translations={"missing.topic": {"steps": ["Prüfen", "Ausführen"]}},
|
||||
)
|
||||
with self.assertRaisesRegex(ValueError, "preserve list length"):
|
||||
with_documentation_structured_translations(
|
||||
manifest,
|
||||
locale="de",
|
||||
translations={topic.id: {"steps": ["Prüfen"]}},
|
||||
)
|
||||
|
||||
def test_documentation_configuration_and_source_extensions_are_validated(self) -> None:
|
||||
resolver = lambda _context, keys: { # noqa: E731
|
||||
key: DocumentationConfigurationDecision(key=key, state="enabled")
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"dependencies": {
|
||||
"@govoplan/access-webui": "file:../../govoplan-access/webui",
|
||||
"@govoplan/addresses-webui": "file:../../govoplan-addresses/webui",
|
||||
|
||||
+190
-190
@@ -1,30 +1,30 @@
|
||||
{
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"dependencies": {
|
||||
"@govoplan/access-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#v0.1.20",
|
||||
"@govoplan/admin-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#v0.1.19",
|
||||
"@govoplan/access-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#v0.1.23",
|
||||
"@govoplan/admin-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#v0.1.22",
|
||||
"@govoplan/audit-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-audit.git#v0.1.18",
|
||||
"@govoplan/calendar-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#v0.1.18",
|
||||
"@govoplan/campaign-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#v0.1.22",
|
||||
"@govoplan/calendar-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#v0.1.22",
|
||||
"@govoplan/campaign-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#v0.1.27",
|
||||
"@govoplan/cases-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-cases.git#v0.1.20",
|
||||
"@govoplan/dashboard-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-dashboard.git#v0.1.18",
|
||||
"@govoplan/docs-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#v0.1.18",
|
||||
"@govoplan/files-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#v0.1.20",
|
||||
"@govoplan/docs-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#v0.1.22",
|
||||
"@govoplan/files-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#v0.1.23",
|
||||
"@govoplan/helpdesk-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-helpdesk.git#v0.1.20",
|
||||
"@govoplan/idm-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#v0.1.19",
|
||||
"@govoplan/mail-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#v0.1.18",
|
||||
"@govoplan/idm-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#v0.1.24",
|
||||
"@govoplan/mail-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#v0.1.24",
|
||||
"@govoplan/ops-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-ops.git#v0.1.18",
|
||||
"@govoplan/organizations-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#v0.1.18",
|
||||
"@govoplan/organizations-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#v0.1.20",
|
||||
"@govoplan/policy-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-policy.git#v0.1.18",
|
||||
"@govoplan/tickets-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#v0.1.20",
|
||||
"@govoplan/wiki-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#v0.1.20",
|
||||
"@govoplan/tickets-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#v0.1.22",
|
||||
"@govoplan/wiki-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#v0.1.22",
|
||||
"@tiptap/core": "^3.29.2",
|
||||
"@tiptap/extension-image": "^3.29.2",
|
||||
"@tiptap/pm": "^3.29.2",
|
||||
@@ -757,8 +757,8 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@govoplan/access-webui": {
|
||||
"version": "0.1.20",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#206873b62a9c77ac5715f9ce7d6bc16d156efa74",
|
||||
"version": "0.1.23",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#e55434f406e953a2fa9e881abb8fb6dccbabd812",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"lucide-react": "^1.23.0",
|
||||
@@ -773,8 +773,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/admin-webui": {
|
||||
"version": "0.1.19",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#ed424c729cd0c1c7a1cbec387a793db0819c91fe",
|
||||
"version": "0.1.22",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#3b450640690c5f1e123db4095663c7d5287873bb",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.35",
|
||||
"lucide-react": "^1.23.0",
|
||||
@@ -805,8 +805,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/calendar-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#089d07b60a99f76f2ef6d72de8c33fd263bc7bac",
|
||||
"version": "0.1.22",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#3792e9ab8a10ff6e301c59df7a3fa47d5ab14952",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@vitejs/plugin-react": "^5.2.0",
|
||||
@@ -824,8 +824,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/campaign-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#4f52f010ee6a117b7b3ad605a59b1da0a459a0c6",
|
||||
"version": "0.1.27",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#1b32427813b435fd47c92c95242d6029741743ec",
|
||||
"dependencies": {
|
||||
"read-excel-file": "9.2.0"
|
||||
},
|
||||
@@ -875,8 +875,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/docs-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#30ea95854b9c65cb5d0fdd1d281a07ad1330e290",
|
||||
"version": "0.1.22",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#9055f3437f0296f15f63a6fc89ff65f133a7bfaf",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@vitejs/plugin-react": "^5.2.0",
|
||||
@@ -894,8 +894,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/files-webui": {
|
||||
"version": "0.1.20",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#378f4d6ac5525d0f07f38eefce893bfa2924f2b9",
|
||||
"version": "0.1.23",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#11b9b7c4c6d919b9f6649034445edfea0c77d042",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@vitejs/plugin-react": "^5.2.0",
|
||||
@@ -929,8 +929,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/idm-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#b0eda351957526bc7e59270c7a42016aa12bc1a3",
|
||||
"version": "0.1.24",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#5c7586f6d9a0d0b3e8d36ab47dca586e0a34a498",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@vitejs/plugin-react": "^5.2.0",
|
||||
@@ -948,8 +948,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/mail-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#62721d204d946fa06160a5437d51de53428e1222",
|
||||
"version": "0.1.24",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#48205e6e461f5f93d88380df8e23db54fdb719f7",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"lucide-react": "^1.23.0",
|
||||
@@ -983,8 +983,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/organizations-webui": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#30fcdbe8327ca56f6561b00a04ecca4572fcb69e",
|
||||
"version": "0.1.20",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#b23e6e4eeedd17d322744a765a473b5f77c08b61",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.18",
|
||||
"@vitejs/plugin-react": "^5.2.0",
|
||||
@@ -1018,8 +1018,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/tickets-webui": {
|
||||
"version": "0.1.20",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#c6c643778bc73d0504e9f1ef5b710ca98436ae41",
|
||||
"version": "0.1.22",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#0ad2ef96b43a83ea7e0e9188487392db735b4a85",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.30",
|
||||
"lucide-react": "^1.23.0",
|
||||
@@ -1034,8 +1034,8 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@govoplan/wiki-webui": {
|
||||
"version": "0.1.20",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#66c91351c9eb693ace606c9b69dd5cd804d7531b",
|
||||
"version": "0.1.22",
|
||||
"resolved": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#705255f378edf7643cd84fe5692cf2a0378b91a2",
|
||||
"peerDependencies": {
|
||||
"@govoplan/core-webui": "^0.1.31",
|
||||
"lucide-react": "^1.23.0",
|
||||
@@ -1484,49 +1484,49 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.30.2.tgz",
|
||||
"integrity": "sha512-QbZC/s1OOqcoUdkhIY16TjR/gCtR0qAk9e4bJwUqOJqZuv5ozqCL5hzWm22jjTPp6c6Ei2tPd6t30VwfIKW4lQ==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.30.3.tgz",
|
||||
"integrity": "sha512-kDD8KY99lBCKntCqTBE9eNR1ul/i/wPFw2METWT+LYZvifljXq2oiX6JaGF1Sk59efe7+sq9IISxOk47YlBiWQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-blockquote": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.30.2.tgz",
|
||||
"integrity": "sha512-BOkwhZenek7vzXBOgKppSrlx4YryBdAYu1p1MXKn0R9A9eNmE2HVhmm0gG49+E8BhsE/TG8wKVclwET42JJiIg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-3.30.3.tgz",
|
||||
"integrity": "sha512-Dh8yfEqBKTqEdBKZ4Ta3DkTecP0VJxvRNA5b1LCF7gBbe54Lm3A28UuVvK/Sdhh9FJDrIVCQTDS0yHGbi6G9ew==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bold": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.30.2.tgz",
|
||||
"integrity": "sha512-MsvJhPgYejY2D9MhwYJv8AmscozvLBI8qtJ7YLdYZBWkMR4bgmxHq5+xqEfBsao9bOMMwBon9p3+P+/Tq5ReWA==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-3.30.3.tgz",
|
||||
"integrity": "sha512-a4BSAjWRN4mWklRTdDCIaG9R+PqyUxXNYGQ2CLtOhO51Wq6daw2qFTHR+cTqAjaiiUSuDYII86UChb2qQRq8Lg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bubble-menu": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.30.2.tgz",
|
||||
"integrity": "sha512-oS0WiWNXHKpiPYMkcnHm1j7iEvufTGGtLFtcJJd3olb5OS6V2acoXVDL0nNJDmRQ32K3QXut3fbRcMseMxT+lw==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.30.3.tgz",
|
||||
"integrity": "sha512-YryCf9fq+9n1XIW6f5weSCD2MbL/LhRQ7jArRToQQ/oNxc422LqYVjijQQTNuk2cZEqE9fdO3Hw27tmwEEs9UQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -1537,80 +1537,80 @@
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bullet-list": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.30.2.tgz",
|
||||
"integrity": "sha512-+awIL/TUz4aB3rL68igU1rWfaaoBIAkPcakkktkRq8gYf0bd9eSb48P6kHkpx/3q+JyK7g9vsnltLNHNh6twnA==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-3.30.3.tgz",
|
||||
"integrity": "sha512-Z/ZqUfrd3Fd8hHpHEPv3XRzqwqVLD4CP67xFMyjy0cqEgnjgvd1iR6QzJsKD79V9zyu0Agu7ab9ZBf4NktpWcw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.30.2"
|
||||
"@tiptap/extension-list": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.30.2.tgz",
|
||||
"integrity": "sha512-r8EZk3R9yGpF6v5xxafAU1HwrD/e+RpbfnmVi2TeB/ZHAsVO62fW96E32G0t6IdaCtOFtAd85hkDAaOfCT4yGg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-3.30.3.tgz",
|
||||
"integrity": "sha512-mOV4Fg+ji6uXmFxTMuug9WK6zk0ksNQepnuvoDR4g4d+tnz2y9iEbgOXFohVxhOXOLDLdNeKdwHxbHQdi5Ivbw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code-block": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.30.2.tgz",
|
||||
"integrity": "sha512-9otGKaQZmePHrLXFtCtz+BYDn5z4sSumTkUqQIQHz0gVxwPoTi7g51RedwxvViTb/zu2XV5ROXYLHIxKxypMPg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-3.30.3.tgz",
|
||||
"integrity": "sha512-xT2cDil/ipy/LklPgv/JqSsXys1mjcqlIPDUetK3llB2DT7XZssYPV3qv278tqRO4pJDbrXk82I6Lh7vLwmIAg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-document": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.30.2.tgz",
|
||||
"integrity": "sha512-+xIv67V+/2L1uvz98FAT5W7kWEfHwfNV3MD7b4UsKPU0lhcCWuVOXy0JB8yYmdNExqpI7xT9g3MWzREoBvBQSg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-3.30.3.tgz",
|
||||
"integrity": "sha512-B9gqrgM1uHjCKr/PSnnSl+bS+YQb5EN/PUW9KWp9nSgmIaqxXws2ufqowS65uTLJLqd7pwF4l5lUrsfhq0EKzw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-dropcursor": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.30.2.tgz",
|
||||
"integrity": "sha512-nyRKUmItATnKI9AiRChmjhcBbCEsNxRu+AaCz+cx8EvnAcNHsVRdNYL5PmBs3WlNA/Et4Eb2DG0hVQDnNF61eg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-3.30.3.tgz",
|
||||
"integrity": "sha512-xdY66lcQakBLvWbJQHeJy/Td0f10YRXLyFeOFzt9PODsX4nqwJMju9tpqcLIGp0waaztu8PGwZ81oSCdQldIHQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.30.2"
|
||||
"@tiptap/extensions": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-floating-menu": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.30.2.tgz",
|
||||
"integrity": "sha512-A8PLvvh8W6PUMrqh+EpBerxm+Ucr0irGxJvwAnzYQmNGNIJ9U4OVgw4OcEU+9JH0gMmEzDcHzMPP2s/s1lIcyw==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-3.30.3.tgz",
|
||||
"integrity": "sha512-4l5Qee1wBk2YBFEFbWHFhUt++6hDY7Yp81BkO3wY6KFToxs+cm9JIm3xr3KF9UJ/vnUpIhBWIbZl3uKf37SJLA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"funding": {
|
||||
@@ -1619,93 +1619,93 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-gapcursor": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.30.2.tgz",
|
||||
"integrity": "sha512-7Xk0ut6FM+RAsvKxDN3bAtk7zvYZ6Aa8pawJ6s7dLAmLR9JwrZevlcL4FSrj4bR7rqKOj92RYCFxzgTEbWimag==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-3.30.3.tgz",
|
||||
"integrity": "sha512-+mwm64+RiArd1G8xSgtaTrvx1X5Lzz6sJ93zTmaiMVNc2N29AN77BVPTJ0e+853+/F6Bec/vOnVkIjTLg/ZBRw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extensions": "3.30.2"
|
||||
"@tiptap/extensions": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-hard-break": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.30.2.tgz",
|
||||
"integrity": "sha512-IxSNgmG3d4OZdUTeebrOI7SxdIWXXJqlcGiSNDabWqxipUitfy3mZ3gDDE6G01koKxZRbhz4KIplAZlpxnTFSg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-3.30.3.tgz",
|
||||
"integrity": "sha512-/tX+IFW2C4RJltbwcn8/4zoHwj5YycRNOugb4Ul9Fl1AOJqjNwRx8xc0NpaOjuADhlMYMczEtSaOiDh5ZEOmjg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-heading": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.30.2.tgz",
|
||||
"integrity": "sha512-PblDvgSJ05p1t6hzyPi02xeiBjB0M2abReoGEImqSWCy79UqnAGacgsZo4EeEawtJV1NEP8chhvmX+nRtzdT1A==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-3.30.3.tgz",
|
||||
"integrity": "sha512-y+0u9qdrUAOGNrP52hAEiH1mvr1ZmzmkCBICICiXRH4+QNXpKkiBK3zlbDOPVQj0g0YIg6XIIU0vIaUBDPIaMQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-horizontal-rule": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.30.2.tgz",
|
||||
"integrity": "sha512-j8aswLTsuEdJKC62DF+kw0EgvIRL7QMUyAVp2fdjR0qgM0ZVlEwCC4qIEq3kK9tFVU4kRtQ5BSj/jn6QwrlbCA==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-3.30.3.tgz",
|
||||
"integrity": "sha512-J/ioKlXu5oJ+pPtybFonByx1LusbR0PUd1nkx6XsZqY9wyW6uecZQgAyI8KUWIXqOfhnAW38UTsHMBRdm2XupA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-image": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-3.30.2.tgz",
|
||||
"integrity": "sha512-K/BPlWauHXI6Y4s7se2A1BLcZ2pnWmRQTEDkPJYe/8kmv1GyJzPu34sZed5Mvfu5chUH8u6aNZ/utZbvSbI/0Q==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-3.30.3.tgz",
|
||||
"integrity": "sha512-vbKMliRLXkABwnPenPlQDEVp3MFN7Hs+WUh1eliVmYfsBfhEo596ahahv+JVoR9JW6HSM+LVdf2TT19Iqmh0sg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-italic": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.30.2.tgz",
|
||||
"integrity": "sha512-pp8uaiuXsUbLm5rYzR1jlWbwm1mAahRajdHwAKBtthFRB2rDvC7ZWhKaCSoKhZvfIDRmu9/B67+uAHoutL0dCA==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-3.30.3.tgz",
|
||||
"integrity": "sha512-dVWqJ/kDXdPHRBp4nU7bwi2G+c3oNruIgQHYVRgYlWkwW/opvnlACZLBUgEhihH7ANiSaGW1zLQ7HuUDSL3vog==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-link": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.30.2.tgz",
|
||||
"integrity": "sha512-jwdcymKcrbFpj5hRAuGVLCq8FieVkGFnENyroYmvkad+XAt8ZLy/MTFYRN6SK3ukH6PZMY7H4iObGtciQaC5nw==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-3.30.3.tgz",
|
||||
"integrity": "sha512-MAAXfLJNf6ZFiFK3w51yiLKc31HAQWJWNV+nQ1dAdRpa6WiXdjpkcrWTuxmPd/o6Qt+yNv+hoItAVxDPEox8qQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"linkifyjs": "^4.3.3"
|
||||
@@ -1715,133 +1715,133 @@
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.30.2.tgz",
|
||||
"integrity": "sha512-MIUpo1Bd9Rf1Qg+TNYNwDZ4xsfFeQahjU9Xhy6UcaszKQzbAM7KCzn5BObNytK1NdcqNHsC8Wj5vFvMKEzrXdw==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list/-/extension-list-3.30.3.tgz",
|
||||
"integrity": "sha512-cCX99WoVb4UyXkamSh0vlXiRFhlZnwk3WXWdnXpR1E9+auxsQewk2Q9NDW1Ra0vwgzer1gkFhlOl9TCVzH2VVg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-item": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.30.2.tgz",
|
||||
"integrity": "sha512-HWgRCRlGxulE+hN1VUcnWD6P2NE08VBgGtcaxOfdXVqaI93BCK6AhRQZGpLsfKgajLk+5DXTBraaitwnBqzCxg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-3.30.3.tgz",
|
||||
"integrity": "sha512-RhSyDlAATvXDTg/1VOw5aFTaewdCm+BAU3EG3eUCw4e5eoZ5pbhPOdOPTtaO45UR4i/AvjQNAZQ9LMDWX5WZFQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.30.2"
|
||||
"@tiptap/extension-list": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-keymap": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.30.2.tgz",
|
||||
"integrity": "sha512-TTve3WOlQaYu1ahMqsQ/T0wzaxfgZvcOl3/OuPyInOi8QtxXhqGhFjmYe5jOr56G9W2QDuFWVsZecVwfDte9zg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-keymap/-/extension-list-keymap-3.30.3.tgz",
|
||||
"integrity": "sha512-u6tOpQFnE1pOyvnzI2MvhW/Yw0omAIMlMfkykYx4N4zB1JDi+16OeOuKf3rX6G3V9VUu+qeOIGpSkifkME6H9Q==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.30.2"
|
||||
"@tiptap/extension-list": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-ordered-list": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.30.2.tgz",
|
||||
"integrity": "sha512-Z7OO1HcF0idda1n6vodXeQ3h2ylN9JR4IfIGUYkar5Xl9JusK8PDETTBQZQn//96p49I2d+GoWsD2LXPtjHXXg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-3.30.3.tgz",
|
||||
"integrity": "sha512-lct/FV8vm9Y5kZFcF5TXIM18opi6m7AAkGoChgGP/A7LYalaniX1X6Ja2j13Y22ZdGaOoPTgd8oKRZXP1/miaA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/extension-list": "3.30.2"
|
||||
"@tiptap/extension-list": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-paragraph": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.30.2.tgz",
|
||||
"integrity": "sha512-ulEu3LNt+kPVAWEnrhoz13Fs8Q/v/8NUxQbAeteuBchQ8joxJXuWExhpy1fUfZir5+b+W5z7/NesgPjZQfv47w==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-3.30.3.tgz",
|
||||
"integrity": "sha512-Z9OHCX9b2bDcMDeR3ODCFRAyHT5eNGO4AsDFeAJS/XSitffMyjFHtOkXlyyZ3+pIHxxX6xkUXAwaLMjyATRo1A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.30.2.tgz",
|
||||
"integrity": "sha512-fBLxMXz6hYIURzLOD+/L6aVATztsKham00ANWmGi13vN0hx2lQMYZffN+gR+QqiCDfMQxBXzrf5a7tJuDiQHLQ==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-3.30.3.tgz",
|
||||
"integrity": "sha512-e9BI8Hzei23GjmYysXxL+CHq3fIgOm29BbSUMbYXxT2cJ+TkkgJp7EvHf74gSABNME0gUN+mG0pRR5wTFoOCcg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.30.2.tgz",
|
||||
"integrity": "sha512-n/iZnirgRmXet6f97kolAnP3j8DsgLSiTbz/KLWc8eBYiFmkjRzkuisOm5xuGdfGIxwpB4x3tlSF4ef4DLnbRg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-3.30.3.tgz",
|
||||
"integrity": "sha512-Jh8ZyI0HLOJOIPZl5a5XRJbTs4pAUakYIWCZ3Hv3lF9ouXW/C0bY67XQU7bv6Rvu8AHzDszhKklnOZ6z1NQPXQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-underline": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.30.2.tgz",
|
||||
"integrity": "sha512-SZiTMnvqXcnrtJX+X25ZbYsuDO83haGOVMBD/O+mAWYNYXhaSc5Rkph5czzItxrd+Yyp/vs4PiwD7XTNbfqmpA==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-3.30.3.tgz",
|
||||
"integrity": "sha512-TiZ+b524Ee4PNlW+HNmkg3x4btR1K6btJy9pEjMuDf0Rx01UaTBvHpHmABR/DbbcC1CuZiQ3ylJwLL+90PaEoA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2"
|
||||
"@tiptap/core": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extensions": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.30.2.tgz",
|
||||
"integrity": "sha512-2LqAHXk26QDsryW+beECxYeBzv5Ylk4GuB3cOmfghS7/G37R2W+Te3TkUK7BT0EWoDryvBT57/5q0DEFIhfZZg==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extensions/-/extensions-3.30.3.tgz",
|
||||
"integrity": "sha512-vig8ZjUL/NFnniEVbYDYj2UOIdkwZVha+9myFZkanShedviE3kl7c4uCY3fMl5EnqgyFIy2TQSKbg/i99xpztA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.30.2.tgz",
|
||||
"integrity": "sha512-BJN8tUx4ppFN3R3cV/FJfrJbJkvo1lj4uciq+nwpjwzdRvFzqIuglWf+HLcJ6CwlYpLOHp7ArgkBg4Q5e60Gog==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-3.30.3.tgz",
|
||||
"integrity": "sha512-VheaqLAFUe+PCYEgHubM96Z1OAiluFhijQ2Cy1Ghiozoxm5OzevSaKhqm8SQ1VGfzZZko59oUjRzOmu8tB8yfA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.4.1",
|
||||
@@ -1864,9 +1864,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/react": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.30.2.tgz",
|
||||
"integrity": "sha512-7hGaTstpUeTmQ008mCPkjz+GSlChWhucgy+PeX0z93v4+nh7qM5F+0lh+kJ9zo6Os5abO7v36GtgHRZdQI6+FQ==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/react/-/react-3.30.3.tgz",
|
||||
"integrity": "sha512-gyK8UXFQlm2XgXEynNz5SzsxnTKtdBUp/PKeTeqFrk/m7L8p1eV+gcdAK+arTX+slubXRwLUm1lXrAQXRuiaTw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
@@ -1878,12 +1878,12 @@
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tiptap/extension-bubble-menu": "^3.30.2",
|
||||
"@tiptap/extension-floating-menu": "^3.30.2"
|
||||
"@tiptap/extension-bubble-menu": "^3.30.3",
|
||||
"@tiptap/extension-floating-menu": "^3.30.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2",
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3",
|
||||
"@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
@@ -1891,35 +1891,35 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/starter-kit": {
|
||||
"version": "3.30.2",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.30.2.tgz",
|
||||
"integrity": "sha512-fJSrhW1CyD4sjYA20evSP4Cp13B/HhbxCdM974K0xpHOVqvCtNU9w2s9hfq9mg2yGoU7MSNHKNYMkJjIi2/Xyw==",
|
||||
"version": "3.30.3",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-3.30.3.tgz",
|
||||
"integrity": "sha512-hj4rAhAoQm+wRk8eLNTyK+wK81+epbuo4O9PvPRv7GJGwYycej+xUN7jGM7Tney7GuTZpHoDCuwLKD2n1oG+pg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "3.30.2",
|
||||
"@tiptap/extension-blockquote": "3.30.2",
|
||||
"@tiptap/extension-bold": "3.30.2",
|
||||
"@tiptap/extension-bullet-list": "3.30.2",
|
||||
"@tiptap/extension-code": "3.30.2",
|
||||
"@tiptap/extension-code-block": "3.30.2",
|
||||
"@tiptap/extension-document": "3.30.2",
|
||||
"@tiptap/extension-dropcursor": "3.30.2",
|
||||
"@tiptap/extension-gapcursor": "3.30.2",
|
||||
"@tiptap/extension-hard-break": "3.30.2",
|
||||
"@tiptap/extension-heading": "3.30.2",
|
||||
"@tiptap/extension-horizontal-rule": "3.30.2",
|
||||
"@tiptap/extension-italic": "3.30.2",
|
||||
"@tiptap/extension-link": "3.30.2",
|
||||
"@tiptap/extension-list": "3.30.2",
|
||||
"@tiptap/extension-list-item": "3.30.2",
|
||||
"@tiptap/extension-list-keymap": "3.30.2",
|
||||
"@tiptap/extension-ordered-list": "3.30.2",
|
||||
"@tiptap/extension-paragraph": "3.30.2",
|
||||
"@tiptap/extension-strike": "3.30.2",
|
||||
"@tiptap/extension-text": "3.30.2",
|
||||
"@tiptap/extension-underline": "3.30.2",
|
||||
"@tiptap/extensions": "3.30.2",
|
||||
"@tiptap/pm": "3.30.2"
|
||||
"@tiptap/core": "3.30.3",
|
||||
"@tiptap/extension-blockquote": "3.30.3",
|
||||
"@tiptap/extension-bold": "3.30.3",
|
||||
"@tiptap/extension-bullet-list": "3.30.3",
|
||||
"@tiptap/extension-code": "3.30.3",
|
||||
"@tiptap/extension-code-block": "3.30.3",
|
||||
"@tiptap/extension-document": "3.30.3",
|
||||
"@tiptap/extension-dropcursor": "3.30.3",
|
||||
"@tiptap/extension-gapcursor": "3.30.3",
|
||||
"@tiptap/extension-hard-break": "3.30.3",
|
||||
"@tiptap/extension-heading": "3.30.3",
|
||||
"@tiptap/extension-horizontal-rule": "3.30.3",
|
||||
"@tiptap/extension-italic": "3.30.3",
|
||||
"@tiptap/extension-link": "3.30.3",
|
||||
"@tiptap/extension-list": "3.30.3",
|
||||
"@tiptap/extension-list-item": "3.30.3",
|
||||
"@tiptap/extension-list-keymap": "3.30.3",
|
||||
"@tiptap/extension-ordered-list": "3.30.3",
|
||||
"@tiptap/extension-paragraph": "3.30.3",
|
||||
"@tiptap/extension-strike": "3.30.3",
|
||||
"@tiptap/extension-text": "3.30.3",
|
||||
"@tiptap/extension-underline": "3.30.3",
|
||||
"@tiptap/extensions": "3.30.3",
|
||||
"@tiptap/pm": "3.30.3"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@@ -1983,9 +1983,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "19.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.4.tgz",
|
||||
"integrity": "sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==",
|
||||
"version": "19.2.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.5.tgz",
|
||||
"integrity": "sha512-fMPwH9v7r/pp43yUd2/Mbiex5KouJwwR3dzHkhLREUC6764VyDsqxhAxv6OFEYR1RhjOyD1naqba8ECDBe7ZQg==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
@@ -2027,9 +2027,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.11.17",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.17.tgz",
|
||||
"integrity": "sha512-KAUDn1OSS0fmPlGO+NOUMRcOQ/b/shUBH3OgkG73mPgdf+JD/BQ6fHboGxNOxnUmlwcq+lLq3dTkayRPuSfXwg==",
|
||||
"version": "2.11.18",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.18.tgz",
|
||||
"integrity": "sha512-1iEmLEYSiE1SeBoAfPo/Mnx3PzfzHUkDK61ASkCpuk3YXugYLH5DYK1SzqV55F8FMI6s0F+/tCP7Polz1QRjxw==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"baseline-browser-mapping": "dist/cli.cjs"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@govoplan/core-webui",
|
||||
"version": "0.1.35",
|
||||
"version": "0.1.39",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
@@ -26,23 +26,23 @@
|
||||
"preview": "vite preview --host 127.0.0.1 --port 4173"
|
||||
},
|
||||
"dependencies": {
|
||||
"@govoplan/access-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#v0.1.20",
|
||||
"@govoplan/admin-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#v0.1.19",
|
||||
"@govoplan/access-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-access.git#v0.1.23",
|
||||
"@govoplan/admin-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-admin.git#v0.1.22",
|
||||
"@govoplan/audit-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-audit.git#v0.1.18",
|
||||
"@govoplan/calendar-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#v0.1.18",
|
||||
"@govoplan/calendar-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-calendar.git#v0.1.22",
|
||||
"@govoplan/cases-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-cases.git#v0.1.20",
|
||||
"@govoplan/dashboard-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-dashboard.git#v0.1.18",
|
||||
"@govoplan/docs-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#v0.1.18",
|
||||
"@govoplan/files-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#v0.1.20",
|
||||
"@govoplan/docs-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-docs.git#v0.1.22",
|
||||
"@govoplan/files-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-files.git#v0.1.23",
|
||||
"@govoplan/helpdesk-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-helpdesk.git#v0.1.20",
|
||||
"@govoplan/idm-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#v0.1.19",
|
||||
"@govoplan/mail-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#v0.1.18",
|
||||
"@govoplan/campaign-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#v0.1.22",
|
||||
"@govoplan/organizations-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#v0.1.18",
|
||||
"@govoplan/idm-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-idm.git#v0.1.24",
|
||||
"@govoplan/mail-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-mail.git#v0.1.24",
|
||||
"@govoplan/campaign-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-campaign.git#v0.1.27",
|
||||
"@govoplan/organizations-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-organizations.git#v0.1.20",
|
||||
"@govoplan/ops-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-ops.git#v0.1.18",
|
||||
"@govoplan/policy-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-policy.git#v0.1.18",
|
||||
"@govoplan/tickets-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#v0.1.20",
|
||||
"@govoplan/wiki-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#v0.1.20",
|
||||
"@govoplan/tickets-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-tickets.git#v0.1.22",
|
||||
"@govoplan/wiki-webui": "git+ssh://git@git.add-ideas.de/GovOPlaN/govoplan-wiki.git#v0.1.22",
|
||||
"@tiptap/core": "^3.29.2",
|
||||
"@tiptap/extension-image": "^3.29.2",
|
||||
"@tiptap/pm": "^3.29.2",
|
||||
|
||||
@@ -3,8 +3,9 @@ import { Dice5, Eye, EyeOff } from "lucide-react";
|
||||
import PasswordGeneratorDialog from "./PasswordGeneratorDialog";
|
||||
import type { PasswordGeneratorOptions } from "./passwordGenerator";
|
||||
import { usePlatformLanguage } from "../i18n/LanguageContext";
|
||||
import type { PlatformInterfaceIdentityProps } from "../types";
|
||||
|
||||
export type PasswordFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange"> & {
|
||||
export type PasswordFieldProps = Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange"> & PlatformInterfaceIdentityProps & {
|
||||
value: string;
|
||||
onValueChange: (value: string) => void;
|
||||
saved?: boolean;
|
||||
@@ -32,6 +33,10 @@ export default function PasswordField({
|
||||
className = "",
|
||||
inputClassName = "",
|
||||
id,
|
||||
interfaceId,
|
||||
helpContextId,
|
||||
helpModuleId,
|
||||
helpTopicId,
|
||||
...inputProps
|
||||
}: PasswordFieldProps) {
|
||||
const generatedId = useId();
|
||||
@@ -50,10 +55,20 @@ export default function PasswordField({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`password-field ${canReveal || canGenerate ? "has-actions" : ""} ${canGenerate ? "has-generator" : ""} ${canReveal ? "has-reveal" : ""} ${showSavedPlaceholder ? "is-saved-empty" : ""} ${className}`.trim()}>
|
||||
<div
|
||||
className={`password-field ${canReveal || canGenerate ? "has-actions" : ""} ${canGenerate ? "has-generator" : ""} ${canReveal ? "has-reveal" : ""} ${showSavedPlaceholder ? "is-saved-empty" : ""} ${className}`.trim()}
|
||||
data-help-scope="field"
|
||||
data-interface-id={interfaceId}
|
||||
data-help-context-id={helpContextId}
|
||||
data-help-module-id={helpModuleId}
|
||||
data-help-topic-id={helpTopicId}
|
||||
>
|
||||
<input
|
||||
{...inputProps}
|
||||
id={inputId}
|
||||
data-help-context-id={helpContextId}
|
||||
data-help-module-id={helpModuleId}
|
||||
data-help-topic-id={helpTopicId}
|
||||
className={inputClassName}
|
||||
type={inputType}
|
||||
value={value}
|
||||
@@ -72,6 +87,9 @@ export default function PasswordField({
|
||||
className="password-field-action"
|
||||
aria-label={translatedGeneratorLabel}
|
||||
title={translatedGeneratorLabel}
|
||||
data-help-context-id={helpContextId}
|
||||
data-help-module-id={helpModuleId}
|
||||
data-help-topic-id={helpTopicId}
|
||||
onClick={() => setGeneratorOpen(true)}
|
||||
>
|
||||
<Dice5 size={17} aria-hidden="true" />
|
||||
@@ -83,6 +101,9 @@ export default function PasswordField({
|
||||
className="password-field-action"
|
||||
aria-label={visible ? translatedHideLabel : translatedRevealLabel}
|
||||
title={visible ? translatedHideLabel : translatedRevealLabel}
|
||||
data-help-context-id={helpContextId}
|
||||
data-help-module-id={helpModuleId}
|
||||
data-help-topic-id={helpTopicId}
|
||||
onClick={() => setVisible((current) => !current)}
|
||||
>
|
||||
{visible ? <EyeOff size={17} aria-hidden="true" /> : <Eye size={17} aria-hidden="true" />}
|
||||
@@ -95,6 +116,9 @@ export default function PasswordField({
|
||||
<PasswordGeneratorDialog
|
||||
open={generatorOpen}
|
||||
initialOptions={generatorOptions}
|
||||
helpContextId={helpContextId}
|
||||
helpModuleId={helpModuleId}
|
||||
helpTopicId={helpTopicId}
|
||||
onUse={(password) => {
|
||||
onValueChange(password);
|
||||
setVisible(false);
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
type PasswordGeneratorOptions
|
||||
} from "./passwordGenerator";
|
||||
import { usePlatformLanguage } from "../i18n/LanguageContext";
|
||||
import type { PlatformInterfaceIdentityProps } from "../types";
|
||||
|
||||
const GENERATION_ERROR_LABELS: Record<PasswordGeneratorErrorCode, string> = {
|
||||
"invalid-length": "i18n:govoplan-core.password_length_must_be_between_12_and_128_character.4d147c07",
|
||||
@@ -23,7 +24,7 @@ const GENERATION_ERROR_LABELS: Record<PasswordGeneratorErrorCode, string> = {
|
||||
"secure-random-unavailable": "i18n:govoplan-core.secure_browser_password_generation_is_unavailable.55275f10"
|
||||
};
|
||||
|
||||
export type PasswordGeneratorDialogProps = {
|
||||
export type PasswordGeneratorDialogProps = PlatformInterfaceIdentityProps & {
|
||||
open: boolean;
|
||||
initialOptions?: Partial<PasswordGeneratorOptions>;
|
||||
onUse: (password: string) => void;
|
||||
@@ -33,6 +34,9 @@ export type PasswordGeneratorDialogProps = {
|
||||
export default function PasswordGeneratorDialog({
|
||||
open,
|
||||
initialOptions,
|
||||
helpContextId,
|
||||
helpModuleId,
|
||||
helpTopicId,
|
||||
onUse,
|
||||
onClose
|
||||
}: PasswordGeneratorDialogProps) {
|
||||
@@ -95,6 +99,9 @@ export default function PasswordGeneratorDialog({
|
||||
bodyClassName="password-generator-body"
|
||||
footerClassName="button-row compact-actions"
|
||||
portal
|
||||
helpContextId={helpContextId}
|
||||
helpModuleId={helpModuleId}
|
||||
helpTopicId={helpTopicId}
|
||||
onClose={onClose}
|
||||
footer={(
|
||||
<>
|
||||
@@ -103,6 +110,9 @@ export default function PasswordGeneratorDialog({
|
||||
type="button"
|
||||
variant="primary"
|
||||
disabled={!candidate}
|
||||
helpContextId={helpContextId}
|
||||
helpModuleId={helpModuleId}
|
||||
helpTopicId={helpTopicId}
|
||||
onClick={() => {
|
||||
if (!candidate) return;
|
||||
onUse(candidate);
|
||||
@@ -116,7 +126,7 @@ export default function PasswordGeneratorDialog({
|
||||
>
|
||||
{error ? <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert> : null}
|
||||
<div className="password-generator-options">
|
||||
<FormField label="i18n:govoplan-core.length.adc95605">
|
||||
<FormField label="i18n:govoplan-core.length.adc95605" helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId}>
|
||||
<input
|
||||
type="number"
|
||||
min={12}
|
||||
@@ -127,13 +137,13 @@ export default function PasswordGeneratorDialog({
|
||||
/>
|
||||
</FormField>
|
||||
<div className="password-generator-character-sets" aria-label={translateText("i18n:govoplan-core.character_sets.db6efda2")}>
|
||||
<ToggleSwitch label="i18n:govoplan-core.lowercase.3b677a18" checked={options.lowercase} onChange={(checked) => setOption("lowercase", checked)} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.uppercase.b463d690" checked={options.uppercase} onChange={(checked) => setOption("uppercase", checked)} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.digits.9cd500d3" checked={options.digits} onChange={(checked) => setOption("digits", checked)} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.symbols.9491fc41" checked={options.symbols} onChange={(checked) => setOption("symbols", checked)} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.lowercase.3b677a18" checked={options.lowercase} onChange={(checked) => setOption("lowercase", checked)} helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.uppercase.b463d690" checked={options.uppercase} onChange={(checked) => setOption("uppercase", checked)} helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.digits.9cd500d3" checked={options.digits} onChange={(checked) => setOption("digits", checked)} helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId} />
|
||||
<ToggleSwitch label="i18n:govoplan-core.symbols.9491fc41" checked={options.symbols} onChange={(checked) => setOption("symbols", checked)} helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId} />
|
||||
</div>
|
||||
</div>
|
||||
<FormField label="i18n:govoplan-core.generated_password.78461854">
|
||||
<FormField label="i18n:govoplan-core.generated_password.78461854" helpContextId={helpContextId} helpModuleId={helpModuleId} helpTopicId={helpTopicId}>
|
||||
<div className="password-generator-result">
|
||||
<input
|
||||
type="text"
|
||||
@@ -147,11 +157,17 @@ export default function PasswordGeneratorDialog({
|
||||
icon={<Copy size={16} />}
|
||||
onClick={() => void copy()}
|
||||
disabled={!candidate || typeof navigator === "undefined" || !navigator.clipboard?.writeText}
|
||||
helpContextId={helpContextId}
|
||||
helpModuleId={helpModuleId}
|
||||
helpTopicId={helpTopicId}
|
||||
/>
|
||||
<IconButton
|
||||
label="i18n:govoplan-core.generate_another_password.d99fc019"
|
||||
icon={<RefreshCw size={16} />}
|
||||
onClick={generate}
|
||||
helpContextId={helpContextId}
|
||||
helpModuleId={helpModuleId}
|
||||
helpTopicId={helpTopicId}
|
||||
/>
|
||||
</div>
|
||||
</FormField>
|
||||
|
||||
@@ -57,13 +57,13 @@ export default function LoginModal({
|
||||
<FormLayout columns={1} collapseAt="standard" id={formId} className="" onSubmit={submit}>
|
||||
{message && <DismissibleAlert tone="info" dismissible={false}>{message}</DismissibleAlert>}
|
||||
{error && <DismissibleAlert tone="danger" resetKey={error}>{error}</DismissibleAlert>}
|
||||
<FormField label="i18n:govoplan-core.email.84add5b2">
|
||||
<input type="email" value={email} autoComplete="username" onChange={(e) => setEmail(e.target.value)} />
|
||||
<FormField label="i18n:govoplan-core.email.84add5b2" helpContextId="access.authentication.email" helpModuleId="access">
|
||||
<input data-help-context-id="access.authentication.email" data-help-module-id="access" type="email" value={email} autoComplete="username" onChange={(e) => setEmail(e.target.value)} />
|
||||
</FormField>
|
||||
<FormField label="i18n:govoplan-core.password.8be3c943">
|
||||
<PasswordField value={password} autoComplete="current-password" onValueChange={setPassword} />
|
||||
<FormField label="i18n:govoplan-core.password.8be3c943" helpContextId="access.authentication.password" helpModuleId="access">
|
||||
<PasswordField helpContextId="access.authentication.password" helpModuleId="access" value={password} autoComplete="current-password" onValueChange={setPassword} />
|
||||
</FormField>
|
||||
</FormLayout>
|
||||
</Dialog>);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -572,8 +572,10 @@ export default function SettingsPage({
|
||||
<FormField label="i18n:govoplan-core.api_base_url.1358fba4" help="i18n:govoplan-core.leave_empty_to_use_the_same_origin_in_vite_dev_a.9a1c25d7">
|
||||
<input value={settings.apiBaseUrl} onChange={(e) => onSettingsChange({ ...settings, apiBaseUrl: e.target.value })} placeholder="https://example.org or empty" />
|
||||
</FormField>
|
||||
<FormField label="i18n:govoplan-core.automation_api_key.5d4e2e6e" help="i18n:govoplan-core.used_only_when_there_is_no_browser_session_token.9d399e70">
|
||||
<FormField label="i18n:govoplan-core.automation_api_key.5d4e2e6e" help="i18n:govoplan-core.used_only_when_there_is_no_browser_session_token.9d399e70" helpContextId="access.settings.automation-api-key" helpModuleId="access">
|
||||
<PasswordField
|
||||
helpContextId="access.settings.automation-api-key"
|
||||
helpModuleId="access"
|
||||
value={settings.apiKey}
|
||||
autoComplete="off"
|
||||
onValueChange={(apiKey) => onSettingsChange({ ...settings, apiKey })} />
|
||||
|
||||
@@ -4,6 +4,7 @@ function assert(condition: unknown, message = "assertion failed"): asserts condi
|
||||
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import PasswordField from "../src/components/PasswordField";
|
||||
import PasswordGeneratorDialog from "../src/components/PasswordGeneratorDialog";
|
||||
import {
|
||||
DEFAULT_PASSWORD_GENERATOR_OPTIONS,
|
||||
generateSecurePassword,
|
||||
@@ -56,11 +57,27 @@ for (const [options, expected] of [
|
||||
|
||||
const markup = renderToStaticMarkup(
|
||||
<PlatformLanguageProvider>
|
||||
<PasswordField value="" onValueChange={() => undefined} generator />
|
||||
<PasswordField value="" onValueChange={() => undefined} generator helpContextId="access.authentication.password" helpModuleId="access" />
|
||||
</PlatformLanguageProvider>
|
||||
);
|
||||
assert(markup.includes('aria-label="Generate password"'), "the opt-in generator action is accessible");
|
||||
assert(markup.includes("lucide-dice-5"), "the familiar generator icon is used");
|
||||
assert(!markup.includes("password-generator-dialog"), "the generator dialog stays closed until explicitly requested");
|
||||
assert(markup.includes('data-help-context-id="access.authentication.password"'), "the owner context reaches the password field and its actions");
|
||||
assert(markup.includes('data-help-module-id="access"'), "the password field retains its documentation owner");
|
||||
|
||||
const dialogMarkup = renderToStaticMarkup(
|
||||
<PlatformLanguageProvider>
|
||||
<PasswordGeneratorDialog
|
||||
open
|
||||
helpContextId="access.authentication.password"
|
||||
helpModuleId="access"
|
||||
onUse={() => undefined}
|
||||
onClose={() => undefined}
|
||||
/>
|
||||
</PlatformLanguageProvider>
|
||||
);
|
||||
assert(dialogMarkup.includes('data-help-context-id="access.authentication.password"'), "the generator dialog inherits the calling credential context");
|
||||
assert(dialogMarkup.includes('data-help-module-id="access"'), "generated-password controls retain the credential owner's module");
|
||||
|
||||
console.log("Password generator contract passed.");
|
||||
|
||||
Reference in New Issue
Block a user