Skip to content

mica-ui: general settings page (/settings/general) #4608

Open

Description

@ymarcon

Port the Angular admin page #/admin/general (mica-webapp/.../app/config/{config-controller.js, views/config-view.html, views/config-form.html}) to the mica-ui Quasar app, at /settings/general (the app is already served under an admin base path, so the settings pages live under /settings).

What the Angular page does

  1. Properties (read-only table + /admin/general/edit form): ~50 fields of MicaConfigDto grouped into Server identification, Data source, Content edition (languages, charset), Content access (open access, summary statistics policy, signup), Sections (enabled document types, concept-tagging taxonomies…), Sets/cart, Compare/export, Data analyses, Statistics summary. Saved with PUT /ws/config (whole DTO).
  2. Encryption keys: create/import a key pair → PUT /config/keystore/system/https (KeyForm); download certificate → GET /config/keystore/system/https.
  3. Opal credentials: list GET /config/opal-credentials; add (key pair create/import, username+password, token) and edit → POST /config/opal-credentials; delete DELETE /config/opal-credential?id=<url>; certificate GET /config/opal-credential/certificate?id=<url> (the Angular URL form /opal-credential/{url}/certificate no longer matches the REST resource).
  4. Roles: add (unique, no uppercase/whitespace/~/!) / delete with confirm → PUT /config with the updated roles.
  5. Permissions: two ACL tables backed by SubjectAclResource: Opal views download (/config/document-sets/permissions, role READER) and crosstabs (/config/contingencies/permissions, role ANALYST), saved with config=true&file=false.

Decisions

  • Routes: /settings (hub, the current placeholder SettingsPage.vue) and /settings/general; drawer entry stays /settings.
  • Editing: no separate edit page. Each properties section is a card with its own edit dialog (opal-ui GeneralConfiguration pattern). A dialog merges its fields into a copy of the current config and PUTs the whole DTO, as Angular does.
  • No window reload after save (Angular reloads when languages/sections/name change): systemStore.init() + initPub() are re-run and everything reading systemStore.configuration is reactive.
  • Reuse FieldsList for the read-only view, ConfirmDialog, AclTable/AclDialog, notifyError.

Steps (one PR each)

Step 1 — Settings hub, general settings view and section editors

  • router/routes.ts: settings → hub page with links to the sections, settings/general → pages/SettingsGeneralPage.vue.
  • stores/system.ts: save(config) → PUT /config then init() + initPub(); loadLanguages(locale) (GET /config/languages?locale=); loadTaxonomiesSummary() (GET /taxonomies/_summary?vocabularies=false) for the concept-tagging taxonomy titles.
  • components/settings/general/GeneralProperties.vue: the sections as cards in two columns, each with a FieldsList and an edit button opening the section dialog.
  • One dialog per section, built on a shared ConfigSectionDialog.vue (title, working copy of the config, validation, save/cancel, saving state). Rules to port: isSingleNetworkEnabled disabled unless isNetworkEnabled; isProjectsCountEnabled/isDataAccessRequestsCountEnabled cleared and disabled when the feature is off; cartTimeToLive disabled unless a cart is enabled; signupGroups as chips; languages multi-select with display names + warning when a language is added; opalViewsGrouping help text varies with the selection; option lists for summaryStatisticsAccessPolicy / opalViewsGrouping; number fields with min/step and required.
  • utils/config.ts (+ vitest): the pure bits — dependent-flag rules, role id validation (for step 2), signup groups split.
  • i18n en/fr: settings_general and a config.* block ported from mica-webapp/src/main/resources/i18n/{en,fr}.json.

Step 2 — Roles, encryption keys, Opal credentials

  • RolesPanel.vue: table + RoleDialog.vue + delete confirm; saves through systemStore.save.
  • KeyPairDialog.vue: mode: 'create' | 'import', withOpalUrl prop — shared by the keystore and the Opal credential. Create: subject fields + collapsible advanced (algo RSA / size 2048); import: private/public PEM textareas. Emits a KeyForm.
  • EncryptionKeysPanel.vue: "Add key pair" dropdown (create / import) → PUT /config/keystore/system/https; "Download certificate".
  • OpalCredentialsPanel.vue + OpalCredentialDialog.vue (username/password with confirmation, or token; edit mode keeps the URL read-only): table (URL, type, actions: delete, edit for USERNAME/TOKEN, certificate download for PUBLIC_KEY_CERTIFICATE). composables/useOpalCredentials.ts (+ vitest).

Step 3 — Configuration permissions

  • Generalize useAcl: role becomes a string, AclEndpoints gets optional fixed params ({ config: true, file: false }).
  • AclDialog: optional roles prop ({value, label, help}[], defaulting to the document roles); AclTable role label fallback so ANALYST renders.
  • components/permissions/ConfigAclPanel.vue: a single permissions table over an endpoint + roles; used twice in the general page (Opal views download READER, crosstabs ANALYST).

Page assembly (SettingsGeneralPage.vue)

Breadcrumbs home / settings / general, then Properties, then a row with Encryption keys + Opal credentials on the left and Roles + Permissions on the right, mirroring the Angular layout. Guarded by authStore.isAdministrator.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions