Skip to content

chore(import): drop broken custom Import flow; rely on per-index Mass Import#829

Merged
rubenvdlinde merged 4 commits into
chore/cleanup-sweepfrom
chore/drop-custom-import
May 22, 2026
Merged

chore(import): drop broken custom Import flow; rely on per-index Mass Import#829
rubenvdlinde merged 4 commits into
chore/cleanup-sweepfrom
chore/drop-custom-import

Conversation

@rubenvdlinde
Copy link
Copy Markdown
Contributor

Summary

Stacked on #827 (cleanup-sweep). Drops the custom /import page and everything that hung off it.

Why this is more than a stylistic cleanup

The custom Import page was already broken at runtime. It POSTed to /index.php/apps/openconnector/api/import — but that backend endpoint was deleted in the chain-C OR-cutover. The comment block at appinfo/routes.php line 62-64 records the removal and points at OR's replacements:

// Import/Export routes deleted in chain-C OR-cutover. OR provides:
//   POST /api/registers/{id}/import
//   POST /api/configurations/{id}/import

So every "Import" button click in the live UI hit a non-existent endpoint and silently failed.

Replacement

Per-index Mass Import via CnIndexPage's built-in Actions menu. showMassImport: true is the CnIndexPage default; CnMassImportDialog wires the upload against OR's per-schema endpoints. Covers the 10 first-class concepts (Sources / Endpoints / Consumers / Webhooks / Jobs / Mappings / Rules / Synchronizations / Contracts / CloudEvents).

If a future workflow needs a multi-file batched-import dispatcher (the original UX), the right home is a fleet-wide CnBatchImportWizard in @conduction/nextcloud-vue targeting the same OR per-schema endpoints — not an openconnector-specific resurrection.

Drops

File LoC Note
src/views/Import/ImportIndex.vue 254 Custom upload UI
src/composables/UseFileSelection.js 98 Drag-drop file-picker; only consumer was ImportIndex
src/store/modules/importExport.js 76 Wrapped the dead /api/import POST
src/manifest.json -16 Removed Import menu item + Import page entry
src/registry.js rewrite Now empty {} + updated comment; future v2 widget slots register here
src/store/store.js trim Drop importExportStore import + export
lib/Controller/UiController.php::import() -13 SPA shell action removed
appinfo/routes.php -1 ui#import route removed

Net: 3 files deleted (~430 LoC), 5 files trimmed, 1 PHP route + 1 PHP controller action removed.

Verification

  • npm run build — green (6.48 MiB main, slightly smaller than pre-drop 6.5 MiB)
  • npm run lint — 0 errors (1 pre-existing parse-warning, unrelated)
  • grep -rln "ImportIndex|UseFileSelection|importExportStore|useImportExportStore" src/ lib/ — zero hits

Test plan

… Import

