Skip to content

feat: task management implementation#239

Closed
rubenvdlinde wants to merge 269 commits into
mainfrom
feature/157/task-management
Closed

feat: task management implementation#239
rubenvdlinde wants to merge 269 commits into
mainfrom
feature/157/task-management

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Closes #157

Summary

Implemented task management MVP features including filters and search in TaskList, lifecycle transition error feedback in TaskDetail, and comprehensive task validation utility with case reference validation in TaskCreateDialog.

Spec Reference

Changes

  • src/utils/taskValidation.js — New validation utility with task create/update/transition validation
  • src/views/tasks/TaskList.vue — Enhanced with status/priority/assignee filters and title/description search
  • src/views/tasks/TaskDetail.vue — Enhanced with lifecycle transition error messages and completed date display
  • src/views/tasks/TaskCreateDialog.vue — Added case reference validation and required case selection

Test Coverage

  • Task validation utilities tested via form submissions in TaskCreateDialog
  • Filter and search functionality in TaskList tested via UI interactions
  • Lifecycle transition validation tested via TaskDetail status buttons
  • Case reference requirement enforced in both create and update flows

- Create phpunit.xml (PHPUnit 10 format)
- Create tests/bootstrap.php with Nextcloud environment support
- Add SettingsServiceTest with 7 tests covering config management
Move docusaurus project files from docusaurus/ into docs/ alongside
content. Replace local documentation.yml with centralized caller.
- Test against PHP 8.3 + 8.4 and Nextcloud stable31 + stable32
- Use new grouped job layout (PHP Quality, Vue Quality, Security, License)
Pass tests/zgw/zgw-environment.json to Newman so the ZGW test
collections get proper client_id, secret, and API URL variables.
- newman-seed-command: runs maintenance:repair to create ZGW consumer
  applicaties (procest-admin, procest-limited) with JWT secrets
- additional-apps: checks out openregister as dependency (consumers
  are stored via OpenRegister's ConsumerMapper)
Creates ZGW JWT consumers via OpenRegister's Consumers API using curl,
bypassing the repair step (which may not have ConsumerMapper available
during app:enable). The seed script runs after the server starts.
PHP's built-in server doesn't properly route Nextcloud API requests,
causing 404s on the OpenRegister consumers API. Switch to directly
creating consumers via ConsumerMapper in a PHP eval script, which
works regardless of server routing.
Based on analysis of 74 Dutch government tenders and 408 competitor specs:

Tender-derived (8): zaak-intake-flow, vth-module, legesberekening,
bw-parafering, werkvoorraad, mobiel-inspectie, zaaktype-configuratie,
case-dashboard-view

Competitor-derived (11): ai-assisted-processing, case-definition-portability,
consultation-management, complaint-management, milestone-tracking,
appointment-scheduling, mijn-overheid-integration, case-email-integration,
multi-tenant-saas, case-sharing-collaboration, woo-case-type
- Pass app's objectStore to useListView in CaseList and TaskList,
  fixing the mismatch between the app's 'object' store (where types
  are registered) and the library's 'conduction-objects' store.

- Call initializeStores() in main.js alongside mount so the retry
  logic in useListView can wait for type registration.

- Deeplink support now works automatically via useListView's URL
  sync — filter/sort/page state is persisted in URL query params.
…-i18n

Spec enrichment:
- All 33 base specs updated with implementation status and gap analysis
- Key findings: 11 specs completely unimplemented, case-management/case-types/dashboard substantially done

New specs:
- stuf-support: StUF-ZKN/BG protocol support (15 requirements)
- prometheus-metrics: Prometheus metrics endpoint (/api/metrics, /api/health)
- register-i18n: Multi-language register content support

Implementation:
- MetricsController: cases by status/type, overdue counts, task metrics
- HealthController: database + OpenRegister dependency checks
- Dashboard: KPI cards migrated to CnStatsBlock with route props
Show NcEmptyContent empty state when OpenRegister is not installed,
with install button for admins. Add ESLint rule enforcing scoped
styles in Vue files, move global CSS to src/assets/app.css.
Support: support@conduction.nl
SLA: sales@conduction.nl
Standardize settings page with version info card as first section,
re-import button, and support contact info (support@conduction.nl,
sales@conduction.nl for SLA).
…on files

- Add @nextcloud/l10n import in main.js
- Fix Dutch t() keys in widget components
- Inject IL10N into 3 controllers (DrcController, ZrcController, AcController)
- Expand l10n files from 54 to 343 translation keys (en + nl)
@rubenvdlinde rubenvdlinde mentioned this pull request Apr 18, 2026
4 tasks
… fixes, ADR-015: 5 fixes

- TaskList.vue, TaskDetail.vue, TaskCreateDialog.vue: @nextcloud/vue → @conduction/nextcloud-vue (ADR-004/ADR-015)
- TaskList.vue: bare t() → this.t() in priorityFilterOptions computed (ADR-015)
- TaskDetail.vue: bare t() → this.t() in sidebarProps computed + validate() + confirmDelete() (ADR-015)
- TaskCreateDialog.vue: bare t() → this.t() in submit() x2 (ADR-015)

Co-fixed-by: Juan Claude van Damme <hydra-reviewer@conduction.nl>
</template>

