From 387bf55b11882005d5dec2e6e54d82f652473655 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 5 Dec 2025 16:32:30 +0000 Subject: [PATCH 01/14] fix version constraint in chill-zimbra-bundle --- packages/ChillZimbraBundle/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/ChillZimbraBundle/composer.json b/packages/ChillZimbraBundle/composer.json index f62e21125..4a53b3ed5 100644 --- a/packages/ChillZimbraBundle/composer.json +++ b/packages/ChillZimbraBundle/composer.json @@ -9,7 +9,7 @@ "social worker" ], "require": { - "chill-project/chill-bundles": "dev-master as v4.6.1", + "chill-project/chill-bundles": "^4.9.0", "zimbra-api/soap-api": "^3.2.2", "psr/http-client": "^1.0", "nyholm/psr7": "^1.0" From 53b02a0ced150bc098484b681aa9d00ecfdaa546 Mon Sep 17 00:00:00 2001 From: LenaertsJ Date: Mon, 8 Dec 2025 12:45:01 +0000 Subject: [PATCH 02/14] Improve the display of upcoming calendar items within the person render box --- .../ChillPersonBundle/Entity/Person.php | 36 +++++++++++++++- .../Resources/views/Entity/person.html.twig | 1 - .../views/Person/list_with_period.html.twig | 41 +++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Entity/Person.php b/src/Bundle/ChillPersonBundle/Entity/Person.php index aa78774b6..2cdb99c54 100644 --- a/src/Bundle/ChillPersonBundle/Entity/Person.php +++ b/src/Bundle/ChillPersonBundle/Entity/Person.php @@ -43,6 +43,7 @@ use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Criteria; +use Doctrine\Common\Collections\Order; use Doctrine\Common\Collections\ReadableCollection; use Doctrine\Common\Collections\Selectable; use Doctrine\ORM\Mapping as ORM; @@ -139,6 +140,12 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI #[ORM\ManyToMany(targetEntity: Calendar::class, mappedBy: 'persons')] private Collection $calendars; + /** + * @var Collection&Selectable + */ + #[ORM\OneToMany(mappedBy: 'person', targetEntity: Calendar::class)] + private Collection $directCalendars; + /** * The person's center. * @@ -406,6 +413,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI public function __construct() { $this->calendars = new ArrayCollection(); + $this->directCalendars = new ArrayCollection(); $this->accompanyingPeriodParticipations = new ArrayCollection(); $this->spokenLanguages = new ArrayCollection(); $this->addresses = new ArrayCollection(); @@ -866,6 +874,30 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI return $this->calendars; } + /** + * Get next calendars for this person (calendars with start date after today). + * Only returns calendars that are directly linked to this person via the person property, + * not those linked through AccompanyingPeriods. + * + * @param int|null $limit Optional limit for the number of results + * + * @return array + */ + public function getNextCalendarsForPerson(?int $limit = null): array + { + $today = new \DateTimeImmutable('today'); + + $criteria = Criteria::create() + ->where(Criteria::expr()->gte('startDate', $today)) + ->orderBy(['startDate' => Order::Ascending]); + + if (null !== $limit) { + $criteria->setMaxResults($limit); + } + + return $this->directCalendars->matching($criteria)->toArray(); + } + public function getCenter(): ?Center { if (null !== $this->centerCurrent) { @@ -1119,7 +1151,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI ->where( $expr->eq('shareHousehold', false) ) - ->orderBy(['startDate' => \Doctrine\Common\Collections\Order::Descending]); + ->orderBy(['startDate' => Order::Descending]); return $this->getHouseholdParticipations() ->matching($criteria); @@ -1141,7 +1173,7 @@ class Person implements HasCenterInterface, TrackCreationInterface, TrackUpdateI ->where( $expr->eq('shareHousehold', true) ) - ->orderBy(['startDate' => \Doctrine\Common\Collections\Order::Descending, 'id' => \Doctrine\Common\Collections\Order::Descending]); + ->orderBy(['startDate' => Order::Descending, 'id' => Order::Descending]); return $this->getHouseholdParticipations() ->matching($criteria); diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig index 5572bd7b1..c373fd58b 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Entity/person.html.twig @@ -212,4 +212,3 @@ {%- endif -%} - diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig index 0840cecb6..cf7fb1466 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/Person/list_with_period.html.twig @@ -301,6 +301,47 @@ 'customButtons': { 'after': _self.button_person_after(person), 'before': _self.button_person_before((person)) } }) }} + {% set calendars = [] %} + {% for c in person.getNextCalendarsForPerson(10) %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_SEE', c) %} + {% set calendars = calendars|merge([c]) %} + {% endif %} + {% endfor %} + + {% if calendars|length > 0 %} +
+
+
+

{{ 'chill_calendar.Next calendars'|trans }}

+
+
+
+ + {% if is_granted('CHILL_CALENDAR_CALENDAR_SEE', person) %} + + {% endif %} +
+
+
+
+ {% endif %} + {#- 'acps' is for AcCompanyingPeriodS #} {%- set acps = [] %} {%- set acpsClosed = [] %} From 473c5a9fa364c4658e76a3c0d0cd3f8751cc8cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 9 Dec 2025 15:27:39 +0100 Subject: [PATCH 03/14] Remove dependency on `@symfony/ux-translator` from `package.json` - Deleted `@symfony/ux-translator` as it is no longer needed. - Documented the change in `.changes/unreleased` with no schema modifications. --- .changes/unreleased/Fixed-20251209-152705.yaml | 7 +++++++ package.json | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20251209-152705.yaml diff --git a/.changes/unreleased/Fixed-20251209-152705.yaml b/.changes/unreleased/Fixed-20251209-152705.yaml new file mode 100644 index 000000000..1468d6caf --- /dev/null +++ b/.changes/unreleased/Fixed-20251209-152705.yaml @@ -0,0 +1,7 @@ +kind: Fixed +body: | + Remove dependency to package @symfony/ux-translator +time: 2025-12-09T15:27:05.621925661+01:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/package.json b/package.json index 1b4c7df13..a013df3da 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "@hotwired/stimulus": "^3.0.0", "@luminateone/eslint-baseline": "^1.0.9", "@symfony/stimulus-bridge": "^3.2.0", - "@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets", "@symfony/webpack-encore": "^4.1.0", "@tsconfig/node20": "^20.1.4", "@types/dompurify": "^3.0.5", From d80661e4794104c1f7b9ecd1b3f9cc7d64a2c2d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 9 Dec 2025 15:31:57 +0100 Subject: [PATCH 04/14] Release v4.10.0 --- .changes/unreleased/Fixed-20251209-152705.yaml | 7 ------- .changes/v4.10.0.md | 6 ++++++ CHANGELOG.md | 7 +++++++ 3 files changed, 13 insertions(+), 7 deletions(-) delete mode 100644 .changes/unreleased/Fixed-20251209-152705.yaml create mode 100644 .changes/v4.10.0.md diff --git a/.changes/unreleased/Fixed-20251209-152705.yaml b/.changes/unreleased/Fixed-20251209-152705.yaml deleted file mode 100644 index 1468d6caf..000000000 --- a/.changes/unreleased/Fixed-20251209-152705.yaml +++ /dev/null @@ -1,7 +0,0 @@ -kind: Fixed -body: | - Remove dependency to package @symfony/ux-translator -time: 2025-12-09T15:27:05.621925661+01:00 -custom: - Issue: "" - SchemaChange: No schema change diff --git a/.changes/v4.10.0.md b/.changes/v4.10.0.md new file mode 100644 index 000000000..e3ecfbf24 --- /dev/null +++ b/.changes/v4.10.0.md @@ -0,0 +1,6 @@ +## v4.10.0 - 2025-12-09 +### Feature +* [MR 928](https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/928) [#462](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/462) Add the future appointments for the person in search results +### Fixed +* Remove dependency to package @symfony/ux-translator + diff --git a/CHANGELOG.md b/CHANGELOG.md index e4669a037..b07fdc914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v4.10.0 - 2025-12-09 +### Feature +* [MR 928](https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/928) [#462](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/462) Add the future appointments for the person in search results +### Fixed +* Remove dependency to package @symfony/ux-translator + + ## v4.9.0 - 2025-12-05 ### Feature * ([#459](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/459)) Add a counter for invitations awaiting reply From 6e1c9b6f29c3822529bd3871a079dcf1e0e735ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 9 Dec 2025 15:37:42 +0100 Subject: [PATCH 05/14] Remove `chill-project/chill-zimbra-bundle` from composer dependencies - This package provoke failures on build in the CI --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index d6864d63f..e7c61424f 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,6 @@ "ext-openssl": "*", "ext-redis": "*", "ext-zlib": "*", - "chill-project/chill-zimbra-bundle": "@dev", "champs-libres/wopi-bundle": "dev-symfony-v5@dev", "champs-libres/wopi-lib": "dev-master@dev", "doctrine/data-fixtures": "^1.8", From 7714b07a9de23e456f4931b00fa7fc5237a17782 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 9 Dec 2025 17:11:11 +0100 Subject: [PATCH 06/14] Add changie for display of upcoming appointments within person context --- .changes/unreleased/Feature-20251209-170951.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changes/unreleased/Feature-20251209-170951.yaml diff --git a/.changes/unreleased/Feature-20251209-170951.yaml b/.changes/unreleased/Feature-20251209-170951.yaml new file mode 100644 index 000000000..77b9a7b15 --- /dev/null +++ b/.changes/unreleased/Feature-20251209-170951.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Display upcoming appointments within the person context in the search results +time: 2025-12-09T17:09:51.811720451+01:00 +custom: + Issue: "462" + SchemaChange: No schema change From 27853c594d0e8ff556d14fdc0691a8ded4145cde Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 04:17:29 +0100 Subject: [PATCH 07/14] Fix missing translation variable in NewLocation component --- .changes/unreleased/Fixed-20251210-041722.yaml | 6 ++++++ .../Activity/components/Location/NewLocation.vue | 12 ++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 .changes/unreleased/Fixed-20251210-041722.yaml diff --git a/.changes/unreleased/Fixed-20251210-041722.yaml b/.changes/unreleased/Fixed-20251210-041722.yaml new file mode 100644 index 000000000..67667cb04 --- /dev/null +++ b/.changes/unreleased/Fixed-20251210-041722.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix missing translation variable in NewLocation component +time: 2025-12-10T04:17:22.40669463+01:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 1cc16ac95..3d771e861 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -136,6 +136,8 @@ import { ACTIVITY_LOCATION_FIELDS_TYPE, ACTIVITY_CHOOSE_LOCATION_TYPE, ACTIVITY_CREATE_NEW_LOCATION, + ACTIVITY_EDIT_ADDRESS, + ACTIVITY_CREATE_ADDRESS, trans, } from "translator"; @@ -156,6 +158,8 @@ export default { ACTIVITY_LOCATION_FIELDS_TYPE, ACTIVITY_CHOOSE_LOCATION_TYPE, ACTIVITY_CREATE_NEW_LOCATION, + ACTIVITY_EDIT_ADDRESS, + ACTIVITY_CREATE_ADDRESS }; }, props: ["availableLocations"], @@ -179,14 +183,14 @@ export default { options: { button: { text: { - create: "activity.create_address", - edit: "activity.edit_address", + create: ACTIVITY_CREATE_ADDRESS, + edit: ACTIVITY_EDIT_ADDRESS, }, size: "btn-sm", }, title: { - create: "activity.create_address", - edit: "activity.edit_address", + create: ACTIVITY_CREATE_ADDRESS, + edit: ACTIVITY_EDIT_ADDRESS, }, }, context: { From c19b2e18ad73a163a1cf881ab3394a22b63c8fd4 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 04:26:27 +0100 Subject: [PATCH 08/14] Move symfony/loco-translation-provider dependency to require-dev --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e7c61424f..829d5e7db 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,6 @@ "symfony/http-client": "^5.4", "symfony/http-foundation": "^5.4", "symfony/intl": "^5.4", - "symfony/loco-translation-provider": "^6.0", "symfony/mailer": "^5.4", "symfony/messenger": "^5.4", "symfony/mime": "^5.4", @@ -118,7 +117,8 @@ "symfony/runtime": "^5.4", "symfony/stopwatch": "^5.4", "symfony/var-dumper": "^5.4", - "symfony/web-profiler-bundle": "^5.4" + "symfony/web-profiler-bundle": "^5.4", + "symfony/loco-translation-provider": "^6.0" }, "conflict": { "symfony/symfony": "*" From 09ef95d13e9b4b35a76dfa04c48d5aa876540af7 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 04:32:19 +0100 Subject: [PATCH 09/14] Translate rst files to md format and add new index entries for translation directives and provider --- docs/source/development/index.md | 2 + .../development/translation_directives.md | 376 ++++++++++++++++ .../development/translation_directives.rst | 419 ------------------ .../development/translation_provider.md | 139 ++++++ .../development/translation_provider.rst | 148 ------- 5 files changed, 517 insertions(+), 567 deletions(-) create mode 100644 docs/source/development/translation_directives.md delete mode 100644 docs/source/development/translation_directives.rst create mode 100644 docs/source/development/translation_provider.md delete mode 100644 docs/source/development/translation_provider.rst diff --git a/docs/source/development/index.md b/docs/source/development/index.md index ab763538c..bb685dbd2 100644 --- a/docs/source/development/index.md +++ b/docs/source/development/index.md @@ -12,6 +12,8 @@ As Chill relies on the [symfony ](http://symfony.com) framework, reading the fra - [Messages to users](messages-to-users.md) - [Pagination](pagination.md) - [Localisation](localisation.md) +- [Translation directives](translation_directives.md) +- [Translation provider](translation_provider.md) - [Logging](logging.md) - [Database migrations](migrations.md) - [Searching](searching.md) diff --git a/docs/source/development/translation_directives.md b/docs/source/development/translation_directives.md new file mode 100644 index 000000000..ce7561904 --- /dev/null +++ b/docs/source/development/translation_directives.md @@ -0,0 +1,376 @@ +# Translation Key Directives + +These directives are meant to ensure better consistency across bundles, avoid duplication, and make keys more predictable. + +## General Principles + +1. **Use lowercase snake_case for all keys** + +2. **Use dot-separated namespaces** + The dot is used to reflect: + - bundle + - feature + - sub-feature + - key type + +3. **Do not use spaces in keys** + +4. **Avoid duplicating the same text in multiple places** + When a translation is needed, try a search for the translation value first and see if it exists elsewhere + +5. **If a key is used across multiple bundles, it must live in ChillMainBundle.** + +6. **If a key is used across multiple bundles and is a generic term, it must be placed in the `common` namespace.** + +## Key Structure + +We use the following structure: + +``` +... +``` + +Where: + +- `` identifies the bundle or shared context +- `` identifies the part of the module using the translation +- `` describes the text purpose +- `` for a multi-level element (e.g., activity.export.person.count.description) + +### Examples of scopes + +- `activity` — ChillActivityBundle +- `person` — ChillPersonBundle +- `common` — neutral shared translation values + +## Naming Scopes + +### 1. Bundle-specific keys + +For most things inside a bundle: + +``` +activity.. +``` + +Example: + +``` +activity.form.save +activity.list.title +activity.entity.type +activity.menu.activities +activity.controller.success_created +``` + +### 2. Shared UI elements (buttons, labels, generic text) + +These belong in the `common` namespace in ChillMainBundle: + +``` +common.save +common.delete +common.edit +common.filter +common.duration_time +``` + +## Translation Workflow + +Use the following workflow when deciding where a key belongs: + +1. **Is this text used in more than one bundle?** + → Place in `main` or `common` + +2. **Is this text generic UI (button, label, pagination, yes/no)?** + → Place in `common` + +3. **Is this text specific to one bundle and one feature?** + → Place in `.feature.` + +4. **Is this text related to an entity or value object?** + → Place in `.entity..` + +5. **Is this text used in forms?** + → `.form.` or `.form.` + +6. **Is this text related to exports?** + → `.export..` + +7. **Is it related to filtering, searching or parameters?** + → `.filter.` or + → `.filter..` for nested filters + +## Examples Based on Translations Within ChillActivityBundle + +Below are concrete examples from `ChillActivityBundle`, refactored according to the guidelines. + +### General activity keys + +Instead of scattered keys like: + +``` +Show the activity +Edit the activity +Activity +Duration time +... +``` + +We use: + +``` +activity.general.show +activity.general.edit +activity.general.title +activity.general.duration +activity.general.travel_time +activity.general.attendee +activity.general.remark +activity.general.no_comments +``` + +### Forms + +Instead of keys like: + +``` +Activity creation +Save activity +Reset form +Choose a type +``` + +Use: + +``` +activity.form.title_create +activity.form.save +activity.form.reset +activity.form.choose_type +activity.form.choose_duration +``` + +Long lists (like durations) should be grouped: + +``` +activity.form.duration.5min +activity.form.duration.10min +activity.form.duration.15min +activity.form.duration.1h +activity.form.duration.1h30 +activity.form.duration.2h +... +``` + +### Entities + +Entity fields should follow: + +``` +activity.entity.activity.date +activity.entity.activity.comment +activity.entity.activity.deleted +activity.entity.location.name +activity.entity.location.type +``` + +### Controller messages + +Instead of strings as keys: + +``` +'Success : activity created!' +'The form is not valid. The activity has not been created !' +``` + +Use: + +``` +activity.controller.success_created +activity.controller.error_invalid_create +activity.controller.success_updated +activity.controller.error_invalid_update +``` + +### Roles + +Access control keys should be: + +``` +activity.role.create +activity.role.update +activity.role.see +activity.role.see_details +activity.role.delete +activity.role.stats +activity.role.list +``` + +### Admin + +``` +activity.admin.configuration +activity.admin.types +activity.admin.reasons +activity.admin.reason_category +activity.admin.presence +``` + +### CRUD + +``` +activity.crud.type.title_new +activity.crud.type.title_edit +activity.crud.presence.title_new +``` + +### Activity Reason + +``` +activity.reason.list +activity.reason.create +activity.reason.active +activity.reason.category +activity.reason.entity_title +``` + +### Exports + +Group them logically: + +``` +activity.export.person.count.title +activity.export.person.count.description +activity.export.person.count.header + +activity.export.period.sum_duration.title +activity.export.period.sum_duration.description +activity.export.period.sum_duration.header +``` + +### Filters + +Use hierarchical filters: + +``` +activity.filter.by_reason +activity.filter.by_type +activity.filter.by_date +activity.filter.by_location +activity.filter.by_sent_received +activity.filter.by_user +``` + +### Aggregators + +``` +activity.aggregator.reason.by_category +activity.aggregator.reason.level +activity.aggregator.user.by_scope +activity.aggregator.user.by_job +``` + +## Global/Shared Keys + +Keys like the following **must not be redeclared** in each bundle: + +- First name +- Last name +- Username +- ID +- Type +- Duration +- Comment +- Date +- Location +- Present / Not present +- Add / Edit / Delete / Save / Update + +These belong in `common` or `main`: + +``` +common.firstname +common.lastname +common.username +common.id +common.type +common.comment +common.date +common.location +common.present +common.absent +common.add +common.edit +common.delete +common.save +common.update +``` + +## Naming Directives Summary + +- **snake_case** +- **namespaced with dots** +- **bundle prefix for bundle-specific concepts** +- **common or main for shared concepts** +- **avoid free-floating keys (without namespace)** +- **reuse common keys wherever possible** + +## Migration Strategy (Optional) + +To apply this structure progressively: + +1. New keys must follow these guidelines. +2. Existing keys may remain as-is until refactored. +3. When refactoring: + - Move cross-bundle keys to ChillMainBundle and possible `common` namespace. + - Replace duplicated keys with shared ones. + +--- + +# Avoiding Duplicate Translations + +## 1. Use Shared Namespaces + +Two namespaces must be used for shared translations: + +- `common.*` — generic UI concepts (save, delete, date, name, etc.) + +If a translation may be reused in multiple bundles, it must be placed in the `common` namespace or in ChillMainBundle. + +## 2. Bundle-Specific Keys + +Keys belonging only to one bundle or one feature are namespaced inside that bundle: + +``` +activity.. +person.. +``` + +## 3. Search Before Creating + +Before adding a new translation key, developers must: + +1. For common translations like "enregistrer/opslaan" look in the `common` namespace. +2. Search in Loco or translations for existing values. + +If a suitable key exists, reuse it. + +## 4. Only Create a New Key When Necessary + +Create a new key only when the text is: + +- specific to the bundle +- specific to the feature +- not reusable elsewhere + +## 5. Progressive Cleanup + +Old duplicates may remain temporarily. When updating code in an area, clean duplicate values by moving them into `common` or `main`. + +## General Workflow + +- **Reuse shared keys** within `common` namespace. +- **Search before creating** new keys. +- **Namespace bundle-specific keys** under their bundle. +- **Refactor progressively** when touching old code. diff --git a/docs/source/development/translation_directives.rst b/docs/source/development/translation_directives.rst deleted file mode 100644 index 106ffb3ab..000000000 --- a/docs/source/development/translation_directives.rst +++ /dev/null @@ -1,419 +0,0 @@ -============================================ -Directives for creating new translation keys -============================================ - -These directives are meant to ensure better consistency across bundles, avoid duplication, and make keys more predictable. - - -General Principles -================== - -1. **Use lowercase snake_case for all keys** - -2. **Use dot-separated namespaces** - The dot is used to reflect: - - bundle - - feature - - sub-feature - - key type - -3. **Do not use spaces in keys** - -4. **Avoid duplicating the same text in multiple places** - When a translation is needed, try a search for the translation value first and see if it exists elsewhere - -5. **If a key is used across multiple bundles, it must live in ChillMainBundle.** - -6. **If a key is used across multiple bundles and is a generic term, it must be placed in the ``common`` namespace.** - - -Key Structure -============= - -We use the following structure: - -.. code-block:: text - - ... - -Where: - -* ``<>`` identifies the bundle or shared context -* ```` identifies the part of the module using the translation -* ```` describes the text purpose -* ```` for a multi-level element ( eg. activity.export.person.count.description) - -Examples of scopes ------------------- - -* ``activity`` — ChillActivityBundle -* ``person`` — ChillPersonBundle -* ``common`` — neutral shared translation values - - -Naming Scopes -============= - -1. **Bundle-specific keys** - - For most things inside a bundle: - - .. code-block:: text - - activity.. - - Example: - - .. code-block:: text - - activity.form.save - activity.list.title - activity.entity.type - activity.menu.activities - activity.controller.success_created - -2. **Shared UI elements (buttons, labels, generic text)** - - These belong in the ``common`` namespace in ChillMainBundle: - - .. code-block:: text - - common.save - common.delete - common.edit - common.filter - common.duration_time - -Translation workflow -==================== - -Use the following workflow when deciding where a key belongs: - -1. **Is this text used in more than one bundle?** - → Place in ``main`` or ``common`` - -2. **Is this text generic UI (button, label, pagination, yes/no)?** - → Place in ``common`` - -3. **Is this text specific to one bundle and one feature?** - → Place in ``.feature.`` - -4. **Is this text related to an entity or value object?** - → Place in ``.entity..`` - -5. **Is this text used in forms?** - → ``.form.`` or ``.form.`` - -6. **Is this text related to exports?** - → ``.export..`` - -7. **Is it related to filtering, searching or parameters?** - → ``.filter.`` or - → ``.filter..`` for nested filters - - -Examples based on translations within ChillActivityBundle -========================================================= - -Below are concrete examples from ``ChillActivityBundle``, -refactored according to the guidelines. - - -General activity keys ---------------------- - -Instead of scattered keys like:: - - Show the activity - Edit the activity - Activity - Duration time - ... - -We use: - -.. code-block:: text - - activity.general.show - activity.general.edit - activity.general.title - activity.general.duration - activity.general.travel_time - activity.general.attendee - activity.general.remark - activity.general.no_comments - - -Forms ------ - -Instead of keys like:: - - Activity creation - Save activity - Reset form - Choose a type - -Use: - -.. code-block:: text - - activity.form.title_create - activity.form.save - activity.form.reset - activity.form.choose_type - activity.form.choose_duration - -Long lists (like durations) should be grouped: - -.. code-block:: text - - activity.form.duration.5min - activity.form.duration.10min - activity.form.duration.15min - activity.form.duration.1h - activity.form.duration.1h30 - activity.form.duration.2h - ... - -Entities --------- - -Entity fields should follow: - -.. code-block:: text - - activity.entity.activity.date - activity.entity.activity.comment - activity.entity.activity.deleted - activity.entity.location.name - activity.entity.location.type - - -Controller messages -------------------- - -Instead of strings as keys:: - - 'Success : activity created!' - 'The form is not valid. The activity has not been created !' - -Use: - -.. code-block:: text - - activity.controller.success_created - activity.controller.error_invalid_create - activity.controller.success_updated - activity.controller.error_invalid_update - - -Roles ------ - -Access control keys should be: - -.. code-block:: text - - activity.role.create - activity.role.update - activity.role.see - activity.role.see_details - activity.role.delete - activity.role.stats - activity.role.list - - -Admin ------ - -.. code-block:: text - - activity.admin.configuration - activity.admin.types - activity.admin.reasons - activity.admin.reason_category - activity.admin.presence - - -CRUD ----- - -.. code-block:: text - - activity.crud.type.title_new - activity.crud.type.title_edit - activity.crud.presence.title_new - - -Activity Reason ---------------- - -.. code-block:: text - - activity.reason.list - activity.reason.create - activity.reason.active - activity.reason.category - activity.reason.entity_title - - -Exports -------- - -Group them logically: - -.. code-block:: text - - activity.export.person.count.title - activity.export.person.count.description - activity.export.person.count.header - - activity.export.period.sum_duration.title - activity.export.period.sum_duration.description - activity.export.period.sum_duration.header - - -Filters -------- - -Use hierarchical filters: - -.. code-block:: text - - activity.filter.by_reason - activity.filter.by_type - activity.filter.by_date - activity.filter.by_location - activity.filter.by_sent_received - activity.filter.by_user - - -Aggregators ------------ - -.. code-block:: text - - activity.aggregator.reason.by_category - activity.aggregator.reason.level - activity.aggregator.user.by_scope - activity.aggregator.user.by_job - - -Global/Shared Keys -================== - -Keys like the following **must not be redeclared** in each bundle: - -- First name -- Last name -- Username -- ID -- Type -- Duration -- Comment -- Date -- Location -- Present / Not present -- Add / Edit / Delete / Save / Update - -These belong in ``common`` or ``main``: - -.. code-block:: text - - common.firstname - common.lastname - common.username - common.id - common.type - common.comment - common.date - common.location - common.present - common.absent - common.add - common.edit - common.delete - common.save - common.update - - -Naming directives summary -========================== - -* **snake_case** -* **namespaced with dots** -* **bundle prefix for bundle-specific concepts** -* **common or main for shared concepts** -* **avoid free-floating keys (without namespace)** -* **reuse common keys wherever possible** - - -Migration Strategy (Optional) -============================= - -To apply this structure progressively: - -1. New keys must follow these guidelines. -2. Existing keys may remain as-is until refactored. -3. When refactoring: - - Move cross-bundle keys to ChillMainBundle and possible `common` namespace. - - Replace duplicated keys with shared ones. - -=========================================== -Avoiding duplicate translations -=========================================== - -1. Use Shared Namespaces -======================== - -Two namespaces must be used for shared translations: - -* ``common.*`` — generic UI concepts (save, delete, date, name, etc.) - -If a translation may be reused in multiple bundles, it must be placed -in the ``common`` namespace or in ChillMainBundle. - -2. Bundle-Specific Keys -======================= - -Keys belonging only to one bundle or one feature are namespaced inside that -bundle: - -.. code-block:: text - - activity.. - person.. - -3. Search Before Creating -========================= - -Before adding a new translation key, developers must: - -1. For common translations like: "enregistrer/opslaan" look in the `common` namespace. -3. Search in Loco or translations for existing values. - -If a suitable key exists, reuse it. - -4. Only Create a New Key When Necessary -======================================= - -Create a new key only when the text is: - -* specific to the bundle -* specific to the feature -* not reusable elsewhere - -6. Progressive Cleanup -====================== - -Old duplicates may remain temporarily. When updating code in an area, clean -duplicate values by moving them into ``common`` or ``main``. - -General workflow -================ - -* **Reuse shared keys** within ``common`` namespace. -* **Search before creating** new keys. -* **Namespace bundle-specific keys** under their bundle. -* **Refactor progressively** when touching old code. diff --git a/docs/source/development/translation_provider.md b/docs/source/development/translation_provider.md new file mode 100644 index 000000000..29301f366 --- /dev/null +++ b/docs/source/development/translation_provider.md @@ -0,0 +1,139 @@ +# Managing Translations Within CHILL Using Loco as a Translation Provider + +Within CHILL we make use of Symfony's translation component together with *Loco* as an external translation provider. Using this setup centralises translations in a single online location (Loco), while still allowing developers to create and update translation keys locally in the project (YAML files). + +## Workflow + +We use the following workflow: + +- Developers create translation keys in YAML files inside each bundle. +- Keys are written in **English**. +- Application UI defaults to **French**, with **Dutch** as an additional locale (other languages can be added in the future). +- Loco acts as the central translation memory and synchronisation source. +- Loco Symfony package was installed so that built-in translation commands can be used to push/pull content between Loco and the local project. + +## Translation Directory Structure + +Each bundle contains its own `translations` directory, for example: + +``` +chill-bundles/ + ChillCoreBundle/ + translations/ + messages.fr.yml + messages.nl.yml + ChillPersonBundle/ + translations/ + messages.fr.yml + messages.nl.yml + ... +``` + +## Configuration + +The translation configuration is defined in `config/packages/translation.yaml`: + +```yaml +framework: + default_locale: '%env(resolve:LOCALE)%' + translator: + default_path: '%kernel.project_dir%/translations' + fallbacks: + - '%env(resolve:LOCALE)%' + - 'en' + providers: + loco: + dsn: '%env(LOCO_DSN)%' + domains: [ 'messages' ] + locales: [ 'fr', 'nl' ] +``` + +Note: + +- `en` is the **source locale** in Loco. +- `fr` and `nl` are the **application locales**. +- `domains: [messages]` means only `messages.*.yml` files are pushed. + +### Environment Variables + +In `.env`: + +``` +LOCALE=fr +``` + +In `.env.local`: + +``` +LOCO_DSN="loco://API_KEY@default" +``` + +Replace `API_KEY` with the key provided by Loco. + +## Working with Loco + +Loco shows all translation keys under three languages: + +- **English (source)** — keys are listed but remain "untranslated" +- **French** — translated strings for French users +- **Dutch** — translated strings for Dutch users + +Note: Don't add translations directly in the English column. This column simply represents the *key*. + +## Pushing Translations to Loco + +You can push local translations to Loco using: + +```bash +symfony console translation:push loco --locales=fr --locales=nl --force +``` + +This will: + +- Upload all French and Dutch translation values from `*.fr.yml` and `*.nl.yml` files +- Ensure Loco stays in sync with local YAML files +- Create any missing keys in Loco + +## Pulling Translations from Loco + +When translators update strings in Loco, developers can fetch updates with: + +```bash +symfony console translation:pull loco --locales=fr --locales=nl --force +``` + +This will: + +- Download the latest French and Dutch translations +- Overwrite the local YAML files with Loco's content +- Keep everything consistent across the team + +## Adding New Translation Keys (Developer Workflow) + +1. Add a new key directly in the appropriate YAML file, for example: + + ``` + chill-bundles/ChillPersonBundle/translations/messages.fr.yml + ``` + + Example key: + + ```yaml + person.form.submit: "Envoyer" + ``` + +2. Add Dutch translation as well if you can (otherwise leave empty to be translated within Loco later): + + ```yaml + person.form.submit: "Verzenden" + ``` + +3. Run a push to send the new key to Loco: + + ```bash + symfony console translation:push loco --locales=fr --locales=nl --force + ``` + +4. The key will now appear in Loco for translation management. + +Note: English appears as "untranslated", because it is merely the source language. diff --git a/docs/source/development/translation_provider.rst b/docs/source/development/translation_provider.rst deleted file mode 100644 index 98b117129..000000000 --- a/docs/source/development/translation_provider.rst +++ /dev/null @@ -1,148 +0,0 @@ -======================================================================= -Managing translations within CHILL using Loco as a translation provider -======================================================================= - -Within CHILL we make use of Symfony's translation component together with *Loco* as an external -translation provider. Using this setup centralise translations in a single online -location (Loco), while still allowing developers to create and update -translation keys locally in the project (YAML files). - -Workflow -======== - -We use the following workflow: - -* Developers create translation keys in YAML files inside each bundle. -* Keys are written in **English**. -* Application UI defaults to **French**, with **Dutch** as an additional locale (other languages can be added in the future). -* Loco acts as the central translation memory and synchronisation source. -* Loco Symfony package was installed so that built-in translation commands can be used to push/pull content - between Loco and the local project. - - -Translation directory structure -=============================== - -Each bundle contains its own ``translations`` directory, for example:: - - chill-bundles/ - ChillCoreBundle/ - translations/ - messages.fr.yml - messages.nl.yml - ChillPersonBundle/ - translations/ - messages.fr.yml - messages.nl.yml - ... - -Configuration -============= - -The translation configuration is defined in -``config/packages/translation.yaml``:: - - framework: - default_locale: '%env(resolve:LOCALE)%' - translator: - default_path: '%kernel.project_dir%/translations' - fallbacks: - - '%env(resolve:LOCALE)%' - - 'en' - providers: - loco: - dsn: '%env(LOCO_DSN)%' - domains: [ 'messages' ] - locales: [ 'fr', 'nl' ] - -Note: - -* ``en`` is the **source locale** in Loco. -* ``fr`` and ``nl`` are the **application locales**. -* ``domains: [messages]`` means only ``messages.*.yml`` files are pushed. - - -Environment variables ---------------------- - -In ``.env``:: - - LOCALE=fr - -In ``.env.local``:: - - LOCO_DSN="loco://API_KEY@default" - -Replace ``API_KEY`` with the key provided by Loco. - - -Working with Loco -================= - -Loco shows all translation keys under three languages: - -* **English (source)** — keys are listed but remain “untranslated” -* **French** — translated strings for French users -* **Dutch** — translated strings for Dutch users - -Note: Don't add translations directly in the English column. -This column simply represents the *key*. - - -Pushing translations to Loco -============================ - -You can push local translations to Loco using: - -.. code-block:: bash - - symfony console translation:push loco --locales=fr --locales=nl --force - -This will: - -* Upload all French and Dutch translation values from ``*.fr.yml`` and - ``*.nl.yml`` files -* Ensures Loco stays in sync with local YAML files -* Creates any missing keys in Loco - - -Pulling translations from Loco -============================== - -When translators update strings in Loco, developers can fetch updates with: - -.. code-block:: bash - - symfony console translation:pull loco --locales=fr --locales=nl --force - -This will: - -* Download the latest French and Dutch translations -* Overwrite the local YAML files with Loco’s content -* Keep everything consistent across the team - - -Adding new translation keys (Developer workflow) -================================================ - -1. Add a new key directly in the appropriate YAML file, for example:: - - chill-bundles/ChillPersonBundle/translations/messages.fr.yml - - Example key:: - - person.form.submit: "Envoyer" - -2. Add Dutch translation as well if you can (otherwise leave empty to be translated within Loco later):: - - person.form.submit: "Verzenden" - -3. Run a push to send the new key to Loco: - -.. code-block:: bash - - symfony console translation:push loco --locales=fr --locales=nl --force - -4. The key will now appear in Loco for translation management. - -Note: English appears as “untranslated”, because it is merely the source language From 2600c6fa2a53f81a7c277db2162fdb7f41e44ab1 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 05:06:03 +0100 Subject: [PATCH 10/14] Fix ByActivityNumberAggregator when used on count exports within ActivityBundle --- .../Aggregator/ACPAggregators/ByActivityNumberAggregator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index e304a9d7f..125b197dc 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -27,7 +27,8 @@ class ByActivityNumberAggregator implements AggregatorInterface public function alterQuery(QueryBuilder $qb, $data, \Chill\MainBundle\Export\ExportGenerationContext $exportGenerationContext): void { $qb - ->addSelect('(SELECT COUNT(activity.id) FROM '.Activity::class.' activity WHERE activity.accompanyingPeriod = acp) AS activity_by_number_aggregator') + // Use a distinct alias inside the subquery to avoid colliding with the root alias "activity" + ->addSelect('(SELECT COUNT(agg_activity.id) FROM '.Activity::class.' agg_activity WHERE agg_activity.accompanyingPeriod = acp) AS activity_by_number_aggregator') ->addGroupBy('activity_by_number_aggregator'); } From c4a069ba2e0361bc36fde4a6842ba640f519a202 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 10 Dec 2025 05:11:56 +0100 Subject: [PATCH 11/14] Fix display of header for ByActivityNumberAggregator --- .changes/unreleased/Fixed-20251210-051234.yaml | 6 ++++++ .changes/unreleased/Fixed-20251210-051313.yaml | 6 ++++++ .../ACPAggregators/ByActivityNumberAggregator.php | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 .changes/unreleased/Fixed-20251210-051234.yaml create mode 100644 .changes/unreleased/Fixed-20251210-051313.yaml diff --git a/.changes/unreleased/Fixed-20251210-051234.yaml b/.changes/unreleased/Fixed-20251210-051234.yaml new file mode 100644 index 000000000..581b37176 --- /dev/null +++ b/.changes/unreleased/Fixed-20251210-051234.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix display of header for ByActivityNumberAggregator +time: 2025-12-10T05:12:34.061935068+01:00 +custom: + Issue: "476" + SchemaChange: No schema change diff --git a/.changes/unreleased/Fixed-20251210-051313.yaml b/.changes/unreleased/Fixed-20251210-051313.yaml new file mode 100644 index 000000000..c0a236e13 --- /dev/null +++ b/.changes/unreleased/Fixed-20251210-051313.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix use of ByActivityNumberAggregator in combination with activity count exports +time: 2025-12-10T05:13:13.246754532+01:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php index 125b197dc..b901b10f5 100644 --- a/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php +++ b/src/Bundle/ChillActivityBundle/Export/Aggregator/ACPAggregators/ByActivityNumberAggregator.php @@ -66,7 +66,7 @@ class ByActivityNumberAggregator implements AggregatorInterface { return static function ($value) { if ('_header' === $value) { - return ''; + return 'Count activities linked to an accompanying period'; } if (null === $value) { From a16d659f695f1633b829fe36d9873277e597d442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 11 Dec 2025 13:26:10 +0000 Subject: [PATCH 12/14] Tentatively fix CTRL+C in Collabora editor with edge and chrome browser (+ remove zimbra bundle from configuration) --- .../unreleased/Fixed-20251211-135111.yaml | 6 ++ config/bundles.php | 1 - config/services.yaml | 3 + phpstan.dist.neon | 1 - .../ChillWopiBundle/chill.webpack.config.js | 2 +- .../src/Resources/public/page/editor/index.js | 46 ------------- .../src/Resources/public/page/editor/index.ts | 68 +++++++++++++++++++ symfony.lock | 3 - 8 files changed, 78 insertions(+), 52 deletions(-) create mode 100644 .changes/unreleased/Fixed-20251211-135111.yaml delete mode 100644 src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js create mode 100644 src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.ts diff --git a/.changes/unreleased/Fixed-20251211-135111.yaml b/.changes/unreleased/Fixed-20251211-135111.yaml new file mode 100644 index 000000000..0a179d649 --- /dev/null +++ b/.changes/unreleased/Fixed-20251211-135111.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Tentatively fix usage of CTRL+C in collabora editor with chrome / edge browser +time: 2025-12-11T13:51:11.425545012+01:00 +custom: + Issue: "483" + SchemaChange: No schema change diff --git a/config/bundles.php b/config/bundles.php index 989338f3e..72b5e22f5 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -37,5 +37,4 @@ return [ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true], Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true], loophp\PsrHttpMessageBridgeBundle\PsrHttpMessageBridgeBundle::class => ['all' => true], - Chill\ZimbraBundle\ChillZimbraBundle::class => ['all' => true], ]; diff --git a/config/services.yaml b/config/services.yaml index 11c095d99..037b57f6d 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -11,3 +11,6 @@ services: autowire: true # Automatically injects dependencies in your services. autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. +when@dev: + services: + ChampsLibres\WopiLib\Contract\Service\ProofValidatorInterface: '@Chill\WopiBundle\Service\Wopi\NullProofValidator' diff --git a/phpstan.dist.neon b/phpstan.dist.neon index 38c3f7b61..60c36771e 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -3,7 +3,6 @@ parameters: paths: - src/ - utils/ - - packages/ tmpDir: var/cache/phpstan reportUnmatchedIgnoredErrors: false excludePaths: diff --git a/src/Bundle/ChillWopiBundle/chill.webpack.config.js b/src/Bundle/ChillWopiBundle/chill.webpack.config.js index 05c231f68..8580597cc 100644 --- a/src/Bundle/ChillWopiBundle/chill.webpack.config.js +++ b/src/Bundle/ChillWopiBundle/chill.webpack.config.js @@ -2,7 +2,7 @@ module.exports = function (encore, entries) { encore.addEntry( "page_wopi_editor", - __dirname + "/src/Resources/public/page/editor/index.js", + __dirname + "/src/Resources/public/page/editor/index.ts", ); encore.addEntry( "mod_reload_page", diff --git a/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js b/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js deleted file mode 100644 index d946977df..000000000 --- a/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js +++ /dev/null @@ -1,46 +0,0 @@ -require("./index.scss"); - -window.addEventListener("DOMContentLoaded", function () { - let frameholder = document.getElementById("frameholder"); - let office_frame = document.createElement("iframe"); - office_frame.name = "office_frame"; - office_frame.id = "office_frame"; - - // The title should be set for accessibility - office_frame.title = "Office Frame"; - - // This attribute allows true fullscreen mode in slideshow view - // when using PowerPoint's 'view' action. - office_frame.setAttribute("allowfullscreen", "true"); - - // The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow - office_frame.setAttribute( - "sandbox", - "allow-downloads allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-top-navigation allow-popups-to-escape-sandbox", - ); - frameholder.appendChild(office_frame); - - document.getElementById("office_form").submit(); - - const url = new URL(editor_url); - const editor_domain = url.origin; - - window.addEventListener("message", function (message) { - if (message.origin !== editor_domain) { - return; - } - - let data = JSON.parse(message.data); - - if ("UI_Close" === data.MessageId) { - closeEditor(); - } - }); -}); - -function closeEditor() { - let params = new URLSearchParams(window.location.search), - returnPath = params.get("returnPath"); - - window.location.assign(returnPath); -} diff --git a/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.ts b/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.ts new file mode 100644 index 000000000..01ddad995 --- /dev/null +++ b/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.ts @@ -0,0 +1,68 @@ +import "./index.scss"; + +// Provided by the server-side template +declare const editor_url: string; + +window.addEventListener("DOMContentLoaded", function () { + const frameholder = document.getElementById("frameholder"); + const office_frame = document.createElement("iframe"); + office_frame.name = "office_frame"; + office_frame.id = "office_frame"; + + // The title should be set for accessibility + office_frame.title = "Office Frame"; + + // This attribute allows true fullscreen mode in slideshow view + // when using PowerPoint's 'view' action. + office_frame.setAttribute("allowfullscreen", "true"); + + // The sandbox attribute is needed to allow automatic redirection to the O365 sign-in page in the business user flow + office_frame.setAttribute( + "sandbox", + "allow-downloads allow-scripts allow-same-origin allow-forms allow-modals allow-popups allow-top-navigation allow-popups-to-escape-sandbox", + ); + + office_frame.setAttribute( + "allow", + "clipboard-read *; clipboard-write *; fullscreen *", + ); + if (frameholder) { + frameholder.appendChild(office_frame); + } + + const officeForm = document.getElementById( + "office_form", + ) as HTMLFormElement | null; + officeForm?.submit(); + + const url = new URL(editor_url); + const editor_domain = url.origin; + + window.addEventListener("message", function (message: MessageEvent) { + if (message.origin !== editor_domain) { + return; + } + + let data: { MessageId: "UI_Close" | null; data: string }; + try { + data = + typeof message.data === "string" + ? JSON.parse(message.data) + : message.data; + } catch (e: unknown) { + console.error("error while parsing data from message UI_CLOSE", e); + return; + } + + if ("UI_Close" === data.MessageId) { + closeEditor(); + } + }); +}); + +function closeEditor(): void { + const params = new URLSearchParams(window.location.search); + const returnPath = params.get("returnPath") ?? "/"; + + window.location.assign(returnPath); +} diff --git a/symfony.lock b/symfony.lock index 5724d23b9..532c9ec98 100644 --- a/symfony.lock +++ b/symfony.lock @@ -2,9 +2,6 @@ "champs-libres/wopi-bundle": { "version": "dev-master" }, - "chill-project/chill-zimbra-bundle": { - "version": "dev-472-zimbra-connector" - }, "doctrine/annotations": { "version": "1.14", "recipe": { From 0f1ff9baf4489ee2367d116a9e4afa311df4eda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 11 Dec 2025 14:43:29 +0100 Subject: [PATCH 13/14] Fix CS --- .../public/vuejs/Activity/components/Location/NewLocation.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue index 3d771e861..dff32b35d 100644 --- a/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue +++ b/src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/components/Location/NewLocation.vue @@ -159,7 +159,7 @@ export default { ACTIVITY_CHOOSE_LOCATION_TYPE, ACTIVITY_CREATE_NEW_LOCATION, ACTIVITY_EDIT_ADDRESS, - ACTIVITY_CREATE_ADDRESS + ACTIVITY_CREATE_ADDRESS, }; }, props: ["availableLocations"], From ba4e44511004daa2994f701a3c281c383886a305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 11 Dec 2025 14:49:07 +0100 Subject: [PATCH 14/14] Release v4.10.1 --- .changes/unreleased/Feature-20251209-170951.yaml | 6 ------ .changes/unreleased/Fixed-20251210-041722.yaml | 6 ------ .changes/unreleased/Fixed-20251210-051234.yaml | 6 ------ .changes/unreleased/Fixed-20251210-051313.yaml | 6 ------ .changes/unreleased/Fixed-20251211-135111.yaml | 6 ------ .changes/v4.10.1.md | 6 ++++++ CHANGELOG.md | 7 +++++++ 7 files changed, 13 insertions(+), 30 deletions(-) delete mode 100644 .changes/unreleased/Feature-20251209-170951.yaml delete mode 100644 .changes/unreleased/Fixed-20251210-041722.yaml delete mode 100644 .changes/unreleased/Fixed-20251210-051234.yaml delete mode 100644 .changes/unreleased/Fixed-20251210-051313.yaml delete mode 100644 .changes/unreleased/Fixed-20251211-135111.yaml create mode 100644 .changes/v4.10.1.md diff --git a/.changes/unreleased/Feature-20251209-170951.yaml b/.changes/unreleased/Feature-20251209-170951.yaml deleted file mode 100644 index 77b9a7b15..000000000 --- a/.changes/unreleased/Feature-20251209-170951.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Feature -body: Display upcoming appointments within the person context in the search results -time: 2025-12-09T17:09:51.811720451+01:00 -custom: - Issue: "462" - SchemaChange: No schema change diff --git a/.changes/unreleased/Fixed-20251210-041722.yaml b/.changes/unreleased/Fixed-20251210-041722.yaml deleted file mode 100644 index 67667cb04..000000000 --- a/.changes/unreleased/Fixed-20251210-041722.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Fix missing translation variable in NewLocation component -time: 2025-12-10T04:17:22.40669463+01:00 -custom: - Issue: "" - SchemaChange: No schema change diff --git a/.changes/unreleased/Fixed-20251210-051234.yaml b/.changes/unreleased/Fixed-20251210-051234.yaml deleted file mode 100644 index 581b37176..000000000 --- a/.changes/unreleased/Fixed-20251210-051234.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Fix display of header for ByActivityNumberAggregator -time: 2025-12-10T05:12:34.061935068+01:00 -custom: - Issue: "476" - SchemaChange: No schema change diff --git a/.changes/unreleased/Fixed-20251210-051313.yaml b/.changes/unreleased/Fixed-20251210-051313.yaml deleted file mode 100644 index c0a236e13..000000000 --- a/.changes/unreleased/Fixed-20251210-051313.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Fix use of ByActivityNumberAggregator in combination with activity count exports -time: 2025-12-10T05:13:13.246754532+01:00 -custom: - Issue: "" - SchemaChange: No schema change diff --git a/.changes/unreleased/Fixed-20251211-135111.yaml b/.changes/unreleased/Fixed-20251211-135111.yaml deleted file mode 100644 index 0a179d649..000000000 --- a/.changes/unreleased/Fixed-20251211-135111.yaml +++ /dev/null @@ -1,6 +0,0 @@ -kind: Fixed -body: Tentatively fix usage of CTRL+C in collabora editor with chrome / edge browser -time: 2025-12-11T13:51:11.425545012+01:00 -custom: - Issue: "483" - SchemaChange: No schema change diff --git a/.changes/v4.10.1.md b/.changes/v4.10.1.md new file mode 100644 index 000000000..410d89bf0 --- /dev/null +++ b/.changes/v4.10.1.md @@ -0,0 +1,6 @@ +## v4.10.1 - 2025-12-11 +### Fixed +* Fix missing translation variable in NewLocation component +* ([#476](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/476)) Fix display of header for ByActivityNumberAggregator +* Fix use of ByActivityNumberAggregator in combination with activity count exports +* ([#483](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/483)) Tentatively fix usage of CTRL+C in collabora editor with chrome / edge browser diff --git a/CHANGELOG.md b/CHANGELOG.md index b07fdc914..5700c47cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), and is generated by [Changie](https://github.com/miniscruff/changie). +## v4.10.1 - 2025-12-11 +### Fixed +* Fix missing translation variable in NewLocation component +* ([#476](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/476)) Fix display of header for ByActivityNumberAggregator +* Fix use of ByActivityNumberAggregator in combination with activity count exports +* ([#483](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/483)) Tentatively fix usage of CTRL+C in collabora editor with chrome / edge browser + ## v4.10.0 - 2025-12-09 ### Feature * [MR 928](https://gitlab.com/Chill-Projet/chill-bundles/-/merge_requests/928) [#462](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/462) Add the future appointments for the person in search results