The custom `/import` page lived as a multi-file YAML/JSON drag-and-drop
shell that POSTed to `/index.php/apps/openconnector/api/import` — but
**that backend endpoint was already deleted in the chain-C OR-cutover**
(see appinfo/routes.php comment "Import/Export routes deleted in chain-C
OR-cutover. OR provides POST /api/registers/{id}/import and POST
/api/configurations/{id}/import"). The Vue page was making a request to
a non-existent route on every Import click — broken at runtime.

Replacement path: every CnIndexPage in the manifest already exposes a
Mass Import action in its Actions menu (`showMassImport: true` by
default), wiring CnMassImportDialog against OR's per-schema endpoints.
That covers the use case for the 10 first-class concepts (Sources,
Endpoints, Consumers, Webhooks, Jobs, Mappings, Rules, Synchronizations,
SynchronizationContracts, CloudEvents) without an openconnector-specific
multi-file dispatcher.

Drops:

  src/manifest.json
    — Import menu item (settings section, order 10)
    — Import page entry (custom, /import, ImportIndex)

  src/views/Import/ImportIndex.vue (254 LoC)
    — The custom upload UI.

  src/composables/UseFileSelection.js (98 LoC)
    — Drag-drop file-picker helper; ImportIndex was its only consumer.

  src/store/modules/importExport.js (76 LoC) + store.js export
    — Wrapped the dead /api/import POST; ImportIndex was its only consumer.

  src/registry.js
    — `ImportIndex` registration; the registry is now empty (next entries
      will be v2 widget slots, not custom pages — see updated comment).

  lib/Controller/UiController.php::import()
  appinfo/routes.php `ui#import` route
    — The PHP SPA shell action for /import; serves nothing meaningful now.

Net: 3 source files deleted (~430 LoC), 5 files trimmed, 1 PHP route +
1 PHP controller action removed. Build still green (6.48 MiB main bundle,
slightly smaller).

If a future workflow needs the multi-file batched-import dispatcher, the
right home is a fleet-wide `CnBatchImportWizard` in @conduction/nextcloud-vue
that targets the same OR per-schema endpoints — not an openconnector-
specific resurrection.
Two-line edit to bring feature/i18n-complete-translations to manifest
v2:
- $schema URL: app-manifest.schema.json → app-manifest-v2.schema.json
- version: 1.0.0 → 2.0.0

Pre-flip Ajv check confirmed the manifest already validates against
v2 schema 2.7.0 with zero errors — the page-level shapes were
already v2-compatible, just the schema header was lagging. No page
content changes needed; downstream PRs (#823 issue-814 bootstrap,
#826 polish, #827 cleanup, #828 menu-trim, #829 drop-import, #830
action-rows, #831 KPI tiles, #838 charts) continue to apply on top
of this v2 base.

State on this branch is now Tier 4:
- schema URL ✓ v2
- version ✓ 2.0.0
- nc-vue pin ✓ ^1.0.0-beta.67
- customs: 1 (Import, justified by _note — "Multi-step file-upload
  + dry-run preview UX exceeds nc-vue v2 form/wizard capability;
  revisit after CnWizardPage ships"). Tier 4 permits justified
  customs.
- The 3 src/views/widgets/*.vue files are NC Dashboard widget
  entry points (separate webpack chunks, registered via
  OCA.Dashboard.register), NOT manifest wrappers — stay.
@rubenvdlinde rubenvdlinde merged commit d588416 into chore/cleanup-sweep May 22, 2026
@rubenvdlinde rubenvdlinde deleted the chore/drop-custom-import branch May 22, 2026 05:11
rubenvdlinde added a commit that referenced this pull request May 22, 2026
…fields (#828)

* chore(manifest): trim log items from menu + add row-level View-logs action

The 3 `*Logs` entries (Source logs / Endpoint logs / Job logs) dominated the
main nav and competed with the 9 first-class concepts (Sources / Endpoints /
Consumers / Webhooks / Jobs / Mappings / Rules / Synchronizations / Cloud
events). Removing them from the menu reclaims that vertical space; access
to the log pages now lives on the parent index pages' row actions instead:

| Index page | Row action `View logs` → |
|---|---|
| Sources | SourceLogs (`/sources/logs`) |
| Endpoints | EndpointLogs (`/endpoints/logs`) |
| Jobs | JobLogs (`/jobs/logs`) |
| Synchronizations | SynchronizationLogs (`/synchronizations/logs`) |
| CloudEvents | CloudEventLogs (`/cloud-events/logs`) |

Synchronizations also gains a `View contracts` row action (→ SynchronizationContracts)
since the contracts page was already pageless-in-menu after chain-E and is the
natural sibling concept to logs.

Log pages remain reachable via direct URL; CnLogsPage's `type: logs` is
inherently read-only (no Add/Edit/Delete prop surface), so the "log pages
must be immutable" todo is already satisfied — no further wiring needed.

Manifest schema used: each page's `config.actions[]` array, same shape as
decidesk's row actions: `{ id, label, icon, handler: "navigate", route }`.
Handler `navigate` passes the row id to the target route — useful once
the log pages accept a `?<parent>=<id>` filter param (follow-up).

* chore(manifest): curate column set per index page

The pre-refactor SourcesIndex.vue (deleted in aacd152) showed a
hand-curated set of fields per source — name, status, type, lastCall,
lastSync, dateModified, etc. — not the full schema. After the OR cutover,
nc-vue's CnIndexPage falls back to schema-driven column generation when
the manifest doesn't declare a `columns` array, which surfaced every
property on the schema (accept / apikey / auth / authorizationHeader /
authorizationPassthroughMethod / configurations / dateCreated / …) and
forced the user to horizontal-scroll the table to see anything useful.

Pin a curated column set per index, picked from the OR schema in
lib/Settings/openconnector_register.json and informed by what the
pre-refactor views showed:

  Sources         name, type, status, isEnabled, lastSync, dateModified
  Endpoints       name, method, endpoint, targetType, updated
  Consumers       name, authorizationType, domains, updated
  Webhooks        name, authorizationType, domains, updated
  Jobs            name, jobClass, interval, isEnabled, lastRun, status
  Mappings        name, description, passThrough, dateModified
  Rules           name, action, timing, type, order
  Synchronizations          name, sourceType, targetType, status, sourceLastSynced
  SynchronizationContracts  synchronization, originId, targetId, sourceLastSynced, updated
  CloudEvents     source, type, subject, status, time

Users can still toggle to other columns via the sidebar's columns panel
(enabled in #826) — these are just the defaults.

* chore(manifest): curate create/edit form fields per index page

The user reported that the auto-generated Create Mapping modal exposed
every property on the schema — `configurations`, `dateCreated`,
`dateModified`, `passThrough`, `slug`, `reference`, `unset` — most of
which are system fields or advanced settings that don't belong in a
"name your new thing" dialog.

`CnIndexPage` forwards a `config.includeFields[]` whitelist to
`CnFormDialog`. Pin per-index curated field lists so the create/edit
dialog only exposes the user-facing fields:

  Sources         name, description, type, isEnabled
  Endpoints       name, description, endpoint, method, targetType
  Consumers       name, description, authorizationType
  Webhooks        name, description, authorizationType
  Jobs            name, description, jobClass, interval, isEnabled
  Mappings        name, description
  Rules           name, description, action, timing, type
  Synchronizations  name, description, sourceType, targetType
  CloudEvents     source, type, subject, data

All other fields remain editable on the Detail page (CnDetailPage's
property grid). System fields (`dateCreated`, `dateModified`, `slug`,
`reference`, `uuid`) stay out of every user-facing form.

This is much smaller than the originally-scoped "extract bespoke
modal" work (which would have rewritten 1537 LoC `EditMapping.vue` +
1076 LoC `EditSynchronization.vue` + 1888 LoC `EditRule.vue`).
`includeFields` solves the user-flagged "form has too many fields"
issue with a JSON config change; the larger bespoke-modal effort can
land later as separate per-schema PRs IF the curated form is still
deemed insufficient (Mapping rules / cast / unset editor, sync source
/ target config editor, rule condition builder).

SynchronizationContracts intentionally has no `includeFields` — contracts
are auto-generated by the sync engine; no user-facing create form.

* feat(manifest): flip to v2 schema URL — Tier 4 on i18n branch

Two-line edit to bring feature/i18n-complete-translations to manifest
v2:
- $schema URL: app-manifest.schema.json → app-manifest-v2.schema.json
- version: 1.0.0 → 2.0.0

Pre-flip Ajv check confirmed the manifest already validates against
v2 schema 2.7.0 with zero errors — the page-level shapes were
already v2-compatible, just the schema header was lagging. No page
content changes needed; downstream PRs (#823 issue-814 bootstrap,
#826 polish, #827 cleanup, #828 menu-trim, #829 drop-import, #830
action-rows, #831 KPI tiles, #838 charts) continue to apply on top
of this v2 base.

State on this branch is now Tier 4:
- schema URL ✓ v2
- version ✓ 2.0.0
- nc-vue pin ✓ ^1.0.0-beta.67
- customs: 1 (Import, justified by _note — "Multi-step file-upload
  + dry-run preview UX exceeds nc-vue v2 form/wizard capability;
  revisit after CnWizardPage ships"). Tier 4 permits justified
  customs.
- The 3 src/views/widgets/*.vue files are NC Dashboard widget
  entry points (separate webpack chunks, registered via
  OCA.Dashboard.register), NOT manifest wrappers — stay.
rubenvdlinde added a commit that referenced this pull request May 22, 2026
* feat(dashboard): wire 6 KPI tiles via manifest stats-block widgets

Restores the top row of the legacy openconnector dashboard (per the user-
shared screenshot): six clickable count tiles for Sources, Mappings,
Synchronizations, Contracts, Jobs and Endpoints. Each tile resolves its
count via OR's `aggregate: 'count'` shorthand and links to the matching
index page on click.

Uses nc-vue's `type: 'stats-block'` widget (mounts CnStatsBlockWidget,
declared in CnDashboardPage docstring lines 263-266). No code added —
manifest-only:

  src/manifest.json — Dashboard page config gains:
    - 6 `stats-block` widget defs, each pointing at a schema slug via
      `dataSource: { register, schema, aggregate: 'count' }`
    - 12-column layout placing the 6 tiles in a single row, each 2 cols
      wide and 2 cells tall

The 6 daily/hourly charts (Outgoing Calls / Job Executions / Sync
Executions, each as a daily and hourly chart) stay deferred to a
follow-up PR — they need:
  1. `@conduction/nextcloud-vue` `CnChartWidget.dataSource.bucket`
     shorthand wired to OR's `groupBy` arg
  2. `CnDashboardPage.dateRange` header providing the `from`/`to` inject
both of which are in flight on `ConductionNL/nextcloud-vue`
`feat/dashboard-date-range`, unblocked by
`ConductionNL/openregister#1611`.

Inline `_note` on the manifest documents the deferred-charts state.

* fix(dashboard): use supported stats-block props (route under props, drop iconClass)

The previous commit used `linkRoute` (string) at the widget def top
level + `iconClass` (string) — neither is forwarded by CnDashboardPage's
`getStatsBlockProps` (nc-vue/src/components/CnDashboardPage/CnDashboardPage.vue
line 732-734). The dispatcher only forwards `props.countLabel`,
`props.variant`, `props.showZeroCount`, `props.horizontal`, AND
`props.route` (Vue-router location object).

Move `route` under `props` as `{ name: 'Sources' }` etc. — that's the
shape CnStatsBlockWidget's `route` prop expects (Object, default null;
nc-vue/src/components/CnStatsBlockWidget/CnStatsBlockWidget.vue line
113-116). Drop `iconClass` since neither the widget def envelope nor
the dispatcher route it anywhere; CnStatsBlock supports icons via a
`<component>` import (e.g. MDI Vue), but that can't ride through a
JSON manifest. KPI tiles ship icon-less for now; layering icons via
the manifest is a follow-up nc-vue feature request.

* feat(manifest): flip to v2 schema URL — Tier 4 on i18n branch

Two-line edit to bring feature/i18n-complete-translations to manifest
v2:
- $schema URL: app-manifest.schema.json → app-manifest-v2.schema.json
- version: 1.0.0 → 2.0.0

Pre-flip Ajv check confirmed the manifest already validates against
v2 schema 2.7.0 with zero errors — the page-level shapes were
already v2-compatible, just the schema header was lagging. No page
content changes needed; downstream PRs (#823 issue-814 bootstrap,
#826 polish, #827 cleanup, #828 menu-trim, #829 drop-import, #830
action-rows, #831 KPI tiles, #838 charts) continue to apply on top
of this v2 base.

State on this branch is now Tier 4:
- schema URL ✓ v2
- version ✓ 2.0.0
- nc-vue pin ✓ ^1.0.0-beta.67
- customs: 1 (Import, justified by _note — "Multi-step file-upload
  + dry-run preview UX exceeds nc-vue v2 form/wizard capability;
  revisit after CnWizardPage ships"). Tier 4 permits justified
  customs.
- The 3 src/views/widgets/*.vue files are NC Dashboard widget
  entry points (separate webpack chunks, registered via
  OCA.Dashboard.register), NOT manifest wrappers — stay.
rubenvdlinde added a commit that referenced this pull request May 22, 2026
* chore(cleanup): retire half-removed NC-core dashboard widget chain

Drops three webpack entries (jobQueueWidget/recentCallsWidget/sourceSyncWidget),
their src/*.js bootstraps, src/views/widgets/*.vue components, and the
matching PHP IWidget classes under lib/Dashboard/.

Why these are dead at runtime:
  appinfo/info.xml has NO <dashboard> declaration block, and
  lib/AppInfo/Application.php's register() never calls registerWidget()
  or new IconAddon(), so NC never instantiates the IWidget classes
  and the webpack-built chunks never get loaded by the NC dashboard.

The user-facing dashboard already comes from the manifest-driven
CnDashboardPage (manifest.json Dashboard page, type=dashboard).
Time-series widgets for that page are blocked on the OR GraphQL
groupBy primitive (opsx-driven follow-up) and will wire via the
manifest, not this widget chain.

Net cleanup: 9 files removed, 3 webpack entries dropped.

* chore(cleanup): delete cascading orphan trees (entities, sidebars, navigation)

The chain-C src/ audit identified `src/modals/Modals.vue` as a barrel-import
that webpack built into the bundle but no live entry point ever loaded — it
kept 47 modal files, the entire `src/entities/` tree, all of `src/sidebars/`,
both `src/navigation/` shells, `src/vue/`, `src/dialogs/`, four 0-byte
placeholder components, and several services alive at build time while
being completely unreachable at runtime.

Cascading deletes (everything below was orphan-rooted at Modals.vue):

  src/entities/ (64 files, ~2,000 LoC)
    — Duplicates OR schemas. useObjectStore + OR's
      /api/objects/openconnector/{schema}/* is the canonical path now.
  src/sidebars/ (7 files, ~3,050 LoC)
    — Replaced by CnLogsPage's built-in filters + CnIndexPage facet
      sidebar (enabled by manifest in #826).
  src/navigation/MainMenu.vue + Configuration.vue
    — Replaced by CnAppRoot + AppSettings manifest page (type: settings).
  src/vue/components/JobLogIndex.vue
    — Replaced by the JobLogs manifest page (type: logs).
  src/dialogs/Dialogs.vue
    — Orphan placeholder.
  src/components/{Create,Edit}{Endpoint,Webhook}Dialog.vue
    — Four 0-byte placeholder files (likely failed scaffolds).
  src/components/{DateRangeCalendar,DateRangeInput,PaginationComponent}.vue
    — Replaced by CnLogsPage's date filter + CnDataTable's pagination.
  src/services/{getTheme,getValidISOstring,isValidJson,openLink}.js +
  src/services/errors/{MissingParameterError,ValidationError,index}.js
    — Only consumed by orphan modals.

`src/modals/Modals.vue` itself deleted (the root of the cascade).
30+ modal files under `src/modals/` deleted alongside it — every modal whose
UX is fully covered by an nc-vue primitive (CnFormDialog / CnDeleteDialog /
CnDetailPage / CnMassDeleteDialog).

Preserved as extraction reference (intentionally broken imports, eslint-
ignored, see src/modals/README.md):

  modals/Mapping/EditMapping.vue           (1537 LoC) — bespoke create/edit
  modals/Synchronization/EditSynchronization.vue (1076 LoC) — bespoke create/edit
  modals/Rule/EditRule.vue                 (1888 LoC) — visual rule-builder
  modals/Endpoint/{AddEndpointRule,EditEndpoint}.vue
  modals/Job/{RunJob,TestJob}.vue          — action surfaces
  modals/Synchronization/{RunSynchronization,TestSynchronization}.vue
  modals/MappingTest/ (4 files)            — test-mapping action + sub-widgets
  modals/Mapping/mappingItem/ (2 files)    — sub-record edit/delete
  modals/TestSource/TestSource.vue         — action surface

Net: 126 files deleted, 1 file (eslint.config.js) edited to ignore the
preserved modals dir, 1 file (src/modals/README.md) added documenting the
extraction plan. ~14,000 LoC removed.

Wire-up untouched — main.js / App.vue / registry.js / manifest.json /
store/store.js still resolve cleanly because none of these deleted trees
were imported by anything in the live entry tree.

* chore(cleanup): trim store registry + drop dead importFile

After the orphan-tree sweep, the only consumers of the per-app pinia stores
are App.vue (useSettingsStore) and views/Import/ImportIndex.vue
(importExportStore.importFiles). Trim the registry to match.

  src/store/modules/{navigation,search}.{js,ts} + their *.spec.{js,ts}
    — deleted. The dispatch-modal-by-name state machine
      (navigationStore.modal === 'editX') was a v1 pattern fully replaced
      by CnIndexPage's #form-dialog / #delete-dialog slots. The search
      store hit `/api/search` from a sidebar that no longer exists.

  src/store/store.js
    — drop useNavigationStore / useSearchStore imports + the
      navigationStore / searchStore exports. Updated the header comment
      to record the chain-E sweep.

  src/store/modules/importExport.js
    — drop the dead `importFile` (singular) action and its broken
      `import { sourceStore, endpointStore, jobStore, mappingStore,
      synchronizationStore, ruleStore } from store.js` — those per-schema
      stores were deleted in chain-C. The live `importFiles` (plural,
      called by ImportIndex.vue) + `exportFile` are kept untouched.

Net: 4 files deleted, 2 files trimmed, ~420 LoC removed.

* chore(import): drop broken custom Import flow; rely on per-index Mass Import (#829)

* chore(import): drop broken custom Import flow; rely on per-index Mass Import

The custom `/import` page lived as a multi-file YAML/JSON drag-and-drop
shell that POSTed to `/index.php/apps/openconnector/api/import` — but
**that backend endpoint was already deleted in the chain-C OR-cutover**
(see appinfo/routes.php comment "Import/Export routes deleted in chain-C
OR-cutover. OR provides POST /api/registers/{id}/import and POST
/api/configurations/{id}/import"). The Vue page was making a request to
a non-existent route on every Import click — broken at runtime.

Replacement path: every CnIndexPage in the manifest already exposes a
Mass Import action in its Actions menu (`showMassImport: true` by
default), wiring CnMassImportDialog against OR's per-schema endpoints.
That covers the use case for the 10 first-class concepts (Sources,
Endpoints, Consumers, Webhooks, Jobs, Mappings, Rules, Synchronizations,
SynchronizationContracts, CloudEvents) without an openconnector-specific
multi-file dispatcher.

Drops:

  src/manifest.json
    — Import menu item (settings section, order 10)
    — Import page entry (custom, /import, ImportIndex)

  src/views/Import/ImportIndex.vue (254 LoC)
    — The custom upload UI.

  src/composables/UseFileSelection.js (98 LoC)
    — Drag-drop file-picker helper; ImportIndex was its only consumer.

  src/store/modules/importExport.js (76 LoC) + store.js export
    — Wrapped the dead /api/import POST; ImportIndex was its only consumer.

  src/registry.js
    — `ImportIndex` registration; the registry is now empty (next entries
      will be v2 widget slots, not custom pages — see updated comment).

  lib/Controller/UiController.php::import()
  appinfo/routes.php `ui#import` route
    — The PHP SPA shell action for /import; serves nothing meaningful now.

Net: 3 source files deleted (~430 LoC), 5 files trimmed, 1 PHP route +
1 PHP controller action removed. Build still green (6.48 MiB main bundle,
slightly smaller).

If a future workflow needs the multi-file batched-import dispatcher, the
right home is a fleet-wide `CnBatchImportWizard` in @conduction/nextcloud-vue
that targets the same OR per-schema endpoints — not an openconnector-
specific resurrection.

* feat(manifest): flip to v2 schema URL — Tier 4 on i18n branch

Two-line edit to bring feature/i18n-complete-translations to manifest
v2:
- $schema URL: app-manifest.schema.json → app-manifest-v2.schema.json
- version: 1.0.0 → 2.0.0

Pre-flip Ajv check confirmed the manifest already validates against
v2 schema 2.7.0 with zero errors — the page-level shapes were
already v2-compatible, just the schema header was lagging. No page
content changes needed; downstream PRs (#823 issue-814 bootstrap,
#826 polish, #827 cleanup, #828 menu-trim, #829 drop-import, #830
action-rows, #831 KPI tiles, #838 charts) continue to apply on top
of this v2 base.

State on this branch is now Tier 4:
- schema URL ✓ v2
- version ✓ 2.0.0
- nc-vue pin ✓ ^1.0.0-beta.67
- customs: 1 (Import, justified by _note — "Multi-step file-upload
  + dry-run preview UX exceeds nc-vue v2 form/wizard capability;
  revisit after CnWizardPage ships"). Tier 4 permits justified
  customs.
- The 3 src/views/widgets/*.vue files are NC Dashboard widget
  entry points (separate webpack chunks, registered via
  OCA.Dashboard.register), NOT manifest wrappers — stay.
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.

1 participant