mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-13 02:04:58 +00:00
Compare commits
14 Commits
ticket-app
...
#361-impro
Author | SHA1 | Date | |
---|---|---|---|
e55a7f2993
|
|||
8cade9ac77
|
|||
eb25f1408e
|
|||
279901ac93
|
|||
b1a7680b5e
|
|||
b1703a4187
|
|||
b16e6c4517
|
|||
d4eddaf671
|
|||
a126f2f06d
|
|||
845aa040cc
|
|||
5a284fe6cf
|
|||
a2b8e0e6ae
|
|||
189a26e0e8
|
|||
2e32b8946b
|
@@ -1,6 +0,0 @@
|
||||
kind: Feature
|
||||
body: |
|
||||
Upgrade import of address list to the last version of compiled addresses of belgian-best-address
|
||||
time: 2024-05-30T16:00:03.440767606+02:00
|
||||
custom:
|
||||
Issue: ""
|
@@ -1,6 +0,0 @@
|
||||
kind: Feature
|
||||
body: |
|
||||
Upgrade CKEditor and refactor configuration with use of typescript
|
||||
time: 2024-05-31T19:02:42.776662753+02:00
|
||||
custom:
|
||||
Issue: ""
|
@@ -1,6 +0,0 @@
|
||||
kind: Feature
|
||||
body: Add a command to generate a list of permissions
|
||||
time: 2025-09-04T18:10:32.334524026+02:00
|
||||
custom:
|
||||
Issue: ""
|
||||
SchemaChange: No schema change
|
@@ -1,12 +0,0 @@
|
||||
## v4.1.0 - 2025-08-26
|
||||
### Feature
|
||||
* ([#400](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/400)) Add filter to social actions list to filter out actions where current user intervenes
|
||||
* ([#399](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/399)) Show filters on list pages unfolded by default
|
||||
* Expansion of event module with new fields in the creation form: thematic, internal/external animator, responsable, and budget elements. Filtering options in the event list + adapted exports
|
||||
|
||||
**Schema Change**: Add columns or tables
|
||||
### Fixed
|
||||
* ([#382](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/382)) adjust display logic for accompanying period dates, include closing date if period is closed.
|
||||
* ([#384](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/384)) add min and step attributes to integer field in DateIntervalType
|
||||
### UX
|
||||
* Limit display of participations in event list
|
@@ -1,10 +0,0 @@
|
||||
## v4.2.0 - 2025-09-02
|
||||
### Feature
|
||||
* ([#64](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/64)) Add external identifier for a Person
|
||||
|
||||
**Schema Change**: Add columns or tables
|
||||
* ([#330](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/330) Allow users to choose for which notifications they want to receive an email
|
||||
### Fixed
|
||||
* ([#422](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/422)) Fixed html layout of pages for recovering password
|
||||
* Fix typo in 'uncheckAll' script for centers selection
|
||||
* Fix incorrect parameter name in event details link
|
@@ -1,6 +0,0 @@
|
||||
## v4.2.1 - 2025-09-03
|
||||
### Fixed
|
||||
* Fix exports to work with DirectExportInterface
|
||||
### DX
|
||||
* Improve error message when a stored object cannot be written on local disk
|
||||
|
@@ -19,11 +19,11 @@ max_line_length = 80
|
||||
[COMMIT_EDITMSG]
|
||||
max_line_length = 0
|
||||
|
||||
[*.{js,vue,ts}]
|
||||
[*.{js, vue, ts}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.rst]
|
||||
indent_size = 3
|
||||
indent_style = space
|
||||
[.rst]
|
||||
ident_size = 3
|
||||
ident_style = space
|
||||
|
||||
|
@@ -7,6 +7,14 @@
|
||||
"message": "'app' is assigned a value but never used.",
|
||||
"hash": "f8c2979921289906e3baabae31ba101ead91504f"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js",
|
||||
"line": 57,
|
||||
"column": 23,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'event' is defined but never used.",
|
||||
"hash": "cf0cf378f71403f62a6425f384ccbbdec433d1f2"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/module/Invite/answer.js",
|
||||
"line": 7,
|
||||
@@ -119,6 +127,46 @@
|
||||
"message": "'payload' is defined but never used.",
|
||||
"hash": "66c545917093ba30f1d6ca10ddaa676140e749bd"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||
"line": 224,
|
||||
"column": 10,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reactive' is defined but never used.",
|
||||
"hash": "96ed76a9828138fb125fc36c4b55e900bbfe87c2"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||
"line": 230,
|
||||
"column": 5,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'DropArg' is defined but never used.",
|
||||
"hash": "bd405399a4091d65e8391404bfb0c4611816c8e0"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||
"line": 251,
|
||||
"column": 9,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'t' is assigned a value but never used.",
|
||||
"hash": "bc09207a496405f7a71c178e522b89aeb1f7ebd3"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||
"line": 356,
|
||||
"column": 32,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'arg' is defined but never used.",
|
||||
"hash": "aeae152f0669b946a1ad681dd52b0ef03393ae79"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/App2.vue",
|
||||
"line": 434,
|
||||
"column": 11,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'changedEvent' is assigned a value but never used.",
|
||||
"hash": "a7a81a6bf09d00c0364e3aa8207ffad853f0547b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/Components/EditLocation.vue",
|
||||
"line": 77,
|
||||
@@ -351,6 +399,14 @@
|
||||
"message": "'error' is defined but never used.",
|
||||
"hash": "e26e5e101e90d2b7ee84d6f5de8c819e52129c17"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/index.ts",
|
||||
"line": 29,
|
||||
"column": 14,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'vm' is defined but never used.",
|
||||
"hash": "8e7f5e89dd72c54459cf82156389b88988f97d63"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/uploader.js",
|
||||
"line": 39,
|
||||
@@ -559,6 +615,14 @@
|
||||
"message": "'ref' is defined but never used.",
|
||||
"hash": "2a27cd6d06a26e1326654c929068e3704137e24b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue",
|
||||
"line": 57,
|
||||
"column": 17,
|
||||
"ruleId": "vue/valid-v-for",
|
||||
"message": "Custom elements in iteration require 'v-bind:key' directives.",
|
||||
"hash": "cce787939524e83dd135869e13738ef332d7156c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue",
|
||||
"line": 15,
|
||||
@@ -919,6 +983,22 @@
|
||||
"message": "'_e' is defined but never used.",
|
||||
"hash": "1d6448401778e8c56554020fe5abd47851ed33f3"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/module/wopi-link/index.js",
|
||||
"line": 21,
|
||||
"column": 55,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'e' is defined but never used.",
|
||||
"hash": "eae499e4f6e9f43a9d17f9cd917cb6d3d97be25c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/page/export/download-export.js",
|
||||
"line": 3,
|
||||
"column": 55,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'e' is defined but never used.",
|
||||
"hash": "088fd383e7807e484aefc9825209bc7c8942bd22"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/page/homepage_widget/index.js",
|
||||
"line": 9,
|
||||
@@ -1009,19 +1089,115 @@
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 516,
|
||||
"column": 21,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"context\" prop.",
|
||||
"hash": "984c4203f2ac1e1bb65f9ce76ecd03b763cfaa83"
|
||||
"line": 247,
|
||||
"column": 5,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'postAddressToPerson' is defined but never used.",
|
||||
"hash": "8a41c437cf2b5554cbbe1704cd51f3102b3d5994"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 517,
|
||||
"line": 248,
|
||||
"column": 5,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'postAddressToHousehold' is defined but never used.",
|
||||
"hash": "66dec84b2ece299daf21308e5e60d497ba442b27"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 490,
|
||||
"column": 21,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"context\" prop.",
|
||||
"hash": "c9fb019bc21bfa77d989ed596913b99dd653c594"
|
||||
"hash": "0d3f40c47974a4371072b3b9ee04b197c830162d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 491,
|
||||
"column": 21,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"context\" prop.",
|
||||
"hash": "8e877b7e588c30e182f7b572bdb9685360f9cf99"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 508,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "5a3e3401bc3c765d91faaf4cfde57697af1262b7"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 525,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "35a741d90379574b9323279f5802193d0c98a9dc"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 553,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "c23d1ddf6c0d10ae97948e74aee9c14b9320b86c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 572,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "4322e81c6ea9d9734c680633a724d5bd4fabacb2"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 803,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "7928a6461b9d394c7d97f048933553936f7d8963"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||
"line": 852,
|
||||
"column": 47,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "e5afdb8efccb5470a08dde48f755b1268fa947b5"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 93,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "68f5e1cf5c03f9ada59c9e0afca0b74c7f3fca4b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 101,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "50d730f6109092baff2db66adc44dc1315e2bda2"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 109,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "573e4c041ce663f28b933d7a675c2a525aba644c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 117,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "293f845eeab515b1df4649d136c2d8219ed59c4d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
@@ -1048,180 +1224,204 @@
|
||||
"hash": "2d5a5e680ff207ad97c7e7b7d999064b561dfd8a"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 149,
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 106,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "e4c1ecd7ae77d46ac3625c5bbe92a24d6a964db9"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 157,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "4dece2db87c6ce1c04ae06c088ddfe916c1c0c61"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 165,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "facc7a0f17bdf19396fae3d0de3da82e60503c0d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||
"line": 173,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "19de32c76518387218264d7c4dab914d143a9cca"
|
||||
"hash": "d52356f2af31d0167c02330ec22d09fbfa6b2b9f"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 130,
|
||||
"line": 114,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "239ac02a02694d5b20ab30d4c7ce5838c51d1515"
|
||||
"hash": "c8e8e06f370f93bf05867e93b5f037dfa46937b1"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 138,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "a54f9bc6d1edfa4df93c7dd7d409cfef3fccf99e"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 152,
|
||||
"line": 128,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "74a5f664d18f3916ea908897fcd0291cb0128f29"
|
||||
"hash": "9abaf71ca4b4f292b3b01e724d0a7733365e71f1"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 129,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "0b0743959778a9e3d93089b132608816ee4e6646"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 132,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "9759da7b7859b8ee8efaf74876430658ac6b6fe2"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 133,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "dba8be9a27ab74ec743b7d9e07c05d857b407dd3"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 134,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "9b1f5bce779aafc46b19d7a5d266eaa29f8f9be9"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 139,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "fe6fc4aea0994ba9da15b7c09d308842b67958cb"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 153,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "740ea5d793c7a34c9f352d8b333f3aa04cc80ee8"
|
||||
"column": 55,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "bd0e024fcad2e3f4566f15293e3c25c840f6dd3e"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 156,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "af8aca18f0226a5988ed90d44d95e2d607bfb5e6"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 157,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "7bc2453017793ae20cd6c10005f941d384b59d84"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 158,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "571b4ee5f22358dd165ec59696bb3439b7c9ff6c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 163,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "cfcb5946c86e289fc61623a794284a5a272d02e8"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 178,
|
||||
"line": 154,
|
||||
"column": 37,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "0ec402e43cb08bf129e0737c0d2c4f6d0c7af8bd"
|
||||
"hash": "596c4b180b926b7829f987384328bf5636cd367a"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 196,
|
||||
"line": 171,
|
||||
"column": 59,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "5b41d5f9b45da074fb7bbbbd45e0da501da72071"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 172,
|
||||
"column": 41,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "ec178d33e067aac892e015002afb6f3a2ff98762"
|
||||
"hash": "d92b92a25043244cca809bd129633b7e024e26b4"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 214,
|
||||
"line": 190,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "c0f4e5454e672b6064eb9cf6c235c6810f7bfa80"
|
||||
"hash": "dd9a85ea740742d620e864796f67c5bff834486d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 215,
|
||||
"line": 191,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "e3dd840d2474f9865a45822872bf9ecfb15961d7"
|
||||
"hash": "e3e59960d0d50709a57b336f66b586710b774892"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 216,
|
||||
"line": 192,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "a32a60382b145cc7a4a7ebe01ec435b8e3103320"
|
||||
"hash": "fe11b0e54396511e7b3b08615a78d22fc27e2fad"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||
"line": 246,
|
||||
"line": 222,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "082447e5c731012f3acc282943502775dfd24797"
|
||||
"hash": "63c14c2150c33ec701bc4a0ff94efde69537d490"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 118,
|
||||
"line": 96,
|
||||
"column": 20,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "d4fba4fe09af3c0937c0dd164928c8930c1591b5"
|
||||
"hash": "d2a9fdaeef0e2810f480022d4c6f99e4f76a818e"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 118,
|
||||
"line": 96,
|
||||
"column": 20,
|
||||
"ruleId": "vue/no-side-effects-in-computed-properties",
|
||||
"message": "Unexpected side effect in \"cities\" computed property.",
|
||||
"hash": "1113a114d5aaf9f32f442916d25458541c5af35c"
|
||||
"hash": "dd92a60a9b1ebefeb9a90941d45326fbfa483733"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 102,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "04be01ab638ce01f568fb0216929e65e1175ca23"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 110,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "8619c8e0b63e87d09268832f90e4fba06b87e41f"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 124,
|
||||
"column": 17,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "fa56a7c93583f0a9d0c2ecac10228c4f4fc1bc3a"
|
||||
"hash": "281f918da00635079501418b1e6b2c05b62eb4a7"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 132,
|
||||
"column": 17,
|
||||
"line": 125,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "9fe87937ea67d1dae95fb3d44d4be0da2eba0905"
|
||||
"hash": "c131b09fa67ab1d069f1d04a54582d6b0f206153"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 126,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "3d3a2a4add64c291b8f5f1cddd90a173cd6a819d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 131,
|
||||
"column": 21,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "ed48f4988914d7897018a2e06830a97e6740b3e8"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 145,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "744f3a7610d4d6015e50e25149bceffd6c6e2763"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
@@ -1241,139 +1441,115 @@
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 148,
|
||||
"column": 13,
|
||||
"line": 149,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "ab4f478fbfbc954b8dff75176dcd432f9ff28cfc"
|
||||
"hash": "1e7b1ad55866f708baaca72dfa4ff26d6f8e5d21"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 153,
|
||||
"column": 21,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "1d907d149f9ddb62e32140a90efe9a74b3e71fef"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 167,
|
||||
"line": 152,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "8aa37d2d4f011773e68838a2c88017875de563b5"
|
||||
"hash": "84779331536ffceec8d4a8c5ca4307310b882549"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 168,
|
||||
"line": 161,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "a4827a357e52a51fa9262319114d81a130296acf"
|
||||
"hash": "0789999841be671a4d8ab080d6fdb679f843eb52"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 169,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "a4c9715664202949e3242b8d4aa4098288b46dc4"
|
||||
"line": 170,
|
||||
"column": 51,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "bbb17afa114f016e2058d90aa32d2a625804f0d1"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 171,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "f3e9e21e433e90ec7b615b8940d43c4177372b66"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 174,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "770b7a24cc24b380e88db47d62422c8e1ece2571"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 183,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "2aef3c519a9ec6abcfe7573989d3de19d5c4c752"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 193,
|
||||
"column": 33,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "5d1f97e4d7d9f47399d312e8b9f95ef9e3843b8c"
|
||||
"hash": "5fbe407ceceb37bff2ac800ceddd7942540132f1"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 190,
|
||||
"column": 55,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'reject' is defined but never used.",
|
||||
"hash": "e2af91def877befbabef8e93deba4c58a3ee2ded"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 191,
|
||||
"column": 37,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "ee8544ee45681a650ed7d4918ae979685cdd8f0f"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 210,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "5d9d2217c8c7e6571bc9f72a98ea5b370edb4968"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 211,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "6e04619b373c23c91f6c36c2aad314ac16cdb697"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 212,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "39df045639a62f64ccdb03a80e286bc3ad772587"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 213,
|
||||
"column": 37,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "c1df874f790ef0c036bf58ae8a8db1ee173685d4"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 232,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "476e6588a28ac9382e8b9d2e63a8babecd23bad8"
|
||||
"hash": "c399a43fa797a8ce61c9d96a644a39cc84a387b7"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 233,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "6a0c82ba72d6d87217bf33a6ad8e40a4b81bc802"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 234,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "741d5af6c7d90041c0dc1c1df2e8699b80fca69a"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 235,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "c3ffd141f58d532663875cc5c7d338ed00db2a6d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||
"line": 267,
|
||||
"line": 245,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "2700f258396516a2fe971618fafbcdf72cdda3ab"
|
||||
"hash": "04337a07944caaa4819cfebcf29e1a7cbfdf248b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||
"line": 94,
|
||||
"line": 76,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "4be1b0592efa775092a91a1d744e16ce98bd216e"
|
||||
"hash": "373a2e31f110d138c66d77f1faf5dc61545c55af"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||
"line": 99,
|
||||
"line": 81,
|
||||
"column": 13,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "19b54b6d76c30249d520a296f826eda9d6eb0668"
|
||||
"hash": "421eb6a63224b4b1d81b216677a710c5c99ddee3"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/DatePane.vue",
|
||||
@@ -1393,19 +1569,19 @@
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||
"line": 169,
|
||||
"line": 155,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "dcb7b34098062760ddbb849655a5bb3ca65c36d3"
|
||||
"hash": "b3a822914fcb5e2fcf28efc331a45b9205002eeb"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||
"line": 178,
|
||||
"line": 164,
|
||||
"column": 17,
|
||||
"ruleId": "vue/no-mutating-props",
|
||||
"message": "Unexpected mutation of \"entity\" prop.",
|
||||
"hash": "86b3ecf201025cac36878c5e4bf8850fb9d58cb5"
|
||||
"hash": "72c7d850f6cdeaf65b373a33234222f9766ee30b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/index.js",
|
||||
@@ -1455,6 +1631,14 @@
|
||||
"message": "'app' is assigned a value but never used.",
|
||||
"hash": "9e6125f4fc387dc362c69cc6e3ce360eb2851f1b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/PickEntity/PickEntity.vue",
|
||||
"line": 60,
|
||||
"column": 22,
|
||||
"ruleId": "vue/require-valid-default-prop",
|
||||
"message": "Type of the default value for 'suggested' prop must be a function.",
|
||||
"hash": "d30212820bc2e97fa02d75dbc3a014558693f169"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue",
|
||||
"line": 24,
|
||||
@@ -1543,6 +1727,14 @@
|
||||
"message": "'tags' is assigned a value but never used.",
|
||||
"hash": "ae9bb2e0651c118ed9efd227e88b86cc83f5d80d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/components/StickyNav.vue",
|
||||
"line": 116,
|
||||
"column": 18,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'event' is defined but never used.",
|
||||
"hash": "201f182769c6dfb87148b841e7d9b592be429669"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js",
|
||||
"line": 19,
|
||||
@@ -1575,6 +1767,14 @@
|
||||
"message": "'app' is assigned a value but never used.",
|
||||
"hash": "aaaaa63e7a60443b8cbf8191feb9142852ebdf1c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/components/FormEvaluation.vue",
|
||||
"line": 79,
|
||||
"column": 13,
|
||||
"ruleId": "vue/require-v-for-key",
|
||||
"message": "Elements in iteration expect to have 'v-bind:key' directives.",
|
||||
"hash": "422f53925922e59655d0f71624c19af75d41628c"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js",
|
||||
"line": 12,
|
||||
@@ -1615,6 +1815,22 @@
|
||||
"message": "'evalFQDN' is assigned a value but never used.",
|
||||
"hash": "7fc32caafa23addddf44f3acbc5045b4523a0271"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/store.js",
|
||||
"line": 611,
|
||||
"column": 9,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'errors' is assigned a value but never used.",
|
||||
"hash": "c41cf979fc1626c38328dbf1028800c3395496bd"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/App.vue",
|
||||
"line": 282,
|
||||
"column": 7,
|
||||
"ruleId": "@typescript-eslint/no-unused-expressions",
|
||||
"message": "Expected an assignment or function call and instead saw an expression.",
|
||||
"hash": "de3a6e2bb10a80a2bacba665be74266c7efc7d64"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js",
|
||||
"line": 16,
|
||||
@@ -1631,6 +1847,38 @@
|
||||
"message": "'app' is assigned a value but never used.",
|
||||
"hash": "2f161e663689e3e4dfe2c53b0d64c91a4d2b1a60"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||
"line": 263,
|
||||
"column": 19,
|
||||
"ruleId": "vue/return-in-computed-property",
|
||||
"message": "Expected to return a value in \"refreshNetwork\" computed property.",
|
||||
"hash": "2c1b08a49098c83b09058cedc0a962126e91e544"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||
"line": 270,
|
||||
"column": 7,
|
||||
"ruleId": "vue/no-side-effects-in-computed-properties",
|
||||
"message": "Unexpected side effect in \"legendLayers\" computed property.",
|
||||
"hash": "760948d2187c853f17ac9a1bd7107e883092d4f4"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||
"line": 281,
|
||||
"column": 5,
|
||||
"ruleId": "vue/no-dupe-keys",
|
||||
"message": "Duplicate key 'checkedLayers'. May cause name collision in script or template tag.",
|
||||
"hash": "447edb461e15e3ff5c60c8ecba88131e442539aa"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/App.vue",
|
||||
"line": 353,
|
||||
"column": 7,
|
||||
"ruleId": "@typescript-eslint/no-unused-expressions",
|
||||
"message": "Expected an assignment or function call and instead saw an expression.",
|
||||
"hash": "9cf656cbf1eb3d7cc0082e63adcd320b6093d14f"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js",
|
||||
"line": 20,
|
||||
@@ -1639,6 +1887,22 @@
|
||||
"message": "'app' is assigned a value but never used.",
|
||||
"hash": "9e94e6412b8a44e47bfe8e66218cad09cff5bed4"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AccompanyingPeriod/SetReferrer.vue",
|
||||
"line": 42,
|
||||
"column": 16,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'response' is defined but never used.",
|
||||
"hash": "62de07b13c662e32332bb062038acee23978ea70"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue",
|
||||
"line": 356,
|
||||
"column": 28,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'_response' is defined but never used.",
|
||||
"hash": "097e7788a2b5dea500b80b8a3cf968e57063a66a"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons/TypeUserGroup.vue",
|
||||
"line": 6,
|
||||
@@ -1654,5 +1918,45 @@
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'UserRenderBoxBadge' is defined but never used.",
|
||||
"hash": "99eba0d8633b2c9497417f4f61ec4194dbb2a96b"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||
"line": 4,
|
||||
"column": 3,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'StoredObjectStatus' is defined but never used.",
|
||||
"hash": "63f8c4572293916850d6165647774b27d4b732c6"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||
"line": 5,
|
||||
"column": 3,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'StoredObjectStatusChange' is defined but never used.",
|
||||
"hash": "a87c178e3eb5999bf0f46b3fa1c6da77e1be08b9"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||
"line": 30,
|
||||
"column": 61,
|
||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||
"message": "'e' is defined but never used.",
|
||||
"hash": "02953121583f4f73742a19adab099ab63df9076e"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||
"line": 31,
|
||||
"column": 32,
|
||||
"ruleId": "@typescript-eslint/no-explicit-any",
|
||||
"message": "Unexpected any. Specify a different type.",
|
||||
"hash": "af48e21a1651b6017ede882dab249c00a818a44d"
|
||||
},
|
||||
{
|
||||
"path": "src/Bundle/ChillWopiBundle/src/Resources/public/module/pending/index.ts",
|
||||
"line": 37,
|
||||
"column": 16,
|
||||
"ruleId": "@typescript-eslint/no-explicit-any",
|
||||
"message": "Unexpected any. Specify a different type.",
|
||||
"hash": "7513ea552a0a649ce4ab93b6cf9d40bfef4f68d9"
|
||||
}
|
||||
]
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -18,9 +18,6 @@ migrations/*
|
||||
templates/*
|
||||
translations/*
|
||||
|
||||
# we allow developers to add customization on their installation, without commiting it
|
||||
config/packages/dev/*
|
||||
|
||||
###> symfony/framework-bundle ###
|
||||
/.env.local
|
||||
/.env.local.php
|
||||
|
@@ -27,11 +27,11 @@ Chill is a comprehensive web application built as a set of Symfony bundles. It i
|
||||
|
||||
## Project Structure
|
||||
|
||||
Note: This is a project that's existed for a long time, and throughout the years we've used multiple structures inside each bundle. When having the choice, the developers should choose the new structure.
|
||||
Note: This is a project which exists from a long time ago, and we found multiple structure inside each bundle. When having the choice, the developers should choose the new structure.
|
||||
|
||||
The project follows a standard Symfony bundle structure:
|
||||
- `/src/Bundle/`: Contains all the Chill bundles. The code is either at the root of the bundle directory, or within a `src/` directory (preferred). See psr4 mapping at the root's `composer.json`.
|
||||
- each bundle comes with its own tests, either in the `Tests` directory (when the code is directly within the bundle directory (for instance `src/Bundle/ChillMainBundle/Tests`, `src/Bundle/ChillPersonBundle/Tests`)), or inside the `tests` directory, alongside the `src/` sub-directory (example: `src/Bundle/ChillWopiBundle/tests`) (this is the preferred way).
|
||||
- each bundle come with his own tests, either in the `Tests` directory (when the code is directly within the bundle directory (for instance `src/Bundle/ChillMainBundle/Tests`, `src/Bundle/ChillPersonBundle/Tests`)), or inside the `tests` directory, alongside to the `src/` sub-directory (example: `src/Bundle/ChillWopiBundle/tests`) (this is the preferred way).
|
||||
- `/docs/`: Contains project documentation
|
||||
|
||||
Each bundle typically has the following structure:
|
||||
@@ -46,13 +46,13 @@ Each bundle typically has the following structure:
|
||||
|
||||
### A special word about TicketBundle
|
||||
|
||||
The ticket bundle is developed using a kind of "Command" pattern. The controller fills a "Command," and a "CommandHandler" handles this command. They are saved in the `src/Bundle/ChillTicketBundle/src/Action` directory.
|
||||
The ticket bundle is developed using a kind of "Command" pattern. The controller fill a "Command", and a "CommandHandler" handle this command. They are savec in the `src/Bundle/ChillTicketBundle/src/Action` directory.
|
||||
|
||||
## Development Guidelines
|
||||
|
||||
### Building and Configuration Instructions
|
||||
|
||||
All the commands should be run through the `symfony` command, which will configure the required variables.
|
||||
All the command should be run through the `symfony` command, which will configure the required variables.
|
||||
|
||||
For assets, we must ensure that we use node at version `^20.0.0`. This is done using `nvm use 20`.
|
||||
|
||||
@@ -87,7 +87,7 @@ For assets, we must ensure that we use node at version `^20.0.0`. This is done u
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
6. **Set Up the Database**:
|
||||
5. **Set Up the Database**:
|
||||
```bash
|
||||
# Create the database
|
||||
symfony console doctrine:database:create
|
||||
@@ -99,20 +99,20 @@ For assets, we must ensure that we use node at version `^20.0.0`. This is done u
|
||||
symfony console doctrine:fixtures:load
|
||||
```
|
||||
|
||||
7. **Build Assets**:
|
||||
6. **Build Assets**:
|
||||
```bash
|
||||
nvm use 20
|
||||
yarn run encore dev
|
||||
```
|
||||
|
||||
8. **Start the Development Server**:
|
||||
7. **Start the Development Server**:
|
||||
```bash
|
||||
symfony server:start -d
|
||||
```
|
||||
|
||||
#### Docker Setup
|
||||
|
||||
The project includes a Docker configuration for easier development:
|
||||
The project includes Docker configuration for easier development:
|
||||
|
||||
1. **Start Docker Services**:
|
||||
```bash
|
||||
@@ -153,9 +153,9 @@ Key configuration files:
|
||||
|
||||
Each time a doctrine entity is created, we generate migration to adapt the database.
|
||||
|
||||
The migration is created using the command `symfony console doctrine:migrations:diff --no-interaction --namespace <namespace>`, where the namespace is the relevant namespace for migration. As this is a bash script, remember to quote the `\` (`\` must become `\\` in your command).
|
||||
The migration are created using the command `symfony console doctrine:migrations:diff --no-interaction --namespace <namespace>`, where the namespace is the relevant namespace for migration. As this is a bash script, do not forget to quote the `\` (`\` must become `\\` in your command).
|
||||
|
||||
Each bundle has his own namespace for migration (always ask me to confirm that command with a list of updated / created entities so that I can confirm to you that it is ok):
|
||||
Each bundle has his own namespace for migration (always ask me to confirm that command, with a list of updated / created entities so that I can confirm you that it is ok):
|
||||
|
||||
- `Chill\Bundle\ActivityBundle` writes migrations to `Chill\Migrations\Activity`;
|
||||
- `Chill\Bundle\BudgetBundle` writes migrations to `Chill\Migrations\Budget`;
|
||||
@@ -183,7 +183,7 @@ Once created the, comment's classes should be removed and a description of the c
|
||||
|
||||
When we need to use a DateTime or DateTimeImmutable that need to express "now", we prefer the usage of
|
||||
`Symfony\Component\Clock\ClockInterface`, where possible. This is usually not possible in doctrine entities,
|
||||
where injection does not work when restoring an entity from a database, but usually possible in services.
|
||||
where injection does not work when restoring an entity from database, but usually possible in services.
|
||||
|
||||
In test, we use `\Symfony\Component\Clock\MockClock` which is an implementation of `Symfony\Component\Clock\ClockInterface`
|
||||
where we have full and easy control of the date.
|
||||
@@ -198,9 +198,9 @@ The project uses PHPUnit for testing. Each bundle has its own test suite, and th
|
||||
|
||||
For creating mock, we prefer using prophecy (library phpspec/prophecy).
|
||||
|
||||
##### Useful helpers and tips that avoid creating a mock
|
||||
##### Useful helpers and tips that avoid create a mock
|
||||
|
||||
Some notable implementations that are test helpers and avoid creating a mock:
|
||||
Some notable implementations that are tests helper, and avoid to create a mock:
|
||||
|
||||
- `\Psr\Log\NullLogger`, an implementation of `\Psr\Log\LoggerInterface`;
|
||||
- `\Symfony\Component\Clock\MockClock`, an implementation of `Symfony\Component\Clock\ClockInterface` (already mentioned above);
|
||||
@@ -234,9 +234,15 @@ This must be a decision made by a human, not by an AI. Every AI task must abort
|
||||
|
||||
#### Running Tests
|
||||
|
||||
The tests are run from the project's root (not from the bundle's root: so, do not change the directory to any bundle directory before running tests).
|
||||
The tests are run from the project's root (not from the bundle's root).
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
vendor/bin/phpunit
|
||||
|
||||
# Run tests for a specific bundle
|
||||
vendor/bin/phpunit --testsuite NameBundle
|
||||
|
||||
# Run a specific test file
|
||||
vendor/bin/phpunit path/to/TestFile.php
|
||||
|
||||
@@ -291,7 +297,7 @@ class TicketTest extends TestCase
|
||||
|
||||
#### Test Database
|
||||
|
||||
For tests that require a database, the project uses a postgresql database filled with fixtures (usage of doctrine-fixtures). You can configure a different database for testing in the `.env.test` file.
|
||||
For tests that require a database, the project uses postgresql database filled by fixtures (usage of doctrine-fixtures). You can configure a different database for testing in the `.env.test` file.
|
||||
|
||||
### Code Quality Tools
|
||||
|
||||
|
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
30
.vscode/launch.json
vendored
30
.vscode/launch.json
vendored
@@ -1,30 +0,0 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Chill Debug",
|
||||
"type": "php",
|
||||
"request": "launch",
|
||||
"port": 9000,
|
||||
"pathMappings": {
|
||||
"/var/www/html": "${workspaceFolder}"
|
||||
},
|
||||
"preLaunchTask": "symfony"
|
||||
},
|
||||
{
|
||||
"name": "Yarn Encore Dev (Watch)",
|
||||
"type": "node-terminal",
|
||||
"request": "launch",
|
||||
"command": "yarn encore dev --watch",
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Chill Debug + Yarn Encore Dev (Watch)",
|
||||
"configurations": ["Chill Debug", "Yarn Encore Dev (Watch)"]
|
||||
}
|
||||
]
|
||||
}
|
23
.vscode/tasks.json
vendored
23
.vscode/tasks.json
vendored
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "symfony",
|
||||
"args": [
|
||||
"server:start",
|
||||
"--allow-http",
|
||||
"--no-tls",
|
||||
"--port=8000",
|
||||
"--allow-all-ip",
|
||||
"-d"
|
||||
],
|
||||
"label": "symfony"
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"command": "yarn",
|
||||
"args": ["encore", "dev", "--watch"],
|
||||
"label": "webpack"
|
||||
}
|
||||
]
|
||||
}
|
31
CHANGELOG.md
31
CHANGELOG.md
@@ -6,37 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||
|
||||
|
||||
## v4.2.1 - 2025-09-03
|
||||
### Fixed
|
||||
* Fix exports to work with DirectExportInterface
|
||||
### DX
|
||||
* Improve error message when a stored object cannot be written on local disk
|
||||
|
||||
|
||||
## v4.2.0 - 2025-09-02
|
||||
### Feature
|
||||
* ([#64](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/64)) Add external identifier for a Person
|
||||
|
||||
**Schema Change**: Add columns or tables
|
||||
* ([#330](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/330) Allow users to choose for which notifications they want to receive an email
|
||||
### Fixed
|
||||
* ([#422](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/422)) Fixed html layout of pages for recovering password
|
||||
* Fix typo in 'uncheckAll' script for centers selection
|
||||
* Fix incorrect parameter name in event details link
|
||||
|
||||
## v4.1.0 - 2025-08-26
|
||||
### Feature
|
||||
* ([#400](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/400)) Add filter to social actions list to filter out actions where current user intervenes
|
||||
* ([#399](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/399)) Show filters on list pages unfolded by default
|
||||
* Expansion of event module with new fields in the creation form: thematic, internal/external animator, responsable, and budget elements. Filtering options in the event list + adapted exports
|
||||
|
||||
**Schema Change**: Add columns or tables
|
||||
### Fixed
|
||||
* ([#382](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/382)) adjust display logic for accompanying period dates, include closing date if period is closed.
|
||||
* ([#384](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/384)) add min and step attributes to integer field in DateIntervalType
|
||||
### UX
|
||||
* Limit display of participations in event list
|
||||
|
||||
## v4.0.2 - 2025-07-09
|
||||
### Fixed
|
||||
* Fix add missing translation
|
||||
|
@@ -54,7 +54,7 @@ Arborescence:
|
||||
- person
|
||||
- personvendee
|
||||
- household_edit_metadata
|
||||
- index.ts
|
||||
- index.js
|
||||
```
|
||||
|
||||
## Organisation des feuilles de styles
|
||||
|
@@ -133,7 +133,6 @@
|
||||
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
|
||||
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
|
||||
"Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src",
|
||||
"Chill\\TicketBundle\\": "src/Bundle/ChillTicketBundle/src",
|
||||
"Chill\\Utils\\Rector\\": "utils/rector/src"
|
||||
}
|
||||
},
|
||||
|
@@ -35,7 +35,6 @@ return [
|
||||
Chill\ThirdPartyBundle\ChillThirdPartyBundle::class => ['all' => true],
|
||||
Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true],
|
||||
Chill\WopiBundle\ChillWopiBundle::class => ['all' => true],
|
||||
Chill\TicketBundle\ChillTicketBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
||||
];
|
||||
|
@@ -1,5 +1,5 @@
|
||||
chill_doc_store:
|
||||
use_driver: local_storage
|
||||
use_driver: openstack
|
||||
local_storage:
|
||||
storage_path: '%kernel.project_dir%/var/storage'
|
||||
openstack:
|
||||
|
@@ -1,5 +0,0 @@
|
||||
chill_ticket:
|
||||
ticket:
|
||||
person_per_ticket: one # One of "one"; "many"
|
||||
response_time_exceeded_delay: PT12H
|
||||
|
@@ -14,7 +14,6 @@ doctrine_migrations:
|
||||
'Chill\Migrations\Calendar': '@ChillCalendarBundle/migrations'
|
||||
'Chill\Migrations\Budget': '@ChillBudgetBundle/migrations'
|
||||
'Chill\Migrations\Report': '@ChillReportBundle/migrations'
|
||||
'Chill\Migrations\Ticket': '@ChillTicketBundle/migrations'
|
||||
all_or_nothing:
|
||||
true
|
||||
|
||||
|
@@ -17,3 +17,9 @@ when@dev:
|
||||
defaults:
|
||||
template: '@ChillMain/Dev/dev.assets.test2.html.twig'
|
||||
|
||||
|
||||
sass_address_picker:
|
||||
path: /_dev/address-picker
|
||||
controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController
|
||||
defaults:
|
||||
template: '@ChillMain/Dev/dev.address-picker.html.twig'
|
||||
|
@@ -1,2 +0,0 @@
|
||||
chill_ticket_bundle:
|
||||
resource: '@ChillTicketBundle/config/routes.yaml'
|
@@ -11,94 +11,24 @@
|
||||
Create a new bundle
|
||||
*******************
|
||||
|
||||
Create your own bundle is not a trivial task.
|
||||
|
||||
The easiest way to achieve this is seems to be :
|
||||
|
||||
1. Prepare a fresh installation of the chill project, in a new directory
|
||||
2. Create a new bundle in this project, in the src directory
|
||||
3. Initialize a git repository **at the root bundle**, and create your initial commit.
|
||||
4. Register the bundle with composer/packagist. If you do not plan to distribute your bundle with packagist, you may use a custom repository for achieve this [#f1]_
|
||||
5. Move to a development installation, made as described in the :ref:`installation-for-development` section, and add your new repository to the composer.json file
|
||||
6. Work as :ref:`usual <editing-code-and-commiting>`
|
||||
|
||||
.. warning::
|
||||
|
||||
This part of the doc is not yet tested
|
||||
|
||||
Create a new directory with Bundle class
|
||||
----------------------------------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
mkdir -p src/Bundle/ChillSomeBundle/src/config
|
||||
mkdir -p src/Bundle/ChillSomeBundle/src/Controller
|
||||
|
||||
Add a bundle file
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\SomeBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||
|
||||
class ChillSomeBundle extends Bundle {}
|
||||
|
||||
And a route file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
chill_ticket_controller:
|
||||
resource: '@ChillTicketBundle/Controller/'
|
||||
type: annotation
|
||||
|
||||
Register the new psr-4 namespace
|
||||
--------------------------------
|
||||
|
||||
In composer.json, add the new psr4 namespace
|
||||
|
||||
.. code-block:: diff
|
||||
|
||||
{
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
+ "Chill\\SomeBundle\\": "src/Bundle/ChillSomeBundle/src",
|
||||
}
|
||||
}
|
||||
}
|
||||
TODO
|
||||
|
||||
|
||||
Register the bundle
|
||||
-------------------
|
||||
|
||||
Register in the file :code:`config/bundles.php`:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
Vendor\Bundle\YourBundle\YourBundle::class => ['all' => true],
|
||||
|
||||
And import routes in :code:`config/routes/chill_some_bundle.yaml`:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
chill_ticket_bundle:
|
||||
resource: '@ChillSomeBundle/config/routes.yaml'
|
||||
|
||||
Add the doctrine_migration namespace
|
||||
------------------------------------
|
||||
|
||||
Add the namespace to :code:`config/packages/doctrine_migrations_chill.yaml`
|
||||
|
||||
.. code-block:: diff
|
||||
|
||||
doctrine_migrations:
|
||||
migrations_paths:
|
||||
+ 'Chill\Some\Ticket': '@ChillSomeBundle/migrations'
|
||||
|
||||
Dump autoloading
|
||||
----------------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
symfony composer dump-autoload
|
||||
.. rubric:: Footnotes
|
||||
|
||||
.. [#f1] Be aware that we use the Affero GPL Licence, which ensure that all users must have access to derivative works done with this software.
|
||||
|
@@ -45,6 +45,7 @@
|
||||
"webpack-cli": "^5.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fragaria/address-formatter": "^6.6.1",
|
||||
"@fullcalendar/core": "^6.1.4",
|
||||
"@fullcalendar/daygrid": "^6.1.4",
|
||||
"@fullcalendar/interaction": "^6.1.4",
|
||||
@@ -69,6 +70,7 @@
|
||||
"vue-i18n": "^9.1.6",
|
||||
"vue-multiselect": "3.0.0-alpha.2",
|
||||
"vue-toast-notification": "^3.1.2",
|
||||
"vue-use-leaflet": "^0.1.7",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
@@ -79,12 +81,12 @@
|
||||
"dev": "encore dev",
|
||||
"watch": "encore dev --watch",
|
||||
"build": "encore production --progress",
|
||||
"specs-build": "yaml-merge src/Bundle/ChillMainBundle/chill.api.specs.yaml src/Bundle/ChillPersonBundle/chill.api.specs.yaml src/Bundle/ChillCalendarBundle/chill.api.specs.yaml src/Bundle/ChillThirdPartyBundle/chill.api.specs.yaml src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml src/Bundle/ChillTicketBundle/chill.api.specs.yaml> templates/api/specs.yaml",
|
||||
"specs-build": "yaml-merge src/Bundle/ChillMainBundle/chill.api.specs.yaml src/Bundle/ChillPersonBundle/chill.api.specs.yaml src/Bundle/ChillCalendarBundle/chill.api.specs.yaml src/Bundle/ChillThirdPartyBundle/chill.api.specs.yaml src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml> templates/api/specs.yaml",
|
||||
"specs-validate": "swagger-cli validate templates/api/specs.yaml",
|
||||
"specs-create-dir": "mkdir -p templates/api",
|
||||
"specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate",
|
||||
"version": "node --version",
|
||||
"eslint": "eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
|
||||
"eslint": "npx eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
@@ -58,10 +58,6 @@
|
||||
<!-- temporarily removed, the time to find a fix -->
|
||||
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonDuplicateControllerViewTest.php</exclude>
|
||||
</testsuite>
|
||||
|
||||
<testsuite name="TicketBundle">
|
||||
<directory suffix="Test.php">src/Bundle/ChillTicketBundle/tests/</directory>
|
||||
</testsuite>
|
||||
<!--
|
||||
<testsuite name="ReportBundle">
|
||||
<directory suffix="Test.php">src/Bundle/ChillReportBundle/Tests/</directory>
|
||||
|
@@ -10,7 +10,10 @@
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0"
|
||||
v-if="
|
||||
getContext === 'accompanyingCourse' &&
|
||||
suggestedEntities.length > 0
|
||||
"
|
||||
>
|
||||
<ul class="list-suggest add-items inline">
|
||||
<li
|
||||
|
@@ -39,11 +39,17 @@
|
||||
<option selected disabled value="">
|
||||
{{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }}
|
||||
</option>
|
||||
<option v-for="t in locationTypes" :value="t" :key="t.id">
|
||||
<option
|
||||
v-for="t in locationTypes"
|
||||
:value="t"
|
||||
:key="t.id"
|
||||
>
|
||||
{{ localizeString(t.title) }}
|
||||
</option>
|
||||
</select>
|
||||
<label>{{ trans(ACTIVITY_LOCATION_FIELDS_TYPE) }}</label>
|
||||
<label>{{
|
||||
trans(ACTIVITY_LOCATION_FIELDS_TYPE)
|
||||
}}</label>
|
||||
</div>
|
||||
|
||||
<div class="form-floating mb-3">
|
||||
@@ -102,7 +108,10 @@
|
||||
</form>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button class="btn btn-save" @click.prevent="saveNewLocation">
|
||||
<button
|
||||
class="btn btn-save"
|
||||
@click.prevent="saveNewLocation"
|
||||
>
|
||||
{{ trans(SAVE) }}
|
||||
</button>
|
||||
</template>
|
||||
@@ -235,7 +244,8 @@ export default {
|
||||
},
|
||||
hasPhonenumber1() {
|
||||
return (
|
||||
this.selected.phonenumber1 !== null && this.selected.phonenumber1 !== ""
|
||||
this.selected.phonenumber1 !== null &&
|
||||
this.selected.phonenumber1 !== ""
|
||||
);
|
||||
},
|
||||
showAddAddress() {
|
||||
|
@@ -49,7 +49,9 @@
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div v-if="actionIsLoading === true">
|
||||
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
|
||||
<i
|
||||
class="chill-green fa fa-circle-o-notch fa-spin fa-lg"
|
||||
></i>
|
||||
</div>
|
||||
|
||||
<span
|
||||
@@ -62,7 +64,8 @@
|
||||
<template
|
||||
v-else-if="
|
||||
socialActionsList.length > 0 &&
|
||||
(socialIssuesSelected.length || socialActionsSelected.length)
|
||||
(socialIssuesSelected.length ||
|
||||
socialActionsSelected.length)
|
||||
"
|
||||
>
|
||||
<div
|
||||
@@ -85,7 +88,9 @@
|
||||
</template>
|
||||
|
||||
<span
|
||||
v-else-if="actionAreLoaded && socialActionsList.length === 0"
|
||||
v-else-if="
|
||||
actionAreLoaded && socialActionsList.length === 0
|
||||
"
|
||||
class="inline-choice chill-no-data-statement mt-3"
|
||||
>
|
||||
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
|
||||
@@ -164,7 +169,8 @@ export default {
|
||||
/* Add in list the issues already associated (if not yet listed) */
|
||||
this.socialIssuesSelected.forEach((issue) => {
|
||||
if (
|
||||
this.socialIssuesList.filter((i) => i.id === issue.id).length !== 1
|
||||
this.socialIssuesList.filter((i) => i.id === issue.id)
|
||||
.length !== 1
|
||||
) {
|
||||
this.$store.commit("addIssueInList", issue);
|
||||
}
|
||||
|
@@ -10,7 +10,9 @@
|
||||
:value="issue"
|
||||
/>
|
||||
<label class="form-check-label" :for="issue.id">
|
||||
<span class="badge bg-chill-l-gray text-dark">{{ issue.text }}</span>
|
||||
<span class="badge bg-chill-l-gray text-dark">{{
|
||||
issue.text
|
||||
}}</span>
|
||||
</label>
|
||||
</div>
|
||||
</span>
|
||||
|
@@ -68,7 +68,9 @@ export type EventInputCalendarRange = EventInput & {
|
||||
export function isEventInputCalendarRange(
|
||||
toBeDetermined: EventInputCalendarRange | EventInput,
|
||||
): toBeDetermined is EventInputCalendarRange {
|
||||
return typeof toBeDetermined.is === "string" && toBeDetermined.is === "range";
|
||||
return (
|
||||
typeof toBeDetermined.is === "string" && toBeDetermined.is === "range"
|
||||
);
|
||||
}
|
||||
|
||||
export {};
|
||||
|
@@ -61,14 +61,22 @@
|
||||
<label class="input-group-text" for="slotDuration"
|
||||
>Durée des créneaux</label
|
||||
>
|
||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
||||
<select
|
||||
v-model="slotDuration"
|
||||
id="slotDuration"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="00:05:00">5 minutes</option>
|
||||
<option value="00:10:00">10 minutes</option>
|
||||
<option value="00:15:00">15 minutes</option>
|
||||
<option value="00:30:00">30 minutes</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMinTime">De</label>
|
||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
||||
<select
|
||||
v-model="slotMinTime"
|
||||
id="slotMinTime"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="00:00:00">0h</option>
|
||||
<option value="01:00:00">1h</option>
|
||||
<option value="02:00:00">2h</option>
|
||||
@@ -84,7 +92,11 @@
|
||||
<option value="12:00:00">12h</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
||||
<select
|
||||
v-model="slotMaxTime"
|
||||
id="slotMaxTime"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="12:00:00">12h</option>
|
||||
<option value="13:00:00">13h</option>
|
||||
<option value="14:00:00">14h</option>
|
||||
@@ -112,7 +124,9 @@
|
||||
v-model="hideWeekends"
|
||||
/>
|
||||
</span>
|
||||
<label for="showHideWE" class="form-check-label input-group-text"
|
||||
<label
|
||||
for="showHideWE"
|
||||
class="form-check-label input-group-text"
|
||||
>Week-ends</label
|
||||
>
|
||||
</div>
|
||||
@@ -128,7 +142,9 @@
|
||||
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||
>{{ arg.timeText }}
|
||||
{{ arg.event.extendedProps.locationName }}
|
||||
<small>{{ arg.event.extendedProps.userLabel }}</small></b
|
||||
<small>{{
|
||||
arg.event.extendedProps.userLabel
|
||||
}}</small></b
|
||||
>
|
||||
<b v-else-if="arg.event.extendedProps.is === 'current'"
|
||||
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||
@@ -136,7 +152,9 @@
|
||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||
arg.event.title
|
||||
}}</b>
|
||||
<b v-else>{{ arg.timeText }} {{ $t("current_selected") }} </b>
|
||||
<b v-else
|
||||
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||
</b>
|
||||
</span>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
@@ -250,7 +268,9 @@ export default {
|
||||
this.$store.state.activity.endDate !== null)
|
||||
) {
|
||||
if (
|
||||
!window.confirm(this.$t("change_main_user_will_reset_event_data"))
|
||||
!window.confirm(
|
||||
this.$t("change_main_user_will_reset_event_data"),
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -258,9 +278,13 @@ export default {
|
||||
|
||||
// add the previous user, if any, in the previous user list (in use for suggestion)
|
||||
if (null !== this.$store.getters.getMainUser) {
|
||||
const suggestedUids = new Set(this.$data.previousUser.map((u) => u.id));
|
||||
const suggestedUids = new Set(
|
||||
this.$data.previousUser.map((u) => u.id),
|
||||
);
|
||||
if (!suggestedUids.has(this.$store.getters.getMainUser.id)) {
|
||||
this.$data.previousUser.push(this.$store.getters.getMainUser);
|
||||
this.$data.previousUser.push(
|
||||
this.$store.getters.getMainUser,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +314,8 @@ export default {
|
||||
// show an alert if changing mainUser
|
||||
if (
|
||||
(this.$store.getters.getMainUser !== null &&
|
||||
this.$store.state.me.id !== this.$store.getters.getMainUser.id) ||
|
||||
this.$store.state.me.id !==
|
||||
this.$store.getters.getMainUser.id) ||
|
||||
this.$store.getters.getMainUser === null
|
||||
) {
|
||||
if (!window.confirm(this.$t("will_change_main_user_for_me"))) {
|
||||
@@ -334,7 +359,9 @@ export default {
|
||||
this.$store.getters.getMainUser.id
|
||||
) {
|
||||
if (
|
||||
!window.confirm(this.$t("this_calendar_range_will_change_main_user"))
|
||||
!window.confirm(
|
||||
this.$t("this_calendar_range_will_change_main_user"),
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@@ -4,9 +4,18 @@
|
||||
{{ user.text }}
|
||||
<template v-if="invite !== null">
|
||||
<i v-if="invite.status === 'accepted'" class="fa fa-check" />
|
||||
<i v-else-if="invite.status === 'declined'" class="fa fa-times" />
|
||||
<i v-else-if="invite.status === 'pending'" class="fa fa-question-o" />
|
||||
<i v-else-if="invite.status === 'tentative'" class="fa fa-question" />
|
||||
<i
|
||||
v-else-if="invite.status === 'declined'"
|
||||
class="fa fa-times"
|
||||
/>
|
||||
<i
|
||||
v-else-if="invite.status === 'pending'"
|
||||
class="fa fa-question-o"
|
||||
/>
|
||||
<i
|
||||
v-else-if="invite.status === 'tentative'"
|
||||
class="fa fa-question"
|
||||
/>
|
||||
<span v-else="">{{ invite.status }}</span>
|
||||
</template>
|
||||
</span>
|
||||
@@ -60,7 +69,8 @@ export default {
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
backgroundColor: this.$store.getters.getUserData(this.user).mainColor,
|
||||
backgroundColor: this.$store.getters.getUserData(this.user)
|
||||
.mainColor,
|
||||
};
|
||||
},
|
||||
rangeShow: {
|
||||
@@ -71,7 +81,9 @@ export default {
|
||||
});
|
||||
},
|
||||
get() {
|
||||
return this.$store.getters.isRangeShownOnCalendarForUser(this.user);
|
||||
return this.$store.getters.isRangeShownOnCalendarForUser(
|
||||
this.user,
|
||||
);
|
||||
},
|
||||
},
|
||||
remoteShow: {
|
||||
@@ -82,7 +94,9 @@ export default {
|
||||
});
|
||||
},
|
||||
get() {
|
||||
return this.$store.getters.isRemoteShownOnCalendarForUser(this.user);
|
||||
return this.$store.getters.isRemoteShownOnCalendarForUser(
|
||||
this.user,
|
||||
);
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@@ -22,25 +22,33 @@
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||
<li v-if="status !== Statuses.ACCEPTED">
|
||||
<a class="dropdown-item" @click="changeStatus(Statuses.ACCEPTED)"
|
||||
><i class="fa fa-check" aria-hidden="true"></i> {{ $t("Accept") }}</a
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="changeStatus(Statuses.ACCEPTED)"
|
||||
><i class="fa fa-check" aria-hidden="true"></i>
|
||||
{{ $t("Accept") }}</a
|
||||
>
|
||||
</li>
|
||||
<li v-if="status !== Statuses.DECLINED">
|
||||
<a class="dropdown-item" @click="changeStatus(Statuses.DECLINED)"
|
||||
><i class="fa fa-times" aria-hidden="true"></i> {{ $t("Decline") }}</a
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="changeStatus(Statuses.DECLINED)"
|
||||
><i class="fa fa-times" aria-hidden="true"></i>
|
||||
{{ $t("Decline") }}</a
|
||||
>
|
||||
</li>
|
||||
<li v-if="status !== Statuses.TENTATIVELY_ACCEPTED">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="changeStatus(Statuses.TENTATIVELY_ACCEPTED)"
|
||||
><i class="fa fa-question"></i> {{ $t("Tentatively_accept") }}</a
|
||||
><i class="fa fa-question"></i>
|
||||
{{ $t("Tentatively_accept") }}</a
|
||||
>
|
||||
</li>
|
||||
<li v-if="status !== Statuses.PENDING">
|
||||
<a class="dropdown-item" @click="changeStatus(Statuses.PENDING)"
|
||||
><i class="fa fa-hourglass-o"></i> {{ $t("Set_pending") }}</a
|
||||
><i class="fa fa-hourglass-o"></i>
|
||||
{{ $t("Set_pending") }}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -83,7 +91,9 @@ export default defineComponent({
|
||||
},
|
||||
},
|
||||
emits: {
|
||||
statusChanged(payload: "accepted" | "declined" | "pending" | "tentative") {
|
||||
statusChanged(
|
||||
payload: "accepted" | "declined" | "pending" | "tentative",
|
||||
) {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
|
@@ -23,14 +23,22 @@
|
||||
<label class="input-group-text" for="slotDuration"
|
||||
>Durée des créneaux</label
|
||||
>
|
||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
||||
<select
|
||||
v-model="slotDuration"
|
||||
id="slotDuration"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="00:05:00">5 minutes</option>
|
||||
<option value="00:10:00">10 minutes</option>
|
||||
<option value="00:15:00">15 minutes</option>
|
||||
<option value="00:30:00">30 minutes</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMinTime">De</label>
|
||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
||||
<select
|
||||
v-model="slotMinTime"
|
||||
id="slotMinTime"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="00:00:00">0h</option>
|
||||
<option value="01:00:00">1h</option>
|
||||
<option value="02:00:00">2h</option>
|
||||
@@ -46,7 +54,11 @@
|
||||
<option value="12:00:00">12h</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
||||
<select
|
||||
v-model="slotMaxTime"
|
||||
id="slotMaxTime"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="12:00:00">12h</option>
|
||||
<option value="13:00:00">13h</option>
|
||||
<option value="14:00:00">14h</option>
|
||||
@@ -74,7 +86,9 @@
|
||||
v-model="showWeekends"
|
||||
/>
|
||||
</span>
|
||||
<label for="showHideWE" class="form-check-label input-group-text"
|
||||
<label
|
||||
for="showHideWE"
|
||||
class="form-check-label input-group-text"
|
||||
>Week-ends</label
|
||||
>
|
||||
</div>
|
||||
@@ -84,12 +98,16 @@
|
||||
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
||||
<template v-slot:eventContent="{ event }: { event: EventApi }">
|
||||
<span :class="eventClasses">
|
||||
<b v-if="event.extendedProps.is === 'remote'">{{ event.title }}</b>
|
||||
<b v-if="event.extendedProps.is === 'remote'">{{
|
||||
event.title
|
||||
}}</b>
|
||||
<b v-else-if="event.extendedProps.is === 'range'"
|
||||
>{{ formatDate(event.startStr) }} -
|
||||
{{ event.extendedProps.locationName }}</b
|
||||
>
|
||||
<b v-else-if="event.extendedProps.is === 'local'">{{ event.title }}</b>
|
||||
<b v-else-if="event.extendedProps.is === 'local'">{{
|
||||
event.title
|
||||
}}</b>
|
||||
<b v-else>no 'is'</b>
|
||||
<a
|
||||
v-if="event.extendedProps.is === 'range'"
|
||||
@@ -108,7 +126,11 @@
|
||||
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-9 col-md-2">
|
||||
<select v-model="dayOrWeek" id="dayOrWeek" class="form-select">
|
||||
<select
|
||||
v-model="dayOrWeek"
|
||||
id="dayOrWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<option value="day">{{ $t("from_day_to_day") }}</option>
|
||||
<option value="week">
|
||||
{{ $t("from_week_to_week") }}
|
||||
@@ -117,16 +139,27 @@
|
||||
</div>
|
||||
<template v-if="dayOrWeek === 'day'">
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<input class="form-control" type="date" v-model="copyFrom" />
|
||||
<input
|
||||
class="form-control"
|
||||
type="date"
|
||||
v-model="copyFrom"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<input class="form-control" type="date" v-model="copyTo" />
|
||||
<input
|
||||
class="form-control"
|
||||
type="date"
|
||||
v-model="copyTo"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||
<button class="btn btn-action float-end" @click="copyDay">
|
||||
<button
|
||||
class="btn btn-action float-end"
|
||||
@click="copyDay"
|
||||
>
|
||||
{{ $t("copy_range") }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -138,7 +171,11 @@
|
||||
id="copyFromWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<option v-for="w in lastWeeks" :value="w.value" :key="w.value">
|
||||
<option
|
||||
v-for="w in lastWeeks"
|
||||
:value="w.value"
|
||||
:key="w.value"
|
||||
>
|
||||
{{ w.text }}
|
||||
</option>
|
||||
</select>
|
||||
@@ -147,14 +184,25 @@
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<select v-model="copyToWeek" id="copyToWeek" class="form-select">
|
||||
<option v-for="w in nextWeeks" :value="w.value" :key="w.value">
|
||||
<select
|
||||
v-model="copyToWeek"
|
||||
id="copyToWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="w in nextWeeks"
|
||||
:value="w.value"
|
||||
:key="w.value"
|
||||
>
|
||||
{{ w.text }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||
<button class="btn btn-action float-end" @click="copyWeek">
|
||||
<button
|
||||
class="btn btn-action float-end"
|
||||
@click="copyWeek"
|
||||
>
|
||||
{{ $t("copy_range") }}
|
||||
</button>
|
||||
</div>
|
||||
|
@@ -41,7 +41,9 @@ const futureStore = function (): Promise<Store<State>> {
|
||||
});
|
||||
|
||||
store.commit("me/setWhoAmi", user, { root: true });
|
||||
store.dispatch("locations/getLocations", null, { root: true }).then((_) => {
|
||||
store
|
||||
.dispatch("locations/getLocations", null, { root: true })
|
||||
.then((_) => {
|
||||
return store.dispatch("locations/getCurrentLocation", null, {
|
||||
root: true,
|
||||
});
|
||||
|
@@ -29,7 +29,10 @@ export default {
|
||||
(state: CalendarLocalsState) =>
|
||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||
for (const range of state.localsLoaded) {
|
||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
||||
if (
|
||||
start.getTime() === range.start &&
|
||||
end.getTime() === range.end
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -51,7 +54,10 @@ export default {
|
||||
});
|
||||
state.key = state.key + toAdd.length;
|
||||
},
|
||||
addLoaded(state: CalendarLocalsState, payload: { start: Date; end: Date }) {
|
||||
addLoaded(
|
||||
state: CalendarLocalsState,
|
||||
payload: { start: Date; end: Date },
|
||||
) {
|
||||
state.localsLoaded.push({
|
||||
start: payload.start.getTime(),
|
||||
end: payload.end.getTime(),
|
||||
@@ -79,7 +85,11 @@ export default {
|
||||
end: end,
|
||||
});
|
||||
|
||||
return fetchCalendarLocalForUser(ctx.rootGetters["me/getMe"], start, end)
|
||||
return fetchCalendarLocalForUser(
|
||||
ctx.rootGetters["me/getMe"],
|
||||
start,
|
||||
end,
|
||||
)
|
||||
.then((remotes: CalendarLight[]) => {
|
||||
// to be add when reactivity problem will be solve ?
|
||||
//ctx.commit('addRemotes', remotes);
|
||||
|
@@ -40,7 +40,10 @@ export default {
|
||||
(state: CalendarRangesState) =>
|
||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||
for (const range of state.rangesLoaded) {
|
||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
||||
if (
|
||||
start.getTime() === range.start &&
|
||||
end.getTime() === range.end
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -107,7 +110,9 @@ export default {
|
||||
state: CalendarRangesState,
|
||||
externalEvents: (EventInput & { id: string })[],
|
||||
) {
|
||||
const toAdd = externalEvents.filter((r) => !state.rangesIndex.has(r.id));
|
||||
const toAdd = externalEvents.filter(
|
||||
(r) => !state.rangesIndex.has(r.id),
|
||||
);
|
||||
|
||||
toAdd.forEach((r) => {
|
||||
state.rangesIndex.add(r.id);
|
||||
@@ -115,7 +120,10 @@ export default {
|
||||
});
|
||||
state.key = state.key + toAdd.length;
|
||||
},
|
||||
addLoaded(state: CalendarRangesState, payload: { start: Date; end: Date }) {
|
||||
addLoaded(
|
||||
state: CalendarRangesState,
|
||||
payload: { start: Date; end: Date },
|
||||
) {
|
||||
state.rangesLoaded.push({
|
||||
start: payload.start.getTime(),
|
||||
end: payload.end.getTime(),
|
||||
@@ -134,12 +142,17 @@ export default {
|
||||
},
|
||||
removeRange(state: CalendarRangesState, calendarRangeId: number) {
|
||||
const found = state.ranges.find(
|
||||
(r) => r.calendarRangeId === calendarRangeId && r.is === "range",
|
||||
(r) =>
|
||||
r.calendarRangeId === calendarRangeId && r.is === "range",
|
||||
);
|
||||
|
||||
if (found !== undefined) {
|
||||
state.ranges = state.ranges.filter(
|
||||
(r) => !(r.calendarRangeId === calendarRangeId && r.is === "range"),
|
||||
(r) =>
|
||||
!(
|
||||
r.calendarRangeId === calendarRangeId &&
|
||||
r.is === "range"
|
||||
),
|
||||
);
|
||||
|
||||
if (typeof found.id === "string") {
|
||||
@@ -198,7 +211,11 @@ export default {
|
||||
},
|
||||
createRange(
|
||||
ctx: Context,
|
||||
{ start, end, location }: { start: Date; end: Date; location: Location },
|
||||
{
|
||||
start,
|
||||
end,
|
||||
location,
|
||||
}: { start: Date; end: Date; location: Location },
|
||||
): Promise<null> {
|
||||
const url = `/api/1.0/calendar/calendar-range.json?`;
|
||||
|
||||
@@ -223,7 +240,11 @@ export default {
|
||||
},
|
||||
} as CalendarRangeCreate;
|
||||
|
||||
return makeFetch<CalendarRangeCreate, CalendarRange>("POST", url, body)
|
||||
return makeFetch<CalendarRangeCreate, CalendarRange>(
|
||||
"POST",
|
||||
url,
|
||||
body,
|
||||
)
|
||||
.then((newRange) => {
|
||||
ctx.commit("addRange", newRange);
|
||||
|
||||
@@ -260,7 +281,11 @@ export default {
|
||||
},
|
||||
} as CalendarRangeEdit;
|
||||
|
||||
return makeFetch<CalendarRangeEdit, CalendarRange>("PATCH", url, body)
|
||||
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||
"PATCH",
|
||||
url,
|
||||
body,
|
||||
)
|
||||
.then((range) => {
|
||||
ctx.commit("updateRange", range);
|
||||
return Promise.resolve(null);
|
||||
@@ -285,7 +310,11 @@ export default {
|
||||
},
|
||||
} as CalendarRangeEdit;
|
||||
|
||||
return makeFetch<CalendarRangeEdit, CalendarRange>("PATCH", url, body)
|
||||
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||
"PATCH",
|
||||
url,
|
||||
body,
|
||||
)
|
||||
.then((range) => {
|
||||
ctx.commit("updateRange", range);
|
||||
return Promise.resolve(null);
|
||||
@@ -305,14 +334,20 @@ export default {
|
||||
|
||||
for (const r of rangesToCopy) {
|
||||
const start = new Date(ISOToDatetime(r.start) as Date);
|
||||
start.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||
start.setFullYear(
|
||||
to.getFullYear(),
|
||||
to.getMonth(),
|
||||
to.getDate(),
|
||||
);
|
||||
const end = new Date(ISOToDatetime(r.end) as Date);
|
||||
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||
const location = ctx.rootGetters["locations/getLocationById"](
|
||||
r.locationId,
|
||||
);
|
||||
|
||||
promises.push(ctx.dispatch("createRange", { start, end, location }));
|
||||
promises.push(
|
||||
ctx.dispatch("createRange", { start, end, location }),
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => Promise.resolve(null));
|
||||
@@ -334,7 +369,9 @@ export default {
|
||||
r.locationId,
|
||||
);
|
||||
|
||||
promises.push(ctx.dispatch("createRange", { start, end, location }));
|
||||
promises.push(
|
||||
ctx.dispatch("createRange", { start, end, location }),
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.all(promises).then(() => Promise.resolve(null));
|
||||
|
@@ -29,7 +29,10 @@ export default {
|
||||
(state: CalendarRemotesState) =>
|
||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||
for (const range of state.remotesLoaded) {
|
||||
if (start.getTime() === range.start && end.getTime() === range.end) {
|
||||
if (
|
||||
start.getTime() === range.start &&
|
||||
end.getTime() === range.end
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -82,7 +85,11 @@ export default {
|
||||
end: end,
|
||||
});
|
||||
|
||||
return fetchCalendarRemoteForUser(ctx.rootGetters["me/getMe"], start, end)
|
||||
return fetchCalendarRemoteForUser(
|
||||
ctx.rootGetters["me/getMe"],
|
||||
start,
|
||||
end,
|
||||
)
|
||||
.then((remotes: CalendarRemote[]) => {
|
||||
// to be add when reactivity problem will be solve ?
|
||||
//ctx.commit('addRemotes', remotes);
|
||||
|
@@ -112,8 +112,11 @@ export default {
|
||||
|
||||
results.forEach((i) => {
|
||||
if (!users.some((j) => i.user.id === j.id)) {
|
||||
let ratio = Math.floor(users.length / COLORS.length);
|
||||
let colorIndex = users.length - ratio * COLORS.length;
|
||||
let ratio = Math.floor(
|
||||
users.length / COLORS.length,
|
||||
);
|
||||
let colorIndex =
|
||||
users.length - ratio * COLORS.length;
|
||||
users.push({
|
||||
id: i.user.id,
|
||||
username: i.user.username,
|
||||
@@ -150,29 +153,45 @@ export default {
|
||||
(me) =>
|
||||
new Promise((resolve, reject) => {
|
||||
this.users.logged = me;
|
||||
let currentUser = users.find((u) => u.id === me.id);
|
||||
let currentUser = users.find(
|
||||
(u) => u.id === me.id,
|
||||
);
|
||||
this.value = currentUser;
|
||||
|
||||
fetchCalendar(currentUser.id).then(
|
||||
(calendar) =>
|
||||
new Promise((resolve, reject) => {
|
||||
let results = calendar.results;
|
||||
let events = results.map((i) => ({
|
||||
start: i.startDate.datetime,
|
||||
end: i.endDate.datetime,
|
||||
}));
|
||||
let calendarEventsCurrentUser = {
|
||||
new Promise(
|
||||
(resolve, reject) => {
|
||||
let results =
|
||||
calendar.results;
|
||||
let events =
|
||||
results.map(
|
||||
(i) => ({
|
||||
start: i
|
||||
.startDate
|
||||
.datetime,
|
||||
end: i
|
||||
.endDate
|
||||
.datetime,
|
||||
}),
|
||||
);
|
||||
let calendarEventsCurrentUser =
|
||||
{
|
||||
events: events,
|
||||
color: "darkblue",
|
||||
id: 1000,
|
||||
editable: false,
|
||||
};
|
||||
this.calendarEvents.user = calendarEventsCurrentUser;
|
||||
this.calendarEvents.user =
|
||||
calendarEventsCurrentUser;
|
||||
|
||||
this.selectUsers(currentUser);
|
||||
this.selectUsers(
|
||||
currentUser,
|
||||
);
|
||||
|
||||
resolve();
|
||||
}),
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
resolve();
|
||||
@@ -190,7 +209,9 @@ export default {
|
||||
return `${value.username}`;
|
||||
},
|
||||
coloriseSelectedValues() {
|
||||
let tags = document.querySelectorAll("div.multiselect__tags-wrap")[0];
|
||||
let tags = document.querySelectorAll(
|
||||
"div.multiselect__tags-wrap",
|
||||
)[0];
|
||||
|
||||
if (tags.hasChildNodes()) {
|
||||
let children = tags.childNodes;
|
||||
@@ -211,8 +232,8 @@ export default {
|
||||
},
|
||||
selectEvents() {
|
||||
let selectedUsersId = this.users.selected.map((a) => a.id);
|
||||
this.calendarEvents.selected = this.calendarEvents.loaded.filter((a) =>
|
||||
selectedUsersId.includes(a.id),
|
||||
this.calendarEvents.selected = this.calendarEvents.loaded.filter(
|
||||
(a) => selectedUsersId.includes(a.id),
|
||||
);
|
||||
},
|
||||
selectUsers(value) {
|
||||
@@ -222,7 +243,9 @@ export default {
|
||||
this.updateEventsSource();
|
||||
},
|
||||
unSelectUsers(value) {
|
||||
this.users.selected = this.users.selected.filter((a) => a.id != value.id);
|
||||
this.users.selected = this.users.selected.filter(
|
||||
(a) => a.id != value.id,
|
||||
);
|
||||
this.selectEvents();
|
||||
this.updateEventsSource();
|
||||
},
|
||||
|
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\CustomFieldsBundle\EntityRepository;
|
||||
|
||||
use Chill\CustomFieldsBundle\Entity\CustomFieldsDefaultGroup;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
class CustomFieldsDefaultGroupRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, CustomFieldsDefaultGroup::class);
|
||||
}
|
||||
|
||||
public function findOneByEntity(string $className): ?CustomFieldsDefaultGroup
|
||||
{
|
||||
return $this->findOneBy(['entity' => $className]);
|
||||
}
|
||||
}
|
@@ -127,7 +127,3 @@ services:
|
||||
factory: ["@doctrine", getRepository]
|
||||
arguments:
|
||||
- "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
|
||||
|
||||
Chill\CustomFieldsBundle\EntityRepository\CustomFieldsDefaultGroupRepository:
|
||||
autowire: true
|
||||
autoconfigure: true
|
||||
|
@@ -20,7 +20,10 @@
|
||||
</option>
|
||||
<template v-for="t in templates" :key="t.id">
|
||||
<option :value="t.id">
|
||||
{{ localizeString(t.name) || "Aucun nom défini" }}
|
||||
{{
|
||||
localizeString(t.name) ||
|
||||
"Aucun nom défini"
|
||||
}}
|
||||
</option>
|
||||
</template>
|
||||
</select>
|
||||
@@ -28,7 +31,9 @@
|
||||
v-if="canGenerate"
|
||||
class="btn btn-update btn-sm change-icon"
|
||||
:href="buildUrlGenerate"
|
||||
@click.prevent="clickGenerate($event, buildUrlGenerate)"
|
||||
@click.prevent="
|
||||
clickGenerate($event, buildUrlGenerate)
|
||||
"
|
||||
><i class="fa fa-fw fa-cog"
|
||||
/></a>
|
||||
<a
|
||||
|
@@ -18,7 +18,6 @@ use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
||||
use Chill\DocStoreBundle\Service\Cryptography\KeyGenerator;
|
||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\Filesystem\Path;
|
||||
|
||||
@@ -148,11 +147,16 @@ class StoredObjectManager implements StoredObjectManagerInterface
|
||||
public function writeContent(string $filename, string $encryptedContent): void
|
||||
{
|
||||
$fullPath = $this->buildPath($filename);
|
||||
$dir = Path::getDirectory($fullPath);
|
||||
|
||||
try {
|
||||
$this->filesystem->dumpFile($fullPath, $encryptedContent);
|
||||
} catch (IOExceptionInterface $exception) {
|
||||
throw StoredObjectManagerException::unableToStoreDocumentOnDisk($exception);
|
||||
if (!$this->filesystem->exists($dir)) {
|
||||
$this->filesystem->mkdir($dir);
|
||||
}
|
||||
|
||||
$result = file_put_contents($fullPath, $encryptedContent);
|
||||
|
||||
if (false === $result) {
|
||||
throw StoredObjectManagerException::unableToStoreDocumentOnDisk();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,9 +13,8 @@ const startApp = (
|
||||
|
||||
const inputTitle = collectionEntry?.querySelector("input[type='text']");
|
||||
|
||||
const input_stored_object: HTMLInputElement | null = divElement.querySelector(
|
||||
"input[data-stored-object]",
|
||||
);
|
||||
const input_stored_object: HTMLInputElement | null =
|
||||
divElement.querySelector("input[data-stored-object]");
|
||||
if (null === input_stored_object) {
|
||||
throw new Error("input to stored object not found");
|
||||
}
|
||||
@@ -54,7 +53,9 @@ const startApp = (
|
||||
console.log("version added", stored_object_version);
|
||||
this.$data.existingDoc = stored_object;
|
||||
this.$data.existingDoc.currentVersion = stored_object_version;
|
||||
input_stored_object.value = JSON.stringify(this.$data.existingDoc);
|
||||
input_stored_object.value = JSON.stringify(
|
||||
this.$data.existingDoc,
|
||||
);
|
||||
if (this.$data.inputTitle) {
|
||||
if (!this.$data.inputTitle?.value) {
|
||||
this.$data.inputTitle.value = file_name;
|
||||
|
@@ -49,7 +49,9 @@
|
||||
<li v-if="isHistoryViewable">
|
||||
<history-button
|
||||
:stored-object="props.storedObject"
|
||||
:can-edit="canEdit && props.storedObject._permissions.canEdit"
|
||||
:can-edit="
|
||||
canEdit && props.storedObject._permissions.canEdit
|
||||
"
|
||||
></history-button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -127,7 +129,9 @@ const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
|
||||
canDownload: true,
|
||||
canConvertPdf: true,
|
||||
returnPath:
|
||||
window.location.pathname + window.location.search + window.location.hash,
|
||||
window.location.pathname +
|
||||
window.location.search +
|
||||
window.location.hash,
|
||||
});
|
||||
|
||||
/**
|
||||
|
@@ -29,7 +29,9 @@
|
||||
</modal>
|
||||
</teleport>
|
||||
<div class="col-12 m-auto sticky-top">
|
||||
<div class="row justify-content-center border-bottom pdf-tools d-md-none">
|
||||
<div
|
||||
class="row justify-content-center border-bottom pdf-tools d-md-none"
|
||||
>
|
||||
<div class="col-5 text-center turn-page">
|
||||
<select
|
||||
class="form-select form-select-sm"
|
||||
@@ -90,7 +92,10 @@
|
||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||
class="col-5 p-0 text-center turnSignature"
|
||||
>
|
||||
<button class="btn btn-light btn-sm" @click="goToSignatureZoneUnique">
|
||||
<button
|
||||
class="btn btn-light btn-sm"
|
||||
@click="goToSignatureZoneUnique"
|
||||
>
|
||||
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -145,7 +150,10 @@
|
||||
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||
>
|
||||
<template v-if="canvasEvent === 'add'">
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<div
|
||||
class="spinner-border spinner-border-sm"
|
||||
role="status"
|
||||
>
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -199,7 +207,10 @@
|
||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||
class="col-4 d-xl-none text-center turnSignature p-0"
|
||||
>
|
||||
<button class="btn btn-light btn-sm" @click="goToSignatureZoneUnique">
|
||||
<button
|
||||
class="btn btn-light btn-sm"
|
||||
@click="goToSignatureZoneUnique"
|
||||
>
|
||||
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -227,7 +238,10 @@
|
||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
||||
>
|
||||
<button class="btn btn-light btn-sm" @click="goToSignatureZoneUnique">
|
||||
<button
|
||||
class="btn btn-light btn-sm"
|
||||
@click="goToSignatureZoneUnique"
|
||||
>
|
||||
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -285,7 +299,10 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ trans(SIGNATURES_CLICK_ON_DOCUMENT) }}
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<div
|
||||
class="spinner-border spinner-border-sm"
|
||||
role="status"
|
||||
>
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -545,8 +562,14 @@ const addCanvasEvents = () => {
|
||||
);
|
||||
});
|
||||
} else {
|
||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
||||
canvas.addEventListener("pointerup", (e) => canvasClick(e, canvas), false);
|
||||
const canvas = document.querySelectorAll(
|
||||
"canvas",
|
||||
)[0] as HTMLCanvasElement;
|
||||
canvas.addEventListener(
|
||||
"pointerup",
|
||||
(e) => canvasClick(e, canvas),
|
||||
false,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -582,7 +605,11 @@ const hitSignature = (
|
||||
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
|
||||
xy[1] &&
|
||||
xy[1] <
|
||||
scaleYToCanvas(zone.height - zone.y, canvas.height, zone.PDFPage.height) +
|
||||
scaleYToCanvas(
|
||||
zone.height - zone.y,
|
||||
canvas.height,
|
||||
zone.PDFPage.height,
|
||||
) +
|
||||
zone.PDFPage.height * zoom.value;
|
||||
|
||||
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
||||
@@ -598,7 +625,8 @@ const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
||||
signature.zones
|
||||
.filter(
|
||||
(z) =>
|
||||
(z.PDFPage.index + 1 === getCanvasId(canvas) && multiPage.value) ||
|
||||
(z.PDFPage.index + 1 === getCanvasId(canvas) &&
|
||||
multiPage.value) ||
|
||||
(z.PDFPage.index + 1 === page.value && !multiPage.value),
|
||||
)
|
||||
.map((z) => {
|
||||
|
@@ -153,10 +153,12 @@ const handleFile = async (file: File): Promise<void> => {
|
||||
</p>
|
||||
<!-- todo i18n -->
|
||||
<p v-if="has_existing_doc">
|
||||
Déposez un document ou cliquez ici pour remplacer le document existant
|
||||
Déposez un document ou cliquez ici pour remplacer le document
|
||||
existant
|
||||
</p>
|
||||
<p v-else>
|
||||
Déposez un document ou cliquez ici pour ouvrir le navigateur de fichier
|
||||
Déposez un document ou cliquez ici pour ouvrir le navigateur de
|
||||
fichier
|
||||
</p>
|
||||
</div>
|
||||
<div v-else class="waiting">
|
||||
|
@@ -35,7 +35,9 @@ async function download_and_open(event: Event): Promise<void> {
|
||||
if (null === state.content) {
|
||||
event.preventDefault();
|
||||
|
||||
const raw = await download_doc(build_convert_link(props.storedObject.uuid));
|
||||
const raw = await download_doc(
|
||||
build_convert_link(props.storedObject.uuid),
|
||||
);
|
||||
state.content = window.URL.createObjectURL(raw);
|
||||
|
||||
button.href = window.URL.createObjectURL(raw);
|
||||
|
@@ -42,7 +42,9 @@ const editionUntilFormatted = computed<string>(() => {
|
||||
<modal v-if="state.modalOpened" @close="state.modalOpened = false">
|
||||
<template v-slot:body>
|
||||
<div class="desktop-edit">
|
||||
<p class="center">Veuillez enregistrer vos modifications avant le</p>
|
||||
<p class="center">
|
||||
Veuillez enregistrer vos modifications avant le
|
||||
</p>
|
||||
<p>
|
||||
<strong>{{ editionUntilFormatted }}</strong>
|
||||
</p>
|
||||
@@ -55,21 +57,23 @@ const editionUntilFormatted = computed<string>(() => {
|
||||
|
||||
<p>
|
||||
<small
|
||||
>Le document peut être édité uniquement en utilisant Libre
|
||||
Office.</small
|
||||
>Le document peut être édité uniquement en utilisant
|
||||
Libre Office.</small
|
||||
>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<small
|
||||
>En cas d'échec lors de l'enregistrement, sauver le document sur
|
||||
le poste de travail avant de le déposer à nouveau ici.</small
|
||||
>En cas d'échec lors de l'enregistrement, sauver le
|
||||
document sur le poste de travail avant de le déposer
|
||||
à nouveau ici.</small
|
||||
>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<small
|
||||
>Vous pouvez naviguez sur d'autres pages pendant l'édition.</small
|
||||
>Vous pouvez naviguez sur d'autres pages pendant
|
||||
l'édition.</small
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
|
@@ -95,7 +95,10 @@ async function download_and_open(): Promise<void> {
|
||||
let raw;
|
||||
|
||||
try {
|
||||
raw = await download_and_decrypt_doc(props.storedObject, props.atVersion);
|
||||
raw = await download_and_decrypt_doc(
|
||||
props.storedObject,
|
||||
props.atVersion,
|
||||
);
|
||||
} catch (e) {
|
||||
console.error("error while downloading and decrypting document");
|
||||
console.error(e);
|
||||
|
@@ -49,7 +49,8 @@ const isRestored = computed<boolean>(
|
||||
);
|
||||
|
||||
const isDuplicated = computed<boolean>(
|
||||
() => props.version.version === 0 && null !== props.version["from-restored"],
|
||||
() =>
|
||||
props.version.version === 0 && null !== props.version["from-restored"],
|
||||
);
|
||||
|
||||
const classes = computed<{
|
||||
@@ -69,9 +70,16 @@ const classes = computed<{
|
||||
<div :class="classes">
|
||||
<div
|
||||
class="col-12 tags"
|
||||
v-if="isCurrent || isKeptBeforeConversion || isRestored || isDuplicated"
|
||||
v-if="
|
||||
isCurrent ||
|
||||
isKeptBeforeConversion ||
|
||||
isRestored ||
|
||||
isDuplicated
|
||||
"
|
||||
>
|
||||
<span class="badge bg-success" v-if="isCurrent"
|
||||
>Version actuelle</span
|
||||
>
|
||||
<span class="badge bg-success" v-if="isCurrent">Version actuelle</span>
|
||||
<span class="badge bg-info" v-if="isKeptBeforeConversion"
|
||||
>Conservée avant conversion dans un autre format</span
|
||||
>
|
||||
@@ -88,17 +96,21 @@ const classes = computed<{
|
||||
<span
|
||||
><strong> #{{ version.version + 1 }} </strong></span
|
||||
>
|
||||
<template v-if="version.createdBy !== null && version.createdAt !== null"
|
||||
<template
|
||||
v-if="version.createdBy !== null && version.createdAt !== null"
|
||||
><strong v-if="version.version == 0">créé par</strong
|
||||
><strong v-else>modifié par</strong>
|
||||
<span class="badge-user"
|
||||
><UserRenderBoxBadge :user="version.createdBy"></UserRenderBoxBadge
|
||||
><UserRenderBoxBadge
|
||||
:user="version.createdBy"
|
||||
></UserRenderBoxBadge
|
||||
></span>
|
||||
<strong>à</strong>
|
||||
{{
|
||||
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
||||
}}</template
|
||||
><template v-if="version.createdBy === null && version.createdAt !== null"
|
||||
><template
|
||||
v-if="version.createdBy === null && version.createdAt !== null"
|
||||
><strong v-if="version.version == 0">Créé le</strong
|
||||
><strong v-else>modifié le</strong>
|
||||
{{
|
||||
|
@@ -2,7 +2,9 @@
|
||||
<a
|
||||
:class="Object.assign(props.classes, { btn: true })"
|
||||
@click="beforeLeave($event)"
|
||||
:href="build_wopi_editor_link(props.storedObject.uuid, props.returnPath)"
|
||||
:href="
|
||||
build_wopi_editor_link(props.storedObject.uuid, props.returnPath)
|
||||
"
|
||||
>
|
||||
<i class="fa fa-paragraph"></i>
|
||||
Editer en ligne
|
||||
|
@@ -145,7 +145,9 @@ async function download_info_link(
|
||||
function build_wopi_editor_link(uuid: string, returnPath?: string) {
|
||||
if (returnPath === undefined) {
|
||||
returnPath =
|
||||
window.location.pathname + window.location.search + window.location.hash;
|
||||
window.location.pathname +
|
||||
window.location.search +
|
||||
window.location.hash;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -184,7 +186,10 @@ async function download_and_decrypt_doc(
|
||||
) {
|
||||
downloadInfo = storedObject._links.downloadLink;
|
||||
} else {
|
||||
downloadInfo = await download_info_link(storedObject, atVersionToDownload);
|
||||
downloadInfo = await download_info_link(
|
||||
storedObject,
|
||||
atVersionToDownload,
|
||||
);
|
||||
}
|
||||
|
||||
const rawResponse = await window.fetch(downloadInfo.url);
|
||||
@@ -239,7 +244,10 @@ async function download_doc_as_pdf(storedObject: StoredObject): Promise<Blob> {
|
||||
}
|
||||
|
||||
if (storedObject.currentVersion?.type === "application/pdf") {
|
||||
return download_and_decrypt_doc(storedObject, storedObject.currentVersion);
|
||||
return download_and_decrypt_doc(
|
||||
storedObject,
|
||||
storedObject.currentVersion,
|
||||
);
|
||||
}
|
||||
|
||||
const convertLink = build_convert_link(storedObject.uuid);
|
||||
|
@@ -43,17 +43,11 @@ class StoredObjectVersionNormalizer implements NormalizerInterface, NormalizerAw
|
||||
'createdBy' => $this->normalizer->normalize($object->getCreatedBy(), $format, [...$context, UserNormalizer::AT_DATE => $object->getCreatedAt()]),
|
||||
];
|
||||
|
||||
$normalizationGroups = $context[AbstractNormalizer::GROUPS] ?? [];
|
||||
|
||||
if (is_string($normalizationGroups)) {
|
||||
$normalizationGroups = [$normalizationGroups];
|
||||
}
|
||||
|
||||
if (in_array(self::WITH_POINT_IN_TIMES_CONTEXT, $normalizationGroups, true)) {
|
||||
if (in_array(self::WITH_POINT_IN_TIMES_CONTEXT, $context[AbstractNormalizer::GROUPS] ?? [], true)) {
|
||||
$data['point-in-times'] = $this->normalizer->normalize($object->getPointInTimes(), $format, $context);
|
||||
}
|
||||
|
||||
if (in_array(self::WITH_RESTORED_CONTEXT, $normalizationGroups, true)) {
|
||||
if (in_array(self::WITH_RESTORED_CONTEXT, $context[AbstractNormalizer::GROUPS] ?? [], true)) {
|
||||
$data['from-restored'] = $this->normalizer->normalize($object->getCreatedFrom(), $format, [AbstractNormalizer::GROUPS => ['read']]);
|
||||
}
|
||||
|
||||
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Controller\Admin;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class EventBudgetKindController extends CRUDController
|
||||
{
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator)
|
||||
{
|
||||
/* @var QueryBuilder $query */
|
||||
$query->addOrderBy('e.type', 'ASC');
|
||||
|
||||
return parent::orderQuery($action, $query, $request, $paginator);
|
||||
}
|
||||
}
|
@@ -23,11 +23,11 @@ use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Chill\PersonBundle\Privacy\PrivacyEvent;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Csv;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Ods;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
@@ -41,8 +41,6 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Serializer\Exception\ExceptionInterface;
|
||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
@@ -60,8 +58,7 @@ final class EventController extends AbstractController
|
||||
private readonly TranslatorInterface $translator,
|
||||
private readonly PaginatorFactory $paginator,
|
||||
private readonly Security $security,
|
||||
private readonly ManagerRegistry $managerRegistry,
|
||||
private readonly NormalizerInterface $normalizer,
|
||||
private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
|
||||
) {}
|
||||
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/delete', name: 'chill_event__event_delete', requirements: ['event_id' => '\d+'], methods: ['GET', 'POST', 'DELETE'])]
|
||||
@@ -78,7 +75,6 @@ final class EventController extends AbstractController
|
||||
|
||||
/** @var array $participations */
|
||||
$participations = $event->getParticipations();
|
||||
$budgetElements = $event->getBudgetElements();
|
||||
|
||||
$form = $this->createDeleteForm($event_id);
|
||||
|
||||
@@ -90,10 +86,6 @@ final class EventController extends AbstractController
|
||||
$em->remove($participation);
|
||||
}
|
||||
|
||||
foreach ($budgetElements as $e) {
|
||||
$em->remove($e);
|
||||
}
|
||||
|
||||
$em->remove($event);
|
||||
$em->flush();
|
||||
|
||||
@@ -111,7 +103,7 @@ final class EventController extends AbstractController
|
||||
}
|
||||
|
||||
return $this->render('@ChillEvent/Event/confirm_delete.html.twig', [
|
||||
'id' => $event->getId(),
|
||||
'event_id' => $event->getId(),
|
||||
'delete_form' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
@@ -177,8 +169,6 @@ final class EventController extends AbstractController
|
||||
|
||||
/**
|
||||
* Displays a form to create a new Event entity.
|
||||
*
|
||||
* @throws ExceptionInterface
|
||||
*/
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new', name: 'chill_event__event_new', methods: ['GET', 'POST'])]
|
||||
public function newAction(?Center $center, Request $request): Response
|
||||
@@ -209,23 +199,26 @@ final class EventController extends AbstractController
|
||||
$this->addFlash('success', $this->translator
|
||||
->trans('The event was created'));
|
||||
|
||||
return $this->redirectToRoute('chill_event__event_show', ['id' => $entity->getId()]);
|
||||
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $entity->getId()]);
|
||||
}
|
||||
|
||||
$entity_array = $this->normalizer->normalize($entity, 'json', ['groups' => 'read']);
|
||||
|
||||
return $this->render('@ChillEvent/Event/new.html.twig', [
|
||||
'entity' => $entity,
|
||||
'form' => $form->createView(),
|
||||
'entity_json' => $entity_array,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* First step of new Event form.
|
||||
*/
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/new/pick-center', name: 'chill_event__event_new_pickcenter', options: [null])]
|
||||
public function newPickCenterAction(): Response
|
||||
{
|
||||
$role = 'CHILL_EVENT_CREATE';
|
||||
|
||||
/**
|
||||
* @var Center $centers
|
||||
*/
|
||||
$centers = $this->authorizationHelper->getReachableCenters($this->getUser(), $role);
|
||||
|
||||
if (1 === \count($centers)) {
|
||||
@@ -245,7 +238,7 @@ final class EventController extends AbstractController
|
||||
->add('center_id', EntityType::class, [
|
||||
'class' => Center::class,
|
||||
'choices' => $centers,
|
||||
'placeholder' => $this->translator->trans('Pick a center'),
|
||||
'placeholder' => '',
|
||||
'label' => 'To which centre should the event be associated ?',
|
||||
])
|
||||
->add('submit', SubmitType::class, [
|
||||
@@ -258,7 +251,16 @@ final class EventController extends AbstractController
|
||||
]);
|
||||
}
|
||||
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{id}/show', name: 'chill_event__event_show')]
|
||||
/**
|
||||
* Finds and displays a Event entity.
|
||||
*
|
||||
* @ParamConverter("event", options={"id": "event_id"})
|
||||
*
|
||||
* @return Response
|
||||
*
|
||||
* @throws \PhpOffice\PhpSpreadsheet\Exception
|
||||
*/
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/event/{event_id}/show', name: 'chill_event__event_show')]
|
||||
public function showAction(Event $event, Request $request)
|
||||
{
|
||||
if (!$event) {
|
||||
@@ -315,7 +317,7 @@ final class EventController extends AbstractController
|
||||
|
||||
$this->addFlash('success', $this->translator->trans('The event was updated'));
|
||||
|
||||
return $this->redirectToRoute('chill_event__event_show', ['id' => $event_id]);
|
||||
return $this->redirectToRoute('chill_event__event_show', ['event_id' => $event_id]);
|
||||
}
|
||||
|
||||
return $this->render('@ChillEvent/Event/edit.html.twig', [
|
||||
|
@@ -15,15 +15,11 @@ use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Entity\EventType;
|
||||
use Chill\EventBundle\Repository\EventACLAwareRepositoryInterface;
|
||||
use Chill\EventBundle\Repository\EventTypeRepository;
|
||||
use Chill\EventBundle\Security\EventVoter;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Pagination\PaginatorFactoryInterface;
|
||||
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
|
||||
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactory;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\PersonBundle\Form\Type\PickPersonDynamicType;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
@@ -33,18 +29,17 @@ use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
final class EventListController extends AbstractController
|
||||
final readonly class EventListController
|
||||
{
|
||||
public function __construct(
|
||||
private readonly Environment $environment,
|
||||
private readonly EventACLAwareRepositoryInterface $eventACLAwareRepository,
|
||||
private readonly EventTypeRepository $eventTypeRepository,
|
||||
private readonly FilterOrderHelperFactory $filterOrderHelperFactory,
|
||||
private readonly FormFactoryInterface $formFactory,
|
||||
private readonly PaginatorFactoryInterface $paginatorFactory,
|
||||
private readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
private readonly AuthorizationHelper $authorizationHelper,
|
||||
private Environment $environment,
|
||||
private EventACLAwareRepositoryInterface $eventACLAwareRepository,
|
||||
private EventTypeRepository $eventTypeRepository,
|
||||
private FilterOrderHelperFactory $filterOrderHelperFactory,
|
||||
private FormFactoryInterface $formFactory,
|
||||
private PaginatorFactoryInterface $paginatorFactory,
|
||||
private TranslatableStringHelperInterface $translatableStringHelper,
|
||||
private UrlGeneratorInterface $urlGenerator,
|
||||
) {}
|
||||
|
||||
#[Route(path: '{_locale}/event/event/list', name: 'chill_event_event_list')]
|
||||
@@ -55,8 +50,6 @@ final class EventListController extends AbstractController
|
||||
'q' => (string) $filter->getQueryString(),
|
||||
'dates' => $filter->getDateRangeData('dates'),
|
||||
'event_types' => $filter->getEntityChoiceData('event_types'),
|
||||
'responsables' => $filter->getUserPickerData('responsables'),
|
||||
'centers' => $filter->getEntityChoiceData('centers'),
|
||||
];
|
||||
$total = $this->eventACLAwareRepository->countAllViewable($filterData);
|
||||
$pagination = $this->paginatorFactory->create($total);
|
||||
@@ -80,7 +73,6 @@ final class EventListController extends AbstractController
|
||||
private function buildFilterOrder(): FilterOrderHelper
|
||||
{
|
||||
$types = $this->eventTypeRepository->findAllActive();
|
||||
$centers = $this->authorizationHelper->getReachableCenters($this->getUser(), EventVoter::SEE);
|
||||
|
||||
$builder = $this->filterOrderHelperFactory->create(__METHOD__);
|
||||
$builder
|
||||
@@ -88,16 +80,6 @@ final class EventListController extends AbstractController
|
||||
->addSearchBox(['name'])
|
||||
->addEntityChoice('event_types', 'event.filter.event_types', EventType::class, $types, [
|
||||
'choice_label' => fn (EventType $e) => $this->translatableStringHelper->localize($e->getName()),
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
])
|
||||
->addUserPicker('responsables', 'event.filter.pick_responsable', ['multiple' => true, 'required' => false])
|
||||
->addEntityChoice('centers', 'event.filter.center', Center::class, $centers, [
|
||||
'choice_label' => fn (Center $c) => $c->getName(),
|
||||
'expanded' => false,
|
||||
'required' => false,
|
||||
'attr' => ['class' => 'select2'],
|
||||
]);
|
||||
|
||||
return $builder->build();
|
||||
|
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Controller;
|
||||
|
||||
use Chill\MainBundle\CRUD\Controller\CRUDController;
|
||||
use Chill\MainBundle\Pagination\PaginatorInterface;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class EventThemeController extends CRUDController
|
||||
{
|
||||
protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
|
||||
{
|
||||
if ('new' === $action) {
|
||||
return parent::createFormFor($action, $entity, $formClass, ['step' => 'create']);
|
||||
}
|
||||
|
||||
if ('edit' === $action) {
|
||||
return parent::createFormFor($action, $entity, $formClass, ['step' => 'edit']);
|
||||
}
|
||||
|
||||
throw new \LogicException('action is not supported: '.$action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryBuilder|mixed $query
|
||||
*/
|
||||
protected function orderQuery(string $action, $query, Request $request, PaginatorInterface $paginator): QueryBuilder
|
||||
{
|
||||
/* @var QueryBuilder $query */
|
||||
return $query->orderBy('e.ordering', 'ASC')
|
||||
->addOrderBy('e.id', 'ASC');
|
||||
}
|
||||
}
|
@@ -228,7 +228,7 @@ final class ParticipationController extends AbstractController
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('chill_event__event_show', [
|
||||
'id' => $participation->getEvent()->getId(),
|
||||
'event_id' => $participation->getEvent()->getId(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ final class ParticipationController extends AbstractController
|
||||
/**
|
||||
* @param int $participation_id
|
||||
*/
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/participation/{participation_id}/delete', name: 'chill_event_participation_delete', requirements: ['participation_id' => '\d+'])]
|
||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/event/participation/{participation_id}/delete', name: 'chill_event_participation_delete', requirements: ['participation_id' => '\d+'], methods: ['GET', 'DELETE'])]
|
||||
public function deleteAction($participation_id, Request $request): Response|\Symfony\Component\HttpFoundation\RedirectResponse
|
||||
{
|
||||
$em = $this->managerRegistry->getManager();
|
||||
@@ -273,7 +273,7 @@ final class ParticipationController extends AbstractController
|
||||
);
|
||||
|
||||
return $this->redirectToRoute('chill_event__event_show', [
|
||||
'id' => $event->getId(),
|
||||
'event_id' => $event->getId(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -442,7 +442,7 @@ final class ParticipationController extends AbstractController
|
||||
));
|
||||
|
||||
return $this->redirectToRoute('chill_event__event_show', [
|
||||
'id' => $participation->getEvent()->getId(),
|
||||
'event_id' => $participation->getEvent()->getId(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@@ -11,12 +11,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace Chill\EventBundle\DependencyInjection;
|
||||
|
||||
use Chill\EventBundle\Controller\Admin\EventBudgetKindController;
|
||||
use Chill\EventBundle\Controller\EventThemeController;
|
||||
use Chill\EventBundle\Entity\EventBudgetKind;
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Chill\EventBundle\Form\EventBudgetKindType;
|
||||
use Chill\EventBundle\Form\EventThemeType;
|
||||
use Chill\EventBundle\Security\EventVoter;
|
||||
use Chill\EventBundle\Security\ParticipationVoter;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
@@ -32,10 +26,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\Extension;
|
||||
*/
|
||||
class ChillEventExtension extends Extension implements PrependExtensionInterface
|
||||
{
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function load(array $configs, ContainerBuilder $container): void
|
||||
public function load(array $configs, ContainerBuilder $container)
|
||||
{
|
||||
$configuration = new Configuration();
|
||||
$config = $this->processConfiguration($configuration, $configs);
|
||||
@@ -54,17 +45,16 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
||||
/** (non-PHPdoc).
|
||||
* @see \Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface::prepend()
|
||||
*/
|
||||
public function prepend(ContainerBuilder $container): void
|
||||
public function prepend(ContainerBuilder $container)
|
||||
{
|
||||
$this->prependAuthorization($container);
|
||||
$this->prependCruds($container);
|
||||
$this->prependRoute($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* add authorization hierarchy.
|
||||
*/
|
||||
protected function prependAuthorization(ContainerBuilder $container): void
|
||||
protected function prependAuthorization(ContainerBuilder $container)
|
||||
{
|
||||
$container->prependExtensionConfig('security', [
|
||||
'role_hierarchy' => [
|
||||
@@ -80,7 +70,7 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
||||
/**
|
||||
* add route to route loader for chill.
|
||||
*/
|
||||
protected function prependRoute(ContainerBuilder $container): void
|
||||
protected function prependRoute(ContainerBuilder $container)
|
||||
{
|
||||
// add routes for custom bundle
|
||||
$container->prependExtensionConfig('chill_main', [
|
||||
@@ -91,54 +81,4 @@ class ChillEventExtension extends Extension implements PrependExtensionInterface
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
protected function prependCruds(ContainerBuilder $container): void
|
||||
{
|
||||
$container->prependExtensionConfig('chill_main', [
|
||||
'cruds' => [
|
||||
[
|
||||
'class' => EventTheme::class,
|
||||
'name' => 'event_theme',
|
||||
'base_path' => '/admin/event/theme',
|
||||
'form_class' => EventThemeType::class,
|
||||
'controller' => EventThemeController::class,
|
||||
'actions' => [
|
||||
'index' => [
|
||||
'template' => '@ChillEvent/Admin/EventTheme/index.html.twig',
|
||||
'role' => 'ROLE_ADMIN',
|
||||
],
|
||||
'new' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillEvent/Admin/EventTheme/new.html.twig',
|
||||
],
|
||||
'edit' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillEvent/Admin/EventTheme/edit.html.twig',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'class' => EventBudgetKind::class,
|
||||
'name' => 'event_budget_kind',
|
||||
'base_path' => '/admin/event/budget',
|
||||
'form_class' => EventBudgetKindType::class,
|
||||
'controller' => EventBudgetKindController::class,
|
||||
'actions' => [
|
||||
'index' => [
|
||||
'template' => '@ChillEvent/Admin/BudgetKind/index.html.twig',
|
||||
'role' => 'ROLE_ADMIN',
|
||||
],
|
||||
'new' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillEvent/Admin/BudgetKind/new.html.twig',
|
||||
],
|
||||
'edit' => [
|
||||
'role' => 'ROLE_ADMIN',
|
||||
'template' => '@ChillEvent/Admin/BudgetKind/edit.html.twig',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Entity;
|
||||
|
||||
enum BudgetTypeEnum: string
|
||||
{
|
||||
case CHARGE = 'Charge';
|
||||
case RESOURCE = 'Resource';
|
||||
}
|
@@ -23,13 +23,10 @@ use Chill\MainBundle\Entity\HasScopeInterface;
|
||||
use Chill\MainBundle\Entity\Location;
|
||||
use Chill\MainBundle\Entity\Scope;
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\ThirdPartyBundle\Entity\ThirdParty;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Symfony\Component\Serializer\Annotation as Serializer;
|
||||
|
||||
/**
|
||||
* Class Event.
|
||||
@@ -49,63 +46,35 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
#[ORM\ManyToOne(targetEntity: Scope::class)]
|
||||
private ?Scope $circle = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DATETIME_MUTABLE)]
|
||||
private ?\DateTime $date = null;
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(name: 'id', type: Types::INTEGER)]
|
||||
#[ORM\Column(name: 'id', type: \Doctrine\DBAL\Types\Types::INTEGER)]
|
||||
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: User::class)]
|
||||
private ?User $moderator = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, User>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: User::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinTable('chill_event_animatorsintern')]
|
||||
private Collection $animatorsIntern;
|
||||
|
||||
/**
|
||||
* @var Collection<int, ThirdParty>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: ThirdParty::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinTable('chill_event_animatorsextern')]
|
||||
private Collection $animatorsExtern;
|
||||
|
||||
#[Assert\NotBlank]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\Column(type: Types::STRING, length: 150)]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 150)]
|
||||
private ?string $name = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, Participation>
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'event', targetEntity: Participation::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
private Collection $participations;
|
||||
|
||||
#[Assert\NotNull]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\ManyToOne(targetEntity: EventType::class)]
|
||||
private ?EventType $type = null;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EventTheme>
|
||||
*/
|
||||
#[ORM\ManyToMany(targetEntity: EventTheme::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinTable('chill_event_eventtheme')]
|
||||
private Collection $themes;
|
||||
|
||||
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_')]
|
||||
private CommentEmbeddable $comment;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Location::class)]
|
||||
#[Serializer\Groups(['read'])]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?Location $location = null;
|
||||
|
||||
@@ -116,17 +85,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
#[ORM\JoinTable('chill_event_event_documents')]
|
||||
private Collection $documents;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EventBudgetElement>
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'event', targetEntity: EventBudgetElement::class, cascade: ['persist'])]
|
||||
#[Serializer\Groups(['read'])]
|
||||
private Collection $budgetElements;
|
||||
|
||||
/**
|
||||
* @deprecated use budgetElements instead
|
||||
*/
|
||||
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 4, nullable: true, options: ['default' => '0.0'])]
|
||||
#[ORM\Column(type: \Doctrine\DBAL\Types\Types::DECIMAL, precision: 10, scale: 4, nullable: true, options: ['default' => '0.0'])]
|
||||
private string $organizationCost = '0.0';
|
||||
|
||||
/**
|
||||
@@ -137,20 +96,6 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
$this->participations = new ArrayCollection();
|
||||
$this->documents = new ArrayCollection();
|
||||
$this->comment = new CommentEmbeddable();
|
||||
$this->themes = new ArrayCollection();
|
||||
$this->budgetElements = new ArrayCollection();
|
||||
$this->animatorsIntern = new ArrayCollection();
|
||||
$this->animatorsExtern = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function addBudgetElement(EventBudgetElement $budgetElement)
|
||||
{
|
||||
if (!$this->budgetElements->contains($budgetElement)) {
|
||||
$this->budgetElements[] = $budgetElement;
|
||||
$budgetElement->setEvent($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -181,79 +126,38 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getThemes(): Collection
|
||||
{
|
||||
return $this->themes;
|
||||
}
|
||||
|
||||
public function addTheme(EventTheme $theme): self
|
||||
{
|
||||
$this->themes->add($theme);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeTheme(EventTheme $theme): void
|
||||
{
|
||||
$this->themes->removeElement($theme);
|
||||
}
|
||||
|
||||
public function getAnimatorsIntern(): Collection
|
||||
{
|
||||
return $this->animatorsIntern;
|
||||
}
|
||||
|
||||
public function getAnimatorsExtern(): Collection
|
||||
{
|
||||
return $this->animatorsExtern;
|
||||
}
|
||||
|
||||
public function addAnimatorsIntern(User $ai): self
|
||||
{
|
||||
$this->animatorsIntern->add($ai);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeAnimatorsIntern(User $ai): void
|
||||
{
|
||||
$this->animatorsIntern->removeElement($ai);
|
||||
}
|
||||
|
||||
public function addAnimatorsExtern(ThirdParty $ae): self
|
||||
{
|
||||
$this->animatorsExtern->add($ae);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeAnimatorsExtern(ThirdParty $ae): void
|
||||
{
|
||||
$this->animatorsExtern->removeElement($ae);
|
||||
}
|
||||
|
||||
public function getCenter(): Center
|
||||
/**
|
||||
* @return Center
|
||||
*/
|
||||
public function getCenter()
|
||||
{
|
||||
return $this->center;
|
||||
}
|
||||
|
||||
public function getCircle(): ?Scope
|
||||
/**
|
||||
* @return Scope
|
||||
*/
|
||||
public function getCircle()
|
||||
{
|
||||
return $this->circle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date.
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getDate(): ?\DateTime
|
||||
public function getDate()
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getId(): ?int
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
@@ -265,20 +169,14 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
|
||||
/**
|
||||
* Get label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): ?string
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, EventBudgetElement>
|
||||
*/
|
||||
public function getBudgetElements(): Collection
|
||||
{
|
||||
return $this->budgetElements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, Participation>
|
||||
*/
|
||||
@@ -301,26 +199,26 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* @return Scope
|
||||
*/
|
||||
public function getScope(): Scope
|
||||
public function getScope()
|
||||
{
|
||||
return $this->getCircle();
|
||||
}
|
||||
|
||||
public function getType(): ?EventType
|
||||
/**
|
||||
* @return EventType
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function removeBudgetElement(EventBudgetElement $budgetElement): void
|
||||
{
|
||||
$this->budgetElements->removeElement($budgetElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove participation.
|
||||
*/
|
||||
public function removeParticipation(Participation $participation): void
|
||||
public function removeParticipation(Participation $participation)
|
||||
{
|
||||
$this->participations->removeElement($participation);
|
||||
}
|
||||
@@ -416,17 +314,11 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter
|
||||
$this->documents = $documents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function getOrganizationCost(): string
|
||||
{
|
||||
return $this->organizationCost;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
public function setOrganizationCost(string $organizationCost): void
|
||||
{
|
||||
$this->organizationCost = $organizationCost;
|
||||
|
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Entity;
|
||||
|
||||
use Chill\EventBundle\Repository\EventThemeRepository;
|
||||
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
#[ORM\Entity(repositoryClass: EventThemeRepository::class)]
|
||||
#[ORM\Table(name: 'chill_event_budget_element')]
|
||||
class EventBudgetElement
|
||||
{
|
||||
#[ORM\Column(name: 'id', type: Types::INTEGER)]
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
||||
private ?int $id = null;
|
||||
|
||||
#[Assert\GreaterThan(value: 0)]
|
||||
#[Assert\NotNull(message: 'The amount cannot be empty')]
|
||||
#[ORM\Column(name: 'amount', type: Types::DECIMAL, precision: 10, scale: 2)]
|
||||
private string $amount;
|
||||
|
||||
#[ORM\Embedded(class: CommentEmbeddable::class, columnPrefix: 'comment_budget_element_')]
|
||||
private ?CommentEmbeddable $comment = null;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Event::class)]
|
||||
private Event $event;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: EventBudgetKind::class, inversedBy: 'EventBudgetElement')]
|
||||
#[ORM\JoinColumn]
|
||||
private EventBudgetKind $kind;
|
||||
|
||||
/* Getters and Setters */
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(?int $id): void
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getAmount(): float
|
||||
{
|
||||
return (float) $this->amount;
|
||||
}
|
||||
|
||||
public function getComment(): ?CommentEmbeddable
|
||||
{
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
public function getEvent(): Event
|
||||
{
|
||||
return $this->event;
|
||||
}
|
||||
|
||||
public function getKind(): EventBudgetKind
|
||||
{
|
||||
return $this->kind;
|
||||
}
|
||||
|
||||
public function setAmount(string $amount): self
|
||||
{
|
||||
$this->amount = $amount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setComment(?CommentEmbeddable $comment = null): self
|
||||
{
|
||||
$this->comment = $comment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setEvent(Event $event): self
|
||||
{
|
||||
$this->event = $event;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setKind(EventBudgetKind $kind): self
|
||||
{
|
||||
$this->kind = $kind;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,78 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Entity;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Type of event budget element.
|
||||
*/
|
||||
#[ORM\Entity]
|
||||
#[ORM\Table(name: 'chill_event_budget_kind')]
|
||||
class EventBudgetKind
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: Types::INTEGER)]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(type: Types::BOOLEAN, options: ['default' => true])]
|
||||
private bool $isActive = true;
|
||||
|
||||
#[ORM\Column(enumType: BudgetTypeEnum::class)]
|
||||
private BudgetTypeEnum $type;
|
||||
|
||||
#[ORM\Column(type: Types::JSON, length: 255, options: ['default' => '{}', 'jsonb' => true])]
|
||||
private array $name = [];
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getIsActive(): bool
|
||||
{
|
||||
return $this->isActive;
|
||||
}
|
||||
|
||||
public function getType(): BudgetTypeEnum
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function getName(): ?array
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setIsActive(bool $isActive): self
|
||||
{
|
||||
$this->isActive = $isActive;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setType(BudgetTypeEnum $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setName(array $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,158 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Entity;
|
||||
|
||||
use Chill\EventBundle\Repository\EventThemeRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* Class EventTheme.
|
||||
*/
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
#[ORM\Entity(repositoryClass: EventThemeRepository::class)]
|
||||
#[ORM\Table(name: 'chill_event_event_theme')]
|
||||
class EventTheme
|
||||
{
|
||||
#[ORM\Column(type: Types::BOOLEAN, nullable: false)]
|
||||
private bool $isActive = true;
|
||||
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(name: 'id', type: Types::INTEGER)]
|
||||
#[ORM\GeneratedValue(strategy: 'AUTO')]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(type: Types::JSON)]
|
||||
private array $name;
|
||||
|
||||
/**
|
||||
* @var Collection<int, EventTheme>
|
||||
*/
|
||||
#[ORM\OneToMany(mappedBy: 'parent', targetEntity: EventTheme::class)]
|
||||
private Collection $children;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: EventTheme::class, inversedBy: 'children')]
|
||||
private ?EventTheme $parent = null;
|
||||
|
||||
#[ORM\Column(name: 'ordering', type: Types::FLOAT, options: ['default' => '0.0'])]
|
||||
private float $ordering = 0.0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->children = new ArrayCollection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active.
|
||||
*/
|
||||
public function getIsActive(): bool
|
||||
{
|
||||
return $this->isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get id.
|
||||
*/
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label.
|
||||
*/
|
||||
public function getName(): array
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setIsActive(bool $active): self
|
||||
{
|
||||
$this->isActive = $active;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setName(array $label): self
|
||||
{
|
||||
$this->name = $label;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addChild(self $child): self
|
||||
{
|
||||
if (!$this->children->contains($child)) {
|
||||
$this->children[] = $child;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeChild(self $child): self
|
||||
{
|
||||
if ($this->children->removeElement($child)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($child->getParent() === $this) {
|
||||
$child->setParent(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getChildren(): Collection
|
||||
{
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
public function hasChildren(): bool
|
||||
{
|
||||
return 0 < $this->getChildren()->count();
|
||||
}
|
||||
|
||||
public function hasParent(): bool
|
||||
{
|
||||
return null !== $this->parent;
|
||||
}
|
||||
|
||||
public function getOrdering(): float
|
||||
{
|
||||
return $this->ordering;
|
||||
}
|
||||
|
||||
public function setOrdering(float $ordering): EventTheme
|
||||
{
|
||||
$this->ordering = $ordering;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getParent(): ?self
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
public function setParent(?self $parent): self
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
$parent?->addChild($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,377 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Export\Export;
|
||||
|
||||
use Chill\EventBundle\Entity\BudgetTypeEnum;
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Export\Declarations;
|
||||
use Chill\EventBundle\Repository\EventBudgetElementRepository;
|
||||
use Chill\EventBundle\Repository\EventThemeRepository;
|
||||
use Chill\EventBundle\Security\EventVoter;
|
||||
use Chill\EventBundle\Templating\Entity\EventThemeRender;
|
||||
use Chill\MainBundle\Export\ExportGenerationContext;
|
||||
use Chill\MainBundle\Export\FormatterInterface;
|
||||
use Chill\MainBundle\Export\GroupedExportInterface;
|
||||
use Chill\MainBundle\Export\ListInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Chill\ThirdPartyBundle\Export\Helper\LabelThirdPartyHelper;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\NativeQuery;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Validator\Constraints\Callback;
|
||||
use Symfony\Component\Validator\Context\ExecutionContextInterface;
|
||||
use Symfony\Contracts\Translation\TranslatableInterface;
|
||||
|
||||
/**
|
||||
* Render a list of events.
|
||||
*/
|
||||
class ListEvents implements ListInterface, GroupedExportInterface
|
||||
{
|
||||
protected array $fields = [
|
||||
'event_id',
|
||||
'event_center',
|
||||
'event_name',
|
||||
'event_date',
|
||||
'event_location',
|
||||
'event_type',
|
||||
'event_themes',
|
||||
'event_moderator',
|
||||
'event_animators',
|
||||
'event_participants_count',
|
||||
'event_budget_resources',
|
||||
'event_budget_charges',
|
||||
];
|
||||
|
||||
private readonly bool $filterStatsByCenters;
|
||||
|
||||
public function __construct(
|
||||
protected readonly EntityManagerInterface $entityManager,
|
||||
ParameterBagInterface $parameterBag,
|
||||
protected readonly TranslatableStringHelperInterface $translatableStringHelper,
|
||||
protected readonly EventThemeRender $eventThemeRender,
|
||||
protected readonly EventThemeRepository $eventThemeRepository,
|
||||
protected readonly LabelThirdPartyHelper $labelThirdPartyHelper,
|
||||
protected readonly EventBudgetElementRepository $eventBudgetElementRepository,
|
||||
) {
|
||||
$this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center'];
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder): void
|
||||
{
|
||||
$builder
|
||||
->add('fields', ChoiceType::class, [
|
||||
'multiple' => true,
|
||||
'expanded' => true,
|
||||
'choices' => array_combine($this->fields, $this->fields),
|
||||
'label' => 'Fields to include in export',
|
||||
'constraints' => [new Callback([
|
||||
'callback' => static function ($selected, ExecutionContextInterface $context) {
|
||||
if (0 === \count($selected)) {
|
||||
$context->buildViolation('You must select at least one element')
|
||||
->atPath('fields')
|
||||
->addViolation();
|
||||
}
|
||||
},
|
||||
])],
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function getFormDefaultData(): array
|
||||
{
|
||||
return [
|
||||
'fields' => $this->fields,
|
||||
];
|
||||
}
|
||||
|
||||
public function getAllowedFormattersTypes(): array
|
||||
{
|
||||
return [FormatterInterface::TYPE_LIST];
|
||||
}
|
||||
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'export.event.list.description';
|
||||
}
|
||||
|
||||
public function getGroup(): string
|
||||
{
|
||||
return 'Exports of events';
|
||||
}
|
||||
|
||||
public function getLabels($key, array $values, $data)
|
||||
{
|
||||
return match ($key) {
|
||||
'event_id' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_name' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_date' => function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
if ($value instanceof \DateTime) {
|
||||
return $value->format('Y-m-d');
|
||||
}
|
||||
|
||||
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $value);
|
||||
|
||||
return $date ? $date->format('Y-m-d') : $value;
|
||||
},
|
||||
'event_type' => function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
return 'export.event.list.'.$key;
|
||||
}
|
||||
|
||||
return $this->translatableStringHelper->localize(json_decode((string) $value, true, 512, JSON_THROW_ON_ERROR));
|
||||
},
|
||||
'event_center' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_moderator' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_participants_count' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_location' => fn ($value) => '_header' === $value ? $key : $value,
|
||||
'event_animators' => $this->labelThirdPartyHelper->getLabelMulti($key, $values, $key),
|
||||
'event_themes' => function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return implode(
|
||||
'|',
|
||||
array_map(
|
||||
fn ($t) => $this->eventThemeRender->renderString($this->eventThemeRepository->find($t), []),
|
||||
json_decode((string) $value, true, 512, JSON_THROW_ON_ERROR)
|
||||
)
|
||||
);
|
||||
},
|
||||
'event_budget_resources' => function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (!$value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$ids = explode(',', $value);
|
||||
$ids = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
|
||||
$elements = $this->eventBudgetElementRepository->findBy(['id' => $ids]);
|
||||
|
||||
return implode('|', array_map(function ($element) {
|
||||
$name = $this->translatableStringHelper->localize($element->getKind()->getName());
|
||||
$amount = number_format($element->getAmount(), 2, '.', '');
|
||||
|
||||
return $name.': '.$amount;
|
||||
}, $elements));
|
||||
},
|
||||
|
||||
'event_budget_charges' => function ($value) use ($key) {
|
||||
if ('_header' === $value) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
if (!$value) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$ids = explode(',', $value);
|
||||
$ids = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
$elements = $this->eventBudgetElementRepository->findBy(['id' => $ids]);
|
||||
|
||||
return implode('|', array_map(function ($element) {
|
||||
$name = $this->translatableStringHelper->localize($element->getKind()->getName());
|
||||
$amount = number_format($element->getAmount(), 2, '.', '');
|
||||
|
||||
return $name.': '.$amount;
|
||||
}, $elements));
|
||||
},
|
||||
|
||||
|
||||
default => fn ($value) => '_header' === $value ? $key : $value,
|
||||
};
|
||||
}
|
||||
|
||||
public function getQueryKeys(array $data): array
|
||||
{
|
||||
return $data['fields'];
|
||||
}
|
||||
|
||||
public function getResult($query, $data, ExportGenerationContext $context): array
|
||||
{
|
||||
return $query->getQuery()->getResult(Query::HYDRATE_SCALAR);
|
||||
}
|
||||
|
||||
public function getTitle(): string|TranslatableInterface
|
||||
{
|
||||
return 'export.event.list.title';
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return Declarations::EVENT;
|
||||
}
|
||||
|
||||
public function initiateQuery(array $requiredModifiers, array $acl, array $data, ExportGenerationContext $context): NativeQuery|QueryBuilder
|
||||
{
|
||||
$centers = array_map(static fn ($el) => $el['center'], $acl);
|
||||
|
||||
// Throw an error if no fields are present
|
||||
if (!\array_key_exists('fields', $data)) {
|
||||
throw new \InvalidArgumentException('No fields have been checked.');
|
||||
}
|
||||
|
||||
$qb = $this->entityManager->createQueryBuilder()
|
||||
->from(Event::class, 'event');
|
||||
|
||||
if ($this->filterStatsByCenters) {
|
||||
$qb
|
||||
->andWhere('event.center IN (:authorized_centers)')
|
||||
->setParameter('authorized_centers', $centers);
|
||||
}
|
||||
|
||||
// Add fields based on selection
|
||||
foreach ($this->fields as $field) {
|
||||
if (\in_array($field, $data['fields'], true)) {
|
||||
switch ($field) {
|
||||
case 'event_id':
|
||||
$qb->addSelect('event.id AS event_id');
|
||||
break;
|
||||
|
||||
case 'event_name':
|
||||
$qb->addSelect('event.name AS event_name');
|
||||
break;
|
||||
|
||||
case 'event_date':
|
||||
$qb->addSelect('event.date AS event_date');
|
||||
break;
|
||||
|
||||
case 'event_type':
|
||||
if (!$this->hasJoin($qb, 'event.type')) {
|
||||
$qb->leftJoin('event.type', 'type');
|
||||
}
|
||||
$qb->addSelect('type.name AS event_type');
|
||||
break;
|
||||
|
||||
case 'event_center':
|
||||
if (!$this->hasJoin($qb, 'event.center')) {
|
||||
$qb->leftJoin('event.center', 'center');
|
||||
}
|
||||
$qb->addSelect('center.name AS event_center');
|
||||
break;
|
||||
|
||||
case 'event_moderator':
|
||||
if (!$this->hasJoin($qb, 'event.moderator')) {
|
||||
$qb->leftJoin('event.moderator', 'user');
|
||||
}
|
||||
$qb->addSelect('user.username AS event_moderator');
|
||||
break;
|
||||
|
||||
case 'event_participants_count':
|
||||
$qb->addSelect('(SELECT COUNT(p.id) FROM Chill\EventBundle\Entity\Participation p WHERE p.event = event.id) AS event_participants_count');
|
||||
break;
|
||||
|
||||
case 'event_location':
|
||||
if (!$this->hasJoin($qb, 'event.location')) {
|
||||
$qb->leftJoin('event.location', 'location');
|
||||
}
|
||||
$qb->addSelect('location.name AS event_location');
|
||||
break;
|
||||
|
||||
case 'event_animators':
|
||||
$qb->addSelect(
|
||||
'(SELECT AGGREGATE(tp.id) FROM Chill\ThirdPartyBundle\Entity\ThirdParty tp WHERE tp MEMBER OF event.animators) AS event_animators'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'event_themes':
|
||||
$qb->addSelect(
|
||||
'(SELECT AGGREGATE(t.id) FROM Chill\EventBundle\Entity\EventTheme t WHERE t MEMBER OF event.themes) AS event_themes'
|
||||
);
|
||||
break;
|
||||
|
||||
case 'event_budget_resources':
|
||||
$qb->addSelect(
|
||||
'(SELECT AGGREGATE(ebr.id)
|
||||
FROM Chill\EventBundle\Entity\EventBudgetElement ebr
|
||||
JOIN ebr.kind kr
|
||||
WHERE ebr.event = event.id AND kr.type = :resource_type) AS event_budget_resources'
|
||||
);
|
||||
$qb->setParameter('resource_type', BudgetTypeEnum::RESOURCE->value);
|
||||
break;
|
||||
|
||||
case 'event_budget_charges':
|
||||
$qb->addSelect(
|
||||
'(SELECT AGGREGATE(ebc.id)
|
||||
FROM Chill\EventBundle\Entity\EventBudgetElement ebc
|
||||
JOIN ebc.kind kc
|
||||
WHERE ebc.event = event.id AND kc.type = :charge_type) AS event_budget_charges'
|
||||
);
|
||||
$qb->setParameter('charge_type', BudgetTypeEnum::CHARGE->value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
public function requiredRole(): string
|
||||
{
|
||||
return EventVoter::STATS;
|
||||
}
|
||||
|
||||
public function supportsModifiers()
|
||||
{
|
||||
return [Declarations::EVENT];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to check if a join already exists in the QueryBuilder.
|
||||
*/
|
||||
private function hasJoin($queryBuilder, $joinPath): bool
|
||||
{
|
||||
$joins = $queryBuilder->getDQLPart('join');
|
||||
if (!isset($joins['event'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($joins['event'] as $join) {
|
||||
if ($join->getJoin() === $joinPath) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function normalizeFormData(array $formData): array
|
||||
{
|
||||
return ['fields' => $formData['fields']];
|
||||
}
|
||||
|
||||
public function denormalizeFormData(array $formData, int $fromVersion): array
|
||||
{
|
||||
return ['fields' => $formData['fields']];
|
||||
}
|
||||
|
||||
public function getNormalizationVersion(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Form;
|
||||
|
||||
use Chill\EventBundle\Entity\BudgetTypeEnum;
|
||||
use Chill\EventBundle\Entity\EventBudgetElement;
|
||||
use Chill\EventBundle\Entity\EventBudgetKind;
|
||||
use Chill\EventBundle\Repository\EventBudgetKindRepository;
|
||||
use Chill\MainBundle\Form\Type\CommentType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class AddEventBudgetElementType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly EventBudgetKindRepository $kindRepository, private readonly TranslatableStringHelperInterface $translatableStringHelper) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$charges = $this->kindRepository->findByType(BudgetTypeEnum::CHARGE->value);
|
||||
$resources = $this->kindRepository->findByType(BudgetTypeEnum::RESOURCE->value);
|
||||
|
||||
$builder->add('kind', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'event.budget.charges' => $charges,
|
||||
'event.budget.resources' => $resources,
|
||||
],
|
||||
'choice_label' => fn (EventBudgetKind $kind) => $this->translatableStringHelper->localize($kind->getName()),
|
||||
'choice_value' => fn (?EventBudgetKind $kind) => $kind?->getId(),
|
||||
'placeholder' => 'event.budget.Select a budget element kind',
|
||||
])
|
||||
->add('amount', NumberType::class, [
|
||||
'required' => true,
|
||||
])
|
||||
->add('comment', CommentType::class, [
|
||||
'label' => 'Comment',
|
||||
'required' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => EventBudgetElement::class,
|
||||
]);
|
||||
}
|
||||
}
|
@@ -1,53 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Form;
|
||||
|
||||
use Chill\EventBundle\Entity\BudgetTypeEnum;
|
||||
use Chill\EventBundle\Entity\EventBudgetKind;
|
||||
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class EventBudgetKindType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly TranslatorInterface $translator) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder
|
||||
->add('name', TranslatableStringFormType::class, [
|
||||
'label' => 'Title',
|
||||
])
|
||||
->add('type', EnumType::class, [
|
||||
'class' => BudgetTypeEnum::class,
|
||||
'choice_label' => fn (BudgetTypeEnum $type): string => $this->translator->trans($type->value),
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'mapped' => true,
|
||||
'label' => 'event.admin.Select budget type',
|
||||
])
|
||||
->add('isActive', CheckboxType::class, [
|
||||
'label' => 'Actif ?',
|
||||
'required' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefault('class', EventBudgetKind::class);
|
||||
}
|
||||
}
|
@@ -1,67 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Form;
|
||||
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Chill\MainBundle\Form\Type\TranslatableStringFormType;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelperInterface;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
|
||||
class EventThemeType extends AbstractType
|
||||
{
|
||||
public function __construct(protected TranslatableStringHelperInterface $translatableStringHelper) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('name', TranslatableStringFormType::class, [
|
||||
'label' => 'Nom',
|
||||
]);
|
||||
|
||||
if ('create' === $options['step']) {
|
||||
$builder
|
||||
->add('parent', EntityType::class, [
|
||||
'class' => EventTheme::class,
|
||||
'required' => false,
|
||||
'choice_label' => fn (EventTheme $theme): ?string => $this->translatableStringHelper->localize($theme->getName()),
|
||||
'mapped' => 'create' == $options['step'],
|
||||
]);
|
||||
}
|
||||
|
||||
$builder
|
||||
->add('ordering', NumberType::class, [
|
||||
'required' => true,
|
||||
'scale' => 6,
|
||||
])
|
||||
->add('isActive', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'Yes' => true,
|
||||
'No' => false,
|
||||
],
|
||||
'expanded' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'data_class' => EventTheme::class,
|
||||
]);
|
||||
$resolver->setRequired('step')
|
||||
->setAllowedValues('step', ['create', 'edit']);
|
||||
}
|
||||
}
|
@@ -13,39 +13,25 @@ namespace Chill\EventBundle\Form;
|
||||
|
||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||
use Chill\DocStoreBundle\Form\StoredObjectType;
|
||||
use Chill\EventBundle\Entity\BudgetTypeEnum;
|
||||
use Chill\EventBundle\Entity\Event;
|
||||
use Chill\EventBundle\Form\Type\PickEventThemeType;
|
||||
use Chill\EventBundle\Form\Type\PickEventTypeType;
|
||||
use Chill\EventBundle\Repository\EventBudgetKindRepository;
|
||||
use Chill\MainBundle\Entity\Center;
|
||||
use Chill\MainBundle\Form\DataTransformer\IdToLocationDataTransformer;
|
||||
use Chill\MainBundle\Form\Type\ChillCollectionType;
|
||||
use Chill\MainBundle\Form\Type\ChillDateTimeType;
|
||||
use Chill\MainBundle\Form\Type\CommentType;
|
||||
use Chill\MainBundle\Form\Type\PickUserDynamicType;
|
||||
use Chill\MainBundle\Form\Type\PickUserLocationType;
|
||||
use Chill\MainBundle\Form\Type\ScopePickerType;
|
||||
use Chill\ThirdPartyBundle\Form\Type\PickThirdpartyDynamicType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\MoneyType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class EventType extends AbstractType
|
||||
{
|
||||
public function __construct(
|
||||
private readonly IdToLocationDataTransformer $idToLocationDataTransformer,
|
||||
private readonly EventBudgetKindRepository $eventBudgetKindRepository,
|
||||
private readonly TranslatorInterface $translator,
|
||||
) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$chargeKinds = $this->eventBudgetKindRepository->findByType(BudgetTypeEnum::CHARGE->value);
|
||||
$resourceKinds = $this->eventBudgetKindRepository->findByType(BudgetTypeEnum::RESOURCE->value);
|
||||
|
||||
$builder
|
||||
->add('name', TextType::class, [
|
||||
'required' => true,
|
||||
@@ -63,28 +49,11 @@ class EventType extends AbstractType
|
||||
'class' => '',
|
||||
],
|
||||
])
|
||||
->add('themes', PickEventThemeType::class, [
|
||||
'multiple' => true,
|
||||
])
|
||||
->add('moderator', PickUserDynamicType::class, [
|
||||
'label' => 'Pick a moderator',
|
||||
])
|
||||
->add('animatorsIntern', PickUserDynamicType::class, [
|
||||
'multiple' => true,
|
||||
'label' => $this->translator->trans('event.fields.internal animators'),
|
||||
'required' => false,
|
||||
])
|
||||
->add('animatorsExtern', PickThirdpartyDynamicType::class, [
|
||||
'multiple' => true,
|
||||
'label' => $this->translator->trans('event.fields.external animators'),
|
||||
'required' => false,
|
||||
])
|
||||
->add('budgetElements', ChillCollectionType::class, [
|
||||
'entry_type' => AddEventBudgetElementType::class,
|
||||
'entry_options' => ['label' => false],
|
||||
'allow_add' => true,
|
||||
'allow_delete' => true,
|
||||
'by_reference' => false,
|
||||
->add('location', PickUserLocationType::class, [
|
||||
'label' => 'event.fields.location',
|
||||
])
|
||||
->add('comment', CommentType::class, [
|
||||
'label' => 'Comment',
|
||||
@@ -100,11 +69,11 @@ class EventType extends AbstractType
|
||||
'delete_empty' => fn (StoredObject $storedObject): bool => '' === $storedObject->getFilename(),
|
||||
'button_remove_label' => 'event.form.remove_document',
|
||||
'button_add_label' => 'event.form.add_document',
|
||||
])
|
||||
->add('organizationCost', MoneyType::class, [
|
||||
'label' => 'event.fields.organizationCost',
|
||||
'help' => 'event.form.organisationCost_help',
|
||||
]);
|
||||
|
||||
$builder->add('location', HiddenType::class)
|
||||
->get('location')
|
||||
->addModelTransformer($this->idToLocationDataTransformer);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
@@ -118,9 +87,11 @@ class EventType extends AbstractType
|
||||
->setAllowedTypes('role', 'string');
|
||||
}
|
||||
|
||||
public function getBlockPrefix(): string
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBlockPrefix()
|
||||
{
|
||||
// as the js shares some hardcoded items from the activity bundle, we have to rewrite block prefix
|
||||
return 'chill_activitybundle_activity';
|
||||
return 'chill_eventbundle_event';
|
||||
}
|
||||
}
|
||||
|
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Form\Type;
|
||||
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Chill\EventBundle\Repository\EventThemeRepository;
|
||||
use Chill\EventBundle\Templating\Entity\EventThemeRender;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class PickEventThemeType extends AbstractType
|
||||
{
|
||||
public function __construct(private readonly EventThemeRender $eventThemeRender, private readonly EventThemeRepository $eventThemeRepository) {}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver
|
||||
->setDefaults([
|
||||
'class' => EventTheme::class,
|
||||
'choices' => $this->eventThemeRepository->findByActiveOrdered(),
|
||||
'choice_label' => fn (EventTheme $et) => $this->eventThemeRender->renderString($et, []),
|
||||
'placeholder' => 'event.form.Select one or more themes',
|
||||
'required' => true,
|
||||
'attr' => ['class' => 'select2'],
|
||||
'label' => 'event.theme.label',
|
||||
'multiple' => false,
|
||||
])
|
||||
->setAllowedTypes('multiple', ['bool']);
|
||||
}
|
||||
|
||||
public function getParent(): string
|
||||
{
|
||||
return EntityType::class;
|
||||
}
|
||||
}
|
@@ -23,7 +23,15 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
*/
|
||||
class PickEventTypeType extends AbstractType
|
||||
{
|
||||
public function __construct(protected TranslatableStringHelper $translatableStringHelper) {}
|
||||
/**
|
||||
* @var TranslatableStringHelper
|
||||
*/
|
||||
protected $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $helper)
|
||||
{
|
||||
$this->translatableStringHelper = $helper;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
|
@@ -17,9 +17,17 @@ use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
|
||||
|
||||
class AdminMenuBuilder implements LocalMenuBuilderInterface
|
||||
{
|
||||
public function __construct(protected AuthorizationCheckerInterface $authorizationChecker) {}
|
||||
/**
|
||||
* @var AuthorizationCheckerInterface
|
||||
*/
|
||||
protected $authorizationChecker;
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||
public function __construct(AuthorizationCheckerInterface $authorizationChecker)
|
||||
{
|
||||
$this->authorizationChecker = $authorizationChecker;
|
||||
}
|
||||
|
||||
public function buildMenu($menuId, MenuItem $menu, array $parameters)
|
||||
{
|
||||
if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) {
|
||||
return;
|
||||
@@ -44,14 +52,6 @@ class AdminMenuBuilder implements LocalMenuBuilderInterface
|
||||
$menu->addChild('Role', [
|
||||
'route' => 'chill_event_admin_role',
|
||||
])->setExtras(['order' => 6530]);
|
||||
|
||||
$menu->addChild('event.theme.label', [
|
||||
'route' => 'chill_crud_event_theme_index',
|
||||
])->setExtras(['order' => 6540]);
|
||||
|
||||
$menu->addChild('event.budget.label', [
|
||||
'route' => 'chill_crud_event_budget_kind_index',
|
||||
])->setExtras(['order' => 6550]);
|
||||
}
|
||||
|
||||
public static function getMenuIds(): array
|
||||
|
@@ -88,16 +88,6 @@ final readonly class EventACLAwareRepository implements EventACLAwareRepositoryI
|
||||
$qb->andWhere('event.type IN (:event_types)');
|
||||
$qb->setParameter('event_types', $filters['event_types']);
|
||||
}
|
||||
|
||||
if (0 < count($filters['centers'] ?? [])) {
|
||||
$qb->andWhere('event.center IN (:centers)');
|
||||
$qb->setParameter('centers', $filters['centers']);
|
||||
}
|
||||
|
||||
if (0 < count($filters['responsables'] ?? [])) {
|
||||
$qb->andWhere('event.moderator IN (:responsables)');
|
||||
$qb->setParameter('responsables', $filters['responsables']);
|
||||
}
|
||||
}
|
||||
|
||||
public function buildQueryByAllViewable(array $filters): QueryBuilder
|
||||
|
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Repository;
|
||||
|
||||
use Chill\EventBundle\Entity\EventBudgetElement;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<EventBudgetElement>
|
||||
*/
|
||||
class EventBudgetElementRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, EventBudgetElement::class);
|
||||
}
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Repository;
|
||||
|
||||
use Chill\EventBundle\Entity\EventBudgetKind;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<EventBudgetKind>
|
||||
*/
|
||||
class EventBudgetKindRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, EventBudgetKind::class);
|
||||
}
|
||||
|
||||
public function findByActive(): array
|
||||
{
|
||||
return $this->createQueryBuilder('e')
|
||||
->select('e')
|
||||
->where('e.active = True')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
|
||||
public function findByType(string $type): array
|
||||
{
|
||||
return $this->createQueryBuilder('e')
|
||||
->select('e')
|
||||
->where('e.type = :type')
|
||||
->setParameter('type', $type)
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Repository;
|
||||
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<EventTheme>
|
||||
*/
|
||||
class EventThemeRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, EventTheme::class);
|
||||
}
|
||||
|
||||
public function findByActiveOrdered(): array
|
||||
{
|
||||
return $this->createQueryBuilder('t')
|
||||
->select('t')
|
||||
->where('t.isActive = True')
|
||||
->orderBy('t.ordering', 'ASC')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
@@ -55,13 +55,3 @@ form#export_tableur {
|
||||
-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
|
||||
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
|
||||
}
|
||||
|
||||
.participation-list {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.participations-wrapper {
|
||||
background-color: whitesmoke;
|
||||
padding: 1rem;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
<template>
|
||||
<location />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Location from "ChillActivityAssets/vuejs/Activity/components/Location.vue";
|
||||
|
||||
export default {
|
||||
name: "App",
|
||||
components: {
|
||||
Location,
|
||||
},
|
||||
};
|
||||
</script>
|
@@ -1,6 +0,0 @@
|
||||
import { createApp } from "vue";
|
||||
|
||||
import App from "./App.vue";
|
||||
import store from "./store";
|
||||
|
||||
createApp(App).use(store).mount("#event");
|
@@ -1,76 +0,0 @@
|
||||
import "es6-promise/auto";
|
||||
import { createStore } from "vuex";
|
||||
|
||||
import prepareLocations from "ChillActivityAssets/vuejs/Activity/store.locations";
|
||||
import { whoami } from "ChillMainAssets/lib/api/user";
|
||||
import { postLocation } from "ChillActivityAssets/vuejs/Activity/api";
|
||||
|
||||
const debug = process.env.NODE_ENV !== "production";
|
||||
|
||||
const store = createStore({
|
||||
strict: debug,
|
||||
state: {
|
||||
activity: window.entity, // activity is the event entity in this case (re-using component from activity bundle)
|
||||
currentEvent: null,
|
||||
availableLocations: [],
|
||||
me: null,
|
||||
},
|
||||
getters: {},
|
||||
actions: {
|
||||
addAvailableLocationGroup({ commit }, payload) {
|
||||
commit("addAvailableLocationGroup", payload);
|
||||
},
|
||||
updateLocation({ commit }, value) {
|
||||
// console.log("### action: updateLocation", value);
|
||||
let hiddenLocation = document.getElementById(
|
||||
"chill_activitybundle_activity_location",
|
||||
);
|
||||
if (value.onthefly) {
|
||||
const body = {
|
||||
type: "location",
|
||||
name:
|
||||
value.name === "__AccompanyingCourseLocation__" ? null : value.name,
|
||||
locationType: {
|
||||
id: value.locationType.id,
|
||||
type: "location-type",
|
||||
},
|
||||
};
|
||||
if (value.address.id) {
|
||||
Object.assign(body, {
|
||||
address: {
|
||||
id: value.address.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
postLocation(body)
|
||||
.then((location) => (hiddenLocation.value = location.id))
|
||||
.catch((err) => {
|
||||
console.log(err.message);
|
||||
});
|
||||
} else {
|
||||
hiddenLocation.value = value.id;
|
||||
}
|
||||
commit("updateLocation", value);
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setWhoAmiI(state, me) {
|
||||
state.me = me;
|
||||
},
|
||||
addAvailableLocationGroup(state, group) {
|
||||
state.availableLocations.push(group);
|
||||
},
|
||||
updateLocation(state, value) {
|
||||
// console.log("### mutation: updateLocation", value);
|
||||
state.activity.location = value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
whoami().then((me) => {
|
||||
store.commit("setWhoAmiI", me);
|
||||
});
|
||||
|
||||
prepareLocations(store);
|
||||
|
||||
export default store;
|
@@ -1,12 +0,0 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
|
||||
{% block content_form_actions_view %}{% endblock %}
|
||||
{% block content_form_actions_save_and_show %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
@@ -1,51 +0,0 @@
|
||||
{% extends '@ChillMain/Admin/layoutWithVerticalMenu.html.twig' %}
|
||||
|
||||
{% block title %}{{ 'event.admin.title.Event budget element list'|trans }}{% endblock title %}
|
||||
|
||||
{% block admin_content %}
|
||||
|
||||
<h1>{{ 'event.admin.title.Event budget element list'|trans }}</h1>
|
||||
|
||||
<table class="records_list table table-bordered border-dark">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'Name'|trans }}</th>
|
||||
<th>{{ 'Type'|trans }}</th>
|
||||
<th>{{ 'Active'|trans }}</th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td>{{ entity.name|localize_translatable_string }}</td>
|
||||
<td>{{ entity.type.value|trans }}</td>
|
||||
<td style="text-align:center;">
|
||||
{%- if entity.isActive -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('chill_crud_event_budget_kind_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{{ chill_pagination(paginator) }}
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li>
|
||||
<a href="{{ path('chill_crud_event_budget_kind_new') }}" class="btn btn-create">
|
||||
{{ 'event.admin.new.Create a new budget kind'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
@@ -1,11 +0,0 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
|
||||
{% block content_form_actions_save_and_show %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
@@ -1,26 +0,0 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_edit_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_edit_content.html.twig' %}
|
||||
|
||||
{% block crud_content_form_rows %}
|
||||
{{ form_row(form.name) }}
|
||||
<div class="mb-3 row">
|
||||
<label class="col-form-label col-sm-4">
|
||||
{{ 'Parent'|trans }}
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
{{ entity.parent|chill_entity_render_box }}
|
||||
</div>
|
||||
</div>
|
||||
{{ form_row(form.ordering) }}
|
||||
{{ form_row(form.isActive) }}
|
||||
{% endblock crud_content_form_rows %}
|
||||
|
||||
{% block content_form_actions_save_and_show %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock admin_content %}
|
@@ -1,45 +0,0 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_index.html.twig' %}
|
||||
{% block table_entities_thead_tr %}
|
||||
<th>{{ 'Id'|trans }}</th>
|
||||
<th>{{ 'Title'|trans }}</th>
|
||||
<th>{{ 'Ordering'|trans }}</th>
|
||||
<th>{{ 'active'|trans }}</th>
|
||||
<th> </th>
|
||||
{% endblock %}
|
||||
|
||||
{% block table_entities_tbody %}
|
||||
{% for entity in entities %}
|
||||
<tr>
|
||||
<td>{{ entity.id }}</td>
|
||||
<td>
|
||||
{{ entity|chill_entity_render_box }}
|
||||
</td>
|
||||
<td>{{ entity.ordering }}</td>
|
||||
<td style="text-align:center;">
|
||||
{%- if entity.isActive -%}
|
||||
<i class="fa fa-check-square-o"></i>
|
||||
{%- else -%}
|
||||
<i class="fa fa-square-o"></i>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_crud_event_theme_edit', { 'id': entity.id }) }}" class="btn btn-edit"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% block actions_before %}
|
||||
<li class='cancel'>
|
||||
<a href="{{ path('chill_main_admin_central') }}" class="btn btn-cancel">{{'Back to the admin'|trans}}</a>
|
||||
</li>
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock %}
|
@@ -1,11 +0,0 @@
|
||||
{% extends '@ChillMain/CRUD/Admin/index.html.twig' %}
|
||||
|
||||
{% block title %}
|
||||
{% include('@ChillMain/CRUD/_new_title.html.twig') %}
|
||||
{% endblock %}
|
||||
|
||||
{% block admin_content %}
|
||||
{% embed '@ChillMain/CRUD/_new_content.html.twig' %}
|
||||
{% block content_form_actions_save_and_show %}{% endblock %}
|
||||
{% endembed %}
|
||||
{% endblock admin_content %}
|
@@ -1,13 +0,0 @@
|
||||
{% set reversed_parents = parents|reverse %}
|
||||
<span class="chill-entity entity-event-theme">
|
||||
<span class="badge bg-chill-l-gray text-dark">
|
||||
{%- for p in reversed_parents %}
|
||||
<span class="parent-{{ loop.revindex0 }}">
|
||||
{{ p.name|localize_translatable_string }}{{ options['default.separator'] }}
|
||||
</span>
|
||||
{%- endfor -%}
|
||||
<span class="child">
|
||||
{{ eventTheme.name|localize_translatable_string }}
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
@@ -12,7 +12,7 @@
|
||||
'title' : 'Delete event'|trans,
|
||||
'confirm_question' : 'Are you sure you want to remove that event ?'|trans,
|
||||
'cancel_route' : activeRouteKey,
|
||||
'cancel_parameters' : { 'id' : id },
|
||||
'cancel_parameters' : { 'event_id' : event_id },
|
||||
'form' : delete_form
|
||||
}
|
||||
) }}
|
||||
|
@@ -17,12 +17,10 @@
|
||||
{{ form_row(edit_form.date) }}
|
||||
|
||||
{{ form_row(edit_form.type, { label: "Event type" }) }}
|
||||
{{ form_row(edit_form.themes) }}
|
||||
{{ form_row(edit_form.moderator) }}
|
||||
{{ form_row(edit_form.animatorsIntern) }}
|
||||
{{ form_row(edit_form.animatorsExtern) }}
|
||||
{{ form_row(edit_form.location) }}
|
||||
{{ form_row(edit_form.budgetElements) }}
|
||||
{{ form_row(edit_form.organizationCost) }}
|
||||
|
||||
{{ form_row(edit_form.comment) }}
|
||||
{{ form_row(edit_form.documents) }}
|
||||
|
||||
|
@@ -34,7 +34,7 @@
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
{# {% if is_granted('CHILL_EVENT_SEE_DETAILS', event) %} #}
|
||||
<a href="{{ path('chill_event__event_show', { 'id' : event.id } ) }}" class="btn btn-view">
|
||||
<a href="{{ path('chill_event__event_show', { 'event_id' : event.id } ) }}" class="btn btn-view">
|
||||
{{ 'See'|trans }}
|
||||
</a>
|
||||
{# {% endif %} #}
|
||||
|
@@ -53,7 +53,7 @@
|
||||
{% set returnLabel = 'Back to %person% events'|trans({ '%person%' : currentPerson } ) %}
|
||||
|
||||
{% if is_granted('CHILL_EVENT_SEE_DETAILS', participation.event) %}
|
||||
<a href="{{ path('chill_event__event_show', { 'id' : participation.event.id, 'return_path' : currentPath, 'return_label' : returnLabel } ) }}"
|
||||
<a href="{{ path('chill_event__event_show', { 'event_id' : participation.event.id, 'return_path' : currentPath, 'return_label' : returnLabel } ) }}"
|
||||
class="btn btn-primary btn-sm" title="{{ 'See details of the event'|trans }}">
|
||||
<i class="fa fa-fw fa-eye"></i>
|
||||
</a>
|
||||
|
@@ -1,30 +1,25 @@
|
||||
{% extends '@ChillEvent/layout.html.twig' %}
|
||||
{% extends '@ChillEvent/layout.html.twig' %} {% block js %}
|
||||
{{ encore_entry_script_tags("mod_async_upload") }}
|
||||
{{ encore_entry_script_tags("mod_pickentity_type") }}
|
||||
|
||||
{% block css %}
|
||||
{% endblock %} {% block css %}
|
||||
{{ encore_entry_link_tags("mod_async_upload") }}
|
||||
{{ encore_entry_link_tags("mod_pickentity_type") }}
|
||||
{{ encore_entry_link_tags('vue_event') }}
|
||||
{% endblock %}
|
||||
|
||||
{% block title 'Event creation'|trans %}
|
||||
|
||||
{% block event_content -%}
|
||||
{% endblock %} {% block title 'Event creation'|trans %} {% block event_content
|
||||
-%}
|
||||
<div class="col-10">
|
||||
<h1>{{ "Event creation" | trans }}</h1>
|
||||
|
||||
{{ form_start(form) }}
|
||||
{{ form_errors(form) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.circle) }}
|
||||
{{ form_row(form.name) }}
|
||||
{{ form_row(form.date) }}
|
||||
{{ form_row(form.type, { label: "Event type" }) }}
|
||||
{{ form_row(form.themes) }}
|
||||
{{ form_row(form.moderator) }}
|
||||
{{ form_row(form.animatorsIntern) }}
|
||||
{{ form_row(form.animatorsExtern) }}
|
||||
{{ form_row(form.location) }}
|
||||
<div id="location"></div>
|
||||
{{ form_row(form.budgetElements) }}
|
||||
{{ form_row(form.organizationCost) }}
|
||||
{{ form_row(form.comment) }}
|
||||
{{ form_row(form.documents) }}
|
||||
|
||||
@@ -45,18 +40,5 @@
|
||||
</ul>
|
||||
|
||||
{{ form_end(form) }}
|
||||
|
||||
<div id="event"></div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block js %}
|
||||
{{ encore_entry_script_tags("mod_async_upload") }}
|
||||
{{ encore_entry_script_tags("mod_pickentity_type") }}
|
||||
{{ encore_entry_script_tags('vue_event') }}
|
||||
<script type="text/javascript">
|
||||
window.entity = {{ entity_json|json_encode|raw }};
|
||||
{% if app.user.currentLocation is not null %}window.default_location_id = {{ app.user.currentLocation.id }};{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@@ -11,7 +11,7 @@ block js %}
|
||||
|
||||
{{ filter | chill_render_filter_order_helper }}
|
||||
|
||||
{% if is_granted('CHILL_EVENT_CREATE') %}
|
||||
{# {% if is_granted('CHILL_EVENT_CREATE') %} #}
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a
|
||||
@@ -25,9 +25,7 @@ block js %}
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% if events|length > 0 %}
|
||||
{# {% endif %} #} {% if events|length > 0 %}
|
||||
<div class="flex-table">
|
||||
{% for e in events %}
|
||||
<div class="item-bloc">
|
||||
@@ -43,12 +41,6 @@ block js %}
|
||||
{{ e.moderator | chill_entity_render_box }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<div>
|
||||
{% for t in e.themes %}
|
||||
<span>{{ t|chill_entity_render_box }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-col">
|
||||
<div class="container" style="text-align: right">
|
||||
@@ -56,21 +48,20 @@ block js %}
|
||||
<p>
|
||||
{{ 'count participations to this event'|trans({'count': e.participations|length}) }}
|
||||
</p>
|
||||
<p>{{ "center"|trans }}: {{ e.center.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if e.participations|length > 0 %}
|
||||
<div class="participation-list item-row separator">
|
||||
<div class="item-row separator">
|
||||
<strong>{{ "Participations" | trans }} : </strong>
|
||||
{% for part in e.participations|slice(0, 5) %} {% include
|
||||
{% for part in e.participations|slice(0, 20) %} {% include
|
||||
'@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
targetEntity: { name: 'person', id: part.person.id }, action:
|
||||
'show', displayBadge: true, buttonText:
|
||||
part.person|chill_entity_render_string, isDead:
|
||||
part.person.deathdate is not null } %} {% endfor %}
|
||||
{% if e.participations|length > 5 %}
|
||||
{{ 'events.and_other_count_participants'|trans({'count': e.participations|length - 5}) }}
|
||||
part.person.deathdate is not null } %} {% endfor %} {% if
|
||||
e.participations|length > 20 %}
|
||||
{{ 'events.and_other_count_participants'|trans({'count': e.participations|length - 20}) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -115,7 +106,7 @@ block js %}
|
||||
href="{{
|
||||
chill_path_add_return_path(
|
||||
'chill_event__event_show',
|
||||
{ id: e.id }
|
||||
{ event_id: e.id }
|
||||
)
|
||||
}}"
|
||||
class="btn btn-show"
|
||||
|
@@ -16,16 +16,6 @@
|
||||
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
|
||||
{% endblock %}
|
||||
|
||||
{% macro insert_onthefly(type, entity, parent = null) %}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
action: 'show', displayBadge: true,
|
||||
targetEntity: { name: type, id: entity.id },
|
||||
buttonText: entity|chill_entity_render_string,
|
||||
isDead: entity.deathdate is defined and entity.deathdate is not null,
|
||||
parent: parent
|
||||
} %}
|
||||
{% endmacro %}
|
||||
|
||||
{% block event_content -%}
|
||||
<div class="col-10">
|
||||
<h1>{{ 'Details of an event'|trans }}</h1>
|
||||
@@ -36,10 +26,6 @@
|
||||
<th>{{ 'Circle'|trans }}</th>
|
||||
<td>{{ event.circle.name|localize_translatable_string }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'Center'|trans }}</th>
|
||||
<td>{{ event.center.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'Name'|trans }}</th>
|
||||
<td>{{ event.name }}</td>
|
||||
@@ -52,33 +38,13 @@
|
||||
<th>{{ 'Event type'|trans }}</th>
|
||||
<td>{{ event.type.name|localize_translatable_string }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'event.theme.label'|trans }}
|
||||
<td>
|
||||
{% for t in event.themes %}
|
||||
{{ t|chill_entity_render_box }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'Moderator'|trans }}</th>
|
||||
<td>{{ event.moderator|chill_entity_render_string }}</td>
|
||||
<td>{{ event.moderator|trans|default('-') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'event.animators.intern'|trans }}</th>
|
||||
<td>
|
||||
{% for a in event.animatorsIntern %}
|
||||
{{ _self.insert_onthefly('user', a) }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'event.animators.extern'|trans }}</th>
|
||||
<td>
|
||||
{% for a in event.animatorsExtern %}
|
||||
{{ _self.insert_onthefly('thirdparty', a) }}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<th>{{ 'event.fields.organizationCost'|trans }}</th>
|
||||
<td>{{ event.organizationCost|format_currency('EUR') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{{ 'event.fields.location'|trans }}</th>
|
||||
@@ -94,77 +60,6 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="budget-wrapper" style="background-color: whitesmoke; padding: 1rem; margin-bottom: .5rem;">
|
||||
{% set resources = event.budgetElements|filter(e => e.kind.type.value == 'Resource') %}
|
||||
{% set charges = event.budgetElements|filter(e => e.kind.type.value == 'Charge') %}
|
||||
|
||||
<h2>Budget de l'événement</h2>
|
||||
|
||||
<h3>Ressources</h3>
|
||||
{% if resources is not empty %}
|
||||
<table class="table table-bordered border-dark align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'event.budget.resource type'|trans }}</th>
|
||||
<th>{{ 'event.budget.amount'|trans }}</th>
|
||||
<th>{{ 'event.budget.comment'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% set totalResources = 0 %}
|
||||
{% for res in resources %}
|
||||
<tr>
|
||||
<td>{{ res.kind.name|localize_translatable_string }}</td>
|
||||
<td>{{ res.amount|format_currency('EUR') }}</td>
|
||||
<td>{{ res.comment.comment|chill_print_or_message(null, 'blockquote') }}</td>
|
||||
</tr>
|
||||
{% set totalResources = totalResources + res.amount %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<td>{{ totalResources|format_currency('EUR') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="chill-no-data-statement">{{ 'event.budget.no elements'|trans }}</p>
|
||||
{% endif %}
|
||||
|
||||
<h3>Charges</h3>
|
||||
{% if charges is not empty %}
|
||||
<table class="table table-bordered border-dark align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'event.budget.charge type'|trans }}</th>
|
||||
<th>{{ 'event.budget.amount'|trans }}</th>
|
||||
<th>{{ 'event.budget.comment'|trans }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% set totalCharges = 0 %}
|
||||
{% for chg in charges %}
|
||||
<tr>
|
||||
<td>{{ chg.kind.name|localize_translatable_string }}</td>
|
||||
<td>{{ chg.amount|format_currency('EUR') }}</td>
|
||||
<td>{{ chg.comment.comment|chill_print_or_message(null, 'blockquote') }}</td>
|
||||
</tr>
|
||||
{% set totalCharges = totalCharges + chg.amount %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th>Total</th>
|
||||
<td>{{ totalCharges|format_currency('EUR') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="chill-no-data-statement">{{ 'event.budget.no elements'|trans }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if event.documents|length > 0 %}
|
||||
<div>
|
||||
<p><strong>{{ 'event.fields.documents'|trans }}</strong></p>
|
||||
@@ -185,10 +80,30 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="participations-wrapper">
|
||||
|
||||
<ul class="record_actions">
|
||||
|
||||
{% set returnPath = app.request.get('return_path') %}
|
||||
{% set returnLabel = app.request.get('return_label') %}
|
||||
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_return_path_or('chill_event_event_list') }}" class="btn btn-cancel">{{ 'Back to the list'|trans|chill_return_path_label }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_event__event_edit', {'event_id': event.id }, false, 'See'|trans) }}" class="btn btn-edit">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('chill_event__event_delete', {'event_id' : event.id } ) }}"
|
||||
class="btn btn-delete">{{ 'Delete event'|trans }}</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>{{ 'Participations'|trans }}</h2>
|
||||
{% set count = event.participations|length %}
|
||||
<p class="chill-no-data-statement">{{ 'count participations to this event'|trans({'count': count}) }}</p>
|
||||
<p>{{ 'count participations to this event'|trans({'count': count}) }}</p>
|
||||
|
||||
{% if count > 0 %}
|
||||
<table class="table table-bordered border-dark align-middle">
|
||||
@@ -241,7 +156,13 @@
|
||||
|
||||
{% endif %}
|
||||
|
||||
<div class="row">
|
||||
<ul class="record_actions">
|
||||
{% if count > 0 %}
|
||||
<li><a href="{{ path('chill_event_participation_edit_multiple', { 'event_id' : event.id } ) }}" class="btn btn-edit">{{ 'Edit all the participations'|trans }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<div class="row" style="margin-bottom: 10em;">
|
||||
<div class="col-8">
|
||||
{{ form_start(form_add_participation_by_person) }}
|
||||
<div class="input-group">
|
||||
@@ -253,11 +174,8 @@
|
||||
<input type="hidden" name="returnPath" value="{{ app.request.requestUri }}" />
|
||||
{{ form_end(form_add_participation_by_person) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
{% if count > 0 %}
|
||||
<li>
|
||||
<div class="col-4">
|
||||
{{ form_start(form_export, {'attr': {'id': 'export_tableur'}}) }}
|
||||
<div class="input-group">
|
||||
{{ form_widget(form_export.format, { 'attr' : { 'class': 'custom-select' } }) }}
|
||||
@@ -268,33 +186,11 @@
|
||||
</div>
|
||||
{{ form_rest(form_export) }}
|
||||
{{ form_end(form_export) }}
|
||||
</li>
|
||||
<li><a href="{{ path('chill_event_participation_edit_multiple', { 'event_id' : event.id } ) }}" class="btn btn-edit">{{ 'Edit all the participations'|trans }}</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="post_show">
|
||||
{{ chill_delegated_block('block_footer_show', { 'event': event }) }}
|
||||
</div>
|
||||
|
||||
<ul class="record_actions">
|
||||
|
||||
{% set returnPath = app.request.get('return_path') %}
|
||||
{% set returnLabel = app.request.get('return_label') %}
|
||||
|
||||
<li class="cancel">
|
||||
<a href="{{ chill_return_path_or('chill_event_event_list') }}" class="btn btn-cancel">{{ 'Back to the list'|trans|chill_return_path_label }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ chill_path_add_return_path('chill_event__event_edit', {'event_id': event.id }, false, 'See'|trans) }}" class="btn btn-edit">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('chill_event__event_delete', {'event_id' : event.id } ) }}"
|
||||
class="btn btn-delete">{{ 'Delete event'|trans }}</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@@ -11,7 +11,7 @@
|
||||
'title' : 'Remove participation'|trans,
|
||||
'confirm_question' : 'Are you sure you want to remove that participation ?'|trans,
|
||||
'cancel_route' : activeRouteKey,
|
||||
'cancel_parameters' : { 'id' : event_id },
|
||||
'cancel_parameters' : { 'event_id' : event_id },
|
||||
'form' : delete_form
|
||||
}
|
||||
) }}
|
||||
|
@@ -33,7 +33,7 @@
|
||||
{% set returnPath = app.request.get('return_path') %}
|
||||
{% set returnLabel = app.request.get('return_label') %}
|
||||
|
||||
<a href="{{ returnPath |default( path('chill_event__event_show', { 'id' : participation.event.id } )) }}" class="btn btn-cancel">
|
||||
<a href="{{ returnPath |default( path('chill_event__event_show', { 'event_id' : participation.event.id } )) }}" class="btn btn-cancel">
|
||||
{{ returnLabel |default('Back to the event'|trans) }}
|
||||
</a>
|
||||
</li>
|
||||
|
@@ -34,7 +34,7 @@
|
||||
|
||||
<ul class="record_actions sticky-form-buttons">
|
||||
<li class="cancel">
|
||||
<a href="{{ path('chill_event__event_show', { 'id' : participation.event.id } ) }}" class="btn btn-cancel">
|
||||
<a href="{{ path('chill_event__event_show', { 'event_id' : participation.event.id } ) }}" class="btn btn-cancel">
|
||||
{{ 'Back to the event'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
@@ -54,9 +54,9 @@ class EventVoter extends AbstractChillVoter implements ProvideRoleHierarchyInter
|
||||
) {
|
||||
$this->voterHelper = $voterHelperFactory
|
||||
->generate(self::class)
|
||||
->addCheckFor(null, [self::SEE, self::CREATE])
|
||||
->addCheckFor(null, [self::SEE])
|
||||
->addCheckFor(Event::class, [...self::ROLES])
|
||||
->addCheckFor(Person::class, [self::SEE])
|
||||
->addCheckFor(Person::class, [self::SEE, self::CREATE])
|
||||
->addCheckFor(Center::class, [self::STATS])
|
||||
->build();
|
||||
}
|
||||
|
@@ -1,109 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* Chill is a software for social workers
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Chill\EventBundle\Templating\Entity;
|
||||
|
||||
use Chill\EventBundle\Entity\EventTheme;
|
||||
use Chill\MainBundle\Templating\Entity\ChillEntityRenderInterface;
|
||||
use Chill\MainBundle\Templating\TranslatableStringHelper;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Error\RuntimeError;
|
||||
use Twig\Error\SyntaxError;
|
||||
|
||||
/**
|
||||
* @implements ChillEntityRenderInterface<EventTheme>
|
||||
*/
|
||||
class EventThemeRender implements ChillEntityRenderInterface
|
||||
{
|
||||
public const AND_CHILDREN_MENTION = 'show_and_children_mention';
|
||||
|
||||
public const DEFAULT_ARGS = [
|
||||
self::SEPARATOR_KEY => ' > ',
|
||||
self::SHOW_AND_CHILDREN => false,
|
||||
self::AND_CHILDREN_MENTION => 'event_theme.and children',
|
||||
];
|
||||
|
||||
public const SEPARATOR_KEY = 'default.separator';
|
||||
|
||||
/**
|
||||
* Show a mention "and children" on each EventTheme, if the event theme
|
||||
* has at least one child.
|
||||
*/
|
||||
public const SHOW_AND_CHILDREN = 'show_and_children';
|
||||
|
||||
public function __construct(private readonly TranslatableStringHelper $translatableStringHelper, private readonly \Twig\Environment $engine, private readonly TranslatorInterface $translator) {}
|
||||
|
||||
/**
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
* @throws LoaderError
|
||||
*/
|
||||
public function renderBox($entity, array $options): string
|
||||
{
|
||||
$options = array_merge(self::DEFAULT_ARGS, $options);
|
||||
// give some help to twig: an array of parents
|
||||
$parents = $this->buildParents($entity);
|
||||
|
||||
return $this
|
||||
->engine
|
||||
->render(
|
||||
'@ChillEvent/Entity/event_theme.html.twig',
|
||||
[
|
||||
'eventTheme' => $entity,
|
||||
'parents' => $parents,
|
||||
'options' => $options,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function renderString($entity, array $options): string
|
||||
{
|
||||
/** @var EventTheme $entity */
|
||||
$options = array_merge(self::DEFAULT_ARGS, $options);
|
||||
|
||||
$titles = [$this->translatableStringHelper->localize($entity->getName())];
|
||||
|
||||
// loop to parent, until root
|
||||
while ($entity->hasParent()) {
|
||||
$entity = $entity->getParent();
|
||||
$titles[] = $this->translatableStringHelper->localize(
|
||||
$entity->getName()
|
||||
);
|
||||
}
|
||||
|
||||
$titles = \array_reverse($titles);
|
||||
|
||||
$title = \implode($options[self::SEPARATOR_KEY], $titles);
|
||||
|
||||
if ($options[self::SHOW_AND_CHILDREN] && $entity->hasChildren()) {
|
||||
$title .= ' ('.$this->translator->trans($options[self::AND_CHILDREN_MENTION]).')';
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
public function supports($entity, array $options): bool
|
||||
{
|
||||
return $entity instanceof EventTheme;
|
||||
}
|
||||
|
||||
private function buildParents(EventTheme $entity): array
|
||||
{
|
||||
$parents = [];
|
||||
|
||||
while ($entity->hasParent()) {
|
||||
$entity = $parents[] = $entity->getParent();
|
||||
}
|
||||
|
||||
return $parents;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user