From d38f9f1785c86ad32347947f93d953cd7e189349 Mon Sep 17 00:00:00 2001 From: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Date: Wed, 8 Jan 2025 17:13:48 +0100 Subject: [PATCH] feat(cat-voices): validation error translations (#1482) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(cat-voices): In-page Information Cards (#1242) * feat: add InPageInformationCard widget and campaign information model for displaying campaign details and status updates * feat: update InPageInformationCard to dynamically display button text based on campaign stage and add corresponding localization entries * fix: add missing line for better formatting in InPageInformationCard widget definition * fix: spelling * fix: import intl * fix: theme in tests * fix: add campaign date formatting utility and integrate it in information cards * refactor: improve date formatting utility and integrate localized date handling in information cards * fix: spelling * fix: to early check if information is DateTimeMixin --------- Co-authored-by: Damian Moliński <47773413+damian-molinski@users.noreply.github.com> * chore(general): merge main into mve3 (#1282) * Feat: update testplan template (#1243) * chore: update testplan * fix * fix * fix * fix * fix: testplan template (#1245) * feat(cat-gateway): Finliaze CIP36 Endpoint Cleanup (#1241) * fix: api endpoint draft Signed-off-by: bkioshn * fix: api health endpoint v1 Signed-off-by: bkioshn * fix: remove bad request from errorResponses Signed-off-by: bkioshn * fix: add bad req to get /registration Signed-off-by: bkioshn * fix: error logging Signed-off-by: bkioshn * fix: remove validation error Signed-off-by: bkioshn * fix: registration get error name Signed-off-by: bkioshn * chore:format Signed-off-by: bkioshn * fix: get json schema from openapi spec Signed-off-by: bkioshn * fix: move schema utils Signed-off-by: bkioshn * fix: optional field Signed-off-by: bkioshn * fix: config key Signed-off-by: bkioshn * fix: cat-gateway code gen Signed-off-by: bkioshn * fix: api name in cat-voice Signed-off-by: bkioshn * fix: cat-voice format Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: change tag config description * test: add test for default validator * fix: add spectral ruleset Signed-off-by: bkioshn * fix(cat-gateway): Sort the spelling words, and use latest deny.toml * fix(cat-gateway): Fix broken pre-push justfile target * docs(cat-gateway): cleanup * docs(cat-gateway): Fix API Groups and document them better * docs(cat-gateway): Add documentation to the health/inspection endpoint * docs(cat-gateway): Add descriptions for cardano/cip36/latest_registration/stake_addr * docs(cat-gateway): Document stake key hash and vote key endpoints for cardano * docs(cat-gateway): add documentation to config/frontend * docs(cat-gateway): Add api docs for frontend schema * docs(cat-gateway): Move legacy registration endpoints into the Legacy TAG. * docs(cat-gateway): Remaining documentable entities documented * fix: update openapi linter Signed-off-by: bkioshn * docs(cat-gateway): Add more constraints to parameters and json bodies * fix: openapi lint FUNCTION name Signed-off-by: bkioshn * fix: CIP36 example and description Signed-off-by: bkioshn * fix(cat-gateway): cleanup error handling, and add a global 429 response to all endpoints. * fix: config endpoint example, desc, and return Signed-off-by: bkioshn * chore: remove todo Signed-off-by: bkioshn * fix: move config object Signed-off-by: bkioshn * fix: move cip36 object Signed-off-by: bkioshn * docs(cat-gateway): Add missing headers to responses * docs(cat-gateway): Cleanup the rest of the documentation in the api * fix(cat-gateway): Fix OpenAPI linting and add autogenerated api file for dart. * refactor(cat-gateway): Better generalize the OpenAPI simple string type creation macro. * fix(cat-gateway): Add APIKey and CatToken auth to some endpoints. Add 401 and 403 common responses. * fix(cat-gateway): Add universal 422 response to all endpoints, and try and make all endpoint validation use it. * fix: add cardano stake address type Signed-off-by: bkioshn * fix(cat-gateway): stake address type Signed-off-by: bkioshn * fix(cat-gateway): Refactor the RBAC Token auth, so it's easier to maintain. * fix(cat-gateway): stake address name Signed-off-by: bkioshn * fix(cat-gateway): Add no auth and no-auth+rbac auth schemes * fix(cat-gateway): format + stake addr example Signed-off-by: bkioshn * fix(cat-gateway): code format * fix(cat-gateway): openapi spectral example rules Signed-off-by: bkioshn * fix(cat-gateway): Move legacy registration endpoint under Legacy Tag * fix(cat-gateway): Add Auth to all endpoints * fix(docs): Remove obsolete lint config file * fix(cat-gateway): Make config.toml match upstream * docs(docs): update project dictionary * feat(cat-gateway): add target to make it quick to check openapi lints locally * fix(cat-gateway): Remove reference to hermes * fix(cat-gateway): Add auth to rbac endpoints * docs(cat-gateway): Add full docs for v1/votes/plan/account-votes * docs(cat-gateway): Add example for ip address query argument * fix(cat-gateway): Define and abstract Ed25519 Public Keys as hex encoded parameters * fix(cat-gateway): Make sure string api types do not directly expose the internal string * fix(cat-gateway): Make conversion from a Ed25519 pub key hex value to a Verifyingkey infallible * fix(cat-gateway): Fix native asset response types * docs(cat-gateway): fix comments * fix(cat-gateway): Autogenerate flutter files * fix(cat-gateway): Exclude legacy endpoints from needing api examples * fix(cat-gateway): WIP improving cip36 endpoint docs * fix(docs): Make targets to re-check the generated schema easy. * fix: spectral ruleset for linting query params description * feat: parameter rule * fix: debug function * docs(cat-gateway): Make schema lint accept description inside a schema in a query parameter * fix(cat-gateway): remove debug logic from api docs lint * fix(cat-gateway): Don't put expanded program into git * Make error response comments consistent * test(cat-gateway): Add local operation to easily expand macros in the service code * fix(cat-gateway): CIP36 Structured endpoint * fix: speling * fix(rust): cleanup/normalize nonce validation * fix(rust): code format * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> --------- Signed-off-by: bkioshn Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj * Revert "Merge branch 'mve3' into main" This reverts commit 01db066663ece91c2c5f6ab3150387803f87885c, reversing changes made to 3bf0ccf6cbc38359e888e53cb24ada753b0f2ebc. * fix(cat-voices): equatable lint issue fix (#1280) * fix: resolve equatable lint issue * fix: missing override --------- Signed-off-by: bkioshn Co-authored-by: Stefano Cunego <93382903+kukkok3@users.noreply.github.com> Co-authored-by: Steven Johnson Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj Co-authored-by: Oleksandr Prokhorenko * feat(cat-voices): discovery page mve3 (#1281) * Feat: update testplan template (#1243) * chore: update testplan * fix * fix * fix * fix * fix: testplan template (#1245) * feat(cat-gateway): Finliaze CIP36 Endpoint Cleanup (#1241) * fix: api endpoint draft Signed-off-by: bkioshn * fix: api health endpoint v1 Signed-off-by: bkioshn * fix: remove bad request from errorResponses Signed-off-by: bkioshn * fix: add bad req to get /registration Signed-off-by: bkioshn * fix: error logging Signed-off-by: bkioshn * fix: remove validation error Signed-off-by: bkioshn * fix: registration get error name Signed-off-by: bkioshn * chore:format Signed-off-by: bkioshn * fix: get json schema from openapi spec Signed-off-by: bkioshn * fix: move schema utils Signed-off-by: bkioshn * fix: optional field Signed-off-by: bkioshn * fix: config key Signed-off-by: bkioshn * fix: cat-gateway code gen Signed-off-by: bkioshn * fix: api name in cat-voice Signed-off-by: bkioshn * fix: cat-voice format Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: change tag config description * test: add test for default validator * fix: add spectral ruleset Signed-off-by: bkioshn * fix(cat-gateway): Sort the spelling words, and use latest deny.toml * fix(cat-gateway): Fix broken pre-push justfile target * docs(cat-gateway): cleanup * docs(cat-gateway): Fix API Groups and document them better * docs(cat-gateway): Add documentation to the health/inspection endpoint * docs(cat-gateway): Add descriptions for cardano/cip36/latest_registration/stake_addr * docs(cat-gateway): Document stake key hash and vote key endpoints for cardano * docs(cat-gateway): add documentation to config/frontend * docs(cat-gateway): Add api docs for frontend schema * docs(cat-gateway): Move legacy registration endpoints into the Legacy TAG. * docs(cat-gateway): Remaining documentable entities documented * fix: update openapi linter Signed-off-by: bkioshn * docs(cat-gateway): Add more constraints to parameters and json bodies * fix: openapi lint FUNCTION name Signed-off-by: bkioshn * fix: CIP36 example and description Signed-off-by: bkioshn * fix(cat-gateway): cleanup error handling, and add a global 429 response to all endpoints. * fix: config endpoint example, desc, and return Signed-off-by: bkioshn * chore: remove todo Signed-off-by: bkioshn * fix: move config object Signed-off-by: bkioshn * fix: move cip36 object Signed-off-by: bkioshn * docs(cat-gateway): Add missing headers to responses * docs(cat-gateway): Cleanup the rest of the documentation in the api * fix(cat-gateway): Fix OpenAPI linting and add autogenerated api file for dart. * refactor(cat-gateway): Better generalize the OpenAPI simple string type creation macro. * fix(cat-gateway): Add APIKey and CatToken auth to some endpoints. Add 401 and 403 common responses. * fix(cat-gateway): Add universal 422 response to all endpoints, and try and make all endpoint validation use it. * fix: add cardano stake address type Signed-off-by: bkioshn * fix(cat-gateway): stake address type Signed-off-by: bkioshn * fix(cat-gateway): Refactor the RBAC Token auth, so it's easier to maintain. * fix(cat-gateway): stake address name Signed-off-by: bkioshn * fix(cat-gateway): Add no auth and no-auth+rbac auth schemes * fix(cat-gateway): format + stake addr example Signed-off-by: bkioshn * fix(cat-gateway): code format * fix(cat-gateway): openapi spectral example rules Signed-off-by: bkioshn * fix(cat-gateway): Move legacy registration endpoint under Legacy Tag * fix(cat-gateway): Add Auth to all endpoints * fix(docs): Remove obsolete lint config file * fix(cat-gateway): Make config.toml match upstream * docs(docs): update project dictionary * feat(cat-gateway): add target to make it quick to check openapi lints locally * fix(cat-gateway): Remove reference to hermes * fix(cat-gateway): Add auth to rbac endpoints * docs(cat-gateway): Add full docs for v1/votes/plan/account-votes * docs(cat-gateway): Add example for ip address query argument * fix(cat-gateway): Define and abstract Ed25519 Public Keys as hex encoded parameters * fix(cat-gateway): Make sure string api types do not directly expose the internal string * fix(cat-gateway): Make conversion from a Ed25519 pub key hex value to a Verifyingkey infallible * fix(cat-gateway): Fix native asset response types * docs(cat-gateway): fix comments * fix(cat-gateway): Autogenerate flutter files * fix(cat-gateway): Exclude legacy endpoints from needing api examples * fix(cat-gateway): WIP improving cip36 endpoint docs * fix(docs): Make targets to re-check the generated schema easy. * fix: spectral ruleset for linting query params description * feat: parameter rule * fix: debug function * docs(cat-gateway): Make schema lint accept description inside a schema in a query parameter * fix(cat-gateway): remove debug logic from api docs lint * fix(cat-gateway): Don't put expanded program into git * Make error response comments consistent * test(cat-gateway): Add local operation to easily expand macros in the service code * fix(cat-gateway): CIP36 Structured endpoint * fix: speling * fix(rust): cleanup/normalize nonce validation * fix(rust): code format * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> --------- Signed-off-by: bkioshn Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj * feat: update segment names * feat: add new discovery page * feat: add empty state for proposals * fix: rename * feat: add proposals cubit * feat: add tests * chore: spelling * chore: cleanup * chore: cleanup * chore: revert unwanted changes * chore: revert merge conflicts * fix: formatting --------- Signed-off-by: bkioshn Co-authored-by: Stefano Cunego <93382903+kukkok3@users.noreply.github.com> Co-authored-by: Steven Johnson Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj * feat(cat-voices): campaign modal (#1289) * refactor: remove onCancel function and define typedef for upload success * feat: basic details dialog * fix: header title color * fix: modal constraints * fix: details tile categories subtitle * chore: dialog test data * feat: dialog border * feat: CampaignDetails bloc and models * feat: header gradient overlay * fix: modal background color * refactor: rename LoadCampaign to LoadCampaignEvent * refactor: update Campaign details dialog path * feat: DiscoveryPage launched CampaignDetailsDialog * feat: introduce CampaignRepository * feat(cat-voices): Date & Time input widget (#1224) * feat: ui widget for date picker commponent * feat: custom controller for date picker widget * feat: adding validation to textfields * feat: enhance date picker with improved validation and error handling messages * feat: improve overlay management in date picker and enhance scroll controller handling in text fields * fix: overlay switch between date and time * chore: remove cached gitignore files * fix: update OK button text in VoicesCalendarDatePicker for localization consistency * feat: refactor date and time pickers to use DateTime for better consistency and state management across the application * feat: implement new date and time picker modules with validation and controllers for better UI interaction * fix: static-analytics * refactor: date time text field (#1293) * refactor: date time text field * fix: doc reference * feat: add date/time input formatting to date and time fields * fix: late final in voices_date_field.dart * fix: late final in voices_time_field.dart * fix: formatting --------- Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Damian Moliński <47773413+damian-molinski@users.noreply.github.com> * feat(cat-voices): admin preview tools (#1309) * chore: rename in-page-card to campaign preview card, extract campaign status to catalyst_voices_models * feat: add translations * fix: typo * feat: add admin preview tools * feat: add views section to switch between auth user states * chore: split into multiple files * style: spelling * fix: browser resize shouldn't reset the dialog offset * chore: cleanup * style: spelling * feat(cat-voices): Campaign managment status UI (#1314) * feat: campaign managment status * fix: structure of the project * fix: earthfile * docs: adding docs for campaign enums * fix: whitespacing * refactor(cat-voices): Move UI models to view_model to models package (#1317) * refactor: Move FundedProposal and PendingProposal to view_model package and introduce general Proposal in models package * refactor: move coin formatting to inside models from view_models package * refactor: move coin formatting to inside models from view_models package * feat(cat-voices): vit ss endpoints generating (#1302) * feat: vit-ss openapi specs + code generating * chore: bump chopper and chopper_generator * refactor: rename from vitss_openapi to vit * fix: exclude openapi from spellchecking * fix: missing cat_gateway_api * refactor: rename generated/catalyst-gateway to generated/api + generated CatGatewayApi to CatGateway * feat(cat-voices): Campaign info dialog on discovery (#1321) * chore: rename in-page-card to campaign preview card, extract campaign status to catalyst_voices_models * feat: add translations * fix: typo * feat: add admin preview tools * feat: add views section to switch between auth user states * chore: split into multiple files * style: spelling * fix: browser resize shouldn't reset the dialog offset * chore: cleanup * style: spelling * feat: add border * chore: reorganize members * chore: rename campaign stage cart * feat: add campaign info dialog on discovery page * feat: calculate campaign stage * fix: tests * chore: add tests * chore: cleanup * feat: add campaign service * fix: convert campaign info into simple class instead of enum * fix: tests * fix: campaign info state * feat(cat-voices): admin tools events timer (#1323) * chore: rename in-page-card to campaign preview card, extract campaign status to catalyst_voices_models * feat: add translations * fix: typo * feat: add admin preview tools * feat: add views section to switch between auth user states * chore: split into multiple files * style: spelling * fix: browser resize shouldn't reset the dialog offset * chore: cleanup * style: spelling * feat: add border * chore: reorganize members * chore: rename campaign stage cart * feat: add campaign info dialog on discovery page * feat: calculate campaign stage * fix: tests * chore: add tests * chore: cleanup * feat: implement timer logic * feat: add campaign service * fix: convert campaign info into simple class instead of enum * fix: tests * fix: campaign info state * feat(cat-voices): Merge main into mve3 (#1334) * Feat: update testplan template (#1243) * chore: update testplan * fix * fix * fix * fix * fix: testplan template (#1245) * feat(cat-gateway): Finliaze CIP36 Endpoint Cleanup (#1241) * fix: api endpoint draft Signed-off-by: bkioshn * fix: api health endpoint v1 Signed-off-by: bkioshn * fix: remove bad request from errorResponses Signed-off-by: bkioshn * fix: add bad req to get /registration Signed-off-by: bkioshn * fix: error logging Signed-off-by: bkioshn * fix: remove validation error Signed-off-by: bkioshn * fix: registration get error name Signed-off-by: bkioshn * chore:format Signed-off-by: bkioshn * fix: get json schema from openapi spec Signed-off-by: bkioshn * fix: move schema utils Signed-off-by: bkioshn * fix: optional field Signed-off-by: bkioshn * fix: config key Signed-off-by: bkioshn * fix: cat-gateway code gen Signed-off-by: bkioshn * fix: api name in cat-voice Signed-off-by: bkioshn * fix: cat-voice format Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: fix spacing Signed-off-by: bkioshn * chore: change tag config description * test: add test for default validator * fix: add spectral ruleset Signed-off-by: bkioshn * fix(cat-gateway): Sort the spelling words, and use latest deny.toml * fix(cat-gateway): Fix broken pre-push justfile target * docs(cat-gateway): cleanup * docs(cat-gateway): Fix API Groups and document them better * docs(cat-gateway): Add documentation to the health/inspection endpoint * docs(cat-gateway): Add descriptions for cardano/cip36/latest_registration/stake_addr * docs(cat-gateway): Document stake key hash and vote key endpoints for cardano * docs(cat-gateway): add documentation to config/frontend * docs(cat-gateway): Add api docs for frontend schema * docs(cat-gateway): Move legacy registration endpoints into the Legacy TAG. * docs(cat-gateway): Remaining documentable entities documented * fix: update openapi linter Signed-off-by: bkioshn * docs(cat-gateway): Add more constraints to parameters and json bodies * fix: openapi lint FUNCTION name Signed-off-by: bkioshn * fix: CIP36 example and description Signed-off-by: bkioshn * fix(cat-gateway): cleanup error handling, and add a global 429 response to all endpoints. * fix: config endpoint example, desc, and return Signed-off-by: bkioshn * chore: remove todo Signed-off-by: bkioshn * fix: move config object Signed-off-by: bkioshn * fix: move cip36 object Signed-off-by: bkioshn * docs(cat-gateway): Add missing headers to responses * docs(cat-gateway): Cleanup the rest of the documentation in the api * fix(cat-gateway): Fix OpenAPI linting and add autogenerated api file for dart. * refactor(cat-gateway): Better generalize the OpenAPI simple string type creation macro. * fix(cat-gateway): Add APIKey and CatToken auth to some endpoints. Add 401 and 403 common responses. * fix(cat-gateway): Add universal 422 response to all endpoints, and try and make all endpoint validation use it. * fix: add cardano stake address type Signed-off-by: bkioshn * fix(cat-gateway): stake address type Signed-off-by: bkioshn * fix(cat-gateway): Refactor the RBAC Token auth, so it's easier to maintain. * fix(cat-gateway): stake address name Signed-off-by: bkioshn * fix(cat-gateway): Add no auth and no-auth+rbac auth schemes * fix(cat-gateway): format + stake addr example Signed-off-by: bkioshn * fix(cat-gateway): code format * fix(cat-gateway): openapi spectral example rules Signed-off-by: bkioshn * fix(cat-gateway): Move legacy registration endpoint under Legacy Tag * fix(cat-gateway): Add Auth to all endpoints * fix(docs): Remove obsolete lint config file * fix(cat-gateway): Make config.toml match upstream * docs(docs): update project dictionary * feat(cat-gateway): add target to make it quick to check openapi lints locally * fix(cat-gateway): Remove reference to hermes * fix(cat-gateway): Add auth to rbac endpoints * docs(cat-gateway): Add full docs for v1/votes/plan/account-votes * docs(cat-gateway): Add example for ip address query argument * fix(cat-gateway): Define and abstract Ed25519 Public Keys as hex encoded parameters * fix(cat-gateway): Make sure string api types do not directly expose the internal string * fix(cat-gateway): Make conversion from a Ed25519 pub key hex value to a Verifyingkey infallible * fix(cat-gateway): Fix native asset response types * docs(cat-gateway): fix comments * fix(cat-gateway): Autogenerate flutter files * fix(cat-gateway): Exclude legacy endpoints from needing api examples * fix(cat-gateway): WIP improving cip36 endpoint docs * fix(docs): Make targets to re-check the generated schema easy. * fix: spectral ruleset for linting query params description * feat: parameter rule * fix: debug function * docs(cat-gateway): Make schema lint accept description inside a schema in a query parameter * fix(cat-gateway): remove debug logic from api docs lint * fix(cat-gateway): Don't put expanded program into git * Make error response comments consistent * test(cat-gateway): Add local operation to easily expand macros in the service code * fix(cat-gateway): CIP36 Structured endpoint * fix: speling * fix(rust): cleanup/normalize nonce validation * fix(rust): code format * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> * Update catalyst-gateway/bin/src/service/common/types/cardano/cip19_shelley_address.rs Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> --------- Signed-off-by: bkioshn Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj * Revert "Merge branch 'mve3' into main" This reverts commit 01db066663ece91c2c5f6ab3150387803f87885c, reversing changes made to 3bf0ccf6cbc38359e888e53cb24ada753b0f2ebc. * fix(cat-voices): equatable lint issue fix (#1280) * fix: resolve equatable lint issue * fix: missing override * fix(flutter/catalyst_key_derivation): Accept non extended public key for rbac (#1288) * fix(flutter/catalyst_key_derivation): Accept non extended public key for rbac * fix: unit tests * chore: rename * fix(dart/catalyst_cardano_serialization): remove key reference from RBAC, use local key ref instead (#1292) * fix(dart/catalyst_cardano_serialization): remove key reference from RBAC, use local key ref * fix: update RBAC issuer properties, catalyst users don't have any of these identifiable * fix: payment key should refer to the first transaction output which is the change address * chore: rename keyOffset to offset * chore: bump version (#1297) * fix(cat-gateway): Fix native asset indexing to be more flexible (#1150) * refactor: rename schema to asset * refactor: vector asset * chore: rename asset fields * refactor: object mapping structs * chore: minor rename * fix: update operation cql * fix: schema version * chore: change asset_id back to policy_id * chore: find rename * fix: schema version * fix: i128 * feat: asset value from i128 * refactor: change &[u8] for asset name * refactor: try from asset value * fix: import * chore: fmtfix * Update catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs Co-authored-by: Steven Johnson * revert: i128 to bigint * fix: unused import * feat: api test * chore: cspell fix * chore: cspell fix * chore: fmtfix --------- Co-authored-by: Oleksandr Prokhorenko Co-authored-by: Steven Johnson * feat(docs): Document the key derivation path for Project Catalyst ED25519 Keys (#1300) * feat(docs): Document the key derivation path for Project Catalyst ED25519 keys * fix(docs): Fix and reference historical dates for accuracy * fix(dart/catalyst_cardano_serialization): x509 distinguished name structure (#1290) * fix: x509 distinguished name structure Signed-off-by: bkioshn * fix: format Signed-off-by: bkioshn * feat: make it possible to override ASN1 tag for subject alt name in the x509 cert * fix: static analysis issue --------- Signed-off-by: bkioshn Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Dominik Toton * feat: additional just functions for faster startup (#1310) * fix(cat-voices): update key derivation path (#1301) * fix(cat-voices): update key derivation path * docs: add source * chore: code cleanup * docs: move relevant docs * chore: extract account constant Co-authored-by: Steven Johnson * chore: reformat --------- Co-authored-by: Steven Johnson * fix: frb unexpected cfg (#1320) Signed-off-by: bkioshn * fix(cat-gateway): bump `scylla` to v0.15.0 (#1316) * refactor: initial * fix: arc type * fix: query iter * fix: functions * fix: final * chore: fmtfix * chore: remove lints * chore: remove lint from database object * chore: remove result wrapper * feat(cat-gateway): Add a signed documents repository storage table in the Event DB (#1322) * refactor(cat-gateway): Move unused schemas out of the main schema directory * feat(cat-gateway): Add signed documents repository table to the postgresql DB. * feat(cat-gateway): Add author, and more indexes to the signed docs repository table * fix(cat-gateway): BYTEA not BLOB * fix(cat-gateway): move unused migrations out of the migrations folder * fix(cat-gateway): Fix comment annotations to refer to correct table * fix(cat-gateway): fix index names in the comments * feat(docs): Define signed document metadata fields (#1315) * feat(docs): Define signed document metadata fields * docs(docs): Fix spelling * feat(cat-voices): Integration tests using flutter_driver (#1304) * custom driver for integration tests * feat: working voices test driver * feat: creating internal lib for voices driver * fix: remove unused import * fix: check-spelling * fix: static analysis * fix: test file * refactor: skiping test for know * fix: adding packages to melos * fix: whitespacing * Update catalyst_voices/packages/libs/catalyst_cardano/catalyst_cardano/example/test_driver/app_test.dart Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> * feat: add extension to driver * fix: remove unused function * fix: add files to gitignore --------- Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> * fix: importing proper menuitem * fix: missing comma in cspell.json --------- Signed-off-by: bkioshn Co-authored-by: Stefano Cunego <93382903+kukkok3@users.noreply.github.com> Co-authored-by: Steven Johnson Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj Co-authored-by: Oleksandr Prokhorenko Co-authored-by: Apisit Ritruengroj <38898766+apskhem@users.noreply.github.com> Co-authored-by: Dominik Toton Co-authored-by: Damian Moliński <47773413+damian-molinski@users.noreply.github.com> * feat(cat-voices): Admin view for overall spaces menu (#1326) * feat: overall spaces admin configuration * feat: additional access control base on user roles * fix: spelling * fix: access controll state check * fix: whitespace in dependecies.dart * fix: missing trailling comma * refactor: simplify account access in UserAccessGuard and AdminAccessGuard, add extension for session state handling --------- Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> * feat(cat-voices): proposal editor template data flow (#1335) * chore: remove workspace test data * chore: workspace bloc * refactor: use MarkdownString instead of DocumentJson * feat: MarkdownCodec * chore: markdown convert lib * refactor: use MarkdownString * feat: updating sections dynamically * fix: section step title wrapping * feat: ProposalSection * feat: saving proposal step answer * refactor: move WorkspaceBloc to app.dart * chore: guidances * chore: use const in constructor * fix: workspace page event order * refactor: rename MarkdownString to MarkdownData * refactor: extract _mapProposalSection * refactor(cat-voices): move api to repository package (#1336) * refactor: move api to repository package * refactor: move storage/crypto related classes to shared package * refactor: rename VaultCryptoService to LocalCryptoService * fix: melos build_runner script * fix: justfile package comment * fix: remove unused deps from services * fix: bring back path dep * chore: remove legacy documentation / code * fix: readme formatting * feat(cat-voices): admin tools mocked data (#1356) * feat: add proposal service * refactor: limit rebuilds in spaces shell page * chore: cleanup code * feat: sync available spaces in admin tools * chore: cleanup * feat: register with RBAC as proposer * feat: use overlay for admin tools to show it above everything else * chore: remove unused code * feat: add admin tools cubit * feat: override session state by admin tools * chore: cleanup * feat: update campaign info dialog to mock the campaign stage * chore: cleanup dummy user service * feat: mock proposals * chore: code cleanup * chore: cleanup and tests * chore: cleanup * chore: campaign info cubit tests * chore: add tests for proposals cubit * style: reformat code * fix: tests * chore: code review feedback * chore: cleanup dummy user factory * chore: simplify proposal view model * Missing autofocus param (#1361) Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> * draft for setup segment * fix: delete unused files * feat: dtos for properties * feat(dart/catalyst_cardano_serialization): replace ulid by UUID in auth token (#1368) * feat: replace ulid by uuid v7 * fix: encode uuid as bytes not as string * feat: add cbor tag for uuid * fix: missing scaffold for global snackbars (#1373) * feat(dart/catalyst_cose): Catalyst COSE_SIGN support (#1374) * refactor!: extract signer and verifier algorithms * feat: add new COSE_SIGN1 implementation * feat: add COSE_SIGN structure * style: spelling * fix: tests * chore: code cleanup * feat(cat-voices): Cached vault unlock state (#1372) * feat: local storage * refactor: local storage clear * feat: add allowList to LocalStorage * feat: SecureStorageVault accepts key with default value * feat: MemoryStorage * chore: export LocalStorage and MemoryStorage * feat: TtlCache * refactor: Delete keychain_metadata in favour of internal initialization value inside SecureStorageVault * chore: fix previous commit files * feat: keychain uses ttl cache for unlock * feat: DependencyProvider instanceName properties * fix: use effective key for secure storage cache * feat: Add SecureStorageVaultCache * fix: LocalTtlCache now extends from now only * chore: make SecureStorageVaultCache private * feat: vault active flag + extending unlocked state * feat: extend last unlock expireDate state when vault becomes inactive * feat: make unlockTtl a optional parameter * feat: AppActiveStateListener and ActiveAware interface * feat: UserService implements ActiveAware * chore: do not sync isUnlocked when building stream * fix: sync unlock state on stream watch * fix: remove unnecessary import * fix: failing tests * docs: AppActiveStateListener * chore: typo * refactor: require storages FlutterSecureStorage/SharedPreferencesAsync to be more explicit about dependencies * feat(cat-voices): app config model (#1378) * feat: app config model * feat: dynamic app config * chore: missing AppConfig params * fix: exclude generated files from analyze * fix: exclude dart_tool from melos analyze script * chore: formatting * refactor: move json_converters to shared package * fix: pubspec libs sorting * feat(cat-voices): caching user (#1391) * chore: wip * feat: caching user model * refactor: move json_converters to shared package * feat: UserDto and AppConfigDto * refactor: move Keychain to shared package * refactor: simplify UserService. Expose only Accounts and User * feat: lockable lastIsUnlocked * fix: typos * fix: typo * refactor: reorder getUser/saveUser in UserRepository * feat(cat-voices): setup campaign stage dates (#1396) * feat: edit campaign stage dates * chore: code cleanup * fix: disable overscroll * chore: cleanup code * chore: cleanup * feat:creating dtos for proposal schema * feat: creating toModels * feat: sort section/elements by xorder * feat: adding missing toModels for definitions * fix: delete unused property from element class * feat: creating generic_proposal.json * feat(cat-voices): multi proposal workspace (#1409) * refactor: rename WorkspacePage to WorkspaceEditorPage * feat: workspace page * refactor: rename WorkspaceEditor to ProposalEditor * feat: Workspace header * chore: workspace bloc/state in progress * refactor: different test draft id * feat: workspace page states widgets * feat: workspace states selectors * feat: Mocked workspace bloc * docs: more todo-s * refactor: rename ProposalEditor to ProposalBuilder * fix: use ellipsis in search string * refactor: Add public selectors widgets for workspace widgets * test: adding unit tests * feat: range class for easier representation for max min values * feat: adding proper from/to Json for proposal_builder class * feat: change name of the files to make it more generic -document- * feat: change name of the document property widget * feat: adding equatable for classes * chore: update chain follower * feat: sortingBy order * chore: missing build_runner for repository, restore wrongly deleted file * feat(cat-voices): proposal template models (#1363) * draft for setup segment * fix: delete unused files * feat: dtos for properties * feat:creating dtos for proposal schema * feat: creating toModels * feat: sort section/elements by xorder * feat: adding missing toModels for definitions * fix: delete unused property from element class * feat: creating generic_proposal.json * test: adding unit tests * feat: range class for easier representation for max min values * feat: adding proper from/to Json for proposal_builder class * feat: change name of the files to make it more generic -document- * feat: change name of the document property widget * feat: adding equatable for classes * chore: update chain follower * feat: sortingBy order * chore: revert merge conflicts --------- Co-authored-by: Dominik Toton * chore: code cleanup * feat(cat-voices): encode/decode cose documents (#1408) * feat: addd melos build_runner_repository to justfile * feat: update cose sign to support multiple different signatures and algs * feat: add document manager that handles signed documents (COSE_SIGN) * fix: kid should be encoded as Uint8List, not as string * style: typo * fix: collection equality * chore: review feedback * feat: add content type * chore: rename document to binary document, export document manager * chore: copyWith fix * fix: json content type * fix: put default alg in top-level headers if all signatures use the same alg * chore: refactor reference uuid to give it a more meaningful name * chore: get rid of equatable from SignedDocument interface * fix: do not put alg in top-level protected headers for COSE_SIGN * chore: update field name * feat: add document node for identifying properties * feat: add document that holds document builder values * chore: convert document node id to a class * chore: rename proposal builder to document builder * chore: rename DocumentParser to BinaryDocumentParser * chore: format * chore: cleanup code * chore: rename DocumentBuilder to Document * chore: rename DocumentManager to SignedDocumentManager * chore: code cleanup * chore: simplify document parsing * chore: cleanup json schema parsing * chore: rename DocumentElement to DocumentProperty * feat: editing property in document * feat: enqueue document changes and render it in a section placeholder * chore: todos * fix: add missing config after solving merge conflicts * chore: cleanup code, make fields optional * feat: make default value optional object * chore: extract properties parsing into converters, parse if-then-else condition * chore: remove equatable from dtos, extract code to separate files * chore: move sorting to model * chore: add default value * chore: add default value * Revert "chore: add default value" This reverts commit 019f6fff8d5c73f03fcfac06cfac70add207eff0. * chore: code cleanup * feat: logic for document checkbox builder widget state * fix: check spelling * chore: revert optional types * fix: cleanup unused files * fix: delete duplicated files * feat: adding final keyword to definition classes * feat: extracting only properties that widgets needs * fix: dart comment style * feat: type casting for value in DocumentPropertyDto * feat: adding select widget * feat: adding markdown support in doc schema and checkbox widget * feat: adding value parsing, and new language definition * feat: adding null check * Update catalyst_voices/packages/internal/catalyst_voices_repositories/lib/src/utils/json_converters.dart Co-authored-by: Dominik Toton <166132265+dtscalac@users.noreply.github.com> * feat: add type safety for document builder * fix: code cleanup for not necessary override methods * feat: edit and save mode on hole section not single property * feat: adding parsing data in DocuemntPropertyDto toJson * chore: making fields private * feat: creating MarkdownText and UrlLauncher * chore: validate that the property is cast by the correct definition * docs: adding todo for future error handling * fix: exposing selectable in MarkdownText * fix: making markdownText param as not named * fix: dependency fix in pubspec * chore: add validation for document properties * feat: add localized document validation result * chore: cleanup * fix: value change callback name change * feat: add validation to document property * chore: use correct key * feat: add validation to document section * style: formatting * chore: move definition file to the parent folder * feat: add validation to single_grouped_tag_selector_definition.dart * feat: parse grouped tags selection from/toJson * chore: fix typo * chore: document parsing tests * fix: document property casting for TokenValueCardanoAdaDefinition widget * chore: align code * chore: docs * chore: update naming * style: improve formatting for docs * fix: validation condition * feat: apply document validtion in document token value widget * feat: define translations for document validation errors * chore: code review changes * chore: split property validation to accept schema and value separately * chore: cache property validation result * chore: add isValid getter to Document section * chore: merge conflicts * fix: missing equatable property * feat: allow range min/max to be null * fix: document schema parsing * feat: translations * feat: translations for validation errors * feat: translations * chore: revert constructor property --------- Signed-off-by: bkioshn Co-authored-by: Ryszard Schossler <51096731+LynxLynxx@users.noreply.github.com> Co-authored-by: Damian Moliński <47773413+damian-molinski@users.noreply.github.com> Co-authored-by: Stefano Cunego <93382903+kukkok3@users.noreply.github.com> Co-authored-by: Steven Johnson Co-authored-by: bkioshn Co-authored-by: bkioshn <35752733+bkioshn@users.noreply.github.com> Co-authored-by: Apisit Ritreungroj Co-authored-by: Oleksandr Prokhorenko Co-authored-by: Apisit Ritruengroj <38898766+apskhem@users.noreply.github.com> Co-authored-by: Ryszard Schossler --- .../document_token_value_widget.dart | 46 +++++---- .../lib/widgets/text_field/token_field.dart | 11 ++- .../tiles/document_builder_section_tile.dart | 7 +- .../lib/l10n/intl_en.arb | 97 +++++++++++++++++++ .../lib/src/range/range.dart | 37 ++++--- .../localized_document_validation_result.dart | 77 +++++++++++---- 6 files changed, 220 insertions(+), 55 deletions(-) diff --git a/catalyst_voices/apps/voices/lib/widgets/document_builder/document_token_value_widget.dart b/catalyst_voices/apps/voices/lib/widgets/document_builder/document_token_value_widget.dart index 5992ab3ea1a..a3ede15e191 100644 --- a/catalyst_voices/apps/voices/lib/widgets/document_builder/document_token_value_widget.dart +++ b/catalyst_voices/apps/voices/lib/widgets/document_builder/document_token_value_widget.dart @@ -1,29 +1,22 @@ import 'package:catalyst_voices/common/ext/string_ext.dart'; import 'package:catalyst_voices/widgets/text_field/token_field.dart'; import 'package:catalyst_voices/widgets/text_field/voices_int_field.dart'; +import 'package:catalyst_voices/widgets/text_field/voices_text_field.dart'; import 'package:catalyst_voices_models/catalyst_voices_models.dart'; -import 'package:catalyst_voices_shared/catalyst_voices_shared.dart'; +import 'package:catalyst_voices_view_models/catalyst_voices_view_models.dart'; import 'package:flutter/material.dart'; class DocumentTokenValueWidget extends StatefulWidget { - final DocumentNodeId id; - final String label; - final int? value; + final DocumentProperty property; final Currency currency; - final Range? range; final bool isEditMode; - final bool isRequired; final ValueChanged onChanged; const DocumentTokenValueWidget({ super.key, - required this.id, - required this.label, - this.value, + required this.property, required this.currency, - this.range, this.isEditMode = false, - this.isRequired = true, required this.onChanged, }); @@ -41,7 +34,7 @@ class _DocumentTokenValueWidgetState extends State { void initState() { super.initState(); - _controller = VoicesIntFieldController(widget.value); + _controller = VoicesIntFieldController(widget.property.value); _controller.addListener(_handleControllerChange); _focusNode = FocusNode(canRequestFocus: widget.isEditMode); } @@ -50,8 +43,8 @@ class _DocumentTokenValueWidgetState extends State { void didUpdateWidget(covariant DocumentTokenValueWidget oldWidget) { super.didUpdateWidget(oldWidget); - if (widget.value != oldWidget.value) { - _controller.value = widget.value; + if (widget.property.value != oldWidget.property.value) { + _controller.value = widget.property.value; } if (widget.isEditMode != oldWidget.isEditMode) { @@ -68,12 +61,16 @@ class _DocumentTokenValueWidgetState extends State { @override Widget build(BuildContext context) { + final schema = widget.property.schema; + final label = schema.title ?? ''; + return TokenField( controller: _controller, focusNode: _focusNode, onFieldSubmitted: _notifyChangeListener, - labelText: widget.label.starred(isEnabled: widget.isRequired), - range: widget.range, + validator: _validate, + labelText: label.starred(isEnabled: schema.isRequired), + range: schema.numRange, currency: widget.currency, showHelper: widget.isEditMode, readOnly: !widget.isEditMode, @@ -97,7 +94,22 @@ class _DocumentTokenValueWidgetState extends State { } void _notifyChangeListener(int? value) { - final change = DocumentChange(nodeId: widget.id, value: value); + final change = DocumentChange( + nodeId: widget.property.schema.nodeId, + value: value, + ); + widget.onChanged(change); } + + VoicesTextFieldValidationResult _validate(int? value, String text) { + final schema = widget.property.schema; + final result = schema.validatePropertyValue(value); + if (result.isValid) { + return const VoicesTextFieldValidationResult.none(); + } else { + final localized = LocalizedDocumentValidationResult.from(result); + return VoicesTextFieldValidationResult.error(localized.message(context)); + } + } } diff --git a/catalyst_voices/apps/voices/lib/widgets/text_field/token_field.dart b/catalyst_voices/apps/voices/lib/widgets/text_field/token_field.dart index cf6ec0c14d9..d7bca6d1e0b 100644 --- a/catalyst_voices/apps/voices/lib/widgets/text_field/token_field.dart +++ b/catalyst_voices/apps/voices/lib/widgets/text_field/token_field.dart @@ -1,3 +1,4 @@ +import 'package:catalyst_voices/widgets/text_field/voices_num_field.dart'; import 'package:catalyst_voices/widgets/widgets.dart'; import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; import 'package:catalyst_voices_models/catalyst_voices_models.dart'; @@ -8,6 +9,7 @@ class TokenField extends StatelessWidget { final VoicesIntFieldController? controller; final ValueChanged? onFieldSubmitted; final ValueChanged? onStatusChanged; + final VoicesNumFieldValidator? validator; final String? labelText; final String? errorText; final FocusNode? focusNode; @@ -22,6 +24,7 @@ class TokenField extends StatelessWidget { this.controller, required this.onFieldSubmitted, this.onStatusChanged, + this.validator, this.labelText, this.errorText, this.focusNode, @@ -74,9 +77,9 @@ class TokenField extends StatelessWidget { return VoicesTextFieldValidationResult.error(message); } - if (value != null && !(range?.contains(value) ?? true)) { - // Do not append any text - return const VoicesTextFieldValidationResult.error(); + final validator = this.validator; + if (validator != null) { + return validator(value, text); } return const VoicesTextFieldValidationResult.none(); @@ -94,6 +97,8 @@ class _Helper extends StatelessWidget { @override Widget build(BuildContext context) { + // TODO(damian-molinski): Range can accept null as min/max + // meaning they are unconstrained, handle it // TODO(damian-molinski): Refactor text formatting with smarter syntax return Text.rich( TextSpan( diff --git a/catalyst_voices/apps/voices/lib/widgets/tiles/document_builder_section_tile.dart b/catalyst_voices/apps/voices/lib/widgets/tiles/document_builder_section_tile.dart index e343118e79d..c286367e95c 100644 --- a/catalyst_voices/apps/voices/lib/widgets/tiles/document_builder_section_tile.dart +++ b/catalyst_voices/apps/voices/lib/widgets/tiles/document_builder_section_tile.dart @@ -244,15 +244,10 @@ class _PropertyBuilder extends StatelessWidget { onChanged: onChanged, ); case TokenValueCardanoADADefinition(): - final castProperty = definition.castProperty(property); return DocumentTokenValueWidget( - id: castProperty.schema.nodeId, - label: castProperty.schema.title ?? '', - value: castProperty.value, + property: definition.castProperty(property), currency: const Currency.ada(), - range: castProperty.schema.numRange, isEditMode: isEditMode, - isRequired: castProperty.schema.isRequired, onChanged: onChanged, ); } diff --git a/catalyst_voices/packages/internal/catalyst_voices_localization/lib/l10n/intl_en.arb b/catalyst_voices/packages/internal/catalyst_voices_localization/lib/l10n/intl_en.arb index 356c26e6833..9f86a390a13 100644 --- a/catalyst_voices/packages/internal/catalyst_voices_localization/lib/l10n/intl_en.arb +++ b/catalyst_voices/packages/internal/catalyst_voices_localization/lib/l10n/intl_en.arb @@ -1186,6 +1186,103 @@ "description": "General text. May be used in context of A4000 and $5000" }, "errorValidationTokenNotParsed": "Invalid input. Could not parse parse.", + "@errorValidationTokenNotParsed": { + "description": "A validation error when user enters input which cannot be parsed into token value." + }, + "errorValidationMissingRequiredField": "Please fill this field.", + "@errorValidationMissingRequiredField": { + "description": "A validation error for a missing required form field." + }, + "errorValidationNumFieldBelowMin": "The value should be at least {min}.", + "@errorValidationNumFieldBelowMin": { + "description": "Validation error when the user entered numerical value is smaller than min", + "placeholders": { + "min": { + "type": "int" + } + } + }, + "errorValidationNumFieldAboveMax": "The value should be no bigger than {max}.", + "@errorValidationNumFieldAboveMax": { + "description": "Validation error when the user entered numerical value is bigger than max", + "placeholders": { + "max": { + "type": "int" + } + } + }, + "errorValidationNumFieldOutOfRange": "The value should be between {min} and {max}", + "@errorValidationNumFieldOutOfRange": { + "description": "Validation error when the numerical value is out of allowed range between min and max (both inclusive)", + "placeholders": { + "min": { + "type": "int" + }, + "max": { + "type": "int" + } + } + }, + "errorValidationStringLengthBelowMin": "The text should be at least {min} {min, plural, =0{characters} =1{character} other{characters}}.", + "@errorValidationStringLengthBelowMin": { + "description": "Validation error when the user entered text is shorter than min length", + "placeholders": { + "min": { + "type": "int" + } + } + }, + "errorValidationStringLengthAboveMax": "The text should be no longer than {max} {max, plural, =0{characters} =1{character} other{characters}}.", + "@errorValidationStringLengthAboveMax": { + "description": "Validation error when the user entered text is longer than max length", + "placeholders": { + "max": { + "type": "int" + } + } + }, + "errorValidationStringLengthOutOfRange": "The text should be between {min} and {max} {max, plural, =0{characters} =1{character} other{characters}}.", + "@errorValidationStringLengthOutOfRange": { + "description": "Validation error when the user entered text is out of allowed range between min and max (both inclusive) characters", + "placeholders": { + "min": { + "type": "int" + }, + "max": { + "type": "int" + } + } + }, + "errorValidationListItemsBelowMin": "There should be at least {min} {min, plural, =0{items} =1{item} other{items}}.", + "@errorValidationListItemsBelowMin": { + "description": "Validation error when the user entered less than min items in the list.", + "placeholders": { + "min": { + "type": "int" + } + } + }, + "errorValidationListItemsAboveMax": "There should be no more than {max} {max, plural, =0{items} =1{item} other{items}}.", + "@errorValidationListItemsAboveMax": { + "description": "Validation error when the user entered more than max items in the list.", + "placeholders": { + "max": { + "type": "int" + } + } + }, + "errorValidationListItemsOutOfRange": "There should be between {min} and {max} {max, plural, =0{items} =1{item} other{items}}.", + "@errorValidationListItemsOutOfRange": { + "description": "The number of items in a list/array is out of allowed range between min and max (both inclusive)", + "placeholders": { + "min": { + "type": "int" + }, + "max": { + "type": "int" + } + } + }, "noTagSelected": "No Tag Selected", "@noTagSelected": { "description": "For example in context of document builder" diff --git a/catalyst_voices/packages/internal/catalyst_voices_shared/lib/src/range/range.dart b/catalyst_voices/packages/internal/catalyst_voices_shared/lib/src/range/range.dart index 249b1e8d3de..2cd79a21509 100644 --- a/catalyst_voices/packages/internal/catalyst_voices_shared/lib/src/range/range.dart +++ b/catalyst_voices/packages/internal/catalyst_voices_shared/lib/src/range/range.dart @@ -1,30 +1,45 @@ import 'package:equatable/equatable.dart'; +/// A numerical range between [min] and [max]. +/// +/// Both [min] and [max] might be unconstrained, +/// this allows to create ranges like: +/// +/// - <-∞, ∞> // from minus infinity to infinity (practically all values). +/// - <0, ∞> // from zero to infinity (negative values are not accepted). +/// - <-∞, 0> // from minus infinity to zero (positive values are not accepted). class Range extends Equatable { /// The minimum range value (inclusive). - final T min; + /// + /// `null` means that the [min] is not constrained. + final T? min; /// The maximum range value (inclusive). - final T max; + /// + /// `null` means that the [max] is not constrained. + final T? max; - const Range({required this.min, required this.max}); + const Range({ + required this.min, + required this.max, + }); /// Creates an [int] [Range] which assumes if /// [min] or [max] are null then they are unconstrained. static Range? optionalIntRangeOf({int? min, int? max}) { - if (min != null && max != null) { - return Range(min: min, max: max); - } else if (max != null) { - return Range(min: 0, max: max); - } else if (min != null) { - return Range(min: min, max: double.maxFinite.toInt()); - } else { + if (min == null && max == null) { return null; } + + return Range(min: min, max: max); } /// Returns true if this range contains the [value], false otherwise. - bool contains(num value) => value >= min && value <= max; + bool contains(num value) { + final min = this.min ?? double.negativeInfinity; + final max = this.max ?? double.infinity; + return value >= min && value <= max; + } @override List get props => [min, max]; diff --git a/catalyst_voices/packages/internal/catalyst_voices_view_models/lib/src/document/validation/localized_document_validation_result.dart b/catalyst_voices/packages/internal/catalyst_voices_view_models/lib/src/document/validation/localized_document_validation_result.dart index 94c06bb9ad6..e7dd83da5f8 100644 --- a/catalyst_voices/packages/internal/catalyst_voices_view_models/lib/src/document/validation/localized_document_validation_result.dart +++ b/catalyst_voices/packages/internal/catalyst_voices_view_models/lib/src/document/validation/localized_document_validation_result.dart @@ -1,6 +1,6 @@ import 'package:catalyst_voices_localization/catalyst_voices_localization.dart'; -import 'package:catalyst_voices_localization/generated/catalyst_voices_localizations.dart'; import 'package:catalyst_voices_models/catalyst_voices_models.dart'; +import 'package:catalyst_voices_shared/catalyst_voices_shared.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; @@ -18,9 +18,12 @@ sealed class LocalizedDocumentValidationResult extends Equatable { const LocalizedSuccessfulDocumentValidation(), MissingRequiredDocumentValue() => const LocalizedMissingRequiredDocumentValue(), - DocumentNumOutOfRange() => const LocalizedDocumentNumOutOfRange(), - DocumentStringOutOfRange() => const LocalizedDocumentStringOutOfRange(), - DocumentItemsOutOfRange() => const LocalizedDocumentItemsOutOfRange(), + DocumentNumOutOfRange() => + LocalizedDocumentNumOutOfRange(range: result.expectedRange), + DocumentStringOutOfRange() => + LocalizedDocumentStringOutOfRange(range: result.expectedRange), + DocumentItemsOutOfRange() => + LocalizedDocumentItemsOutOfRange(range: result.expectedRange), }; } @@ -52,8 +55,7 @@ final class LocalizedMissingRequiredDocumentValue @override String? message(BuildContext context) { - // TODO(dtscalac): define the text - return 'LocalizedMissingRequiredDocumentValue'; + return context.l10n.errorValidationMissingRequiredField; } @override @@ -62,42 +64,81 @@ final class LocalizedMissingRequiredDocumentValue final class LocalizedDocumentNumOutOfRange extends LocalizedDocumentValidationResult { - const LocalizedDocumentNumOutOfRange(); + final Range range; + + const LocalizedDocumentNumOutOfRange({required this.range}); @override String? message(BuildContext context) { - // TODO(dtscalac): define the text - return 'LocalizedDocumentNumOutOfRange'; + final min = range.min; + final max = range.max; + + if (min != null && max != null) { + return context.l10n.errorValidationNumFieldOutOfRange(min, max); + } else if (min != null) { + return context.l10n.errorValidationNumFieldBelowMin(min); + } else if (max != null) { + return context.l10n.errorValidationNumFieldAboveMax(max); + } else { + // the range is unconstrained, so any value is allowed + return null; + } } @override - List get props => []; + List get props => [range]; } final class LocalizedDocumentStringOutOfRange extends LocalizedDocumentValidationResult { - const LocalizedDocumentStringOutOfRange(); + final Range range; + + const LocalizedDocumentStringOutOfRange({required this.range}); @override String? message(BuildContext context) { - // TODO(dtscalac): define the text - return 'LocalizedDocumentStringOutOfRange'; + final min = range.min; + final max = range.max; + + if (min != null && max != null) { + return context.l10n.errorValidationStringLengthOutOfRange(min, max); + } else if (min != null) { + return context.l10n.errorValidationStringLengthBelowMin(min); + } else if (max != null) { + return context.l10n.errorValidationStringLengthAboveMax(max); + } else { + // the range is unconstrained, so any value is allowed + return null; + } } @override - List get props => []; + List get props => [range]; } final class LocalizedDocumentItemsOutOfRange extends LocalizedDocumentValidationResult { - const LocalizedDocumentItemsOutOfRange(); + final Range range; + + const LocalizedDocumentItemsOutOfRange({required this.range}); @override String? message(BuildContext context) { - // TODO(dtscalac): define the text - return 'LocalizedDocumentItemsOutOfRange'; + final min = range.min; + final max = range.max; + + if (min != null && max != null) { + return context.l10n.errorValidationListItemsOutOfRange(min, max); + } else if (min != null) { + return context.l10n.errorValidationListItemsBelowMin(min); + } else if (max != null) { + return context.l10n.errorValidationListItemsAboveMax(max); + } else { + // the range is unconstrained, so any value is allowed + return null; + } } @override - List get props => []; + List get props => [range]; }