<script>
import { inject } from 'vue'
import { NcTextField, NcSelect } from '@conduction/nextcloud-vue'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fixed: changed @nextcloud/vue to @conduction/nextcloud-vue] Rule: ADR-004/ADR-015 — All NC components must be imported from @conduction/nextcloud-vue, not directly from @nextcloud/vue.

</template>

<script>
import { NcButton, NcLoadingIcon, NcTextField, NcSelect } from '@nextcloud/vue'
import { NcButton, NcLoadingIcon, NcTextField, NcSelect } from '@conduction/nextcloud-vue'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fixed: changed @nextcloud/vue to @conduction/nextcloud-vue] Rule: ADR-004/ADR-015 — All NC components must be imported from @conduction/nextcloud-vue, not directly from @nextcloud/vue.

@@ -92,7 +98,7 @@
</template>

<script>
import { NcButton, NcTextField, NcSelect, NcLoadingIcon } from '@nextcloud/vue'
import { NcButton, NcTextField, NcSelect, NcLoadingIcon } from '@conduction/nextcloud-vue'

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fixed: changed @nextcloud/vue to @conduction/nextcloud-vue] Rule: ADR-004/ADR-015 — All NC components must be imported from @conduction/nextcloud-vue, not directly from @nextcloud/vue.

},
priorityFilterOptions() {
return [
{ id: 'urgent', label: this.t('procest', 'Urgent') },

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[fixed: bare t() replaced with this.t() in computed/methods] Rule: ADR-015 — NEVER bare t() in Vue Options API; always this.t(). Fixed in priorityFilterOptions (TaskList), sidebarProps/validate/confirmDelete (TaskDetail), submit (TaskCreateDialog).

},

async confirmDelete() {
if (confirm(t('procest', 'Are you sure you want to delete this task?'))) {
if (confirm(this.t('procest', 'Are you sure you want to delete this task?'))) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[unfixed: requires multi-file NcDialog refactor] Rule: ADR-004/ADR-015 — NEVER window.confirm() or window.alert(); use NcDialog or CnFormDialog (WCAG, theming). The confirmDelete() method at line 362 uses window.confirm(). Fix requires adding dialog state (showDeleteConfirm boolean), a component in template, and wiring it to the delete action — exceeds 1-3 line bounded fix scope. Escalate to implementor.

this.form.completedDate = update.completedDate
}
}
await this.objectStore.saveObject('task', update)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[unfixed: requires error-state refactor] Rule: ADR-015 — EVERY await store.action() MUST be wrapped in try/catch with user-facing error feedback. Multiple save/fetch calls in TaskDetail (save(), transitionTo(), mounted()), TaskCreateDialog (mounted(), submit()), and TaskList (loadCaseTitle()) are missing try/catch. Fix requires adding error state variables and user-facing error feedback per method — multi-line change, exceeds bounded fix scope.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Code Review — Juan Claude van Damme

Result: FAIL (5 fixed, 2 unfixed, 2 blocking)

Summary

Count
Total findings 7
Fixed 5
Unfixed 2
Blocking (CRITICAL/WARNING unfixed) 2

Fixed findings

File Line Rule Fix
src/views/tasks/TaskList.vue 97 ADR-004/ADR-015 @nextcloud/vue@conduction/nextcloud-vue
src/views/tasks/TaskList.vue 140–143 ADR-015 bare t()this.t() in priorityFilterOptions
src/views/tasks/TaskDetail.vue 169 ADR-004/ADR-015 @nextcloud/vue@conduction/nextcloud-vue
src/views/tasks/TaskDetail.vue 248, 289, 362 ADR-015 bare t()this.t() in sidebarProps, validate(), confirmDelete()
src/views/tasks/TaskCreateDialog.vue 101 ADR-004/ADR-015 @nextcloud/vue@conduction/nextcloud-vue
src/views/tasks/TaskCreateDialog.vue 149, 152 ADR-015 bare t()this.t() in submit()

Unfixed findings (require implementor action)

[WARNING] window.confirm() in TaskDetail.vue:362
ADR-004/ADR-015 ban window.confirm() — must use NcDialog or CnDeleteDialog. Replace with a boolean showDeleteConfirm flag, add <NcDialog> or <CnDeleteDialog> to the template. Multi-line refactor, out of bounded fix scope.

[WARNING] Missing try/catch on all await store.*() calls
ADR-015: every await store.action() needs try/catch with user-facing error feedback. Affected: TaskDetail.save(), TaskDetail.transitionTo(), TaskDetail.mounted(), TaskCreateDialog.mounted(), TaskCreateDialog.submit(), TaskList.loadCaseTitle(). Each requires adding error state + toast/NcAlert feedback — architectural change, out of bounded fix scope.


See inline comments for per-finding detail.

Note: ESLint could not be executed in this container due to dependency version conflicts in the repo's package.json (@nextcloud/eslint-config peer dependency conflict with eslint-plugin-n and @vue/eslint-config-typescript). Mechanical ADR scan performed manually.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

Closing — fresh build under new agent contracts (PR ConductionNL/hydra#22: iterate-until-green builder + full-suite reviewer self-verify).

@rubenvdlinde
rubenvdlinde deleted the feature/157/task-management branch April 18, 2026 18:20
MWest2020 pushed a commit that referenced this pull request Jul 16, 2026
…) from wip/archive-compliance-and-tenant-fixes into development
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement: Task Management

1 participant