Repository navigation
mica-ui: data access settings page (/settings/data-access) #4615
Copy link
Copy link
Open
Labels
Description
Follows #4613: the Settings › Data access page of the mica-ui app, reachable from the Settings page when isDataAccessEnabled. Reference: the Angular admin page #/admin/data-access-config (tabs: application form, preliminary, feasibility, amendment, end user agreement, notifications, other settings, permissions). Each of the five forms is edited with QJsonFormBuilder, as the entity forms are, and the texts of a form are stored with it (translations) rather than in the Mica bundle.
Branch feat/mica-ui-data-access-settings, merged into mica-ui.
Findings
- The five forms (
/config/data-access-form,-preliminary-form,-feasibility-form,-amendment-form,-agreement-form) have a draft / published revision lifecycle:GET ?revision=draft|latest,PUTsaves the draft (revision 0),PUT /_publishcreates the next revision. The Angular page enables Publish when the draftlastUpdateDatediffers from the latest one. There is no mandatory part (nodefinition-mandatory.json): the builder edits the whole form. - The domain classes extend
EntityConfig, so they already carrytranslations, but the five DTOs (DataAccess*FormDto) do not, andMicaConfigDtosdoes not map it.AbstractDataAccessEntityFormService.validateFormrequires the definition to be a JSON array: a JSON Forms UI schema (object) is rejected. - Where the forms are rendered or read on the server:
- the portal pages (
DataAccessMainFormControllerand the four others) build aSchemaFormConfigthat resolves thet()tokens with the Mica bundle only: the texts stored with the form are ignored.EntityConfigKeyTranslationService.translateSchemaForm(CSV export, diffs) already looks them up first (FormTranslations). - the portal renderer (
mica-webapp/src/main/vue/data-access-form/DataAccessForm.vue) converts the ASF pair at render time (convertAsf(schema, definition[])): a JSON Forms pair (object definition) is not handled. - the Word export (
DataAccessEntityExporter.traverseDefinitionTree) walks the ASF definition (key,items,type: help|tabs): a UI schema (elements,scope,Label,Group...) is not walked. - the default forms (
config/data-access-*-form/definition.json) are ASF arrays, and the forms already stored by existing deployments are ASF too. - the CSV export and the title / summary / end date extraction (
titleFieldPath...) read the schema and the model only: unaffected.
- the portal pages (
- The default forms hold
t(data-access-request.default.*)tokens, some embedded in HTML help blocks (<h2>I - t(...)</h2>).useEntityConfigFormkeeps a token whose key is not translated by the form as a literal, resolved by the server at render time: the texts would not be editable in the builder. DataAccessFormDtocarries more than the form pair:pdfTemplates(one PDF per language, uploaded through/files/tempand saved asjustUploadedattachments),pdfDownloadType(Template|Embedded),titleFieldPath,summaryFieldPath,endDateFieldPath,properties. The amendment DTO has the three field paths too (itswithReview/approvedFinalare not edited by the Angular page). A save must round trip these fields.- Notifications and other settings are the
DataAccessConfigDto(GET/PUT /config/data-access, whole object replaced): thecsvExportFormatfields it also holds must be sent back as received. - Permissions:
/config/data-access-form/permissionsis aSubjectAclResourceon/data-access-requestwith the single roleREADER, a file resource, and two other resources (action-logs,private-comment) granted through the repeatedotherResourcesquery parameter.useAcl/AclDialog/AclTabledo not handle other resources yet (AclDto.otherResourcesis typed). - The legacy Angular editor (
mica-webapp/src/main/webapp/app/access-config) edits the ASF pair as JSON text: it is the reference for the page, and stays as is.
Decisions
- Same storage model as the entity forms: the JSON Forms pair with the texts stored in the form
translations(by locale, flat keys), the server resolving them before the Mica bundle everywhere the form is rendered. - The texts come from the builder: when a form is loaded whose
translationsdo not cover itst()tokens (legacy form), the texts of these keys are fetched from the resolved bundles (GET /config/i18n/{lang}.json, one per configured language) and seeded into the builder translations; a string that is exactlyt(key)keepskeyas its translation key, a token embedded in HTML is replaced by its text in each language (the builder then owns that text under its generated key). The first save persists them with the form. A leftover token (a key missing from the bundles) is kept literal and still resolved by the server. The seeding lives in the shared composable, so the entity forms benefit from it too. - One page, one drawer, as
SettingsEntityConfigPage: five form panels, Notifications, Other settings, Permissions. Every form panel has Save and Publish (enabled when the draft is newer than the published revision), the unsaved-changes guard on panel switch and route leave. - No backward compatibility on the editing side once the page is in mica-ui: a data access form is saved as a JSON Forms pair only (the form service accepts a UI schema object, not an ASF array), the default forms ship as JSON Forms. The Angular
access-configmodule is left untouched, as a reference. The mica-ui builder page converts a stored ASF form on load (toJsonForms) so that the administrator can save and publish it. - No data migration: the request contents have the same schema whichever dialect captured them. The form definitions of an existing deployment stay in the ASF dialect in two places: the published revision until the form is published again from the mica-ui page (the page flags such a form and asks for it), and the revisions that submitted requests were pinned to on submission (
DataAccessEntityResource.submit, unpinned on reopen only), for good. The ASF dialect is kept as a read-only rendering path so that such a request is still shown and exported with the exact form it was submitted with: the portal renderer keepsconvertAsffor an array definition (and renders an object definition directly), the Word export keeps its ASF walk beside the new UI schema walk, and thet()tokens of those revisions keep resolving through the Mica bundle.
Plan
1. Server (mica-core, mica-web-model, mica-rest, mica-webapp)
-
Mica.proto: optionaltranslationson the fiveDataAccess*FormDto;MicaConfigDtosasDto / fromDto map it;Mica.tsregenerated / updated -
AbstractDataAccessEntityFormService.validateForm: the definition is a UI schema (JSON object); the translations, when present, are a JSON object (asEntityConfigService.validateTranslations, shared helper). A stored ASF form is still served byGET(the builder converts it) but can no longer be saved as is - default forms:
definition.jsonof the fiveconfig/data-access-*-form/folders replaced byuischema.jsongenerated withtoJsonForms(as theuischema-mandatory.jsonfiles were),t()tokens kept;createDefault*Form()read it -
SchemaFormConfig: takes the form (EntityConfig) and translates withFormTranslations.translator(form, lang, bundle); the five portal controllers pass the form;data-access-form-scripts.ftldefault definition becomes{} -
DataAccessEntityExporter: a UI schema (object) is adapted to the definition tree the exporter walks (UischemaDefinition:Control→ keyed item,Label→ help, labelledGroup/Category→ titled section), option labels read from the schemaoneOfas well as the ASFtitleMap; the ASF traversal kept for an array (pinned revisions) - portal renderer
DataAccessForm.vue/types.ts/main.ts:definition: unknown; an object is rendered byQJsonFormas is, an array goes throughconvertAsf(read-only rendering of pinned ASF revisions); bundle rebuilt (mica-webapp/src/main/vue) -
UPGRADE.md: the data access forms are to be published once from the new page for the portal to use the JSON Forms dialect (existing requests keep rendering with their pinned revision) - tests:
FormValidationTest,DataAccessFormServicesTest(defaults are JSON Forms pairs, object accepted, array rejected, invalid translations),SchemaFormConfigTest(stored texts first, then the bundle),UischemaDefinitionTest,DataAccessEntityExporterTest(UI schema, ASF,oneOf/titleMaplabels; the file was JUnit 4 and never ran in mica-core, now JUnit 5) - verified against the local Mica: an ASF draft served by
GET, saved back as a UI schema withtranslations, an array or invalid translations rejected (400), published (revisionbumped), the portal page rendering the UI schema with the stored texts inenandfr, the Word export using them; a request redirected to an ASF preliminary revision still renders through the read-only path
2. mica-ui: generic configuration form composable and builder
-
useEntityConfigFormsplit into a genericuseConfigForm(source)where the source gives the resource path, the load query (revision=draftfor the data access forms), the extra DTO fields to carry over on save, and an optionalpublish;useEntityConfigFormand the newuseDataAccessConfigForm(kind)are thin wrappers;prepareForm/parseTranslationsshared - translation seeding from
GET /config/i18n/{lang}.jsonper configured language (decision 2), the bundles cached informsStore; a wholet(key)keepskeywith the bundle texts, an embedded token becomes a text of the builder throughsetText(own key, resolved per language); vitest coverage: whole-token keys, embedded tokens, missing keys, form already translated (no bundle fetched) -
EntityFormBuilder.vuebecomesConfigFormBuilder.vue: the composable state as prop, Save / Cancel, optional Publish (publisheddate andcanPublishfrom the source),confirmLeaveexposed;SettingsEntityConfigPageupdated - latest revision date:
GET ?revision=latestafter load / save / publish, to drive the Publish button and show the published date
3. mica-ui: data access page, routes and form panels
- route
settings/data-access→SettingsDataAccessPage.vue; Settings page entry (Content column, shown whenisDataAccessEnabled), breadcrumbs - drawer items: Application form, Preliminary form, Feasibility form, Amendment form, End user agreement form, Notifications, Other settings, Permissions (a form whose feature is disabled in the settings is still editable, as in Angular, with a caption saying it is disabled); the last three panels are filled by steps 4 to 6
- five form panels with
ConfigFormBuilder(/config/data-access-form,-preliminary-form,-feasibility-form,-amendment-form,-agreement-form); a legacy form (array definition, converted on load) shows a banner asking to save and publish it, and is reported dirty so that Save is enabled - application form panel, below the builder: Properties (
titleFieldPath,summaryFieldPath,endDateFieldPath) and PDF download (pdfDownloadTyperadio; forTemplate, one PDF file input per configured language, uploaded throughuseTempFiles, the stored template shown by name and size and removable; there is no endpoint to download a stored template, so none is offered); saved with the form - amendment form panel: Properties (
titleFieldPath,summaryFieldPath,endDateFieldPath), saved with the form
4. mica-ui: notifications panel
-
DataAccessNotificationsPanel.vueon a working copy ofDataAccessConfigDto(GET /config/data-access), three tabs as Angular: Events (created, submitted, reviewed, reopened, conditionally approved, rejected, approved, commented, attachment: toggle + subject input enabled with the toggle, placeholder[${organization}] ${title}), Reports (final / intermediate report toggles and subjects,nbOfDaysBeforeReport), Collaborators (invitation subject, collaborator accepted toggle and subject, enabled when collaborators are enabled) - Save (
PUT /config/data-accesswith the whole DTO), Cancel (reload), dirty guard (useConfirmLeave, shared with the form builder);useDataAccessConfigcomposable shared with the other settings panel (one loaded copy, saved from either panel)
5. mica-ui: other settings panel
- General: permissions (
daoCanEdit), collaborators (collaboratorsEnabled,collaboratorInvitationDays), other forms (preliminaryEnabled,mergePreliminaryContentEnabled,feasibilityEnabled,amendmentsEnabled,agreementEnabled,agreementOpenedPolicyselect ALWAYS / PRELIMINARY_APPROVED / MAIN_APPROVED), variables (variablesEnabled,preliminaryVariablesEnabled,feasibilityVariablesEnabled,amendmentVariablesEnabled), with the same enabling dependencies as Angular - ID generation:
idPrefix(pattern[a-zA-Z0-9_-]+),idLength,randomId,allowIdWithLeadingZeros - Workflow:
withReview,withConditionalApproval,approvedFinal,rejectedFinal - Predefined action names:
predefinedActionsas a list of keys (chips input), help text naming thedata-access-request.action-log.config.label.translation prefix (the translations editor is not in mica-ui yet: plain text, no link) - Save / Cancel, dirty guard, layout in two columns as the general settings page (
ConfigToggle/ConfigInputreused or generalized to a message-key prefix)
6. mica-ui: permissions panel
-
useAcl: optionalotherResourcesinAclInput, sent as repeatedotherResourcesquery parameters on save;AclEndpoints.otherResourceslists the ones offered -
AclDialog: a checkbox per offered other resource (labels: "Apply the same permission to associated action logs", "Give access to the private comments section");AclTable: the granted other resources shown with the role - panel:
ConfigAclPanelextended (file option, other resources), on/config/data-access-form/permissions, roleREADERonly, admin only - server: the Shiro annotations moved off the
permissions()locator ofDataAccessFormResource(and its class) onto its methods, the sub-resource checking the permission itself: the annotated locator failed the unauthenticated CORS preflight of the dev server - vitest:
useAclother resources parameters
7. i18n (en / fr)
-
settings.data_access/settings.data_access_caption;config.data_access.*keys ported from the Angular bundle (data-access-config.*ofmica-webapp/src/main/resources/i18n/{en,fr}.json): panel titles and infos (the form infos reworded for the builder, no angular-schema-form link), properties, PDF download, notifications, settings, ID generation, workflow, action names, permissions, save / publish messages
8. Verification
- vitest, lint,
vue-tsc, prettier; mica-core tests; portal bundle build - against the local Mica (rebuilt web-model, core, rest, webapp): an ASF form is flagged, converted, saved and published from mica-ui and round trips with its
translations; a request pinned to an ASF revision still renders and exports with that revision; a fresh Mica gets the JSON Forms defaults;_publishbumps the revision; the portal page/data-access-form/{id}renders the JSON Forms form with the stored texts in each language; Word export of a request; notifications / settings / permissions saved and re-read; PDF template upload - headless screenshots of every panel
Reactions are currently unavailable
Activity
mica-ui: review fixes of the data access settings (#4615)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)
mica-ui: data access settings page (#4615) (#4617)