From f55785ce1357b803581ffa357789df71215ce517 Mon Sep 17 00:00:00 2001 From: Grace Nakiyemba Date: Wed, 7 Oct 2026 12:07:23 +0300 Subject: [PATCH 01/28] fix(desktop): improve small-screen navigation layout --- desktop/src/App.css | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/desktop/src/App.css b/desktop/src/App.css index 219c43c23..a319d881f 100644 --- a/desktop/src/App.css +++ b/desktop/src/App.css @@ -3094,14 +3094,59 @@ input:not([type]) { grid-template-rows: auto minmax(0, 1fr); } + /* Keep navigation compact on smaller desktop windows so page content remains usable. */ .sidebar { position: sticky; top: 0; z-index: 4; + display: grid; + grid-template-columns: minmax(0, 1fr) auto auto; + grid-template-areas: + 'brand mode status' + 'nav nav nav'; + align-items: center; + gap: 0.65rem 1rem; + padding: 0.75rem 1rem; border-right: 0; border-bottom: 1px solid #2d3449; } + .brand { + grid-area: brand; + min-width: 0; + } + + .brand p { + display: none; + } + + .mode-switch { + grid-area: mode; + } + + .nav { + grid-area: nav; + flex-direction: row; + gap: 0.35rem; + overflow-x: auto; + overscroll-behavior-inline: contain; + padding-bottom: 0.15rem; + } + + .nav-link { + flex: 0 0 auto; + white-space: nowrap; + } + + .sidebar-footer { + grid-area: status; + margin-top: 0; + } + + .sidebar-footer > span { + display: none; + } + .cards { grid-template-columns: 1fr; } From 1daccc2122a5af5960cfb7b0cbcf335c6781baac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:04 +0300 Subject: [PATCH 02/28] chore(deps): update gradle to v8.14.5 (#964) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- formulus/android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/formulus/android/gradle/wrapper/gradle-wrapper.properties b/formulus/android/gradle/wrapper/gradle-wrapper.properties index 36e4933e1..a4cf193f6 100644 --- a/formulus/android/gradle/wrapper/gradle-wrapper.properties +++ b/formulus/android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=20f1b1176237254a6fc204d8434196fa11a4cfb387567519c61556e8710aed78 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip +distributionSha256Sum=6f74b601422d6d6fc4e1f9a1ab6522f642c2fdcbc15ae33ebd30ba3d7198e854 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.5-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 2bc3040b9ba0b04767b93edf0cd1165be835eb0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:09 +0300 Subject: [PATCH 03/28] fix(deps): update dependency androidx.appcompat:appcompat to v1.8.0 (#965) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- formulus/android/app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/formulus/android/app/build.gradle b/formulus/android/app/build.gradle index dbff82cdd..a497deac0 100644 --- a/formulus/android/app/build.gradle +++ b/formulus/android/app/build.gradle @@ -198,7 +198,7 @@ dependencies { // Explicitly include AndroidX dependencies to avoid conflicts implementation 'androidx.core:core:1.9.0' - implementation 'androidx.appcompat:appcompat:1.7.1' + implementation 'androidx.appcompat:appcompat:1.8.0' // Fix for react-native-push-notification duplicate class conflicts configurations.all { @@ -206,7 +206,7 @@ dependencies { exclude group: 'androidx.legacy', module: 'legacy-support-v4' resolutionStrategy { force 'androidx.core:core:1.9.0' - force 'androidx.appcompat:appcompat:1.7.1' + force 'androidx.appcompat:appcompat:1.8.0' } } } From 2f5c3902f12c4e9e591797f88f7551ecb3d262a9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:14 +0300 Subject: [PATCH 04/28] chore(deps): update alpine docker tag to v3.24 (#961) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- Dockerfile.cli.slim | 2 +- Dockerfile.slim | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 02b64dce7..9d003478e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,7 +61,7 @@ RUN echo "Building Synkronus with version: ${SYNKRONUS_VERSION}" && \ go build -a -ldflags="-w -s -X github.com/opendataensemble/synkronus/pkg/version.version=${SYNKRONUS_VERSION}" -o synkronus ./cmd/synkronus # Stage 3: Minimal runtime image — single Go server (API + portal) -FROM alpine:3.23 +FROM alpine:3.24 RUN apk --no-cache add ca-certificates tzdata wget diff --git a/Dockerfile.cli.slim b/Dockerfile.cli.slim index 48a1c0fa1..93bfd28dc 100644 --- a/Dockerfile.cli.slim +++ b/Dockerfile.cli.slim @@ -1,7 +1,7 @@ # CI/runtime-only image: expects a pre-built synk binary in the build context. # Build context layout: ./synk (static binary) -FROM alpine:3.23 +FROM alpine:3.24 RUN apk --no-cache add ca-certificates diff --git a/Dockerfile.slim b/Dockerfile.slim index 781427a45..ee6d18490 100644 --- a/Dockerfile.slim +++ b/Dockerfile.slim @@ -2,7 +2,7 @@ # Build context layout: ./synkronus (binary), ./openapi/, ./static/ # Portal assets are embedded in the binary at compile time. -FROM alpine:3.23 +FROM alpine:3.24 RUN apk --no-cache add ca-certificates tzdata wget From 77976dc2c2dcc143bd75df0e28e1e303cc6f763f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:19 +0300 Subject: [PATCH 05/28] chore(deps): update golang docker tag to v1.27.1 (#963) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Dockerfile | 2 +- synkronus/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9d003478e..4374915a5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,7 +42,7 @@ WORKDIR /app/synkronus-portal RUN pnpm run build # Stage 2: Build the Go application (Synkronus) with embedded portal -FROM golang:1.26.0-alpine AS synkronus-builder +FROM golang:1.27.1-alpine AS synkronus-builder RUN apk add --no-cache git diff --git a/synkronus/Dockerfile b/synkronus/Dockerfile index dcddf3115..a4d228465 100644 --- a/synkronus/Dockerfile +++ b/synkronus/Dockerfile @@ -1,7 +1,7 @@ # Multi-stage build for Synkronus # Stage 1: Build the Go application # Pure Go build (PostgreSQL only, SQLite/CGO disabled by default) -FROM golang:1.26.0-alpine AS builder +FROM golang:1.27.1-alpine AS builder # Install build dependencies (no C toolchain needed for pure Go build) RUN apk add --no-cache git From 290b90f7a3d566df89d948d729ef49537731a36b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:24 +0300 Subject: [PATCH 06/28] chore(deps): update actions/attest-build-provenance action to v4 (#967) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/synkronus-cli-docker.yml | 2 +- .github/workflows/synkronus-docker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 0a5b3ff21..1560e3530 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -289,7 +289,7 @@ jobs: echo "digest=${DIGEST}" >> "${GITHUB_OUTPUT}" - name: Generate artifact attestation - uses: actions/attest-build-provenance@v1 + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.manifest-digest.outputs.digest }} diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index 5681fe50e..c1ffefc0b 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -337,7 +337,7 @@ jobs: echo "digest=${DIGEST}" >> "${GITHUB_OUTPUT}" - name: Generate artifact attestation - uses: actions/attest-build-provenance@ef244123eb79f2f7a7e75d99086184180e6d0018 # v1 + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4 with: subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} subject-digest: ${{ steps.manifest-digest.outputs.digest }} From 054971bfc03a9b804084cc6364dc66fda7779437 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:29 +0300 Subject: [PATCH 07/28] chore(deps): update actions/cache action to v6 (#968) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/formulus-android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/formulus-android.yml b/.github/workflows/formulus-android.yml index 821f317c8..24402639e 100644 --- a/.github/workflows/formulus-android.yml +++ b/.github/workflows/formulus-android.yml @@ -126,7 +126,7 @@ jobs: # vendor-notifee-core.mjs is a no-op when third_party/notifee is already at the pinned commit. - name: Cache vendored Notifee - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: path: formulus/third_party/notifee key: notifee-${{ hashFiles('formulus/scripts/vendor-notifee-core.mjs') }} From a1e427d50ae36106751d996a5165d50e666d554e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:08:39 +0300 Subject: [PATCH 08/28] chore(deps): update actions/labeler action to v7 (#970) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/auto-label.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/auto-label.yml b/.github/workflows/auto-label.yml index f8a782270..fefaa6850 100644 --- a/.github/workflows/auto-label.yml +++ b/.github/workflows/auto-label.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Label PR based on changed files - uses: actions/labeler@8558fd74291d67161a8a78ce36a881fa63b766a9 # v5 + uses: actions/labeler@bf12e9b00b37c5c0ca2b87b79b2daf7891dbda13 # v7 with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/labeler.yml From ed1389b263d6f80d37a56557dcc1fb5339378755 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:09:00 +0300 Subject: [PATCH 09/28] chore(deps): update dorny/paths-filter action to v4 (#979) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5678bd034..cd6d95d4a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: fetch-depth: 0 - name: Detect changed components - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2 + uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4 id: filter with: filters: | From 74771b8457422bb20f753044b7509c3c1e2787c7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:11:34 +0300 Subject: [PATCH 10/28] chore(deps): update softprops/action-gh-release action to v3 (#989) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/formulus-android.yml | 2 +- .github/workflows/ode-desktop.yml | 2 +- .github/workflows/sbom-release.yml | 2 +- .github/workflows/synkronus-cli.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/formulus-android.yml b/.github/workflows/formulus-android.yml index 24402639e..1daad28f4 100644 --- a/.github/workflows/formulus-android.yml +++ b/.github/workflows/formulus-android.yml @@ -243,7 +243,7 @@ jobs: - name: Upload universal APK + AAB to GitHub Release if: github.event_name == 'release' - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3 with: files: | formulus/android/app/build/outputs/apk/**/**/*-universal-*.apk diff --git a/.github/workflows/ode-desktop.yml b/.github/workflows/ode-desktop.yml index 74546b842..a74f5b04a 100644 --- a/.github/workflows/ode-desktop.yml +++ b/.github/workflows/ode-desktop.yml @@ -459,7 +459,7 @@ jobs: fi - name: Attach installers to Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3 with: tag_name: ${{ github.event.release.tag_name }} files: desktop/dist-release/* diff --git a/.github/workflows/sbom-release.yml b/.github/workflows/sbom-release.yml index f1619eaf2..fab719622 100644 --- a/.github/workflows/sbom-release.yml +++ b/.github/workflows/sbom-release.yml @@ -71,7 +71,7 @@ jobs: - name: Upload SBOMs to GitHub Release if: github.event_name == 'release' - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3 with: tag_name: ${{ github.event.release.tag_name }} files: sbom-dist/*.cdx.json diff --git a/.github/workflows/synkronus-cli.yml b/.github/workflows/synkronus-cli.yml index 5ba04fb87..cab62c3f8 100644 --- a/.github/workflows/synkronus-cli.yml +++ b/.github/workflows/synkronus-cli.yml @@ -103,7 +103,7 @@ jobs: ls -R dist - name: Upload assets to GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3 with: files: | synkronus-cli/dist/synkronus-cli-* From 34de318f104954de38a77767d6f7bed5ec506adf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:12:23 +0300 Subject: [PATCH 11/28] chore(deps): update redhat-actions/push-to-registry action to v3 (#988) --- .github/workflows/synkronus-cli-docker.yml | 4 ++-- .github/workflows/synkronus-docker.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 1560e3530..5da8ea4f4 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -135,7 +135,7 @@ jobs: - name: Push image to registry id: push if: github.event_name != 'pull_request' - uses: redhat-actions/push-to-registry@v2 + uses: redhat-actions/push-to-registry@94ade333c38ecc0e60e94785125d9a52ca423b37 # v3 with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} @@ -199,7 +199,7 @@ jobs: - name: Push image to registry id: push if: github.event_name != 'pull_request' - uses: redhat-actions/push-to-registry@v2 + uses: redhat-actions/push-to-registry@94ade333c38ecc0e60e94785125d9a52ca423b37 # v3 with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index c1ffefc0b..1363e9422 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -181,7 +181,7 @@ jobs: - name: Push image to registry id: push if: github.event_name != 'pull_request' - uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2 + uses: redhat-actions/push-to-registry@94ade333c38ecc0e60e94785125d9a52ca423b37 # v3 with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} @@ -247,7 +247,7 @@ jobs: - name: Push image to registry id: push if: github.event_name != 'pull_request' - uses: redhat-actions/push-to-registry@5ed88d269cf581ea9ef6dd6806d01562096bee9c # v2 + uses: redhat-actions/push-to-registry@94ade333c38ecc0e60e94785125d9a52ca423b37 # v3 with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} From 3524f94491225c49d545837e46019b151253d205 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:12:49 +0300 Subject: [PATCH 12/28] chore(deps): update redhat-actions/podman-login action to v2 (#987) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/synkronus-cli-docker.yml | 4 ++-- .github/workflows/synkronus-docker.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 5da8ea4f4..4973d9100 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -105,7 +105,7 @@ jobs: - name: Log in to Github Container Registry if: github.event_name != 'pull_request' - uses: redhat-actions/podman-login@v1 + uses: redhat-actions/podman-login@50c2d9a331bb67c8fdab99b86455fad05e2e3252 # v2 with: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} @@ -169,7 +169,7 @@ jobs: - name: Log in to Github Container Registry if: github.event_name != 'pull_request' - uses: redhat-actions/podman-login@v1 + uses: redhat-actions/podman-login@50c2d9a331bb67c8fdab99b86455fad05e2e3252 # v2 with: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index 1363e9422..458c48b89 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -151,7 +151,7 @@ jobs: - name: Log in to Github Container Registry if: github.event_name != 'pull_request' - uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1 + uses: redhat-actions/podman-login@50c2d9a331bb67c8fdab99b86455fad05e2e3252 # v2 with: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} @@ -217,7 +217,7 @@ jobs: - name: Log in to Github Container Registry if: github.event_name != 'pull_request' - uses: redhat-actions/podman-login@4934294ad0449894bcd1e9f191899d7292469603 # v1 + uses: redhat-actions/podman-login@50c2d9a331bb67c8fdab99b86455fad05e2e3252 # v2 with: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} From 7641fa444a4d94f5ff701301665f02fe4eb1edae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:13:07 +0300 Subject: [PATCH 13/28] chore(deps): update redhat-actions/buildah-build action to v3 (#986) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/synkronus-cli-docker.yml | 4 ++-- .github/workflows/synkronus-docker.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 4973d9100..277afc599 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -122,7 +122,7 @@ jobs: - name: Build image with Buildah id: build-image - uses: redhat-actions/buildah-build@v2 + uses: redhat-actions/buildah-build@719e3c40d8af9790c23eca13f7daa339f2867034 # v3 with: image: ${{ env.IMAGE_NAME }} tags: ${{ steps.meta.outputs.tag-names }} @@ -186,7 +186,7 @@ jobs: - name: Build image with Buildah id: build-image - uses: redhat-actions/buildah-build@v2 + uses: redhat-actions/buildah-build@719e3c40d8af9790c23eca13f7daa339f2867034 # v3 with: image: ${{ env.IMAGE_NAME }} tags: ${{ steps.meta.outputs.tag-names }} diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index 458c48b89..1ff414401 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -168,7 +168,7 @@ jobs: - name: Build image with Buildah id: build-image - uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2 + uses: redhat-actions/buildah-build@719e3c40d8af9790c23eca13f7daa339f2867034 # v3 with: image: ${{ env.IMAGE_NAME }} tags: ${{ steps.meta.outputs.tag-names }} @@ -234,7 +234,7 @@ jobs: - name: Build image with Buildah id: build-image - uses: redhat-actions/buildah-build@7a95fa7ee0f02d552a32753e7414641a04307056 # v2 + uses: redhat-actions/buildah-build@719e3c40d8af9790c23eca13f7daa339f2867034 # v3 with: image: ${{ env.IMAGE_NAME }} tags: ${{ steps.meta.outputs.tag-names }} From d2083f1a3db23fef9c9e6dfa153d66853adacbaa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:13:23 +0300 Subject: [PATCH 14/28] chore(deps): update pnpm/action-setup action to v6 (#985) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/docs.yml | 4 ++-- .github/workflows/e2e-attachments.yml | 2 +- .github/workflows/formulus-android.yml | 4 ++-- .github/workflows/ode-desktop.yml | 8 ++++---- .github/workflows/sbom-release.yml | 2 +- .github/workflows/synkronus-docker.yml | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd6d95d4a..b96e4615b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -71,7 +71,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 @@ -114,7 +114,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 64ebf94e0..717aa9f45 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -38,7 +38,7 @@ jobs: fetch-depth: 0 - name: Set up pnpm - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 @@ -84,7 +84,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Set up pnpm - uses: pnpm/action-setup@f40ffcd9367d9f12939873eb1018b921a783ffaa # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 diff --git a/.github/workflows/e2e-attachments.yml b/.github/workflows/e2e-attachments.yml index b01441b09..12fae07f6 100644 --- a/.github/workflows/e2e-attachments.yml +++ b/.github/workflows/e2e-attachments.yml @@ -76,7 +76,7 @@ jobs: - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 diff --git a/.github/workflows/formulus-android.yml b/.github/workflows/formulus-android.yml index 1daad28f4..91d3a64d9 100644 --- a/.github/workflows/formulus-android.yml +++ b/.github/workflows/formulus-android.yml @@ -44,7 +44,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Setup pnpm - uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 with: version: 11.22.0 @@ -95,7 +95,7 @@ jobs: path: formulus/android/app/src/main/assets/formplayer_dist - name: Setup pnpm - uses: pnpm/action-setup@7088e561eb65bb68695d245aa206f005ef30921d # v4.1 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 with: version: 11.22.0 diff --git a/.github/workflows/ode-desktop.yml b/.github/workflows/ode-desktop.yml index a74f5b04a..a0b0154c7 100644 --- a/.github/workflows/ode-desktop.yml +++ b/.github/workflows/ode-desktop.yml @@ -48,7 +48,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 @@ -120,7 +120,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 @@ -189,7 +189,7 @@ jobs: path: desktop/public/formplayer_dist - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 @@ -350,7 +350,7 @@ jobs: path: desktop/public/formplayer_dist - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 diff --git a/.github/workflows/sbom-release.yml b/.github/workflows/sbom-release.yml index fab719622..92da1ef50 100644 --- a/.github/workflows/sbom-release.yml +++ b/.github/workflows/sbom-release.yml @@ -27,7 +27,7 @@ jobs: - name: Setup pnpm # scripts/sbom/generate-sboms.mjs shells out to `pnpm list`; needs pnpm on PATH. - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index 1ff414401..0578ffb53 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -69,7 +69,7 @@ jobs: cache-dependency-path: synkronus/go.sum - name: Setup pnpm - uses: pnpm/action-setup@b906affcce14559ad1aafd4ab0e942779e9f58b1 # v4 + uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6 with: version: 11.22.0 From 11cb582156b21eda9a4880ba6edbc39fd6c605a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:13:39 +0300 Subject: [PATCH 15/28] chore(deps): update gradle/actions action to v6 (#982) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/formulus-android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/formulus-android.yml b/.github/workflows/formulus-android.yml index 91d3a64d9..a706d1802 100644 --- a/.github/workflows/formulus-android.yml +++ b/.github/workflows/formulus-android.yml @@ -153,7 +153,7 @@ jobs: # Gradle dependency/wrapper caching is handled by gradle/actions/setup-gradle below. - name: Setup Gradle - uses: gradle/actions/setup-gradle@017a9effdb900e5b5b2fddfb590a105619dca3c3 # v4.4.2 + uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 with: # Persist the Gradle build cache across CI runs (wrapper + deps + task outputs). # Leave the daemon on so assembleRelease + bundleRelease share one JVM. From 710371904c992715a831c5b9bc216077a18f8b4b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:13:53 +0300 Subject: [PATCH 16/28] chore(deps): update github artifact actions (#981) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/formulus-android.yml | 8 ++++---- .github/workflows/ode-desktop.yml | 4 ++-- .github/workflows/sbom-release.yml | 2 +- .github/workflows/synkronus-cli-docker.yml | 6 +++--- .github/workflows/synkronus-docker.yml | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/formulus-android.yml b/.github/workflows/formulus-android.yml index a706d1802..52220c511 100644 --- a/.github/workflows/formulus-android.yml +++ b/.github/workflows/formulus-android.yml @@ -70,7 +70,7 @@ jobs: run: pnpm run build:copy - name: Upload formplayer assets artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: formplayer-assets path: formulus/android/app/src/main/assets/formplayer_dist @@ -89,7 +89,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 - name: Download formplayer assets artifact - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: formplayer-assets path: formulus/android/app/src/main/assets/formplayer_dist @@ -227,7 +227,7 @@ jobs: -PreactNativeArchitectures=${{ env.FORMULUS_ABIS_RELEASE }} - name: Upload APK artifact - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: formulus-android-apk-${{ github.event_name }}-${{ github.run_id }} path: | @@ -235,7 +235,7 @@ jobs: - name: Upload AAB artifact if: github.event_name != 'pull_request' - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: formulus-android-aab-${{ github.event_name }}-${{ github.run_id }} path: | diff --git a/.github/workflows/ode-desktop.yml b/.github/workflows/ode-desktop.yml index a0b0154c7..9620a542e 100644 --- a/.github/workflows/ode-desktop.yml +++ b/.github/workflows/ode-desktop.yml @@ -183,7 +183,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Download embedded formplayer - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: desktop-formplayer-dist path: desktop/public/formplayer_dist @@ -344,7 +344,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Download embedded formplayer - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: desktop-formplayer-dist path: desktop/public/formplayer_dist diff --git a/.github/workflows/sbom-release.yml b/.github/workflows/sbom-release.yml index 92da1ef50..3208400c7 100644 --- a/.github/workflows/sbom-release.yml +++ b/.github/workflows/sbom-release.yml @@ -63,7 +63,7 @@ jobs: - name: Upload SBOM artifact (manual runs) if: github.event_name == 'workflow_dispatch' - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: cyclonedx-sbom path: sbom-dist/*.cdx.json diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 277afc599..452589ce0 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -71,7 +71,7 @@ jobs: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="${LD_FLAGS}" -o "${ROOT}/docker-dist/synk-linux-arm64" ./cmd/synkronus - name: Upload docker build context artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: synkronus-cli-docker-dist path: docker-dist/ @@ -91,7 +91,7 @@ jobs: uses: actions/checkout@v4 - name: Download docker build context - uses: actions/download-artifact@v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: synkronus-cli-docker-dist path: docker-dist/ @@ -155,7 +155,7 @@ jobs: uses: actions/checkout@v4 - name: Download docker build context - uses: actions/download-artifact@v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: synkronus-cli-docker-dist path: docker-dist/ diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index 0578ffb53..e5873f1d7 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -115,7 +115,7 @@ jobs: cp -a static "${ROOT}/docker-dist/" - name: Upload docker build context artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: synkronus-docker-dist path: docker-dist/ @@ -135,7 +135,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Download docker build context - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: synkronus-docker-dist path: docker-dist/ @@ -201,7 +201,7 @@ jobs: uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - name: Download docker build context - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: synkronus-docker-dist path: docker-dist/ From f95d11b4cd84f330eb961937f62c37cdf3ad320a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 9 Oct 2026 20:14:17 +0300 Subject: [PATCH 17/28] chore(deps): update docker/login-action action to v4 (#978) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/synkronus-cli-docker.yml | 2 +- .github/workflows/synkronus-docker.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/synkronus-cli-docker.yml b/.github/workflows/synkronus-cli-docker.yml index 452589ce0..9326eb829 100644 --- a/.github/workflows/synkronus-cli-docker.yml +++ b/.github/workflows/synkronus-cli-docker.yml @@ -217,7 +217,7 @@ jobs: attestations: write steps: - name: Log in to Github Container Registry (docker) - uses: docker/login-action@v3 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} diff --git a/.github/workflows/synkronus-docker.yml b/.github/workflows/synkronus-docker.yml index e5873f1d7..8226b965b 100644 --- a/.github/workflows/synkronus-docker.yml +++ b/.github/workflows/synkronus-docker.yml @@ -265,7 +265,7 @@ jobs: attestations: write steps: - name: Log in to Github Container Registry (docker) - uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} From 4a721d339024a41a6c6926e07b8f7a313c00640d Mon Sep 17 00:00:00 2001 From: "Lemeri G. Festus" Date: Fri, 9 Oct 2026 20:15:09 +0300 Subject: [PATCH 18/28] feat(i18n): Added swahili translations (#948) * added swahili translations * Resolve format issues * fix: add missing translations for all locales including Swahili - Add signature.* keys (title, hint, clear, save) - Add welcome.* keys (title, profilesSubtitle, getStarted) - Add settings.theme.* keys (system, light, dark) - Ensure all locale files (en, pt, fr, sw) have matching keys - Fixes CI test failure in locale.test.ts * style: format uiLocale.ts * fix(i18n): complete formplayer locale keys --------- Co-authored-by: Emil Rossing Co-authored-by: Najuna Brian <160729266+najuna-brian@users.noreply.github.com> --- AGENTS.md | 2 +- FORM_LOCALIZATION_GUIDE.md | 6 +- desktop/src/lib/uiLocale.ts | 8 +- desktop/src/pages/FormPreviewPage.tsx | 1 + formulus-formplayer/AGENTS.md | 8 +- formulus-formplayer/README.md | 2 +- formulus-formplayer/src/i18n/createOdeI18n.ts | 2 + .../src/i18n/localeUtils.test.ts | 23 ++ formulus-formplayer/src/i18n/localeUtils.ts | 2 +- formulus-formplayer/src/locales/en.json | 1 + formulus-formplayer/src/locales/fr.json | 1 + formulus-formplayer/src/locales/pt.json | 1 + formulus-formplayer/src/locales/sw.json | 117 +++++++ formulus/AGENTS.md | 2 +- .../main/assets/webview/placeholder_app.html | 1 + .../src/components/common/LocalePicker.tsx | 1 + formulus/src/i18n/bootstrap.ts | 2 + formulus/src/lib/locale.test.ts | 33 ++ formulus/src/lib/locale.ts | 5 +- formulus/src/locales/en.json | 1 + formulus/src/locales/fr.json | 1 + formulus/src/locales/pt.json | 1 + formulus/src/locales/sw.json | 318 ++++++++++++++++++ .../src/services/LocaleSettingsService.ts | 8 +- formulus/src/types/AppConfig.ts | 2 +- 25 files changed, 524 insertions(+), 25 deletions(-) create mode 100644 formulus-formplayer/src/i18n/localeUtils.test.ts create mode 100644 formulus-formplayer/src/locales/sw.json create mode 100644 formulus/src/locales/sw.json diff --git a/AGENTS.md b/AGENTS.md index 546d3fbb4..f153bc9d1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -137,7 +137,7 @@ git push origin v1.1.1-alpha.3 - **Custom app bridge (v1.1.0+):** `persistObservation` (headless write), `sync`, `getConnectivityStatus`, `getCurrentDataRevisionCount`, and `openFormplayer` options `skipFinalize` / `skipDraftSelection` — contract in [`FormulusInterfaceDefinition.ts`](formulus/src/webview/FormulusInterfaceDefinition.ts); run `pnpm run sync-interface` in formplayer after changes. - **Sub-observations:** Each nested Formplayer session validates its own schema; `skipFinalize` only skips the Finalize page. Custom validators are per-session — see [Custom Extensions — nested sessions](https://opendataensemble.org/docs/guides/custom-extensions#nested-sessions-and-custom-validators) (docs site). - **Shared UI tokens:** Install **tokens** before **components** / **formplayer** where the docs require it (see package READMEs and formplayer AGENTS). -- **i18n (two layers):** ODE-owned locales (`en`/`pt`/`fr`) for Formulus + Formplayer chrome via Settings → Language; form-owned copy via optional `translations` on `ui.json` elements (preprocessed at form init). See [FORM_LOCALIZATION_GUIDE.md](FORM_LOCALIZATION_GUIDE.md) (monorepo) and [form translations guide](https://opendataensemble.org/docs/guides/form-translations) (published). +- **i18n (two layers):** ODE-owned locales (`en`/`pt`/`fr`/`sw`) for Formulus + Formplayer chrome via Settings → Language; form-owned copy via optional `translations` on `ui.json` elements (preprocessed at form init). See [FORM_LOCALIZATION_GUIDE.md](FORM_LOCALIZATION_GUIDE.md) (monorepo) and [form translations guide](https://opendataensemble.org/docs/guides/form-translations) (published). --- diff --git a/FORM_LOCALIZATION_GUIDE.md b/FORM_LOCALIZATION_GUIDE.md index bbd7f9921..d0dd62042 100644 --- a/FORM_LOCALIZATION_GUIDE.md +++ b/FORM_LOCALIZATION_GUIDE.md @@ -12,7 +12,7 @@ How **user-defined forms** (JSON Schema + `ui.json` in custom app bundles) suppo | Layer | Who owns it | Where strings live | When it applies | |-------|-------------|-------------------|-----------------| -| **ODE chrome** | ODE platform | `formulus-formplayer/src/locales/{en,pt,fr}.json`, Formulus i18n catalogs | Next/Back, validation errors, sub-obs “+ Add …” template, loading text | +| **ODE chrome** | ODE platform | `formulus-formplayer/src/locales/{en,pt,fr,sw}.json`, Formulus i18n catalogs | Next/Back, validation errors, sub-obs “+ Add …” template, loading text | | **Form copy** | Form / app author | `ui.json` base fields + optional `translations` blocks | Field labels, descriptions, SwipeLayout headers, custom widget copy | Form authors **do not** edit ODE locale JSON. They embed translations in each form’s `ui.json`. ODE developers extend chrome strings when adding new platform UI. @@ -21,7 +21,7 @@ Form authors **do not** edit ODE locale JSON. They embed translations in each fo ## How form locale is chosen -1. User setting in Formulus **Settings → Language** (`auto`, `en`, `pt`, `fr`) +1. User setting in Formulus **Settings → Language** (`auto`, `en`, `pt`, `fr`, `sw`) 2. **Auto** → device language; if unsupported, bundle `defaultLocale` from `app.config.json` 3. Fallback `en` @@ -240,7 +240,7 @@ When changing merge rules or label resolution, update **`applyFormUiTranslations ## Author checklist - [ ] Every visible field has `Control.label` in `ui.json` (not only `schema.title`) -- [ ] Base `label` set; `translations` added for other ODE UI locales you ship (`en`, `pt`, `fr`) +- [ ] Base `label` set; `translations` added for other ODE UI locales you ship (`en`, `pt`, `fr`, `sw`) - [ ] SwipeLayout headers/buttons translated where needed - [ ] Sub-obs columns use `key` only; labels live on linked child forms - [ ] Custom question type strings in `options`, not in renderer JS diff --git a/desktop/src/lib/uiLocale.ts b/desktop/src/lib/uiLocale.ts index 6cf31b636..08b2704a7 100644 --- a/desktop/src/lib/uiLocale.ts +++ b/desktop/src/lib/uiLocale.ts @@ -1,7 +1,7 @@ /** Desktop UI locale — mirrors Formulus Settings key and resolution rules. */ const STORAGE_KEY = '@ode/uiLocale'; -const ODE_UI_LOCALES = ['en', 'pt', 'fr'] as const; +const ODE_UI_LOCALES = ['en', 'pt', 'fr', 'sw'] as const; export type DesktopUiLocale = (typeof ODE_UI_LOCALES)[number]; export type UiLocalePreference = 'auto' | DesktopUiLocale; @@ -32,11 +32,9 @@ export function getDesktopLocalePreference(): UiLocalePreference { const stored = localStorage.getItem(STORAGE_KEY); if ( stored === 'auto' || - stored === 'en' || - stored === 'pt' || - stored === 'fr' + (stored != null && (ODE_UI_LOCALES as readonly string[]).includes(stored)) ) { - return stored; + return stored as UiLocalePreference; } } catch { // ignore diff --git a/desktop/src/pages/FormPreviewPage.tsx b/desktop/src/pages/FormPreviewPage.tsx index df2cbca02..fcf24fdcf 100644 --- a/desktop/src/pages/FormPreviewPage.tsx +++ b/desktop/src/pages/FormPreviewPage.tsx @@ -735,6 +735,7 @@ export function FormPreviewPage() { + +
+
+
+
+
+ +

Your ODE journey

+
How have you taken part in ODE so far?

Select all that apply.

+
+ + + + + + + + + + + + + +
+

Links to pull requests, issues, posts or events are welcome.

+ +

Council

+
Which council are you applying to? (required) +
+ + + + +
+

What interests you about this area, and why do you want a more active role?

+
+
+
+
+
+
+ +

Availability

+
How much time could you usually give? +
+ + + + + +
+
How would you prefer to take part?

Select all that apply.

+
+ + + + + + +
+

Optional. It helps us plan and won't count against you.

+ +

Working with others

+
+
+
+
+ +
+ +
+

Your answers stay on this device until you send them. They are read only by ODE council members.

+
+ + + + + + +