Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee7dbd99b8 | ||
|
|
c2a3c24f82 | ||
|
|
bb6ebf194a | ||
|
|
5c186b565e |
@@ -10,3 +10,21 @@ Notifications keeps delivery state, and each domain module keeps its business
|
|||||||
objects and commands.
|
objects and commands.
|
||||||
|
|
||||||
See [Tasks Domain And Unified Work Inbox](docs/TASKS_DOMAIN.md).
|
See [Tasks Domain And Unified Work Inbox](docs/TASKS_DOMAIN.md).
|
||||||
|
|
||||||
|
## Git-source WebUI package
|
||||||
|
|
||||||
|
The repository root exposes `@govoplan/tasks-webui` for Git-tagged release
|
||||||
|
dependencies. It mirrors the owning `webui/package.json` version, public
|
||||||
|
TypeScript/CSS exports and peer requirements, with entry paths under
|
||||||
|
`webui/src`. Consumers provide the shared Core/React peers; the facade runs no
|
||||||
|
development or install scripts. The source archive contains `webui/src`, this
|
||||||
|
README and any repository license file. Run module development checks from `webui/`; Python
|
||||||
|
installation remains governed by `pyproject.toml`.
|
||||||
|
|
||||||
|
Das Repository stellt `@govoplan/tasks-webui` am Wurzelpfad für versionierte
|
||||||
|
Git-Abhängigkeiten bereit. Version, öffentliche TypeScript-/CSS-Exporte und
|
||||||
|
Peer-Anforderungen entsprechen `webui/package.json`; die Einstiegspfade liegen
|
||||||
|
unter `webui/src`. Gemeinsame Core-/React-Peers stellt die einbindende Anwendung
|
||||||
|
bereit. Die Fassade führt keine Entwicklungs- oder Installationsskripte aus.
|
||||||
|
Entwicklungsprüfungen bleiben in `webui/`, die Python-Installation weiterhin in
|
||||||
|
`pyproject.toml` definiert.
|
||||||
|
|||||||
+29
-3
@@ -1,8 +1,34 @@
|
|||||||
{
|
{
|
||||||
"name": "@govoplan/tasks",
|
"name": "@govoplan/tasks-webui",
|
||||||
"version": "0.1.21",
|
"version": "0.1.23",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "Governed work items and unified work inbox for GovOPlaN.",
|
"description": "Governed work items and unified work inbox for GovOPlaN.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"peerDependencies": {}
|
"peerDependencies": {
|
||||||
|
"@govoplan/core-webui": "^0.1.45",
|
||||||
|
"lucide-react": "^1.23.0",
|
||||||
|
"react": ">=19.2.7 <20",
|
||||||
|
"react-dom": ">=19.2.7 <20",
|
||||||
|
"react-router": ">=8.3.0 <9"
|
||||||
|
},
|
||||||
|
"main": "webui/src/index.ts",
|
||||||
|
"module": "webui/src/index.ts",
|
||||||
|
"types": "webui/src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./webui/src/index.ts",
|
||||||
|
"import": "./webui/src/index.ts"
|
||||||
|
},
|
||||||
|
"./styles/tasks.css": "./webui/src/styles/tasks.css"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@govoplan/core-webui": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"webui/src",
|
||||||
|
"README.md",
|
||||||
|
"LICENSE"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -4,13 +4,13 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "govoplan-tasks"
|
name = "govoplan-tasks"
|
||||||
version = "0.1.21"
|
version = "0.1.23"
|
||||||
description = "Governed work items and unified work inbox for GovOPlaN."
|
description = "Governed work items and unified work inbox for GovOPlaN."
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
authors = [{ name = "GovOPlaN" }]
|
authors = [{ name = "GovOPlaN" }]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"govoplan-core>=0.1.18",
|
"govoplan-core>=0.1.45",
|
||||||
"govoplan-access>=0.1.18",
|
"govoplan-access>=0.1.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
"""GovOPlaN Tasks module."""
|
"""GovOPlaN Tasks module."""
|
||||||
|
|
||||||
__version__ = "0.1.21"
|
__version__ = "0.1.23"
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ from govoplan_core.core.modules import (
|
|||||||
ModuleManifest,
|
ModuleManifest,
|
||||||
NavItem,
|
NavItem,
|
||||||
PermissionDefinition,
|
PermissionDefinition,
|
||||||
|
ProductAvailabilityExplanation,
|
||||||
ProductAreaContribution,
|
ProductAreaContribution,
|
||||||
|
ProductSurfaceContribution,
|
||||||
QuickAccessTool,
|
QuickAccessTool,
|
||||||
RoleTemplate,
|
RoleTemplate,
|
||||||
)
|
)
|
||||||
@@ -47,7 +49,7 @@ from govoplan_tasks.backend.service import SqlTaskService
|
|||||||
|
|
||||||
MODULE_ID = "tasks"
|
MODULE_ID = "tasks"
|
||||||
MODULE_NAME = "Tasks"
|
MODULE_NAME = "Tasks"
|
||||||
MODULE_VERSION = "0.1.21"
|
MODULE_VERSION = "0.1.23"
|
||||||
READ_SCOPE = "tasks:item:read"
|
READ_SCOPE = "tasks:item:read"
|
||||||
WRITE_SCOPE = "tasks:item:write"
|
WRITE_SCOPE = "tasks:item:write"
|
||||||
ADMIN_SCOPE = "tasks:item:admin"
|
ADMIN_SCOPE = "tasks:item:admin"
|
||||||
@@ -134,6 +136,26 @@ ROLE_TEMPLATES = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
DOCUMENTATION = (
|
DOCUMENTATION = (
|
||||||
|
DocumentationTopic(
|
||||||
|
id="tasks.workspace-layout",
|
||||||
|
title="Tasks workspace actions",
|
||||||
|
summary="Find collection-wide commands in their consistent workspace position.",
|
||||||
|
body="Documentation books sit immediately beside the visible heading or contextual label for "
|
||||||
|
"Tasks, not among operational action buttons. Field help remains beside its label. "
|
||||||
|
"Reload and Create task use the persistent full-width workspace header at the upper right; Reload sits immediately before creation. Selecting a record, changing filters, or opening an editor does not move these collection-wide commands into the left pane. Search and status filters stay in the task list; completion, ownership, and other task-specific actions remain with the selected task. Existing permissions, disabled-state rules, and unsaved-change guards still apply. Administrators configure authority through the existing permission system; no new permission or automatic operation is introduced.",
|
||||||
|
layer="static",
|
||||||
|
documentation_types=("user", "admin"),
|
||||||
|
audience=("user", "module_admin", "operator"),
|
||||||
|
order=5,
|
||||||
|
translations={"de": {
|
||||||
|
"title": "Aufgaben: Aktionen im Arbeitsbereich",
|
||||||
|
"summary": "Sammlungsweite Aktionen an ihrer einheitlichen Position im Arbeitsbereich finden.",
|
||||||
|
"body": "Dokumentationsbücher stehen unmittelbar neben der sichtbaren Überschrift oder "
|
||||||
|
"Kontextbezeichnung für Aufgaben, nicht zwischen ausführbaren Aktionsschaltflächen. Feldhilfe "
|
||||||
|
"bleibt neben der Feldbezeichnung. "
|
||||||
|
"Neu laden und Aufgabe anlegen stehen oben rechts in der dauerhaft sichtbaren, arbeitsbereichsweiten Leiste; Neu laden steht unmittelbar vor dem Anlegen. Auswahl, Filterwechsel und Bearbeitung verschieben diese sammlungsweiten Aktionen nicht in den linken Bereich. Suche und Statusfilter bleiben in der Aufgabenliste; Abschluss, Zuständigkeit und weitere aufgabenspezifische Aktionen bleiben bei der ausgewählten Aufgabe. Bestehende Berechtigungen, Deaktivierungsregeln und der Schutz ungespeicherter Änderungen gelten weiterhin. Administratoren konfigurieren Rechte im bestehenden Berechtigungssystem; es entstehen weder neue Rechte noch automatische Vorgänge.",
|
||||||
|
}},
|
||||||
|
),
|
||||||
DocumentationTopic(
|
DocumentationTopic(
|
||||||
id="tasks.data-subject-requests",
|
id="tasks.data-subject-requests",
|
||||||
title="Task data-subject requests",
|
title="Task data-subject requests",
|
||||||
@@ -209,7 +231,8 @@ DOCUMENTATION = (
|
|||||||
title="Work in product navigation and Quick Access",
|
title="Work in product navigation and Quick Access",
|
||||||
summary="Keep assigned work available in the Work area and the optional right-side Quick Access rail.",
|
summary="Keep assigned work available in the Work area and the optional right-side Quick Access rail.",
|
||||||
body=(
|
body=(
|
||||||
"Tasks contributes its authorized workspace to the Work product area. When Quick Access is enabled, "
|
"Tasks contributes its authorized workspace to the stable Work destination at /work. The owner route "
|
||||||
|
"/tasks remains available through All available tools and as a compatible deep link. When Quick Access is enabled, "
|
||||||
"a bounded seven-item authorized inbox and detail can appear beside the current page. Explicit Tasks can be "
|
"a bounded seven-item authorized inbox and detail can appear beside the current page. Explicit Tasks can be "
|
||||||
"started or completed there; work from another provider exposes only that provider's launch path. Every load "
|
"started or completed there; work from another provider exposes only that provider's launch path. Every load "
|
||||||
"and command is rechecked by Tasks, and completion returns a typed work-item reference to the host. Views may "
|
"and command is rechecked by Tasks, and completion returns a typed work-item reference to the host. Views may "
|
||||||
@@ -224,7 +247,8 @@ DOCUMENTATION = (
|
|||||||
"title": "Arbeit in Produktnavigation und Schnellzugriff",
|
"title": "Arbeit in Produktnavigation und Schnellzugriff",
|
||||||
"summary": "Zugewiesene Arbeit im Produktbereich Arbeit und optional in der rechten Schnellzugriffsleiste verwenden.",
|
"summary": "Zugewiesene Arbeit im Produktbereich Arbeit und optional in der rechten Schnellzugriffsleiste verwenden.",
|
||||||
"body": (
|
"body": (
|
||||||
"Tasks ordnet den berechtigten Arbeitsbereich dem Produktbereich Arbeit zu. Ist der Schnellzugriff aktiviert, "
|
"Tasks ordnet den berechtigten Arbeitsbereich dem stabilen Produktziel Arbeit unter /work zu. Der Eigentümerpfad "
|
||||||
|
"/tasks bleibt unter Alle verfügbaren Werkzeuge und als kompatibler Direktlink erreichbar. Ist der Schnellzugriff aktiviert, "
|
||||||
"kann ein begrenzter, berechtigungsgeprüfter Arbeitsvorrat mit sieben Einträgen und Details neben der "
|
"kann ein begrenzter, berechtigungsgeprüfter Arbeitsvorrat mit sieben Einträgen und Details neben der "
|
||||||
"aktuellen Seite erscheinen. Explizite Tasks lassen sich dort beginnen oder abschließen; fremde Quellen "
|
"aktuellen Seite erscheinen. Explizite Tasks lassen sich dort beginnen oder abschließen; fremde Quellen "
|
||||||
"behalten ihre eigenen Befehle und Startpfade. Jeder Aufruf wird erneut durch Tasks geprüft. Ansichten "
|
"behalten ihre eigenen Befehle und Startpfade. Jeder Aufruf wird erneut durch Tasks geprüft. Ansichten "
|
||||||
@@ -407,6 +431,30 @@ manifest = ModuleManifest(
|
|||||||
order=10,
|
order=10,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
product_surfaces=(
|
||||||
|
ProductSurfaceContribution(
|
||||||
|
id="work.items",
|
||||||
|
module_id=MODULE_ID,
|
||||||
|
label="i18n:govoplan-core.product_surface.work",
|
||||||
|
description="i18n:govoplan-core.product_surface.work_description",
|
||||||
|
icon="list-checks",
|
||||||
|
entry_path="/work",
|
||||||
|
route_path="/tasks",
|
||||||
|
surface_ids=("tasks.route.work",),
|
||||||
|
presentations=("task", "reader"),
|
||||||
|
help_context_ids=("tasks.route.work",),
|
||||||
|
documentation_topic_ids=("tasks.quick-access-and-product-area",),
|
||||||
|
required_any=(READ_SCOPE,),
|
||||||
|
order=10,
|
||||||
|
unavailable=ProductAvailabilityExplanation(
|
||||||
|
reason="authorization",
|
||||||
|
title="i18n:govoplan-core.product_surface.unavailable",
|
||||||
|
description="i18n:govoplan-core.product_surface.unavailable_description",
|
||||||
|
resolution="i18n:govoplan-core.product_surface.unavailable_resolution",
|
||||||
|
responsible_role="i18n:govoplan-core.access_administrator",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
quick_access_tools=(
|
quick_access_tools=(
|
||||||
QuickAccessTool(
|
QuickAccessTool(
|
||||||
id="tasks.work",
|
id="tasks.work",
|
||||||
|
|||||||
@@ -16,7 +16,12 @@ class TasksQuickAccessContractTests(unittest.TestCase):
|
|||||||
topics = get_manifest().documentation
|
topics = get_manifest().documentation
|
||||||
kinds = {topic.metadata.get("kind", "system") for topic in topics}
|
kinds = {topic.metadata.get("kind", "system") for topic in topics}
|
||||||
|
|
||||||
self.assertEqual(3, len(topics))
|
self.assertEqual({
|
||||||
|
"tasks.workspace-layout",
|
||||||
|
"tasks.data-subject-requests",
|
||||||
|
"tasks.quick-access-and-product-area",
|
||||||
|
"tasks.work-inbox",
|
||||||
|
}, {topic.id for topic in topics})
|
||||||
self.assertTrue({"workflow", "reference"}.issubset(kinds))
|
self.assertTrue({"workflow", "reference"}.issubset(kinds))
|
||||||
for topic in topics:
|
for topic in topics:
|
||||||
translation = topic.translations["de"]
|
translation = topic.translations["de"]
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@govoplan/tasks-webui",
|
"name": "@govoplan/tasks-webui",
|
||||||
"version": "0.1.21",
|
"version": "0.1.23",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
"./styles/tasks.css": "./src/styles/tasks.css"
|
"./styles/tasks.css": "./src/styles/tasks.css"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@govoplan/core-webui": "^0.1.18",
|
"@govoplan/core-webui": "^0.1.45",
|
||||||
"lucide-react": "^1.23.0",
|
"lucide-react": "^1.23.0",
|
||||||
"react": ">=19.2.7 <20",
|
"react": ">=19.2.7 <20",
|
||||||
"react-dom": ">=19.2.7 <20",
|
"react-dom": ">=19.2.7 <20",
|
||||||
|
|||||||
@@ -124,6 +124,23 @@ export default function TasksPage({ settings, auth }: { settings: ApiSettings; a
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkspaceFrame as="main" height="viewport" surface="plain" className="tasks-page" label="Task inbox" data-help-context-id="tasks.page.inbox">
|
<WorkspaceFrame as="main" height="viewport" surface="plain" className="tasks-page" label="Task inbox" data-help-context-id="tasks.page.inbox">
|
||||||
|
<WorkspaceActionBar
|
||||||
|
scope="workspace"
|
||||||
|
variant="collection"
|
||||||
|
refreshable
|
||||||
|
reloadAction={{ onReload: () => void load(), loading: loading || busy, label: "i18n:govoplan-tasks.refresh" }}
|
||||||
|
contextActions={<span className="tasks-title"><ListChecks size={18} /><strong>i18n:govoplan-tasks.work</strong></span>}
|
||||||
|
createAction={canWrite ? (
|
||||||
|
<Button
|
||||||
|
variant="primary"
|
||||||
|
onClick={() => setCreateOpen(true)}
|
||||||
|
disabled={busy}
|
||||||
|
helpContextId="tasks.action.create"
|
||||||
|
>
|
||||||
|
<Plus size={16} aria-hidden="true" /> i18n:govoplan-tasks.create_task
|
||||||
|
</Button>
|
||||||
|
) : undefined}
|
||||||
|
/>
|
||||||
<WorkspaceLayout
|
<WorkspaceLayout
|
||||||
variant="split"
|
variant="split"
|
||||||
primarySize="default"
|
primarySize="default"
|
||||||
@@ -138,24 +155,6 @@ export default function TasksPage({ settings, auth }: { settings: ApiSettings; a
|
|||||||
helpContextId="tasks.page.inbox"
|
helpContextId="tasks.page.inbox"
|
||||||
helpModuleId="tasks"
|
helpModuleId="tasks"
|
||||||
primary={<>
|
primary={<>
|
||||||
<WorkspaceActionBar
|
|
||||||
scope="collection-pane"
|
|
||||||
variant="collection"
|
|
||||||
refreshable
|
|
||||||
reloadAction={{ onReload: () => void load(), loading: loading || busy, label: "i18n:govoplan-tasks.refresh" }}
|
|
||||||
className="tasks-sidebar-bar"
|
|
||||||
contextActions={<span className="tasks-title"><ListChecks size={18} /><strong>i18n:govoplan-tasks.work</strong></span>}
|
|
||||||
createAction={canWrite ? (
|
|
||||||
<Button
|
|
||||||
variant="primary"
|
|
||||||
onClick={() => setCreateOpen(true)}
|
|
||||||
disabled={busy}
|
|
||||||
helpContextId="tasks.action.create"
|
|
||||||
>
|
|
||||||
<Plus size={16} aria-hidden="true" /> i18n:govoplan-tasks.create_task
|
|
||||||
</Button>
|
|
||||||
) : undefined}
|
|
||||||
/>
|
|
||||||
<FilterBar as="form" surface="control" wrap="never" className="tasks-search" onSubmit={submitSearch} role="search">
|
<FilterBar as="form" surface="control" wrap="never" className="tasks-search" onSubmit={submitSearch} role="search">
|
||||||
<Search size={15} aria-hidden="true" />
|
<Search size={15} aria-hidden="true" />
|
||||||
<input
|
<input
|
||||||
@@ -204,8 +203,8 @@ export default function TasksPage({ settings, auth }: { settings: ApiSettings; a
|
|||||||
variant="detail"
|
variant="detail"
|
||||||
className="tasks-topbar"
|
className="tasks-topbar"
|
||||||
data-help-context-id="tasks.page.detail"
|
data-help-context-id="tasks.page.detail"
|
||||||
contextActions={<span className="tasks-detail-title"><ListChecks size={18} /><strong>{selected?.title ?? "i18n:govoplan-tasks.work_details"}</strong></span>}
|
title={<span className="tasks-detail-title"><ListChecks size={18} aria-hidden="true" /><strong>{selected?.title ?? "i18n:govoplan-tasks.work_details"}</strong></span>}
|
||||||
helpAction={<DocumentationHelpLink reference={DOCUMENTATION} />}
|
titleHelp={<DocumentationHelpLink reference={DOCUMENTATION} />}
|
||||||
primaryActions={selected?.provider_id === "tasks.explicit" && canWrite ? (
|
primaryActions={selected?.provider_id === "tasks.explicit" && canWrite ? (
|
||||||
<TaskPrimaryActions item={selected} busy={busy} onAction={(action) => action === "defer" ? setDeferOpen(true) : void runAction(action)} />
|
<TaskPrimaryActions item={selected} busy={busy} onAction={(action) => action === "defer" ? setDeferOpen(true) : void runAction(action)} />
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
|||||||
+7
-2
@@ -4,6 +4,7 @@ import type {
|
|||||||
PlatformWebModule,
|
PlatformWebModule,
|
||||||
QuickAccessToolsUiCapability
|
QuickAccessToolsUiCapability
|
||||||
} from "@govoplan/core-webui";
|
} from "@govoplan/core-webui";
|
||||||
|
import { generatedTranslations as productSurfaceTranslations } from "@govoplan/core-webui/outcome-product-surface-translations";
|
||||||
import TasksSummaryWidget from "./features/tasks/TasksSummaryWidget";
|
import TasksSummaryWidget from "./features/tasks/TasksSummaryWidget";
|
||||||
import TasksQuickAccess from "./features/tasks/TasksQuickAccess";
|
import TasksQuickAccess from "./features/tasks/TasksQuickAccess";
|
||||||
import { generatedTranslations } from "./i18n/generatedTranslations";
|
import { generatedTranslations } from "./i18n/generatedTranslations";
|
||||||
@@ -11,6 +12,10 @@ import "./styles/tasks.css";
|
|||||||
|
|
||||||
const TasksPage = lazy(() => import("./features/tasks/TasksPage"));
|
const TasksPage = lazy(() => import("./features/tasks/TasksPage"));
|
||||||
const readScope = ["tasks:item:read"];
|
const readScope = ["tasks:item:read"];
|
||||||
|
const translations = {
|
||||||
|
en: { ...generatedTranslations.en, ...productSurfaceTranslations.en },
|
||||||
|
de: { ...generatedTranslations.de, ...productSurfaceTranslations.de }
|
||||||
|
};
|
||||||
|
|
||||||
const dashboardWidgets: DashboardWidgetsUiCapability = {
|
const dashboardWidgets: DashboardWidgetsUiCapability = {
|
||||||
widgets: [
|
widgets: [
|
||||||
@@ -44,10 +49,10 @@ const quickAccessTools: QuickAccessToolsUiCapability = {
|
|||||||
export const tasksModule: PlatformWebModule = {
|
export const tasksModule: PlatformWebModule = {
|
||||||
id: "tasks",
|
id: "tasks",
|
||||||
label: "i18n:govoplan-tasks.work",
|
label: "i18n:govoplan-tasks.work",
|
||||||
version: "0.1.20",
|
version: "0.1.22",
|
||||||
dependencies: ["access"],
|
dependencies: ["access"],
|
||||||
optionalDependencies: ["idm", "organizations", "workflow_engine", "workflow", "notifications", "postbox", "approvals", "views", "dashboard", "search"],
|
optionalDependencies: ["idm", "organizations", "workflow_engine", "workflow", "notifications", "postbox", "approvals", "views", "dashboard", "search"],
|
||||||
translations: generatedTranslations,
|
translations,
|
||||||
navItems: [
|
navItems: [
|
||||||
{
|
{
|
||||||
to: "/tasks",
|
to: "/tasks",
|
||||||
|
|||||||
Reference in New Issue
Block a user