mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-17 12:14:58 +00:00
Compare commits
271 Commits
ticket-app
...
testing-20
Author | SHA1 | Date | |
---|---|---|---|
cf36070c82
|
|||
8ee836eec3
|
|||
388030952b
|
|||
82a08f1e27
|
|||
925fbaed6d
|
|||
c407c3029f
|
|||
81b6ae193c
|
|||
51168ac3c4
|
|||
12ee091d09
|
|||
49607e431f
|
|||
ea4cbfe3b9
|
|||
9d00b8ae60
|
|||
00350b9efc
|
|||
9a50dad671
|
|||
4206d17345
|
|||
110a2e894f
|
|||
a0daf4428f
|
|||
f78b8cad9c
|
|||
6b0c85cdf0
|
|||
92b71af239
|
|||
a0db7cd7e6 | |||
011b6a29e4 | |||
527dc971d7 | |||
43e5bc8337
|
|||
845e582c44
|
|||
f3e04bd2bf
|
|||
96e95dd8f1 | |||
c40e790425
|
|||
3a016aa12a
|
|||
be448c650e
|
|||
9f32b5ac48
|
|||
e89f5e4713
|
|||
e79d6d670b
|
|||
9adbde0308
|
|||
fe31cfd544
|
|||
e8bca6a502
|
|||
b0918ddd09 | |||
a368e68abb | |||
85b9784eef | |||
26fd16ab07 | |||
9a3fef862e | |||
2c01516f71 | |||
246546b313 | |||
bfe658d4fd | |||
7ea6638c3a | |||
b04f0a9aa4
|
|||
ebdfa04843
|
|||
be213d5b5c
|
|||
4d1032c115
|
|||
e43dfc9a20
|
|||
b11684fb3b
|
|||
b8826c6c0f
|
|||
a996b05ead
|
|||
cfcecf1cdc
|
|||
b6985e0e5f
|
|||
6d76b94644
|
|||
ff6ec45575
|
|||
f3fd18e6fb
|
|||
c8851a8e8a
|
|||
abdfe49c33
|
|||
e933f3e781
|
|||
fb1c34f9c1
|
|||
d506409d93
|
|||
9be8a533ff
|
|||
b414b27ba9
|
|||
8521672660
|
|||
3f5ce5f841
|
|||
e1404bf16d
|
|||
65b7ed0755
|
|||
a74118e5d4
|
|||
828739edf5
|
|||
d0811c8118
|
|||
176bff0551
|
|||
66c089e862
|
|||
aa44577484
|
|||
8c59cbc6a0
|
|||
8c5a7ac3e1
|
|||
a6e523ee0a
|
|||
d49058805a
|
|||
73496e0e1f
|
|||
973450110b
|
|||
0f6b10aa0a
|
|||
edeb8edbea
|
|||
fc8e3789e0
|
|||
52a80f9621
|
|||
5632697c05
|
|||
75932b0e29
|
|||
7e2bf91e09
|
|||
0581b59dbd
|
|||
4661ba9932
|
|||
f85b0c8cf7
|
|||
e701e96187
|
|||
d9d151aa89
|
|||
a14ed78e25
|
|||
420dd4f868
|
|||
3d9b9ea672
|
|||
9f12b42961
|
|||
2842548c17
|
|||
35f5501489
|
|||
5e2d960a19
|
|||
4129283a58
|
|||
f807d62dab
|
|||
5a7bba83f7
|
|||
50c75dff1a
|
|||
e37f3e7c37
|
|||
b6375cad6c
|
|||
8516c87a14
|
|||
8c5abbff74
|
|||
e0f94ae900
|
|||
f683e45b6e
|
|||
b1b7fb6401
|
|||
8fa06e143d
|
|||
ec3d901d2f
|
|||
f12d689382
|
|||
1c04219859
|
|||
2b88593e64
|
|||
ee65c46d2a
|
|||
7c239eaf6a
|
|||
694b1f3c1f
|
|||
80b9ce3c3e
|
|||
3f218e7183
|
|||
a2713041da
|
|||
3a904e8ea1
|
|||
6f1a26742d
|
|||
0d0a626f50
|
|||
ec5f4ed1d6
|
|||
d9251239f7
|
|||
b2d3d806b6
|
|||
8e952cc966
|
|||
1c4ee37507
|
|||
8331a836f2
|
|||
2482dcc62e
|
|||
f9a55a1bfd
|
|||
15aa565caf
|
|||
566b72ec9e
|
|||
bb42ee25ff
|
|||
aebeca1d7a
|
|||
1955249a60
|
|||
3b0a4e9c73
|
|||
b5fd9cf4af
|
|||
bb30ddc876
|
|||
5ebb53173e
|
|||
d1d6a00ebf
|
|||
e48bec490c
|
|||
128d365a72
|
|||
10f66afdcd
|
|||
89aed74355
|
|||
b3bf405c5b | |||
9124fa68e8
|
|||
68b61b7d8a
|
|||
80d8f967fa
|
|||
1375a41de2
|
|||
4fa4d3b65c | |||
bd4c34cc1d | |||
4cea678e93 | |||
5e6833975b | |||
f523b9adb3 | |||
a211549432 | |||
17b1363113 | |||
3356ed8e57 | |||
2a7fa517ee | |||
95972399a1 | |||
85781c8e14 | |||
00eb435896 | |||
ed71cffd6a | |||
ae679e6997 | |||
e1d308fd97 | |||
d9acda67e3 | |||
e88da74882 | |||
591c44d1a0 | |||
bf04b7981c | |||
df33eec30f | |||
c657c98918 | |||
ef5eb5b907 | |||
d683fe002d | |||
555bbca59b | |||
e9e9d5c458 | |||
b1842a33ae | |||
6afeaccf24 | |||
fb76bac480 | |||
6ded185289 | |||
95adc29f9d | |||
4d0c3e683f | |||
018aafc773 | |||
c4aea4efc2 | |||
225e3ca13f | |||
8c1fa7956a | |||
e253d1b276 | |||
a52aac2d98 | |||
9e8cf60dd8 | |||
7682d81d50 | |||
5d31ce96c1 | |||
81ef64a246 | |||
49d1f78001 | |||
0d0f3528e2 | |||
d97d5e689a | |||
95d80ce13e | |||
668720984d | |||
245c3fa121 | |||
1af3e4c7ec | |||
5d0fc7a189 | |||
483d50e776 | |||
b4c6ccf309 | |||
ac6a81cbd8 | |||
9503cb89b6 | |||
b130dbdcdc | |||
b2b1865837 | |||
ec5c4d51b3 | |||
180437f637
|
|||
0c2508d26d
|
|||
b2d8d21f04
|
|||
6a2aa77ecc
|
|||
e7cd9e00f9
|
|||
39f60b5b34
|
|||
c9c29b9105
|
|||
fb806a9579
|
|||
70ca4acafb
|
|||
bd61eedfbb
|
|||
80ce7f0bf1
|
|||
1ebf838bde
|
|||
85a9c6bb67
|
|||
db073fc920
|
|||
46ebfca28f
|
|||
22a2605381
|
|||
4f6a7116a4
|
|||
cac7d33a44
|
|||
0609e3f4c3
|
|||
3a738179f2
|
|||
a789bf5e1c
|
|||
0a21fada42
|
|||
4f030eb11a
|
|||
0d2a487ae7
|
|||
6cb23344fc
|
|||
da0d7a3b9e
|
|||
fcc61aa4c0
|
|||
21ec96b75c
|
|||
93f934152f
|
|||
49f4cce72a
|
|||
e69b679938
|
|||
229f9b7125
|
|||
4fc433cd63
|
|||
2c91d2e10f
|
|||
4302506471 | |||
09b7558e92 | |||
6ba5c91ee6 | |||
535409e529 | |||
9979378e78 | |||
58291c7402 | |||
3d397c0145 | |||
d84f3ee5ad | |||
6db16e6d0b | |||
ed60c6aaa3 | |||
13b1d20ade | |||
5999c73c98 | |||
580366de6d | |||
7f69f21b64 | |||
683a0bc4e9 | |||
4d6d40629f | |||
2185791665 | |||
bf14c92567 | |||
7c1c1ed800 | |||
3b3659f13f | |||
ebfdc57fcf | |||
a562690512 | |||
1751c65731
|
|||
791f5bb4be
|
|||
2c812fc5fe
|
|||
1f1d38acef
|
|||
057c34610d
|
|||
732b7dc8f7
|
|||
cb068cdee7
|
6
.changes/unreleased/DX-20250401-144728.yaml
Normal file
6
.changes/unreleased/DX-20250401-144728.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: DX
|
||||||
|
body: Allow TranslatableMessage in flash messages
|
||||||
|
time: 2025-04-01T14:47:28.814268801+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
44
.changes/unreleased/DX-20250407-121010.yaml
Normal file
44
.changes/unreleased/DX-20250407-121010.yaml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
kind: DX
|
||||||
|
body: |
|
||||||
|
Rewrite exports to run them asynchronously
|
||||||
|
|
||||||
|
changelog: |
|
||||||
|
- Add new methods to serialize data using the rector rule
|
||||||
|
- Remove all references to the Request in filters, aggregators, filters. Actually, the most frequent occurence is `$security->getUser()`.
|
||||||
|
- Refactor manually the initializeQuery method
|
||||||
|
- Remove the injection of ExportManager into the constructor of each export element:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
|
||||||
|
- class MyFormatter implements FormatterInterface
|
||||||
|
+ class MyFormatter implements FormatterInterface, \Chill\MainBundle\Export\ExportManagerAwareInterface
|
||||||
|
{
|
||||||
|
+ use \Chill\MainBundle\Export\Helper\ExportManagerAwareTrait;
|
||||||
|
|
||||||
|
- public function __construct(private ExportManager $exportmanager) {}
|
||||||
|
|
||||||
|
public function MyMethod(): void
|
||||||
|
{
|
||||||
|
- $this->exportManager->getFilter('alias');
|
||||||
|
+ $this->getExportManager()->getFilter('alias');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- configure messenger to handle export in a queue:
|
||||||
|
|
||||||
|
```diff
|
||||||
|
# config/packages/messenger.yaml
|
||||||
|
framework:
|
||||||
|
messenger:
|
||||||
|
routing:
|
||||||
|
+ 'Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage': priority
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
time: 2025-04-07T12:10:10.682561327+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: Add columns or tables
|
6
.changes/unreleased/DX-20250430-144550.yaml
Normal file
6
.changes/unreleased/DX-20250430-144550.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: DX
|
||||||
|
body: Remove dead code for wopi-link module
|
||||||
|
time: 2025-04-30T14:45:50.406111606+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "352"
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/DX-20250528-165813.yaml
Normal file
6
.changes/unreleased/DX-20250528-165813.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: DX
|
||||||
|
body: Replace library node-sass by sass, and upgrade bootstrap to version 5.3 (yarn upgrade / install is required)
|
||||||
|
time: 2025-05-28T16:58:13.226870341+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
@@ -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: ""
|
|
6
.changes/unreleased/Feature-20250211-142243.yaml
Normal file
6
.changes/unreleased/Feature-20250211-142243.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Allow the merge of two accompanying period works
|
||||||
|
time: 2025-02-11T14:22:43.134106669+01:00
|
||||||
|
custom:
|
||||||
|
Issue: "359"
|
||||||
|
SchemaChange: No schema change
|
7
.changes/unreleased/Feature-20250424-142211.yaml
Normal file
7
.changes/unreleased/Feature-20250424-142211.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Add the document file name to the document title when a user upload a document,
|
||||||
|
unless there is already a document title.
|
||||||
|
time: 2025-04-24T14:22:11.800975422+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "377"
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Feature-20250520-095628.yaml
Normal file
6
.changes/unreleased/Feature-20250520-095628.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Add desactivation date for social action and issue csv export
|
||||||
|
time: 2025-05-20T09:56:28.108941934+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Feature-20250523-133341.yaml
Normal file
6
.changes/unreleased/Feature-20250523-133341.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Add Emoji and Fullscreen feature to ckeditor configuration
|
||||||
|
time: 2025-05-23T13:33:41.645095128+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Feature-20250523-133434.yaml
Normal file
6
.changes/unreleased/Feature-20250523-133434.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Feature
|
||||||
|
body: Create editor which allow us to toggle between rich and simple text editor
|
||||||
|
time: 2025-05-23T13:34:34.56795603+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "321"
|
||||||
|
SchemaChange: No schema change
|
@@ -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
|
|
7
.changes/unreleased/Fixed-20250424-133943.yaml
Normal file
7
.changes/unreleased/Fixed-20250424-133943.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: trying to prevent bug of typeerror in doc-history + improved display of document
|
||||||
|
history
|
||||||
|
time: 2025-04-24T13:39:43.878468232+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "376"
|
||||||
|
SchemaChange: No schema change
|
7
.changes/unreleased/Fixed-20250424-163746.yaml
Normal file
7
.changes/unreleased/Fixed-20250424-163746.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Display previous participation in acc course work even if the person has left
|
||||||
|
the acc course
|
||||||
|
time: 2025-04-24T16:37:46.970203594+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "381"
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Fixed-20250505-102715.yaml
Normal file
6
.changes/unreleased/Fixed-20250505-102715.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix display of text in calendar events
|
||||||
|
time: 2025-05-05T10:27:15.461493066+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "372"
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Fixed-20250514-145339.yaml
Normal file
6
.changes/unreleased/Fixed-20250514-145339.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Add missing translation for user_group.no_user_groups
|
||||||
|
time: 2025-05-14T14:53:39.53927329+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Fixed-20250520-140008.yaml
Normal file
6
.changes/unreleased/Fixed-20250520-140008.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix retrieve schema to form full tablename and construct sql statements correctly in Thirdparty merger.
|
||||||
|
time: 2025-05-20T14:00:08.987229634+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Fixed-20250520-140433.yaml
Normal file
6
.changes/unreleased/Fixed-20250520-140433.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix add missing translation
|
||||||
|
time: 2025-05-20T14:04:33.612140549+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/Fixed-20250520-164429.yaml
Normal file
6
.changes/unreleased/Fixed-20250520-164429.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Fixed
|
||||||
|
body: Fix the transfer of evaluations and documents during of accompanyingperiodwork
|
||||||
|
time: 2025-05-20T16:44:29.093304653+02:00
|
||||||
|
custom:
|
||||||
|
Issue: ""
|
||||||
|
SchemaChange: No schema change
|
6
.changes/unreleased/UX-20250423-172624.yaml
Normal file
6
.changes/unreleased/UX-20250423-172624.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: UX
|
||||||
|
body: Remove default filter in_progress for the page 'my tasks'; Allows for new tasks to be displayed upon opening of the page
|
||||||
|
time: 2025-04-23T17:26:24.45777387+02:00
|
||||||
|
custom:
|
||||||
|
Issue: "374"
|
||||||
|
SchemaChange: No schema change
|
@@ -1,22 +0,0 @@
|
|||||||
## v3.12.0 - 2025-06-30
|
|
||||||
### Feature
|
|
||||||
* ([#377](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/377)) Add the document file name to the document title when a user upload a document, unless there is already a document title.
|
|
||||||
* Add desactivation date for social action and issue csv export
|
|
||||||
* Add Emoji and Fullscreen feature to ckeditor configuration
|
|
||||||
* ([#321](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/321)) Create editor which allow us to toggle between rich and simple text editor
|
|
||||||
* Do not remove workflow which are automatically canceled after staling for more than 30 days
|
|
||||||
### Fixed
|
|
||||||
* ([#376](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/376)) trying to prevent bug of typeerror in doc-history + improved display of document history
|
|
||||||
* ([#381](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/381)) Display previous participation in acc course work even if the person has left the acc course
|
|
||||||
* ([#372](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/372)) Fix display of text in calendar events
|
|
||||||
* Add missing translation for user_group.no_user_groups
|
|
||||||
* Fix admin entity edit actions for event admin entities and activity reason (category) entities
|
|
||||||
* ([#392](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/392)) Allow null and cast as string to setContent method for NewsItem
|
|
||||||
|
|
||||||
* ([#393](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/393)) Doc Generation: the "dump only" method send the document as an email attachment.
|
|
||||||
### DX
|
|
||||||
* ([#352](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/352)) Remove dead code for wopi-link module
|
|
||||||
* Replace library node-sass by sass, and upgrade bootstrap to version 5.3 (yarn upgrade / install is required)
|
|
||||||
### UX
|
|
||||||
* ([#374](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/374)) Remove default filter in_progress for the page 'my tasks'; Allows for new tasks to be displayed upon opening of the page
|
|
||||||
* Improve labeling of fields in person resource creation form
|
|
@@ -1,3 +0,0 @@
|
|||||||
## v3.12.1 - 2025-06-30
|
|
||||||
### Fixed
|
|
||||||
* Fix loading of the list of documents
|
|
@@ -1,74 +0,0 @@
|
|||||||
## v4.0.0 - 2025-07-08
|
|
||||||
### Feature
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Allow the merge of two accompanying period works
|
|
||||||
### Fixed
|
|
||||||
* ([#390](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/390)) Display the list of participant in the results, even if there is only one participant and that the search result display the requestor
|
|
||||||
* Fix admin entity edit actions for event admin entities and activity reason (category) entities
|
|
||||||
* Fix translations for social action fields in admin form: results, goals, evaluations
|
|
||||||
### DX
|
|
||||||
* Rewrite exports to run them asynchronously
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* Allow TranslatableMessage in flash messages
|
|
||||||
### UX
|
|
||||||
* Improve labeling of fields in person resource creation form
|
|
||||||
|
|
||||||
|
|
||||||
**Release notes**
|
|
||||||
|
|
||||||
- Add new methods to serialize data using the rector rule
|
|
||||||
- Remove all references to the Request in filters, aggregators, filters. Actually, the most frequent occurence is `$security->getUser()`.
|
|
||||||
- Refactor manually the initializeQuery method
|
|
||||||
- Remove the injection of ExportManager into the constructor of each export element:
|
|
||||||
|
|
||||||
```diff
|
|
||||||
|
|
||||||
- class MyFormatter implements FormatterInterface
|
|
||||||
+ class MyFormatter implements FormatterInterface, \Chill\MainBundle\Export\ExportManagerAwareInterface
|
|
||||||
{
|
|
||||||
+ use \Chill\MainBundle\Export\Helper\ExportManagerAwareTrait;
|
|
||||||
|
|
||||||
- public function __construct(private ExportManager $exportmanager) {}
|
|
||||||
|
|
||||||
public function MyMethod(): void
|
|
||||||
{
|
|
||||||
- $this->exportManager->getFilter('alias');
|
|
||||||
+ $this->getExportManager()->getFilter('alias');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- configure messenger to handle export in a queue:
|
|
||||||
|
|
||||||
```diff
|
|
||||||
# config/packages/messenger.yaml
|
|
||||||
framework:
|
|
||||||
messenger:
|
|
||||||
routing:
|
|
||||||
+ 'Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage': priority
|
|
||||||
```
|
|
||||||
|
|
||||||
- add missing methods to exports, aggregators, filters, formatter:
|
|
||||||
|
|
||||||
```php
|
|
||||||
public function normalizeFormData(array $formData): array;
|
|
||||||
|
|
||||||
public function denormalizeFormData(array $formData, int $fromVersion): array;
|
|
||||||
```
|
|
||||||
|
|
||||||
There are rector rules to generate those methods:
|
|
||||||
|
|
||||||
- `Chill\Utils\Rector\Rector\ChillBundleAddNormalizationMethodsOnExportRector`
|
|
||||||
|
|
||||||
See:
|
|
||||||
|
|
||||||
```php
|
|
||||||
// upgrade chill exports
|
|
||||||
$rectorConfig->rules([\Chill\Utils\Rector\Rector\ChillBundleAddNormalizationMethodsOnExportRector::class]);
|
|
||||||
```
|
|
||||||
|
|
||||||
This rule will create most of the work necessary, but some manuals changes are still necessary:
|
|
||||||
|
|
||||||
- we must set manually the correct repository for method `denormalizeDoctrineEntity`;
|
|
||||||
- when the form data contains some entities, and the form type is not one of EntityType::class, PickUserDynamicType::class, PickUserLocationType::class, PickThirdpartyDynamicType::class, Select2CountryType::class, then we must handle the normalization manually (using the `\Chill\MainBundle\Export\ExportDataNormalizerTrait`)
|
|
||||||
|
|
||||||
|
|
@@ -1,4 +0,0 @@
|
|||||||
## v4.0.1 - 2025-07-08
|
|
||||||
### Fixed
|
|
||||||
* Fix package.json for compilation
|
|
||||||
|
|
@@ -1,4 +0,0 @@
|
|||||||
## v4.0.2 - 2025-07-09
|
|
||||||
### Fixed
|
|
||||||
* Fix add missing translation
|
|
||||||
* Fix the transfer of evaluations and documents during of accompanyingperiodwork
|
|
@@ -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]
|
[COMMIT_EDITMSG]
|
||||||
max_line_length = 0
|
max_line_length = 0
|
||||||
|
|
||||||
[*.{js,vue,ts}]
|
[*.{js, vue, ts}]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
|
||||||
[*.rst]
|
[.rst]
|
||||||
indent_size = 3
|
ident_size = 3
|
||||||
indent_style = space
|
ident_style = space
|
||||||
|
|
||||||
|
@@ -7,6 +7,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "f8c2979921289906e3baabae31ba101ead91504f"
|
"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",
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/module/Invite/answer.js",
|
||||||
"line": 7,
|
"line": 7,
|
||||||
@@ -119,6 +127,46 @@
|
|||||||
"message": "'payload' is defined but never used.",
|
"message": "'payload' is defined but never used.",
|
||||||
"hash": "66c545917093ba30f1d6ca10ddaa676140e749bd"
|
"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",
|
"path": "src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/Components/EditLocation.vue",
|
||||||
"line": 77,
|
"line": 77,
|
||||||
@@ -351,6 +399,14 @@
|
|||||||
"message": "'error' is defined but never used.",
|
"message": "'error' is defined but never used.",
|
||||||
"hash": "e26e5e101e90d2b7ee84d6f5de8c819e52129c17"
|
"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",
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/uploader.js",
|
||||||
"line": 39,
|
"line": 39,
|
||||||
@@ -559,6 +615,14 @@
|
|||||||
"message": "'ref' is defined but never used.",
|
"message": "'ref' is defined but never used.",
|
||||||
"hash": "2a27cd6d06a26e1326654c929068e3704137e24b"
|
"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",
|
"path": "src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/StoredObjectButton/WopiEditButton.vue",
|
||||||
"line": 15,
|
"line": 15,
|
||||||
@@ -919,6 +983,22 @@
|
|||||||
"message": "'_e' is defined but never used.",
|
"message": "'_e' is defined but never used.",
|
||||||
"hash": "1d6448401778e8c56554020fe5abd47851ed33f3"
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/page/homepage_widget/index.js",
|
||||||
"line": 9,
|
"line": 9,
|
||||||
@@ -1009,19 +1089,115 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
||||||
"line": 516,
|
"line": 247,
|
||||||
"column": 21,
|
"column": 5,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"context\" prop.",
|
"message": "'postAddressToPerson' is defined but never used.",
|
||||||
"hash": "984c4203f2ac1e1bb65f9ce76ecd03b763cfaa83"
|
"hash": "8a41c437cf2b5554cbbe1704cd51f3102b3d5994"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress.vue",
|
"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,
|
"column": 21,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"context\" prop.",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
||||||
@@ -1048,180 +1224,204 @@
|
|||||||
"hash": "2d5a5e680ff207ad97c7e7b7d999064b561dfd8a"
|
"hash": "2d5a5e680ff207ad97c7e7b7d999064b561dfd8a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressMore.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 149,
|
"line": 106,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "e4c1ecd7ae77d46ac3625c5bbe92a24d6a964db9"
|
"hash": "d52356f2af31d0167c02330ec22d09fbfa6b2b9f"
|
||||||
},
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 130,
|
"line": 114,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "239ac02a02694d5b20ab30d4c7ce5838c51d1515"
|
"hash": "c8e8e06f370f93bf05867e93b5f037dfa46937b1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 138,
|
"line": 128,
|
||||||
"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,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 153,
|
"line": 153,
|
||||||
"column": 13,
|
"column": 55,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "'reject' is defined but never used.",
|
||||||
"hash": "740ea5d793c7a34c9f352d8b333f3aa04cc80ee8"
|
"hash": "bd0e024fcad2e3f4566f15293e3c25c840f6dd3e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 156,
|
"line": 154,
|
||||||
"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,
|
|
||||||
"column": 37,
|
"column": 37,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "0ec402e43cb08bf129e0737c0d2c4f6d0c7af8bd"
|
"hash": "596c4b180b926b7829f987384328bf5636cd367a"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"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,
|
"column": 41,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "ec178d33e067aac892e015002afb6f3a2ff98762"
|
"hash": "d92b92a25043244cca809bd129633b7e024e26b4"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 214,
|
"line": 190,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "c0f4e5454e672b6064eb9cf6c235c6810f7bfa80"
|
"hash": "dd9a85ea740742d620e864796f67c5bff834486d"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 215,
|
"line": 191,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "e3dd840d2474f9865a45822872bf9ecfb15961d7"
|
"hash": "e3e59960d0d50709a57b336f66b586710b774892"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 216,
|
"line": 192,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "a32a60382b145cc7a4a7ebe01ec435b8e3103320"
|
"hash": "fe11b0e54396511e7b3b08615a78d22fc27e2fad"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/AddressSelection.vue",
|
||||||
"line": 246,
|
"line": 222,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "082447e5c731012f3acc282943502775dfd24797"
|
"hash": "63c14c2150c33ec701bc4a0ff94efde69537d490"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 118,
|
"line": 96,
|
||||||
"column": 20,
|
"column": 20,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "d4fba4fe09af3c0937c0dd164928c8930c1591b5"
|
"hash": "d2a9fdaeef0e2810f480022d4c6f99e4f76a818e"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 118,
|
"line": 96,
|
||||||
"column": 20,
|
"column": 20,
|
||||||
"ruleId": "vue/no-side-effects-in-computed-properties",
|
"ruleId": "vue/no-side-effects-in-computed-properties",
|
||||||
"message": "Unexpected side effect in \"cities\" computed property.",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 124,
|
"line": 124,
|
||||||
"column": 17,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "fa56a7c93583f0a9d0c2ecac10228c4f4fc1bc3a"
|
"hash": "281f918da00635079501418b1e6b2c05b62eb4a7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 132,
|
"line": 125,
|
||||||
"column": 17,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"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",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 148,
|
"line": 149,
|
||||||
"column": 13,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "ab4f478fbfbc954b8dff75176dcd432f9ff28cfc"
|
"hash": "1e7b1ad55866f708baaca72dfa4ff26d6f8e5d21"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 153,
|
"line": 152,
|
||||||
"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,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "8aa37d2d4f011773e68838a2c88017875de563b5"
|
"hash": "84779331536ffceec8d4a8c5ca4307310b882549"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 168,
|
"line": 161,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "a4827a357e52a51fa9262319114d81a130296acf"
|
"hash": "0789999841be671a4d8ab080d6fdb679f843eb52"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 169,
|
"line": 170,
|
||||||
"column": 13,
|
"column": 51,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "'reject' is defined but never used.",
|
||||||
"hash": "a4c9715664202949e3242b8d4aa4098288b46dc4"
|
"hash": "bbb17afa114f016e2058d90aa32d2a625804f0d1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 171,
|
"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,
|
"column": 33,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 213,
|
"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,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "476e6588a28ac9382e8b9d2e63a8babecd23bad8"
|
"hash": "c399a43fa797a8ce61c9d96a644a39cc84a387b7"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CitySelection.vue",
|
||||||
"line": 233,
|
"line": 245,
|
||||||
"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,
|
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "2700f258396516a2fe971618fafbcdf72cdda3ab"
|
"hash": "04337a07944caaa4819cfebcf29e1a7cbfdf248b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||||
"line": 94,
|
"line": 76,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "4be1b0592efa775092a91a1d744e16ce98bd216e"
|
"hash": "373a2e31f110d138c66d77f1faf5dc61545c55af"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/AddAddress/CountrySelection.vue",
|
||||||
"line": 99,
|
"line": 81,
|
||||||
"column": 13,
|
"column": 13,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "19b54b6d76c30249d520a296f826eda9d6eb0668"
|
"hash": "421eb6a63224b4b1d81b216677a710c5c99ddee3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/DatePane.vue",
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||||
"line": 169,
|
"line": 155,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "dcb7b34098062760ddbb849655a5bb3ca65c36d3"
|
"hash": "b3a822914fcb5e2fcf28efc331a45b9205002eeb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/components/EditPane.vue",
|
||||||
"line": 178,
|
"line": 164,
|
||||||
"column": 17,
|
"column": 17,
|
||||||
"ruleId": "vue/no-mutating-props",
|
"ruleId": "vue/no-mutating-props",
|
||||||
"message": "Unexpected mutation of \"entity\" prop.",
|
"message": "Unexpected mutation of \"entity\" prop.",
|
||||||
"hash": "86b3ecf201025cac36878c5e4bf8850fb9d58cb5"
|
"hash": "72c7d850f6cdeaf65b373a33234222f9766ee30b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/index.js",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/Address/index.js",
|
||||||
@@ -1455,6 +1631,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "9e6125f4fc387dc362c69cc6e3ce360eb2851f1b"
|
"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",
|
"path": "src/Bundle/ChillMainBundle/Resources/public/vuejs/_components/AddressDetails/Parts/AddressDetailsMap.vue",
|
||||||
"line": 24,
|
"line": 24,
|
||||||
@@ -1543,6 +1727,14 @@
|
|||||||
"message": "'tags' is assigned a value but never used.",
|
"message": "'tags' is assigned a value but never used.",
|
||||||
"hash": "ae9bb2e0651c118ed9efd227e88b86cc83f5d80d"
|
"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",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourse/index.js",
|
||||||
"line": 19,
|
"line": 19,
|
||||||
@@ -1575,6 +1767,14 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "aaaaa63e7a60443b8cbf8191feb9142852ebdf1c"
|
"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",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/AccompanyingCourseWorkEdit/index.js",
|
||||||
"line": 12,
|
"line": 12,
|
||||||
@@ -1615,6 +1815,22 @@
|
|||||||
"message": "'evalFQDN' is assigned a value but never used.",
|
"message": "'evalFQDN' is assigned a value but never used.",
|
||||||
"hash": "7fc32caafa23addddf44f3acbc5045b4523a0271"
|
"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",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/ExportFormActionGoalResult/index.js",
|
||||||
"line": 16,
|
"line": 16,
|
||||||
@@ -1631,6 +1847,38 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "2f161e663689e3e4dfe2c53b0d64c91a4d2b1a60"
|
"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",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/index.js",
|
||||||
"line": 20,
|
"line": 20,
|
||||||
@@ -1639,6 +1887,22 @@
|
|||||||
"message": "'app' is assigned a value but never used.",
|
"message": "'app' is assigned a value but never used.",
|
||||||
"hash": "9e94e6412b8a44e47bfe8e66218cad09cff5bed4"
|
"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",
|
"path": "src/Bundle/ChillPersonBundle/Resources/public/vuejs/_components/AddPersons/TypeUserGroup.vue",
|
||||||
"line": 6,
|
"line": 6,
|
||||||
@@ -1654,5 +1918,45 @@
|
|||||||
"ruleId": "@typescript-eslint/no-unused-vars",
|
"ruleId": "@typescript-eslint/no-unused-vars",
|
||||||
"message": "'UserRenderBoxBadge' is defined but never used.",
|
"message": "'UserRenderBoxBadge' is defined but never used.",
|
||||||
"hash": "99eba0d8633b2c9497417f4f61ec4194dbb2a96b"
|
"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/*
|
templates/*
|
||||||
translations/*
|
translations/*
|
||||||
|
|
||||||
# we allow developers to add customization on their installation, without commiting it
|
|
||||||
config/packages/dev/*
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
###> symfony/framework-bundle ###
|
||||||
/.env.local
|
/.env.local
|
||||||
/.env.local.php
|
/.env.local.php
|
||||||
|
@@ -22,16 +22,16 @@ Chill is a comprehensive web application built as a set of Symfony bundles. It i
|
|||||||
- **Backend**: PHP 8.3+, Symfony 5.4
|
- **Backend**: PHP 8.3+, Symfony 5.4
|
||||||
- **Frontend**: JavaScript/TypeScript, Vue.js 3, Bootstrap 5
|
- **Frontend**: JavaScript/TypeScript, Vue.js 3, Bootstrap 5
|
||||||
- **Build Tools**: Webpack Encore, Yarn
|
- **Build Tools**: Webpack Encore, Yarn
|
||||||
- **Database**: PostgreSQL with materialized views. We do not support other databases.
|
- **Database**: PostgreSQL with materialized views
|
||||||
- **Other Services**: Redis, AMQP (RabbitMQ), SMTP
|
- **Other Services**: Redis, AMQP (RabbitMQ), SMTP
|
||||||
|
|
||||||
## Project Structure
|
## 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:
|
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`.
|
- `/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
|
- `/docs/`: Contains project documentation
|
||||||
|
|
||||||
Each bundle typically has the following structure:
|
Each bundle typically has the following structure:
|
||||||
@@ -46,13 +46,13 @@ Each bundle typically has the following structure:
|
|||||||
|
|
||||||
### A special word about TicketBundle
|
### 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
|
## Development Guidelines
|
||||||
|
|
||||||
### Building and Configuration Instructions
|
### 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`.
|
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
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
6. **Set Up the Database**:
|
5. **Set Up the Database**:
|
||||||
```bash
|
```bash
|
||||||
# Create the database
|
# Create the database
|
||||||
symfony console doctrine:database:create
|
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
|
symfony console doctrine:fixtures:load
|
||||||
```
|
```
|
||||||
|
|
||||||
7. **Build Assets**:
|
6. **Build Assets**:
|
||||||
```bash
|
```bash
|
||||||
nvm use 20
|
nvm use 20
|
||||||
yarn run encore dev
|
yarn run encore dev
|
||||||
```
|
```
|
||||||
|
|
||||||
8. **Start the Development Server**:
|
7. **Start the Development Server**:
|
||||||
```bash
|
```bash
|
||||||
symfony server:start -d
|
symfony server:start -d
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Docker Setup
|
#### Docker Setup
|
||||||
|
|
||||||
The project includes a Docker configuration for easier development:
|
The project includes Docker configuration for easier development:
|
||||||
|
|
||||||
1. **Start Docker Services**:
|
1. **Start Docker Services**:
|
||||||
```bash
|
```bash
|
||||||
@@ -149,94 +149,21 @@ Key configuration files:
|
|||||||
- `package.json`: JavaScript dependencies and scripts
|
- `package.json`: JavaScript dependencies and scripts
|
||||||
- `.env`: Default environment variables. Must usually not be updated: use `.env.local` instead.
|
- `.env`: Default environment variables. Must usually not be updated: use `.env.local` instead.
|
||||||
|
|
||||||
### Database migrations
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
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):
|
|
||||||
|
|
||||||
- `Chill\Bundle\ActivityBundle` writes migrations to `Chill\Migrations\Activity`;
|
|
||||||
- `Chill\Bundle\BudgetBundle` writes migrations to `Chill\Migrations\Budget`;
|
|
||||||
- `Chill\Bundle\CustomFieldsBundle` writes migrations to `Chill\Migrations\CustomFields`;
|
|
||||||
- `Chill\Bundle\DocGeneratorBundle` writes migrations to `Chill\Migrations\DocGenerator`;
|
|
||||||
- `Chill\Bundle\DocStoreBundle` writes migrations to `Chill\Migrations\DocStore`;
|
|
||||||
- `Chill\Bundle\EventBundle` writes migrations to `Chill\Migrations\Event`;
|
|
||||||
- `Chill\Bundle\CalendarBundle` writes migrations to `Chill\Migrations\Calendar`;
|
|
||||||
- `Chill\Bundle\FamilyMembersBundle` writes migrations to `Chill\Migrations\FamilyMembers`;
|
|
||||||
- `Chill\Bundle\FranceTravailApiBundle` writes migrations to `Chill\Migrations\FranceTravailApi`;
|
|
||||||
- `Chill\Bundle\JobBundle` writes migrations to `Chill\Migrations\Job`;
|
|
||||||
- `Chill\Bundle\MainBundle` writes migrations to `Chill\Migrations\Main`;
|
|
||||||
- `Chill\Bundle\PersonBundle` writes migrations to `Chill\Migrations\Person`;
|
|
||||||
- `Chill\Bundle\ReportBundle` writes migrations to `Chill\Migrations\Report`;
|
|
||||||
- `Chill\Bundle\TaskBundle` writes migrations to `Chill\Migrations\Task`;
|
|
||||||
- `Chill\Bundle\ThirdPartyBundle` writes migrations to `Chill\Migrations\ThirdParty`;
|
|
||||||
- `Chill\Bundle\TicketBundle` writes migrations to `Chill\Migrations\Ticket`;
|
|
||||||
- `Chill\Bundle\WopiBundle` writes migrations to `Chill\Migrations\Wopi`;
|
|
||||||
|
|
||||||
Once created the, comment's classes should be removed and a description of the changes made to the entities should be added to the migrations, using the `getDescription` method. The migration should not be cleaned by any artificial intelligence, as modifying this migration is error prone.
|
|
||||||
|
|
||||||
### Guidelines related to code structure and requirements
|
|
||||||
|
|
||||||
#### Usage of clock
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
### Testing Information
|
### Testing Information
|
||||||
|
|
||||||
The project uses PHPUnit for testing. Each bundle has its own test suite, and there's also a global test suite at the root level.
|
The project uses PHPUnit for testing. Each bundle has its own test suite, and there's also a global test suite at the root level.
|
||||||
|
|
||||||
#### Use of mock in tests
|
|
||||||
|
|
||||||
##### General mocking
|
|
||||||
|
|
||||||
For creating mock, we prefer using prophecy (library phpspec/prophecy).
|
For creating mock, we prefer using prophecy (library phpspec/prophecy).
|
||||||
|
|
||||||
##### Useful helpers and tips that avoid creating a mock
|
|
||||||
|
|
||||||
Some notable implementations that are test helpers and avoid creating 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);
|
|
||||||
- `\Symfony\Component\HttpClient\MockHttpClient`, an implementation of `\Symfony\Contracts\HttpClient\HttpClientInterface`;
|
|
||||||
- When using `\Symfony\Component\Mailer\MailerInterface`, we can create the mock with "InMemoryTransport":
|
|
||||||
|
|
||||||
```php
|
|
||||||
use Symfony\Component\Mailer\Transport\InMemoryTransport;
|
|
||||||
use \Symfony\Component\Mailer\Mailer;
|
|
||||||
|
|
||||||
$transport = new InMemoryTransport();
|
|
||||||
$mailer = new Mailer($transport);
|
|
||||||
|
|
||||||
// After sending:
|
|
||||||
$messages = $transport->getSent(); // array of SentMessage
|
|
||||||
```
|
|
||||||
- When using `\Symfony\Contracts\EventDispatcher\EventDispatcherInterface`, we can use directly an instance of `\Symfony\Component\EventDispatcher\EventDispatcher`;
|
|
||||||
|
|
||||||
##### When we prefer not creating a mock
|
|
||||||
|
|
||||||
- When we use Doctrine Entities related to the project, we prefer not to use a mock: we instantiate them directly (unless it requires too much code to write);
|
|
||||||
|
|
||||||
##### Mocking final and readonly classes
|
|
||||||
|
|
||||||
Classes marked as final can't be mocked. To avoid that, either:
|
|
||||||
|
|
||||||
- we remove the `final` keyword from the class;
|
|
||||||
- we extract an interface from the final class.
|
|
||||||
|
|
||||||
This must be a decision made by a human, not by an AI. Every AI task must abort with an explicit message in that case.
|
|
||||||
|
|
||||||
#### Running Tests
|
#### 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).
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Run all tests
|
||||||
|
vendor/bin/phpunit
|
||||||
|
|
||||||
|
# Run tests for a specific bundle
|
||||||
|
vendor/bin/phpunit --testsuite NameBundle
|
||||||
|
|
||||||
# Run a specific test file
|
# Run a specific test file
|
||||||
vendor/bin/phpunit path/to/TestFile.php
|
vendor/bin/phpunit path/to/TestFile.php
|
||||||
|
|
||||||
@@ -291,7 +218,7 @@ class TicketTest extends TestCase
|
|||||||
|
|
||||||
#### Test Database
|
#### 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 an in-memory SQLite database by default. You can configure a different database for testing in the `.env.test` file.
|
||||||
|
|
||||||
### Code Quality Tools
|
### 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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
163
CHANGELOG.md
163
CHANGELOG.md
@@ -6,169 +6,6 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
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
|
|
||||||
* Fix the transfer of evaluations and documents during of accompanyingperiodwork
|
|
||||||
|
|
||||||
## v4.0.1 - 2025-07-08
|
|
||||||
### Fixed
|
|
||||||
* Fix package.json for compilation
|
|
||||||
|
|
||||||
|
|
||||||
## v4.0.0 - 2025-07-08
|
|
||||||
### Feature
|
|
||||||
* ([#359](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/359)) Allow the merge of two accompanying period works
|
|
||||||
### Fixed
|
|
||||||
* ([#390](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/390)) Display the list of participant in the results, even if there is only one participant and that the search result display the requestor
|
|
||||||
* Fix admin entity edit actions for event admin entities and activity reason (category) entities
|
|
||||||
* Fix translations for social action fields in admin form: results, goals, evaluations
|
|
||||||
### DX
|
|
||||||
* Rewrite exports to run them asynchronously
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* Allow TranslatableMessage in flash messages
|
|
||||||
### UX
|
|
||||||
* Improve labeling of fields in person resource creation form
|
|
||||||
|
|
||||||
|
|
||||||
**Release notes**
|
|
||||||
|
|
||||||
- Add new methods to serialize data using the rector rule
|
|
||||||
- Remove all references to the Request in filters, aggregators, filters. Actually, the most frequent occurence is `$security->getUser()`.
|
|
||||||
- Refactor manually the initializeQuery method
|
|
||||||
- Remove the injection of ExportManager into the constructor of each export element:
|
|
||||||
|
|
||||||
```diff
|
|
||||||
|
|
||||||
- class MyFormatter implements FormatterInterface
|
|
||||||
+ class MyFormatter implements FormatterInterface, \Chill\MainBundle\Export\ExportManagerAwareInterface
|
|
||||||
{
|
|
||||||
+ use \Chill\MainBundle\Export\Helper\ExportManagerAwareTrait;
|
|
||||||
|
|
||||||
- public function __construct(private ExportManager $exportmanager) {}
|
|
||||||
|
|
||||||
public function MyMethod(): void
|
|
||||||
{
|
|
||||||
- $this->exportManager->getFilter('alias');
|
|
||||||
+ $this->getExportManager()->getFilter('alias');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
- configure messenger to handle export in a queue:
|
|
||||||
|
|
||||||
```diff
|
|
||||||
# config/packages/messenger.yaml
|
|
||||||
framework:
|
|
||||||
messenger:
|
|
||||||
routing:
|
|
||||||
+ 'Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage': priority
|
|
||||||
```
|
|
||||||
|
|
||||||
- add missing methods to exports, aggregators, filters, formatter:
|
|
||||||
|
|
||||||
```php
|
|
||||||
public function normalizeFormData(array $formData): array;
|
|
||||||
|
|
||||||
public function denormalizeFormData(array $formData, int $fromVersion): array;
|
|
||||||
```
|
|
||||||
|
|
||||||
There are rector rules to generate those methods:
|
|
||||||
|
|
||||||
- `Chill\Utils\Rector\Rector\ChillBundleAddNormalizationMethodsOnExportRector`
|
|
||||||
|
|
||||||
See:
|
|
||||||
|
|
||||||
```php
|
|
||||||
// upgrade chill exports
|
|
||||||
$rectorConfig->rules([\Chill\Utils\Rector\Rector\ChillBundleAddNormalizationMethodsOnExportRector::class]);
|
|
||||||
```
|
|
||||||
|
|
||||||
This rule will create most of the work necessary, but some manuals changes are still necessary:
|
|
||||||
|
|
||||||
- we must set manually the correct repository for method `denormalizeDoctrineEntity`;
|
|
||||||
- when the form data contains some entities, and the form type is not one of EntityType::class, PickUserDynamicType::class, PickUserLocationType::class, PickThirdpartyDynamicType::class, Select2CountryType::class, then we must handle the normalization manually (using the `\Chill\MainBundle\Export\ExportDataNormalizerTrait`)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## v3.12.1 - 2025-06-30
|
|
||||||
### Fixed
|
|
||||||
* Fix loading of the list of documents
|
|
||||||
|
|
||||||
## v3.12.0 - 2025-06-30
|
|
||||||
### Feature
|
|
||||||
* ([#377](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/377)) Add the document file name to the document title when a user upload a document, unless there is already a document title.
|
|
||||||
* Add desactivation date for social action and issue csv export
|
|
||||||
* Add Emoji and Fullscreen feature to ckeditor configuration
|
|
||||||
* ([#321](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/321)) Create editor which allow us to toggle between rich and simple text editor
|
|
||||||
* Do not remove workflow which are automatically canceled after staling for more than 30 days
|
|
||||||
### Fixed
|
|
||||||
* ([#376](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/376)) trying to prevent bug of typeerror in doc-history + improved display of document history
|
|
||||||
* ([#381](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/381)) Display previous participation in acc course work even if the person has left the acc course
|
|
||||||
* ([#372](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/372)) Fix display of text in calendar events
|
|
||||||
* Add missing translation for user_group.no_user_groups
|
|
||||||
* Fix admin entity edit actions for event admin entities and activity reason (category) entities
|
|
||||||
* ([#392](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/392)) Allow null and cast as string to setContent method for NewsItem
|
|
||||||
|
|
||||||
* ([#393](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/393)) Doc Generation: the "dump only" method send the document as an email attachment.
|
|
||||||
### DX
|
|
||||||
* ([#352](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/352)) Remove dead code for wopi-link module
|
|
||||||
* Replace library node-sass by sass, and upgrade bootstrap to version 5.3 (yarn upgrade / install is required)
|
|
||||||
### UX
|
|
||||||
* ([#374](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/374)) Remove default filter in_progress for the page 'my tasks'; Allows for new tasks to be displayed upon opening of the page
|
|
||||||
* Improve labeling of fields in person resource creation form
|
|
||||||
|
|
||||||
## v3.11.0 - 2025-04-17
|
|
||||||
### Feature
|
|
||||||
* ([#365](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/365)) Add counters of actions and activities, with 2 boxes to (1) show the number of active actions on total actions and (2) show the number of activities in a accompanying period, and pills in menus for showing the number of active actions and the number of activities.
|
|
||||||
* ([#364](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/364)) Added a second phone number "telephone2" to the thirdParty entity. Adapted twig templates and vuejs apps to handle this phone number
|
|
||||||
|
|
||||||
**Schema Change**: Add columns or tables
|
|
||||||
* Signature: add a button to go directly to the signature zone, even if there is only one
|
|
||||||
### Fixed
|
|
||||||
* Fixed wrong translations in the on-the-fly for creation of thirdParty
|
|
||||||
* Fixed update of phone number in on-the-fly edition of thirdParty
|
|
||||||
* Fixed closing of modal when editing thirdParty in accompanying course works
|
|
||||||
* Shorten the delay between two execution of AccompanyingPeriodStepChangeCronjob, to ensure at least one execution in a day
|
|
||||||
* ([#102](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/102)) Fix display of title in document list
|
|
||||||
* When cleaning the old stored object versions, do not throw an error if the stored object is not found on disk
|
|
||||||
* Add consistent log prefix and key to logs when stale workflows are automatically canceled
|
|
||||||
* ([#380](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/380)) Remove the "not null" validation constraint on recently added properties on HouseholdComposition
|
|
||||||
|
|
||||||
### DX
|
|
||||||
* Add new chill-col style for displaying title and aside in a flex table
|
|
||||||
|
|
||||||
## v3.10.3 - 2025-03-18
|
## v3.10.3 - 2025-03-18
|
||||||
### DX
|
### DX
|
||||||
* Eslint fixes
|
* Eslint fixes
|
||||||
|
@@ -54,7 +54,7 @@ Arborescence:
|
|||||||
- person
|
- person
|
||||||
- personvendee
|
- personvendee
|
||||||
- household_edit_metadata
|
- household_edit_metadata
|
||||||
- index.ts
|
- index.js
|
||||||
```
|
```
|
||||||
|
|
||||||
## Organisation des feuilles de styles
|
## Organisation des feuilles de styles
|
||||||
|
@@ -133,7 +133,6 @@
|
|||||||
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
|
"Chill\\TaskBundle\\": "src/Bundle/ChillTaskBundle",
|
||||||
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
|
"Chill\\ThirdPartyBundle\\": "src/Bundle/ChillThirdPartyBundle",
|
||||||
"Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src",
|
"Chill\\WopiBundle\\": "src/Bundle/ChillWopiBundle/src",
|
||||||
"Chill\\TicketBundle\\": "src/Bundle/ChillTicketBundle/src",
|
|
||||||
"Chill\\Utils\\Rector\\": "utils/rector/src"
|
"Chill\\Utils\\Rector\\": "utils/rector/src"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -35,7 +35,6 @@ return [
|
|||||||
Chill\ThirdPartyBundle\ChillThirdPartyBundle::class => ['all' => true],
|
Chill\ThirdPartyBundle\ChillThirdPartyBundle::class => ['all' => true],
|
||||||
Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true],
|
Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true],
|
||||||
Chill\WopiBundle\ChillWopiBundle::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\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||||
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
chill_doc_store:
|
chill_doc_store:
|
||||||
use_driver: local_storage
|
use_driver: openstack
|
||||||
local_storage:
|
local_storage:
|
||||||
storage_path: '%kernel.project_dir%/var/storage'
|
storage_path: '%kernel.project_dir%/var/storage'
|
||||||
openstack:
|
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\Calendar': '@ChillCalendarBundle/migrations'
|
||||||
'Chill\Migrations\Budget': '@ChillBudgetBundle/migrations'
|
'Chill\Migrations\Budget': '@ChillBudgetBundle/migrations'
|
||||||
'Chill\Migrations\Report': '@ChillReportBundle/migrations'
|
'Chill\Migrations\Report': '@ChillReportBundle/migrations'
|
||||||
'Chill\Migrations\Ticket': '@ChillTicketBundle/migrations'
|
|
||||||
all_or_nothing:
|
all_or_nothing:
|
||||||
true
|
true
|
||||||
|
|
||||||
|
@@ -62,10 +62,8 @@ framework:
|
|||||||
'Chill\MainBundle\Workflow\Messenger\PostSignatureStateChangeMessage': priority
|
'Chill\MainBundle\Workflow\Messenger\PostSignatureStateChangeMessage': priority
|
||||||
'Chill\MainBundle\Workflow\Messenger\PostPublicViewMessage': async
|
'Chill\MainBundle\Workflow\Messenger\PostPublicViewMessage': async
|
||||||
'Chill\MainBundle\Service\Workflow\CancelStaleWorkflowMessage': async
|
'Chill\MainBundle\Service\Workflow\CancelStaleWorkflowMessage': async
|
||||||
'Chill\MainBundle\Notification\Email\NotificationEmailMessages\SendImmediateNotificationEmailMessage': async
|
|
||||||
'Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage': priority
|
'Chill\MainBundle\Export\Messenger\ExportRequestGenerationMessage': priority
|
||||||
'Chill\MainBundle\Export\Messenger\RemoveExportGenerationMessage': async
|
'Chill\MainBundle\Export\Messenger\RemoveExportGenerationMessage': async
|
||||||
'Chill\MainBundle\Notification\Email\NotificationEmailMessages\ScheduleDailyNotificationDigestMessage': async
|
|
||||||
# end of routes added by chill-bundles recipes
|
# end of routes added by chill-bundles recipes
|
||||||
# Route your messages to the transports
|
# Route your messages to the transports
|
||||||
# 'App\Message\YourMessage': async
|
# 'App\Message\YourMessage': async
|
||||||
|
@@ -1,2 +0,0 @@
|
|||||||
chill_ticket_bundle:
|
|
||||||
resource: '@ChillTicketBundle/config/routes.yaml'
|
|
@@ -11,94 +11,24 @@
|
|||||||
Create a new bundle
|
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::
|
.. warning::
|
||||||
|
|
||||||
This part of the doc is not yet tested
|
This part of the doc is not yet tested
|
||||||
|
|
||||||
Create a new directory with Bundle class
|
TODO
|
||||||
----------------------------------------
|
|
||||||
|
|
||||||
.. 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",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Register the bundle
|
.. rubric:: Footnotes
|
||||||
-------------------
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
.. [#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.
|
||||||
|
@@ -79,12 +79,12 @@
|
|||||||
"dev": "encore dev",
|
"dev": "encore dev",
|
||||||
"watch": "encore dev --watch",
|
"watch": "encore dev --watch",
|
||||||
"build": "encore production --progress",
|
"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-validate": "swagger-cli validate templates/api/specs.yaml",
|
||||||
"specs-create-dir": "mkdir -p templates/api",
|
"specs-create-dir": "mkdir -p templates/api",
|
||||||
"specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate",
|
"specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate",
|
||||||
"version": "node --version",
|
"version": "node --version",
|
||||||
"eslint": "eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
|
"eslint": "npx eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
@@ -2154,6 +2154,11 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php
|
path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadSheetFormatter.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Instanceof between string and DateTimeInterface will always evaluate to false\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: src/Bundle/ChillMainBundle/Export/Formatter/SpreadsheetListFormatter.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Export\\\\Helper\\\\ExportAddressHelper\\:\\:\\$unitNamesKeysCache contains unresolvable type\\.$#"
|
message: "#^PHPDoc tag @var for property Chill\\\\MainBundle\\\\Export\\\\Helper\\\\ExportAddressHelper\\:\\:\\$unitNamesKeysCache contains unresolvable type\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
@@ -58,10 +58,6 @@
|
|||||||
<!-- temporarily removed, the time to find a fix -->
|
<!-- temporarily removed, the time to find a fix -->
|
||||||
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonDuplicateControllerViewTest.php</exclude>
|
<exclude>src/Bundle/ChillPersonBundle/Tests/Controller/PersonDuplicateControllerViewTest.php</exclude>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
||||||
<testsuite name="TicketBundle">
|
|
||||||
<directory suffix="Test.php">src/Bundle/ChillTicketBundle/tests/</directory>
|
|
||||||
</testsuite>
|
|
||||||
<!--
|
<!--
|
||||||
<testsuite name="ReportBundle">
|
<testsuite name="ReportBundle">
|
||||||
<directory suffix="Test.php">src/Bundle/ChillReportBundle/Tests/</directory>
|
<directory suffix="Test.php">src/Bundle/ChillReportBundle/Tests/</directory>
|
||||||
|
@@ -37,6 +37,9 @@ return static function (RectorConfig $rectorConfig): void {
|
|||||||
$rectorConfig->rule(Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector::class);
|
$rectorConfig->rule(Rector\TypeDeclaration\Rector\Class_\MergeDateTimePropertyTypeDeclarationRector::class);
|
||||||
$rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class);
|
$rectorConfig->rule(Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector::class);
|
||||||
|
|
||||||
|
// upgrade chill exports
|
||||||
|
$rectorConfig->rules([\Chill\Utils\Rector\Rector\ChillBundleAddNormalizationMethodsOnExportRector::class]);
|
||||||
|
|
||||||
// part of the symfony 54 rules
|
// part of the symfony 54 rules
|
||||||
$rectorConfig->rule(\Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector::class);
|
$rectorConfig->rule(\Rector\Symfony\Symfony53\Rector\StaticPropertyFetch\KernelTestCaseContainerPropertyDeprecationRector::class);
|
||||||
$rectorConfig->rule(\Rector\Symfony\Symfony60\Rector\MethodCall\GetHelperControllerToServiceRector::class);
|
$rectorConfig->rule(\Rector\Symfony\Symfony60\Rector\MethodCall\GetHelperControllerToServiceRector::class);
|
||||||
|
@@ -48,6 +48,28 @@ class ActivityReasonCategoryController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a form to edit an existing ActivityReasonCategory entity.
|
||||||
|
*/
|
||||||
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/edit', name: 'chill_activity_activityreasoncategory_edit')]
|
||||||
|
public function editAction(mixed $id)
|
||||||
|
{
|
||||||
|
$em = $this->managerRegistry->getManager();
|
||||||
|
|
||||||
|
$entity = $em->getRepository(ActivityReasonCategory::class)->find($id);
|
||||||
|
|
||||||
|
if (!$entity) {
|
||||||
|
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$editForm = $this->createEditForm($entity);
|
||||||
|
|
||||||
|
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
|
||||||
|
'entity' => $entity,
|
||||||
|
'edit_form' => $editForm->createView(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists all ActivityReasonCategory entities.
|
* Lists all ActivityReasonCategory entities.
|
||||||
*/
|
*/
|
||||||
@@ -78,10 +100,29 @@ class ActivityReasonCategoryController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and displays a ActivityReasonCategory entity.
|
||||||
|
*/
|
||||||
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/show', name: 'chill_activity_activityreasoncategory_show')]
|
||||||
|
public function showAction(mixed $id)
|
||||||
|
{
|
||||||
|
$em = $this->managerRegistry->getManager();
|
||||||
|
|
||||||
|
$entity = $em->getRepository(ActivityReasonCategory::class)->find($id);
|
||||||
|
|
||||||
|
if (!$entity) {
|
||||||
|
throw $this->createNotFoundException('Unable to find ActivityReasonCategory entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('@ChillActivity/ActivityReasonCategory/show.html.twig', [
|
||||||
|
'entity' => $entity,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits an existing ActivityReasonCategory entity.
|
* Edits an existing ActivityReasonCategory entity.
|
||||||
*/
|
*/
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update')]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreasoncategory/{id}/update', name: 'chill_activity_activityreasoncategory_update', methods: ['POST', 'PUT'])]
|
||||||
public function updateAction(Request $request, mixed $id)
|
public function updateAction(Request $request, mixed $id)
|
||||||
{
|
{
|
||||||
$em = $this->managerRegistry->getManager();
|
$em = $this->managerRegistry->getManager();
|
||||||
@@ -98,7 +139,7 @@ class ActivityReasonCategoryController extends AbstractController
|
|||||||
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
if ($editForm->isSubmitted() && $editForm->isValid()) {
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
||||||
return $this->redirectToRoute('chill_activity_activityreasoncategory', ['id' => $id]);
|
return $this->redirectToRoute('chill_activity_activityreasoncategory_edit', ['id' => $id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
|
return $this->render('@ChillActivity/ActivityReasonCategory/edit.html.twig', [
|
||||||
@@ -137,7 +178,7 @@ class ActivityReasonCategoryController extends AbstractController
|
|||||||
{
|
{
|
||||||
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, [
|
$form = $this->createForm(ActivityReasonCategoryType::class, $entity, [
|
||||||
'action' => $this->generateUrl('chill_activity_activityreasoncategory_update', ['id' => $entity->getId()]),
|
'action' => $this->generateUrl('chill_activity_activityreasoncategory_update', ['id' => $entity->getId()]),
|
||||||
'method' => 'POST',
|
'method' => 'PUT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, ['label' => 'Update']);
|
$form->add('submit', SubmitType::class, ['label' => 'Update']);
|
||||||
|
@@ -17,6 +17,7 @@ use Chill\ActivityBundle\Repository\ActivityReasonRepository;
|
|||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ActivityReason controller.
|
* ActivityReason controller.
|
||||||
@@ -49,6 +50,28 @@ class ActivityReasonController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a form to edit an existing ActivityReason entity.
|
||||||
|
*/
|
||||||
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/edit', name: 'chill_activity_activityreason_edit')]
|
||||||
|
public function editAction(mixed $id)
|
||||||
|
{
|
||||||
|
$em = $this->managerRegistry->getManager();
|
||||||
|
|
||||||
|
$entity = $em->getRepository(ActivityReason::class)->find($id);
|
||||||
|
|
||||||
|
if (null === $entity) {
|
||||||
|
throw new NotFoundHttpException('Unable to find ActivityReason entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$editForm = $this->createEditForm($entity);
|
||||||
|
|
||||||
|
return $this->render('@ChillActivity/ActivityReason/edit.html.twig', [
|
||||||
|
'entity' => $entity,
|
||||||
|
'edit_form' => $editForm->createView(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists all ActivityReason entities.
|
* Lists all ActivityReason entities.
|
||||||
*/
|
*/
|
||||||
@@ -79,10 +102,29 @@ class ActivityReasonController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds and displays a ActivityReason entity.
|
||||||
|
*/
|
||||||
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/show', name: 'chill_activity_activityreason_show')]
|
||||||
|
public function showAction(mixed $id)
|
||||||
|
{
|
||||||
|
$em = $this->managerRegistry->getManager();
|
||||||
|
|
||||||
|
$entity = $em->getRepository(ActivityReason::class)->find($id);
|
||||||
|
|
||||||
|
if (!$entity) {
|
||||||
|
throw $this->createNotFoundException('Unable to find ActivityReason entity.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('@ChillActivity/ActivityReason/show.html.twig', [
|
||||||
|
'entity' => $entity,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits an existing ActivityReason entity.
|
* Edits an existing ActivityReason entity.
|
||||||
*/
|
*/
|
||||||
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update')]
|
#[\Symfony\Component\Routing\Annotation\Route(path: '/{_locale}/admin/activityreason/{id}/update', name: 'chill_activity_activityreason_update', methods: ['POST', 'PUT'])]
|
||||||
public function updateAction(Request $request, mixed $id)
|
public function updateAction(Request $request, mixed $id)
|
||||||
{
|
{
|
||||||
$em = $this->managerRegistry->getManager();
|
$em = $this->managerRegistry->getManager();
|
||||||
@@ -138,7 +180,7 @@ class ActivityReasonController extends AbstractController
|
|||||||
{
|
{
|
||||||
$form = $this->createForm(ActivityReasonType::class, $entity, [
|
$form = $this->createForm(ActivityReasonType::class, $entity, [
|
||||||
'action' => $this->generateUrl('chill_activity_activityreason_update', ['id' => $entity->getId()]),
|
'action' => $this->generateUrl('chill_activity_activityreason_update', ['id' => $entity->getId()]),
|
||||||
'method' => 'POST',
|
'method' => 'PUT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$form->add('submit', SubmitType::class, ['label' => 'Update']);
|
$form->add('submit', SubmitType::class, ['label' => 'Update']);
|
||||||
|
@@ -10,7 +10,10 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="getContext === 'accompanyingCourse' && suggestedEntities.length > 0"
|
v-if="
|
||||||
|
getContext === 'accompanyingCourse' &&
|
||||||
|
suggestedEntities.length > 0
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<ul class="list-suggest add-items inline">
|
<ul class="list-suggest add-items inline">
|
||||||
<li
|
<li
|
||||||
|
@@ -39,11 +39,17 @@
|
|||||||
<option selected disabled value="">
|
<option selected disabled value="">
|
||||||
{{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }}
|
{{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }}
|
||||||
</option>
|
</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) }}
|
{{ localizeString(t.title) }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<label>{{ trans(ACTIVITY_LOCATION_FIELDS_TYPE) }}</label>
|
<label>{{
|
||||||
|
trans(ACTIVITY_LOCATION_FIELDS_TYPE)
|
||||||
|
}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-floating mb-3">
|
<div class="form-floating mb-3">
|
||||||
@@ -102,7 +108,10 @@
|
|||||||
</form>
|
</form>
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<button class="btn btn-save" @click.prevent="saveNewLocation">
|
<button
|
||||||
|
class="btn btn-save"
|
||||||
|
@click.prevent="saveNewLocation"
|
||||||
|
>
|
||||||
{{ trans(SAVE) }}
|
{{ trans(SAVE) }}
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
@@ -235,7 +244,8 @@ export default {
|
|||||||
},
|
},
|
||||||
hasPhonenumber1() {
|
hasPhonenumber1() {
|
||||||
return (
|
return (
|
||||||
this.selected.phonenumber1 !== null && this.selected.phonenumber1 !== ""
|
this.selected.phonenumber1 !== null &&
|
||||||
|
this.selected.phonenumber1 !== ""
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
showAddAddress() {
|
showAddAddress() {
|
||||||
|
@@ -49,7 +49,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<div v-if="actionIsLoading === true">
|
<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>
|
</div>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
@@ -62,7 +64,8 @@
|
|||||||
<template
|
<template
|
||||||
v-else-if="
|
v-else-if="
|
||||||
socialActionsList.length > 0 &&
|
socialActionsList.length > 0 &&
|
||||||
(socialIssuesSelected.length || socialActionsSelected.length)
|
(socialIssuesSelected.length ||
|
||||||
|
socialActionsSelected.length)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
@@ -85,7 +88,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-else-if="actionAreLoaded && socialActionsList.length === 0"
|
v-else-if="
|
||||||
|
actionAreLoaded && socialActionsList.length === 0
|
||||||
|
"
|
||||||
class="inline-choice chill-no-data-statement mt-3"
|
class="inline-choice chill-no-data-statement mt-3"
|
||||||
>
|
>
|
||||||
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
|
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
|
||||||
@@ -164,7 +169,8 @@ export default {
|
|||||||
/* Add in list the issues already associated (if not yet listed) */
|
/* Add in list the issues already associated (if not yet listed) */
|
||||||
this.socialIssuesSelected.forEach((issue) => {
|
this.socialIssuesSelected.forEach((issue) => {
|
||||||
if (
|
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);
|
this.$store.commit("addIssueInList", issue);
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,9 @@
|
|||||||
:value="issue"
|
:value="issue"
|
||||||
/>
|
/>
|
||||||
<label class="form-check-label" :for="issue.id">
|
<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>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
@@ -2,7 +2,7 @@ import "es6-promise/auto";
|
|||||||
import { createStore } from "vuex";
|
import { createStore } from "vuex";
|
||||||
import { postLocation } from "./api";
|
import { postLocation } from "./api";
|
||||||
import prepareLocations from "./store.locations.js";
|
import prepareLocations from "./store.locations.js";
|
||||||
import { fetchResults, makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
import {fetchResults, makeFetch} from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
const debug = process.env.NODE_ENV !== "production";
|
const debug = process.env.NODE_ENV !== "production";
|
||||||
//console.log('window.activity', window.activity);
|
//console.log('window.activity', window.activity);
|
||||||
@@ -369,7 +369,7 @@ const store = createStore({
|
|||||||
// console.log('works', works);
|
// console.log('works', works);
|
||||||
commit("setAccompanyingPeriodWorks", works);
|
commit("setAccompanyingPeriodWorks", works);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fetch works:", error);
|
console.error('Failed to fetch works:', error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getWhoAmI({ commit }) {
|
getWhoAmI({ commit }) {
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{% block admin_content %}
|
{% block admin_content %}
|
||||||
<h1>{{ 'ActivityReason list'|trans }}</h1>
|
<h1>{{ 'ActivityReason list'|trans }}</h1>
|
||||||
|
|
||||||
<table class="table table-bordered border-dark align-middle">
|
<table class="records_list">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ 'Name'|trans }}</th>
|
<th>{{ 'Name'|trans }}</th>
|
||||||
@@ -29,7 +29,10 @@
|
|||||||
<td>
|
<td>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('chill_activity_activityreason_update', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
|
<a href="{{ path('chill_activity_activityreason_show', { 'id': entity.id }) }}" class="btn btn-show" title="{{ 'show'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_activity_activityreason_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
{% block admin_content %}
|
{% block admin_content %}
|
||||||
<h1>{{ 'ActivityReasonCategory list'|trans }}</h1>
|
<h1>{{ 'ActivityReasonCategory list'|trans }}</h1>
|
||||||
|
|
||||||
<table class="table table-bordered border-dark align-middle">
|
<table class="records_list">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{ 'Name'|trans }}</th>
|
<th>{{ 'Name'|trans }}</th>
|
||||||
@@ -23,7 +23,10 @@
|
|||||||
<td>
|
<td>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('chill_activity_activityreasoncategory_update', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
|
<a href="{{ path('chill_activity_activityreasoncategory_show', { 'id': entity.id }) }}" class="btn btn-show" title="{{ 'show'|trans }}"></a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_activity_activityreasoncategory_edit', { 'id': entity.id }) }}" class="btn btn-edit" title="{{ 'edit'|trans }}"></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
|
@@ -22,52 +22,6 @@ use Symfony\Component\Security\Core\Role\Role;
|
|||||||
*/
|
*/
|
||||||
final class ActivityControllerTest extends WebTestCase
|
final class ActivityControllerTest extends WebTestCase
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @dataProvider getSecuredPagesUnauthenticated
|
|
||||||
*/
|
|
||||||
public function testAccessIsDeniedForUnauthenticated(mixed $url)
|
|
||||||
{
|
|
||||||
$client = $this->createClient();
|
|
||||||
|
|
||||||
$client->request('GET', $url);
|
|
||||||
|
|
||||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
|
||||||
$this->assertTrue(
|
|
||||||
$client->getResponse()->isRedirect('http://localhost/login'),
|
|
||||||
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide a client unauthenticated and.
|
|
||||||
*/
|
|
||||||
public function getSecuredPagesUnauthenticated()
|
|
||||||
{
|
|
||||||
self::bootKernel();
|
|
||||||
$person = $this->getPersonFromFixtures();
|
|
||||||
$activities = $this->getActivitiesForPerson($person);
|
|
||||||
|
|
||||||
return [
|
|
||||||
[sprintf('fr/person/%d/activity/', $person->getId())],
|
|
||||||
[sprintf('fr/person/%d/activity/new', $person->getId())],
|
|
||||||
[sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())],
|
|
||||||
[sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider getSecuredPagesAuthenticated
|
|
||||||
*
|
|
||||||
* @param type $client
|
|
||||||
* @param type $url
|
|
||||||
*/
|
|
||||||
public function testAccessIsDeniedForUnauthorized($client, $url)
|
|
||||||
{
|
|
||||||
$client->request('GET', $url);
|
|
||||||
|
|
||||||
$this->assertEquals(403, $client->getResponse()->getStatusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSecuredPagesAuthenticated()
|
public function getSecuredPagesAuthenticated()
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
@@ -101,6 +55,52 @@ final class ActivityControllerTest extends WebTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a client unauthenticated and.
|
||||||
|
*/
|
||||||
|
public function getSecuredPagesUnauthenticated()
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
$person = $this->getPersonFromFixtures();
|
||||||
|
$activities = $this->getActivitiesForPerson($person);
|
||||||
|
|
||||||
|
return [
|
||||||
|
[sprintf('fr/person/%d/activity/', $person->getId())],
|
||||||
|
[sprintf('fr/person/%d/activity/new', $person->getId())],
|
||||||
|
[sprintf('fr/person/%d/activity/%d/show', $person->getId(), $activities[0]->getId())],
|
||||||
|
[sprintf('fr/person/%d/activity/%d/edit', $person->getId(), $activities[0]->getId())],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getSecuredPagesUnauthenticated
|
||||||
|
*/
|
||||||
|
public function testAccessIsDeniedForUnauthenticated(mixed $url)
|
||||||
|
{
|
||||||
|
$client = $this->createClient();
|
||||||
|
|
||||||
|
$client->request('GET', $url);
|
||||||
|
|
||||||
|
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||||
|
$this->assertTrue(
|
||||||
|
$client->getResponse()->isRedirect('http://localhost/login'),
|
||||||
|
sprintf('the page "%s" does not redirect to http://localhost/login', $url)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getSecuredPagesAuthenticated
|
||||||
|
*
|
||||||
|
* @param type $client
|
||||||
|
* @param type $url
|
||||||
|
*/
|
||||||
|
public function testAccessIsDeniedForUnauthorized($client, $url)
|
||||||
|
{
|
||||||
|
$client->request('GET', $url);
|
||||||
|
|
||||||
|
$this->assertEquals(403, $client->getResponse()->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
public function testCompleteScenario()
|
public function testCompleteScenario()
|
||||||
{
|
{
|
||||||
// Create a new client to browse the application
|
// Create a new client to browse the application
|
||||||
|
@@ -137,64 +137,6 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase
|
|||||||
self::assertIsArray($actual);
|
self::assertIsArray($actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function provideDataFindByAccompanyingPeriod(): iterable
|
|
||||||
{
|
|
||||||
$this->setUp();
|
|
||||||
|
|
||||||
if (null === $period = $this->entityManager
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('a')
|
|
||||||
->from(AccompanyingPeriod::class, 'a')
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getQuery()
|
|
||||||
->getSingleResult()) {
|
|
||||||
throw new \RuntimeException('no period found');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([] === $types = $this->entityManager
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('t')
|
|
||||||
->from(ActivityType::class, 't')
|
|
||||||
->setMaxResults(2)
|
|
||||||
->getQuery()
|
|
||||||
->getResult()) {
|
|
||||||
throw new \RuntimeException('no types');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([] === $jobs = $this->entityManager
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('j')
|
|
||||||
->from(UserJob::class, 'j')
|
|
||||||
->setMaxResults(2)
|
|
||||||
->getQuery()
|
|
||||||
->getResult()
|
|
||||||
) {
|
|
||||||
$job = new UserJob();
|
|
||||||
$job->setLabel(['fr' => 'test']);
|
|
||||||
$this->entityManager->persist($job);
|
|
||||||
$this->entityManager->flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === $user = $this->entityManager
|
|
||||||
->createQueryBuilder()
|
|
||||||
->select('u')
|
|
||||||
->from(User::class, 'u')
|
|
||||||
->setMaxResults(1)
|
|
||||||
->getQuery()
|
|
||||||
->getSingleResult()
|
|
||||||
) {
|
|
||||||
throw new \RuntimeException('no user found');
|
|
||||||
}
|
|
||||||
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['my_activities' => true]];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['types' => $types]];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['jobs' => $jobs]];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
|
|
||||||
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider provideDataFindByPerson
|
* @dataProvider provideDataFindByPerson
|
||||||
*/
|
*/
|
||||||
@@ -349,4 +291,62 @@ class ActivityACLAwareRepositoryTest extends KernelTestCase
|
|||||||
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
|
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
|
||||||
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
|
yield [$person, $user, $centers, $scopes, ActivityVoter::SEE, 0, 5, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function provideDataFindByAccompanyingPeriod(): iterable
|
||||||
|
{
|
||||||
|
$this->setUp();
|
||||||
|
|
||||||
|
if (null === $period = $this->entityManager
|
||||||
|
->createQueryBuilder()
|
||||||
|
->select('a')
|
||||||
|
->from(AccompanyingPeriod::class, 'a')
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getQuery()
|
||||||
|
->getSingleResult()) {
|
||||||
|
throw new \RuntimeException('no period found');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([] === $types = $this->entityManager
|
||||||
|
->createQueryBuilder()
|
||||||
|
->select('t')
|
||||||
|
->from(ActivityType::class, 't')
|
||||||
|
->setMaxResults(2)
|
||||||
|
->getQuery()
|
||||||
|
->getResult()) {
|
||||||
|
throw new \RuntimeException('no types');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([] === $jobs = $this->entityManager
|
||||||
|
->createQueryBuilder()
|
||||||
|
->select('j')
|
||||||
|
->from(UserJob::class, 'j')
|
||||||
|
->setMaxResults(2)
|
||||||
|
->getQuery()
|
||||||
|
->getResult()
|
||||||
|
) {
|
||||||
|
$job = new UserJob();
|
||||||
|
$job->setLabel(['fr' => 'test']);
|
||||||
|
$this->entityManager->persist($job);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === $user = $this->entityManager
|
||||||
|
->createQueryBuilder()
|
||||||
|
->select('u')
|
||||||
|
->from(User::class, 'u')
|
||||||
|
->setMaxResults(1)
|
||||||
|
->getQuery()
|
||||||
|
->getSingleResult()
|
||||||
|
) {
|
||||||
|
throw new \RuntimeException('no user found');
|
||||||
|
}
|
||||||
|
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], []];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['my_activities' => true]];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['types' => $types]];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['jobs' => $jobs]];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago')]];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['before' => new \DateTimeImmutable('1 year ago')]];
|
||||||
|
yield [$period, $user, ActivityVoter::SEE, 0, 10, ['date' => 'DESC'], ['after' => new \DateTimeImmutable('1 year ago'), 'before' => new \DateTimeImmutable('1 month ago')]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,46 +57,6 @@ final class ActivityVoterTest extends KernelTestCase
|
|||||||
$this->prophet = new \Prophecy\Prophet();
|
$this->prophet = new \Prophecy\Prophet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNullUser()
|
|
||||||
{
|
|
||||||
$token = $this->prepareToken();
|
|
||||||
$center = $this->prepareCenter(1, 'center');
|
|
||||||
$person = $this->preparePerson($center);
|
|
||||||
$scope = $this->prepareScope(1, 'default');
|
|
||||||
$activity = $this->prepareActivity($scope, $person);
|
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
VoterInterface::ACCESS_DENIED,
|
|
||||||
$this->voter->vote($token, $activity, ['CHILL_ACTIVITY_SEE']),
|
|
||||||
'assert that a null user is not allowed to see'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataProvider_testVoteAction
|
|
||||||
*
|
|
||||||
* @param type $expectedResult
|
|
||||||
* @param string $attribute
|
|
||||||
* @param string $message
|
|
||||||
*/
|
|
||||||
public function testVoteAction(
|
|
||||||
$expectedResult,
|
|
||||||
User $user,
|
|
||||||
Scope $scope,
|
|
||||||
Center $center,
|
|
||||||
$attribute,
|
|
||||||
$message,
|
|
||||||
) {
|
|
||||||
$token = $this->prepareToken($user);
|
|
||||||
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
|
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
$expectedResult,
|
|
||||||
$this->voter->vote($token, $activity, [$attribute]),
|
|
||||||
$message
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataProvider_testVoteAction()
|
public function dataProvider_testVoteAction()
|
||||||
{
|
{
|
||||||
$centerA = $this->prepareCenter(1, 'center A');
|
$centerA = $this->prepareCenter(1, 'center A');
|
||||||
@@ -150,6 +110,46 @@ final class ActivityVoterTest extends KernelTestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNullUser()
|
||||||
|
{
|
||||||
|
$token = $this->prepareToken();
|
||||||
|
$center = $this->prepareCenter(1, 'center');
|
||||||
|
$person = $this->preparePerson($center);
|
||||||
|
$scope = $this->prepareScope(1, 'default');
|
||||||
|
$activity = $this->prepareActivity($scope, $person);
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
VoterInterface::ACCESS_DENIED,
|
||||||
|
$this->voter->vote($token, $activity, ['CHILL_ACTIVITY_SEE']),
|
||||||
|
'assert that a null user is not allowed to see'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider dataProvider_testVoteAction
|
||||||
|
*
|
||||||
|
* @param type $expectedResult
|
||||||
|
* @param string $attribute
|
||||||
|
* @param string $message
|
||||||
|
*/
|
||||||
|
public function testVoteAction(
|
||||||
|
$expectedResult,
|
||||||
|
User $user,
|
||||||
|
Scope $scope,
|
||||||
|
Center $center,
|
||||||
|
$attribute,
|
||||||
|
$message,
|
||||||
|
) {
|
||||||
|
$token = $this->prepareToken($user);
|
||||||
|
$activity = $this->prepareActivity($scope, $this->preparePerson($center));
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
$expectedResult,
|
||||||
|
$this->voter->vote($token, $activity, [$attribute]),
|
||||||
|
$message
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* prepare a token interface with correct rights.
|
* prepare a token interface with correct rights.
|
||||||
*
|
*
|
||||||
|
@@ -30,18 +30,6 @@ final class AsideActivityControllerTest extends WebTestCase
|
|||||||
self::ensureKernelShutdown();
|
self::ensureKernelShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider generateAsideActivityId
|
|
||||||
*/
|
|
||||||
public function testEditWithoutUsers(int $asideActivityId)
|
|
||||||
{
|
|
||||||
self::ensureKernelShutdown();
|
|
||||||
$client = $this->getClientAuthenticated();
|
|
||||||
$client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit");
|
|
||||||
|
|
||||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function generateAsideActivityId(): iterable
|
public static function generateAsideActivityId(): iterable
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
@@ -70,6 +58,18 @@ final class AsideActivityControllerTest extends WebTestCase
|
|||||||
self::ensureKernelShutdown();
|
self::ensureKernelShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateAsideActivityId
|
||||||
|
*/
|
||||||
|
public function testEditWithoutUsers(int $asideActivityId)
|
||||||
|
{
|
||||||
|
self::ensureKernelShutdown();
|
||||||
|
$client = $this->getClientAuthenticated();
|
||||||
|
$client->request('GET', "/fr/asideactivity/{$asideActivityId}/edit");
|
||||||
|
|
||||||
|
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
public function testIndexWithoutUsers()
|
public function testIndexWithoutUsers()
|
||||||
{
|
{
|
||||||
self::ensureKernelShutdown();
|
self::ensureKernelShutdown();
|
||||||
|
@@ -68,7 +68,9 @@ export type EventInputCalendarRange = EventInput & {
|
|||||||
export function isEventInputCalendarRange(
|
export function isEventInputCalendarRange(
|
||||||
toBeDetermined: EventInputCalendarRange | EventInput,
|
toBeDetermined: EventInputCalendarRange | EventInput,
|
||||||
): toBeDetermined is EventInputCalendarRange {
|
): toBeDetermined is EventInputCalendarRange {
|
||||||
return typeof toBeDetermined.is === "string" && toBeDetermined.is === "range";
|
return (
|
||||||
|
typeof toBeDetermined.is === "string" && toBeDetermined.is === "range"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
@@ -61,14 +61,22 @@
|
|||||||
<label class="input-group-text" for="slotDuration"
|
<label class="input-group-text" for="slotDuration"
|
||||||
>Durée des créneaux</label
|
>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:05:00">5 minutes</option>
|
||||||
<option value="00:10:00">10 minutes</option>
|
<option value="00:10:00">10 minutes</option>
|
||||||
<option value="00:15:00">15 minutes</option>
|
<option value="00:15:00">15 minutes</option>
|
||||||
<option value="00:30:00">30 minutes</option>
|
<option value="00:30:00">30 minutes</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMinTime">De</label>
|
<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="00:00:00">0h</option>
|
||||||
<option value="01:00:00">1h</option>
|
<option value="01:00:00">1h</option>
|
||||||
<option value="02:00:00">2h</option>
|
<option value="02:00:00">2h</option>
|
||||||
@@ -84,7 +92,11 @@
|
|||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
<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="12:00:00">12h</option>
|
||||||
<option value="13:00:00">13h</option>
|
<option value="13:00:00">13h</option>
|
||||||
<option value="14:00:00">14h</option>
|
<option value="14:00:00">14h</option>
|
||||||
@@ -112,7 +124,9 @@
|
|||||||
v-model="hideWeekends"
|
v-model="hideWeekends"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<label for="showHideWE" class="form-check-label input-group-text"
|
<label
|
||||||
|
for="showHideWE"
|
||||||
|
class="form-check-label input-group-text"
|
||||||
>Week-ends</label
|
>Week-ends</label
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -128,7 +142,9 @@
|
|||||||
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||||
>{{ arg.timeText }}
|
>{{ arg.timeText }}
|
||||||
{{ arg.event.extendedProps.locationName }}
|
{{ 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'"
|
<b v-else-if="arg.event.extendedProps.is === 'current'"
|
||||||
>{{ arg.timeText }} {{ $t("current_selected") }}
|
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||||
@@ -136,7 +152,9 @@
|
|||||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||||
arg.event.title
|
arg.event.title
|
||||||
}}</b>
|
}}</b>
|
||||||
<b v-else>{{ arg.timeText }} {{ $t("current_selected") }} </b>
|
<b v-else
|
||||||
|
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||||
|
</b>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</FullCalendar>
|
</FullCalendar>
|
||||||
@@ -250,7 +268,9 @@ export default {
|
|||||||
this.$store.state.activity.endDate !== null)
|
this.$store.state.activity.endDate !== null)
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
!window.confirm(this.$t("change_main_user_will_reset_event_data"))
|
!window.confirm(
|
||||||
|
this.$t("change_main_user_will_reset_event_data"),
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -258,9 +278,13 @@ export default {
|
|||||||
|
|
||||||
// add the previous user, if any, in the previous user list (in use for suggestion)
|
// add the previous user, if any, in the previous user list (in use for suggestion)
|
||||||
if (null !== this.$store.getters.getMainUser) {
|
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)) {
|
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
|
// show an alert if changing mainUser
|
||||||
if (
|
if (
|
||||||
(this.$store.getters.getMainUser !== null &&
|
(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
|
this.$store.getters.getMainUser === null
|
||||||
) {
|
) {
|
||||||
if (!window.confirm(this.$t("will_change_main_user_for_me"))) {
|
if (!window.confirm(this.$t("will_change_main_user_for_me"))) {
|
||||||
@@ -334,7 +359,9 @@ export default {
|
|||||||
this.$store.getters.getMainUser.id
|
this.$store.getters.getMainUser.id
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
!window.confirm(this.$t("this_calendar_range_will_change_main_user"))
|
!window.confirm(
|
||||||
|
this.$t("this_calendar_range_will_change_main_user"),
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -4,9 +4,18 @@
|
|||||||
{{ user.text }}
|
{{ user.text }}
|
||||||
<template v-if="invite !== null">
|
<template v-if="invite !== null">
|
||||||
<i v-if="invite.status === 'accepted'" class="fa fa-check" />
|
<i v-if="invite.status === 'accepted'" class="fa fa-check" />
|
||||||
<i v-else-if="invite.status === 'declined'" class="fa fa-times" />
|
<i
|
||||||
<i v-else-if="invite.status === 'pending'" class="fa fa-question-o" />
|
v-else-if="invite.status === 'declined'"
|
||||||
<i v-else-if="invite.status === 'tentative'" class="fa fa-question" />
|
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>
|
<span v-else="">{{ invite.status }}</span>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
@@ -60,7 +69,8 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
style() {
|
style() {
|
||||||
return {
|
return {
|
||||||
backgroundColor: this.$store.getters.getUserData(this.user).mainColor,
|
backgroundColor: this.$store.getters.getUserData(this.user)
|
||||||
|
.mainColor,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
rangeShow: {
|
rangeShow: {
|
||||||
@@ -71,7 +81,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.$store.getters.isRangeShownOnCalendarForUser(this.user);
|
return this.$store.getters.isRangeShownOnCalendarForUser(
|
||||||
|
this.user,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
remoteShow: {
|
remoteShow: {
|
||||||
@@ -82,7 +94,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
get() {
|
get() {
|
||||||
return this.$store.getters.isRemoteShownOnCalendarForUser(this.user);
|
return this.$store.getters.isRemoteShownOnCalendarForUser(
|
||||||
|
this.user,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -22,25 +22,33 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
|
||||||
<li v-if="status !== Statuses.ACCEPTED">
|
<li v-if="status !== Statuses.ACCEPTED">
|
||||||
<a class="dropdown-item" @click="changeStatus(Statuses.ACCEPTED)"
|
<a
|
||||||
><i class="fa fa-check" aria-hidden="true"></i> {{ $t("Accept") }}</a
|
class="dropdown-item"
|
||||||
|
@click="changeStatus(Statuses.ACCEPTED)"
|
||||||
|
><i class="fa fa-check" aria-hidden="true"></i>
|
||||||
|
{{ $t("Accept") }}</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="status !== Statuses.DECLINED">
|
<li v-if="status !== Statuses.DECLINED">
|
||||||
<a class="dropdown-item" @click="changeStatus(Statuses.DECLINED)"
|
<a
|
||||||
><i class="fa fa-times" aria-hidden="true"></i> {{ $t("Decline") }}</a
|
class="dropdown-item"
|
||||||
|
@click="changeStatus(Statuses.DECLINED)"
|
||||||
|
><i class="fa fa-times" aria-hidden="true"></i>
|
||||||
|
{{ $t("Decline") }}</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="status !== Statuses.TENTATIVELY_ACCEPTED">
|
<li v-if="status !== Statuses.TENTATIVELY_ACCEPTED">
|
||||||
<a
|
<a
|
||||||
class="dropdown-item"
|
class="dropdown-item"
|
||||||
@click="changeStatus(Statuses.TENTATIVELY_ACCEPTED)"
|
@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>
|
||||||
<li v-if="status !== Statuses.PENDING">
|
<li v-if="status !== Statuses.PENDING">
|
||||||
<a class="dropdown-item" @click="changeStatus(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>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -83,7 +91,9 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
statusChanged(payload: "accepted" | "declined" | "pending" | "tentative") {
|
statusChanged(
|
||||||
|
payload: "accepted" | "declined" | "pending" | "tentative",
|
||||||
|
) {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@@ -23,14 +23,22 @@
|
|||||||
<label class="input-group-text" for="slotDuration"
|
<label class="input-group-text" for="slotDuration"
|
||||||
>Durée des créneaux</label
|
>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:05:00">5 minutes</option>
|
||||||
<option value="00:10:00">10 minutes</option>
|
<option value="00:10:00">10 minutes</option>
|
||||||
<option value="00:15:00">15 minutes</option>
|
<option value="00:15:00">15 minutes</option>
|
||||||
<option value="00:30:00">30 minutes</option>
|
<option value="00:30:00">30 minutes</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMinTime">De</label>
|
<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="00:00:00">0h</option>
|
||||||
<option value="01:00:00">1h</option>
|
<option value="01:00:00">1h</option>
|
||||||
<option value="02:00:00">2h</option>
|
<option value="02:00:00">2h</option>
|
||||||
@@ -46,7 +54,11 @@
|
|||||||
<option value="12:00:00">12h</option>
|
<option value="12:00:00">12h</option>
|
||||||
</select>
|
</select>
|
||||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
<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="12:00:00">12h</option>
|
||||||
<option value="13:00:00">13h</option>
|
<option value="13:00:00">13h</option>
|
||||||
<option value="14:00:00">14h</option>
|
<option value="14:00:00">14h</option>
|
||||||
@@ -74,7 +86,9 @@
|
|||||||
v-model="showWeekends"
|
v-model="showWeekends"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<label for="showHideWE" class="form-check-label input-group-text"
|
<label
|
||||||
|
for="showHideWE"
|
||||||
|
class="form-check-label input-group-text"
|
||||||
>Week-ends</label
|
>Week-ends</label
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -84,12 +98,16 @@
|
|||||||
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
||||||
<template v-slot:eventContent="{ event }: { event: EventApi }">
|
<template v-slot:eventContent="{ event }: { event: EventApi }">
|
||||||
<span :class="eventClasses">
|
<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'"
|
<b v-else-if="event.extendedProps.is === 'range'"
|
||||||
>{{ formatDate(event.startStr) }} -
|
>{{ formatDate(event.startStr) }} -
|
||||||
{{ event.extendedProps.locationName }}</b
|
{{ 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>
|
<b v-else>no 'is'</b>
|
||||||
<a
|
<a
|
||||||
v-if="event.extendedProps.is === 'range'"
|
v-if="event.extendedProps.is === 'range'"
|
||||||
@@ -108,7 +126,11 @@
|
|||||||
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-9 col-md-2">
|
<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="day">{{ $t("from_day_to_day") }}</option>
|
||||||
<option value="week">
|
<option value="week">
|
||||||
{{ $t("from_week_to_week") }}
|
{{ $t("from_week_to_week") }}
|
||||||
@@ -117,16 +139,27 @@
|
|||||||
</div>
|
</div>
|
||||||
<template v-if="dayOrWeek === 'day'">
|
<template v-if="dayOrWeek === 'day'">
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<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>
|
||||||
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||||
<i class="fa fa-angle-double-right"></i>
|
<i class="fa fa-angle-double-right"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<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>
|
||||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
<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") }}
|
{{ $t("copy_range") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -138,7 +171,11 @@
|
|||||||
id="copyFromWeek"
|
id="copyFromWeek"
|
||||||
class="form-select"
|
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 }}
|
{{ w.text }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -147,14 +184,25 @@
|
|||||||
<i class="fa fa-angle-double-right"></i>
|
<i class="fa fa-angle-double-right"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||||
<select v-model="copyToWeek" id="copyToWeek" class="form-select">
|
<select
|
||||||
<option v-for="w in nextWeeks" :value="w.value" :key="w.value">
|
v-model="copyToWeek"
|
||||||
|
id="copyToWeek"
|
||||||
|
class="form-select"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="w in nextWeeks"
|
||||||
|
:value="w.value"
|
||||||
|
:key="w.value"
|
||||||
|
>
|
||||||
{{ w.text }}
|
{{ w.text }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
<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") }}
|
{{ $t("copy_range") }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -41,7 +41,9 @@ const futureStore = function (): Promise<Store<State>> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
store.commit("me/setWhoAmi", user, { root: true });
|
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, {
|
return store.dispatch("locations/getCurrentLocation", null, {
|
||||||
root: true,
|
root: true,
|
||||||
});
|
});
|
||||||
|
@@ -29,7 +29,10 @@ export default {
|
|||||||
(state: CalendarLocalsState) =>
|
(state: CalendarLocalsState) =>
|
||||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
for (const range of state.localsLoaded) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,7 +54,10 @@ export default {
|
|||||||
});
|
});
|
||||||
state.key = state.key + toAdd.length;
|
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({
|
state.localsLoaded.push({
|
||||||
start: payload.start.getTime(),
|
start: payload.start.getTime(),
|
||||||
end: payload.end.getTime(),
|
end: payload.end.getTime(),
|
||||||
@@ -79,7 +85,11 @@ export default {
|
|||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchCalendarLocalForUser(ctx.rootGetters["me/getMe"], start, end)
|
return fetchCalendarLocalForUser(
|
||||||
|
ctx.rootGetters["me/getMe"],
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
)
|
||||||
.then((remotes: CalendarLight[]) => {
|
.then((remotes: CalendarLight[]) => {
|
||||||
// to be add when reactivity problem will be solve ?
|
// to be add when reactivity problem will be solve ?
|
||||||
//ctx.commit('addRemotes', remotes);
|
//ctx.commit('addRemotes', remotes);
|
||||||
|
@@ -40,7 +40,10 @@ export default {
|
|||||||
(state: CalendarRangesState) =>
|
(state: CalendarRangesState) =>
|
||||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
for (const range of state.rangesLoaded) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +110,9 @@ export default {
|
|||||||
state: CalendarRangesState,
|
state: CalendarRangesState,
|
||||||
externalEvents: (EventInput & { id: string })[],
|
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) => {
|
toAdd.forEach((r) => {
|
||||||
state.rangesIndex.add(r.id);
|
state.rangesIndex.add(r.id);
|
||||||
@@ -115,7 +120,10 @@ export default {
|
|||||||
});
|
});
|
||||||
state.key = state.key + toAdd.length;
|
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({
|
state.rangesLoaded.push({
|
||||||
start: payload.start.getTime(),
|
start: payload.start.getTime(),
|
||||||
end: payload.end.getTime(),
|
end: payload.end.getTime(),
|
||||||
@@ -134,12 +142,17 @@ export default {
|
|||||||
},
|
},
|
||||||
removeRange(state: CalendarRangesState, calendarRangeId: number) {
|
removeRange(state: CalendarRangesState, calendarRangeId: number) {
|
||||||
const found = state.ranges.find(
|
const found = state.ranges.find(
|
||||||
(r) => r.calendarRangeId === calendarRangeId && r.is === "range",
|
(r) =>
|
||||||
|
r.calendarRangeId === calendarRangeId && r.is === "range",
|
||||||
);
|
);
|
||||||
|
|
||||||
if (found !== undefined) {
|
if (found !== undefined) {
|
||||||
state.ranges = state.ranges.filter(
|
state.ranges = state.ranges.filter(
|
||||||
(r) => !(r.calendarRangeId === calendarRangeId && r.is === "range"),
|
(r) =>
|
||||||
|
!(
|
||||||
|
r.calendarRangeId === calendarRangeId &&
|
||||||
|
r.is === "range"
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (typeof found.id === "string") {
|
if (typeof found.id === "string") {
|
||||||
@@ -198,7 +211,11 @@ export default {
|
|||||||
},
|
},
|
||||||
createRange(
|
createRange(
|
||||||
ctx: Context,
|
ctx: Context,
|
||||||
{ start, end, location }: { start: Date; end: Date; location: Location },
|
{
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
location,
|
||||||
|
}: { start: Date; end: Date; location: Location },
|
||||||
): Promise<null> {
|
): Promise<null> {
|
||||||
const url = `/api/1.0/calendar/calendar-range.json?`;
|
const url = `/api/1.0/calendar/calendar-range.json?`;
|
||||||
|
|
||||||
@@ -223,7 +240,11 @@ export default {
|
|||||||
},
|
},
|
||||||
} as CalendarRangeCreate;
|
} as CalendarRangeCreate;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeCreate, CalendarRange>("POST", url, body)
|
return makeFetch<CalendarRangeCreate, CalendarRange>(
|
||||||
|
"POST",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((newRange) => {
|
.then((newRange) => {
|
||||||
ctx.commit("addRange", newRange);
|
ctx.commit("addRange", newRange);
|
||||||
|
|
||||||
@@ -260,7 +281,11 @@ export default {
|
|||||||
},
|
},
|
||||||
} as CalendarRangeEdit;
|
} as CalendarRangeEdit;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeEdit, CalendarRange>("PATCH", url, body)
|
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||||
|
"PATCH",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((range) => {
|
.then((range) => {
|
||||||
ctx.commit("updateRange", range);
|
ctx.commit("updateRange", range);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
@@ -285,7 +310,11 @@ export default {
|
|||||||
},
|
},
|
||||||
} as CalendarRangeEdit;
|
} as CalendarRangeEdit;
|
||||||
|
|
||||||
return makeFetch<CalendarRangeEdit, CalendarRange>("PATCH", url, body)
|
return makeFetch<CalendarRangeEdit, CalendarRange>(
|
||||||
|
"PATCH",
|
||||||
|
url,
|
||||||
|
body,
|
||||||
|
)
|
||||||
.then((range) => {
|
.then((range) => {
|
||||||
ctx.commit("updateRange", range);
|
ctx.commit("updateRange", range);
|
||||||
return Promise.resolve(null);
|
return Promise.resolve(null);
|
||||||
@@ -305,14 +334,20 @@ export default {
|
|||||||
|
|
||||||
for (const r of rangesToCopy) {
|
for (const r of rangesToCopy) {
|
||||||
const start = new Date(ISOToDatetime(r.start) as Date);
|
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);
|
const end = new Date(ISOToDatetime(r.end) as Date);
|
||||||
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
end.setFullYear(to.getFullYear(), to.getMonth(), to.getDate());
|
||||||
const location = ctx.rootGetters["locations/getLocationById"](
|
const location = ctx.rootGetters["locations/getLocationById"](
|
||||||
r.locationId,
|
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));
|
return Promise.all(promises).then(() => Promise.resolve(null));
|
||||||
@@ -334,7 +369,9 @@ export default {
|
|||||||
r.locationId,
|
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));
|
return Promise.all(promises).then(() => Promise.resolve(null));
|
||||||
|
@@ -29,7 +29,10 @@ export default {
|
|||||||
(state: CalendarRemotesState) =>
|
(state: CalendarRemotesState) =>
|
||||||
({ start, end }: { start: Date; end: Date }): boolean => {
|
({ start, end }: { start: Date; end: Date }): boolean => {
|
||||||
for (const range of state.remotesLoaded) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +85,11 @@ export default {
|
|||||||
end: end,
|
end: end,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchCalendarRemoteForUser(ctx.rootGetters["me/getMe"], start, end)
|
return fetchCalendarRemoteForUser(
|
||||||
|
ctx.rootGetters["me/getMe"],
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
)
|
||||||
.then((remotes: CalendarRemote[]) => {
|
.then((remotes: CalendarRemote[]) => {
|
||||||
// to be add when reactivity problem will be solve ?
|
// to be add when reactivity problem will be solve ?
|
||||||
//ctx.commit('addRemotes', remotes);
|
//ctx.commit('addRemotes', remotes);
|
||||||
|
@@ -112,8 +112,11 @@ export default {
|
|||||||
|
|
||||||
results.forEach((i) => {
|
results.forEach((i) => {
|
||||||
if (!users.some((j) => i.user.id === j.id)) {
|
if (!users.some((j) => i.user.id === j.id)) {
|
||||||
let ratio = Math.floor(users.length / COLORS.length);
|
let ratio = Math.floor(
|
||||||
let colorIndex = users.length - ratio * COLORS.length;
|
users.length / COLORS.length,
|
||||||
|
);
|
||||||
|
let colorIndex =
|
||||||
|
users.length - ratio * COLORS.length;
|
||||||
users.push({
|
users.push({
|
||||||
id: i.user.id,
|
id: i.user.id,
|
||||||
username: i.user.username,
|
username: i.user.username,
|
||||||
@@ -150,29 +153,45 @@ export default {
|
|||||||
(me) =>
|
(me) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
this.users.logged = me;
|
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;
|
this.value = currentUser;
|
||||||
|
|
||||||
fetchCalendar(currentUser.id).then(
|
fetchCalendar(currentUser.id).then(
|
||||||
(calendar) =>
|
(calendar) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise(
|
||||||
let results = calendar.results;
|
(resolve, reject) => {
|
||||||
let events = results.map((i) => ({
|
let results =
|
||||||
start: i.startDate.datetime,
|
calendar.results;
|
||||||
end: i.endDate.datetime,
|
let events =
|
||||||
}));
|
results.map(
|
||||||
let calendarEventsCurrentUser = {
|
(i) => ({
|
||||||
|
start: i
|
||||||
|
.startDate
|
||||||
|
.datetime,
|
||||||
|
end: i
|
||||||
|
.endDate
|
||||||
|
.datetime,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
let calendarEventsCurrentUser =
|
||||||
|
{
|
||||||
events: events,
|
events: events,
|
||||||
color: "darkblue",
|
color: "darkblue",
|
||||||
id: 1000,
|
id: 1000,
|
||||||
editable: false,
|
editable: false,
|
||||||
};
|
};
|
||||||
this.calendarEvents.user = calendarEventsCurrentUser;
|
this.calendarEvents.user =
|
||||||
|
calendarEventsCurrentUser;
|
||||||
|
|
||||||
this.selectUsers(currentUser);
|
this.selectUsers(
|
||||||
|
currentUser,
|
||||||
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
}),
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
@@ -190,7 +209,9 @@ export default {
|
|||||||
return `${value.username}`;
|
return `${value.username}`;
|
||||||
},
|
},
|
||||||
coloriseSelectedValues() {
|
coloriseSelectedValues() {
|
||||||
let tags = document.querySelectorAll("div.multiselect__tags-wrap")[0];
|
let tags = document.querySelectorAll(
|
||||||
|
"div.multiselect__tags-wrap",
|
||||||
|
)[0];
|
||||||
|
|
||||||
if (tags.hasChildNodes()) {
|
if (tags.hasChildNodes()) {
|
||||||
let children = tags.childNodes;
|
let children = tags.childNodes;
|
||||||
@@ -211,8 +232,8 @@ export default {
|
|||||||
},
|
},
|
||||||
selectEvents() {
|
selectEvents() {
|
||||||
let selectedUsersId = this.users.selected.map((a) => a.id);
|
let selectedUsersId = this.users.selected.map((a) => a.id);
|
||||||
this.calendarEvents.selected = this.calendarEvents.loaded.filter((a) =>
|
this.calendarEvents.selected = this.calendarEvents.loaded.filter(
|
||||||
selectedUsersId.includes(a.id),
|
(a) => selectedUsersId.includes(a.id),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
selectUsers(value) {
|
selectUsers(value) {
|
||||||
@@ -222,7 +243,9 @@ export default {
|
|||||||
this.updateEventsSource();
|
this.updateEventsSource();
|
||||||
},
|
},
|
||||||
unSelectUsers(value) {
|
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.selectEvents();
|
||||||
this.updateEventsSource();
|
this.updateEventsSource();
|
||||||
},
|
},
|
||||||
|
@@ -24,11 +24,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
|
|
||||||
class CalendarForShortMessageProvider
|
class CalendarForShortMessageProvider
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(private readonly CalendarRepository $calendarRepository, private readonly EntityManagerInterface $em, private readonly RangeGeneratorInterface $rangeGenerator) {}
|
||||||
private readonly CalendarRepository $calendarRepository,
|
|
||||||
private readonly EntityManagerInterface $em,
|
|
||||||
private readonly RangeGeneratorInterface $rangeGenerator,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate calendars instance.
|
* Generate calendars instance.
|
||||||
|
@@ -42,32 +42,6 @@ final class CalendarControllerTest extends WebTestCase
|
|||||||
self::ensureKernelShutdown();
|
self::ensureKernelShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider provideAccompanyingPeriod
|
|
||||||
*/
|
|
||||||
public function testList(int $accompanyingPeriodId)
|
|
||||||
{
|
|
||||||
$this->client->request(
|
|
||||||
Request::METHOD_GET,
|
|
||||||
sprintf('/fr/calendar/calendar/by-period/%d', $accompanyingPeriodId)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider provideAccompanyingPeriod
|
|
||||||
*/
|
|
||||||
public function testNew(int $accompanyingPeriodId)
|
|
||||||
{
|
|
||||||
$this->client->request(
|
|
||||||
Request::METHOD_GET,
|
|
||||||
sprintf('/fr/calendar/calendar/new?accompanying_period_id=%d', $accompanyingPeriodId)
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function provideAccompanyingPeriod(): iterable
|
public static function provideAccompanyingPeriod(): iterable
|
||||||
{
|
{
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
@@ -108,4 +82,30 @@ final class CalendarControllerTest extends WebTestCase
|
|||||||
|
|
||||||
self::ensureKernelShutdown();
|
self::ensureKernelShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideAccompanyingPeriod
|
||||||
|
*/
|
||||||
|
public function testList(int $accompanyingPeriodId)
|
||||||
|
{
|
||||||
|
$this->client->request(
|
||||||
|
Request::METHOD_GET,
|
||||||
|
sprintf('/fr/calendar/calendar/by-period/%d', $accompanyingPeriodId)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideAccompanyingPeriod
|
||||||
|
*/
|
||||||
|
public function testNew(int $accompanyingPeriodId)
|
||||||
|
{
|
||||||
|
$this->client->request(
|
||||||
|
Request::METHOD_GET,
|
||||||
|
sprintf('/fr/calendar/calendar/new?accompanying_period_id=%d', $accompanyingPeriodId)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $this->client->getResponse()->getStatusCode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,6 +45,20 @@ class MSUserAbsenceReaderTest extends TestCase
|
|||||||
self::assertEquals($expected, $absenceReader->isUserAbsent($user), $message);
|
self::assertEquals($expected, $absenceReader->isUserAbsent($user), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIsUserAbsentWithoutRemoteId(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$client = new MockHttpClient();
|
||||||
|
|
||||||
|
$mapUser = $this->prophesize(MapCalendarToUser::class);
|
||||||
|
$mapUser->getUserId($user)->willReturn(null);
|
||||||
|
$clock = new MockClock(new \DateTimeImmutable('2023-07-07T12:00:00'));
|
||||||
|
|
||||||
|
$absenceReader = new MSUserAbsenceReader($client, $mapUser->reveal(), $clock);
|
||||||
|
|
||||||
|
self::assertNull($absenceReader->isUserAbsent($user), 'when no user found, absence should be null');
|
||||||
|
}
|
||||||
|
|
||||||
public static function provideDataTestUserAbsence(): iterable
|
public static function provideDataTestUserAbsence(): iterable
|
||||||
{
|
{
|
||||||
// contains data that was retrieved from microsoft graph api on 2023-07-06
|
// contains data that was retrieved from microsoft graph api on 2023-07-06
|
||||||
@@ -159,18 +173,4 @@ class MSUserAbsenceReaderTest extends TestCase
|
|||||||
'User is absent: absence is always enabled',
|
'User is absent: absence is always enabled',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIsUserAbsentWithoutRemoteId(): void
|
|
||||||
{
|
|
||||||
$user = new User();
|
|
||||||
$client = new MockHttpClient();
|
|
||||||
|
|
||||||
$mapUser = $this->prophesize(MapCalendarToUser::class);
|
|
||||||
$mapUser->getUserId($user)->willReturn(null);
|
|
||||||
$clock = new MockClock(new \DateTimeImmutable('2023-07-07T12:00:00'));
|
|
||||||
|
|
||||||
$absenceReader = new MSUserAbsenceReader($client, $mapUser->reveal(), $clock);
|
|
||||||
|
|
||||||
self::assertNull($absenceReader->isUserAbsent($user), 'when no user found, absence should be null');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -21,6 +21,7 @@ namespace Chill\CalendarBundle\Tests\Service\ShortMessageNotification;
|
|||||||
use Chill\CalendarBundle\Entity\Calendar;
|
use Chill\CalendarBundle\Entity\Calendar;
|
||||||
use Chill\CalendarBundle\Repository\CalendarRepository;
|
use Chill\CalendarBundle\Repository\CalendarRepository;
|
||||||
use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider;
|
use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider;
|
||||||
|
use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultRangeGenerator;
|
||||||
use Chill\CalendarBundle\Service\ShortMessageNotification\RangeGeneratorInterface;
|
use Chill\CalendarBundle\Service\ShortMessageNotification\RangeGeneratorInterface;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
@@ -81,16 +82,10 @@ final class CalendarForShortMessageProviderTest extends TestCase
|
|||||||
$em = $this->prophesize(EntityManagerInterface::class);
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
$em->clear()->shouldBeCalled();
|
$em->clear()->shouldBeCalled();
|
||||||
|
|
||||||
$calendarRangeGenerator = $this->prophesize(RangeGeneratorInterface::class);
|
|
||||||
$calendarRangeGenerator->generateRange(Argument::any())->willReturn([
|
|
||||||
'startDate' => new \DateTimeImmutable('yesterday'),
|
|
||||||
'endDate' => new \DateTimeImmutable('now'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$provider = new CalendarForShortMessageProvider(
|
$provider = new CalendarForShortMessageProvider(
|
||||||
$calendarRepository->reveal(),
|
$calendarRepository->reveal(),
|
||||||
$em->reveal(),
|
$em->reveal(),
|
||||||
$calendarRangeGenerator->reveal(),
|
new DefaultRangeGenerator()
|
||||||
);
|
);
|
||||||
|
|
||||||
$calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now')));
|
$calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now')));
|
||||||
@@ -108,32 +103,26 @@ final class CalendarForShortMessageProviderTest extends TestCase
|
|||||||
Argument::type(\DateTimeImmutable::class),
|
Argument::type(\DateTimeImmutable::class),
|
||||||
Argument::type('int'),
|
Argument::type('int'),
|
||||||
Argument::exact(0)
|
Argument::exact(0)
|
||||||
)->will(static fn ($args) => array_fill(0, 10, new Calendar()))->shouldBeCalledTimes(1);
|
)->will(static fn ($args) => array_fill(0, 1, new Calendar()))->shouldBeCalledTimes(1);
|
||||||
$calendarRepository->findByNotificationAvailable(
|
$calendarRepository->findByNotificationAvailable(
|
||||||
Argument::type(\DateTimeImmutable::class),
|
Argument::type(\DateTimeImmutable::class),
|
||||||
Argument::type(\DateTimeImmutable::class),
|
Argument::type(\DateTimeImmutable::class),
|
||||||
Argument::type('int'),
|
Argument::type('int'),
|
||||||
Argument::exact(10)
|
Argument::not(0)
|
||||||
)->will(static fn ($args) => [])->shouldBeCalledTimes(1);
|
)->will(static fn ($args) => [])->shouldBeCalledTimes(1);
|
||||||
|
|
||||||
$em = $this->prophesize(EntityManagerInterface::class);
|
$em = $this->prophesize(EntityManagerInterface::class);
|
||||||
$em->clear()->shouldBeCalled();
|
$em->clear()->shouldBeCalled();
|
||||||
|
|
||||||
$calendarRangeGenerator = $this->prophesize(RangeGeneratorInterface::class);
|
|
||||||
$calendarRangeGenerator->generateRange(Argument::any())->willReturn([
|
|
||||||
'startDate' => new \DateTimeImmutable('yesterday'),
|
|
||||||
'endDate' => new \DateTimeImmutable('now'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$provider = new CalendarForShortMessageProvider(
|
$provider = new CalendarForShortMessageProvider(
|
||||||
$calendarRepository->reveal(),
|
$calendarRepository->reveal(),
|
||||||
$em->reveal(),
|
$em->reveal(),
|
||||||
$calendarRangeGenerator->reveal(),
|
new DefaultRangeGenerator()
|
||||||
);
|
);
|
||||||
|
|
||||||
$calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now')));
|
$calendars = iterator_to_array($provider->getCalendars(new \DateTimeImmutable('now')));
|
||||||
|
|
||||||
$this->assertEquals(10, \count($calendars));
|
$this->assertEquals(1, \count($calendars));
|
||||||
$this->assertContainsOnly(Calendar::class, $calendars);
|
$this->assertContainsOnly(Calendar::class, $calendars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -28,24 +28,6 @@ use PHPUnit\Framework\TestCase;
|
|||||||
*/
|
*/
|
||||||
final class DefaultRangeGeneratorTest extends TestCase
|
final class DefaultRangeGeneratorTest extends TestCase
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @dataProvider generateData
|
|
||||||
*/
|
|
||||||
public function testGenerateRange(\DateTimeImmutable $date, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate)
|
|
||||||
{
|
|
||||||
$generator = new DefaultRangeGenerator();
|
|
||||||
|
|
||||||
['startDate' => $actualStartDate, 'endDate' => $actualEndDate] = $generator->generateRange($date);
|
|
||||||
|
|
||||||
if (null === $startDate) {
|
|
||||||
$this->assertNull($actualStartDate);
|
|
||||||
$this->assertNull($actualEndDate);
|
|
||||||
} else {
|
|
||||||
$this->assertEquals($startDate->format(\DateTimeImmutable::ATOM), $actualStartDate->format(\DateTimeImmutable::ATOM));
|
|
||||||
$this->assertEquals($endDate->format(\DateTimeImmutable::ATOM), $actualEndDate->format(\DateTimeImmutable::ATOM));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * Lundi => Envoi des rdv du mardi et mercredi.
|
* * Lundi => Envoi des rdv du mardi et mercredi.
|
||||||
* * Mardi => Envoi des rdv du jeudi.
|
* * Mardi => Envoi des rdv du jeudi.
|
||||||
@@ -97,4 +79,22 @@ final class DefaultRangeGeneratorTest extends TestCase
|
|||||||
null,
|
null,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateData
|
||||||
|
*/
|
||||||
|
public function testGenerateRange(\DateTimeImmutable $date, ?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate)
|
||||||
|
{
|
||||||
|
$generator = new DefaultRangeGenerator();
|
||||||
|
|
||||||
|
['startDate' => $actualStartDate, 'endDate' => $actualEndDate] = $generator->generateRange($date);
|
||||||
|
|
||||||
|
if (null === $startDate) {
|
||||||
|
$this->assertNull($actualStartDate);
|
||||||
|
$this->assertNull($actualEndDate);
|
||||||
|
} else {
|
||||||
|
$this->assertEquals($startDate->format(\DateTimeImmutable::ATOM), $actualStartDate->format(\DateTimeImmutable::ATOM));
|
||||||
|
$this->assertEquals($endDate->format(\DateTimeImmutable::ATOM), $actualEndDate->format(\DateTimeImmutable::ATOM));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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]);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -49,6 +49,80 @@ final class CustomFieldsChoiceTest extends KernelTestCase
|
|||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provide empty data in different possible representations.
|
||||||
|
* Those data are supposed to be deserialized.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function emptyDataProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
// 0
|
||||||
|
[
|
||||||
|
// signle
|
||||||
|
'',
|
||||||
|
],
|
||||||
|
// 1
|
||||||
|
[
|
||||||
|
// single
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
// 2
|
||||||
|
[
|
||||||
|
// signle with allow other
|
||||||
|
['_other' => 'something', '_choices' => ''],
|
||||||
|
],
|
||||||
|
// 3
|
||||||
|
[
|
||||||
|
// multiple
|
||||||
|
[],
|
||||||
|
],
|
||||||
|
// 4
|
||||||
|
[
|
||||||
|
// multiple with allow other
|
||||||
|
['_other' => 'something', '_choices' => []],
|
||||||
|
],
|
||||||
|
// 5
|
||||||
|
[
|
||||||
|
// multiple with allow other
|
||||||
|
['_other' => '', '_choices' => []],
|
||||||
|
],
|
||||||
|
// 6
|
||||||
|
[
|
||||||
|
// empty
|
||||||
|
['_other' => null, '_choices' => null],
|
||||||
|
],
|
||||||
|
// 7
|
||||||
|
[
|
||||||
|
// empty
|
||||||
|
[null],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function serializedRepresentationDataProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
// multiple => false, allow_other => false
|
||||||
|
'my-value',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
// multiple => true, allow_ther => false
|
||||||
|
['my-value'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
// multiple => false, allow_other => true, current value not in other
|
||||||
|
['_other' => '', '_choices' => 'my-value'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
// multiple => true, allow_other => true, current value not in other
|
||||||
|
['_other' => '', '_choices' => ['my-value']],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the representation of the data is deserialized to an array text
|
* Test if the representation of the data is deserialized to an array text
|
||||||
* with an "allow_other" field.
|
* with an "allow_other" field.
|
||||||
@@ -338,58 +412,6 @@ final class CustomFieldsChoiceTest extends KernelTestCase
|
|||||||
$this->assertTrue($isEmpty);
|
$this->assertTrue($isEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* provide empty data in different possible representations.
|
|
||||||
* Those data are supposed to be deserialized.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public static function emptyDataProvider()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
// 0
|
|
||||||
[
|
|
||||||
// signle
|
|
||||||
'',
|
|
||||||
],
|
|
||||||
// 1
|
|
||||||
[
|
|
||||||
// single
|
|
||||||
null,
|
|
||||||
],
|
|
||||||
// 2
|
|
||||||
[
|
|
||||||
// signle with allow other
|
|
||||||
['_other' => 'something', '_choices' => ''],
|
|
||||||
],
|
|
||||||
// 3
|
|
||||||
[
|
|
||||||
// multiple
|
|
||||||
[],
|
|
||||||
],
|
|
||||||
// 4
|
|
||||||
[
|
|
||||||
// multiple with allow other
|
|
||||||
['_other' => 'something', '_choices' => []],
|
|
||||||
],
|
|
||||||
// 5
|
|
||||||
[
|
|
||||||
// multiple with allow other
|
|
||||||
['_other' => '', '_choices' => []],
|
|
||||||
],
|
|
||||||
// 6
|
|
||||||
[
|
|
||||||
// empty
|
|
||||||
['_other' => null, '_choices' => null],
|
|
||||||
],
|
|
||||||
// 7
|
|
||||||
[
|
|
||||||
// empty
|
|
||||||
[null],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// ///////////////////////////////////////
|
// ///////////////////////////////////////
|
||||||
//
|
//
|
||||||
// test function isEmptyValue
|
// test function isEmptyValue
|
||||||
@@ -413,28 +435,6 @@ final class CustomFieldsChoiceTest extends KernelTestCase
|
|||||||
$this->assertFalse($isEmpty);
|
$this->assertFalse($isEmpty);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function serializedRepresentationDataProvider()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
[
|
|
||||||
// multiple => false, allow_other => false
|
|
||||||
'my-value',
|
|
||||||
],
|
|
||||||
[
|
|
||||||
// multiple => true, allow_ther => false
|
|
||||||
['my-value'],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
// multiple => false, allow_other => true, current value not in other
|
|
||||||
['_other' => '', '_choices' => 'my-value'],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
// multiple => true, allow_other => true, current value not in other
|
|
||||||
['_other' => '', '_choices' => ['my-value']],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $options
|
* @param array $options
|
||||||
*
|
*
|
||||||
|
@@ -127,7 +127,3 @@ services:
|
|||||||
factory: ["@doctrine", getRepository]
|
factory: ["@doctrine", getRepository]
|
||||||
arguments:
|
arguments:
|
||||||
- "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
|
- "Chill\\CustomFieldsBundle\\Entity\\CustomFieldLongChoice\\Option"
|
||||||
|
|
||||||
Chill\CustomFieldsBundle\EntityRepository\CustomFieldsDefaultGroupRepository:
|
|
||||||
autowire: true
|
|
||||||
autoconfigure: true
|
|
||||||
|
@@ -20,7 +20,10 @@
|
|||||||
</option>
|
</option>
|
||||||
<template v-for="t in templates" :key="t.id">
|
<template v-for="t in templates" :key="t.id">
|
||||||
<option :value="t.id">
|
<option :value="t.id">
|
||||||
{{ localizeString(t.name) || "Aucun nom défini" }}
|
{{
|
||||||
|
localizeString(t.name) ||
|
||||||
|
"Aucun nom défini"
|
||||||
|
}}
|
||||||
</option>
|
</option>
|
||||||
</template>
|
</template>
|
||||||
</select>
|
</select>
|
||||||
@@ -28,7 +31,9 @@
|
|||||||
v-if="canGenerate"
|
v-if="canGenerate"
|
||||||
class="btn btn-update btn-sm change-icon"
|
class="btn btn-update btn-sm change-icon"
|
||||||
:href="buildUrlGenerate"
|
:href="buildUrlGenerate"
|
||||||
@click.prevent="clickGenerate($event, buildUrlGenerate)"
|
@click.prevent="
|
||||||
|
clickGenerate($event, buildUrlGenerate)
|
||||||
|
"
|
||||||
><i class="fa fa-fw fa-cog"
|
><i class="fa fa-fw fa-cog"
|
||||||
/></a>
|
/></a>
|
||||||
<a
|
<a
|
||||||
@@ -53,7 +58,6 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { buildLink } from "ChillDocGeneratorAssets/lib/document-generator";
|
import { buildLink } from "ChillDocGeneratorAssets/lib/document-generator";
|
||||||
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "PickTemplate",
|
name: "PickTemplate",
|
||||||
@@ -109,9 +113,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
localizeString(str) {
|
|
||||||
return localizeString(str);
|
|
||||||
},
|
|
||||||
clickGenerate(event, link) {
|
clickGenerate(event, link) {
|
||||||
if (!this.preventDefaultMoveToGenerate) {
|
if (!this.preventDefaultMoveToGenerate) {
|
||||||
window.location.assign(link);
|
window.location.assign(link);
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
{{ 'docgen.data_dump_email.Dear'|trans }}
|
{{ 'docgen.data_dump_email.Dear'|trans }}
|
||||||
|
|
||||||
{{ 'docgen.data_dump_email.data_dump_ready_and_attached'|trans }}
|
{{ 'docgen.data_dump_email.data_dump_ready_and_link'|trans }}
|
||||||
|
|
||||||
{{ 'docgen.data_dump_email.filename'|trans({filename: filename}) }}
|
{{ link }}
|
||||||
|
|
||||||
|
{{ 'docgen.data_dump_email.link_valid_until'|trans({validity: validity}) }}
|
||||||
|
@@ -11,13 +11,13 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Chill\DocGeneratorBundle\Service\Messenger;
|
namespace Chill\DocGeneratorBundle\Service\Messenger;
|
||||||
|
|
||||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
|
||||||
|
use Chill\DocGeneratorBundle\Service\Generator\Generator;
|
||||||
use Chill\DocGeneratorBundle\Service\Generator\GeneratorException;
|
use Chill\DocGeneratorBundle\Service\Generator\GeneratorException;
|
||||||
use Chill\DocGeneratorBundle\Service\Generator\GeneratorInterface;
|
use Chill\DocStoreBundle\AsyncUpload\TempUrlGeneratorInterface;
|
||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
use Chill\DocStoreBundle\Entity\StoredObject;
|
||||||
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
||||||
use Chill\DocStoreBundle\Repository\StoredObjectRepositoryInterface;
|
use Chill\DocStoreBundle\Repository\StoredObjectRepository;
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
|
||||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@@ -37,15 +37,15 @@ class RequestGenerationHandler implements MessageHandlerInterface
|
|||||||
private const LOG_PREFIX = '[docgen message handler] ';
|
private const LOG_PREFIX = '[docgen message handler] ';
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly DocGeneratorTemplateRepositoryInterface $docGeneratorTemplateRepository,
|
private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
|
||||||
private readonly EntityManagerInterface $entityManager,
|
private readonly EntityManagerInterface $entityManager,
|
||||||
private readonly GeneratorInterface $generator,
|
private readonly Generator $generator,
|
||||||
private readonly LoggerInterface $logger,
|
private readonly LoggerInterface $logger,
|
||||||
private readonly StoredObjectRepositoryInterface $storedObjectRepository,
|
private readonly StoredObjectRepository $storedObjectRepository,
|
||||||
private readonly UserRepositoryInterface $userRepository,
|
private readonly UserRepositoryInterface $userRepository,
|
||||||
private readonly MailerInterface $mailer,
|
private readonly MailerInterface $mailer,
|
||||||
|
private readonly TempUrlGeneratorInterface $tempUrlGenerator,
|
||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
private readonly StoredObjectManagerInterface $storedObjectManager,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function __invoke(RequestGenerationMessage $message)
|
public function __invoke(RequestGenerationMessage $message)
|
||||||
@@ -90,7 +90,7 @@ class RequestGenerationHandler implements MessageHandlerInterface
|
|||||||
|
|
||||||
$this->sendDataDump($destinationStoredObject, $message);
|
$this->sendDataDump($destinationStoredObject, $message);
|
||||||
} else {
|
} else {
|
||||||
$this->generator->generateDocFromTemplate(
|
$destinationStoredObject = $this->generator->generateDocFromTemplate(
|
||||||
$template,
|
$template,
|
||||||
$message->getEntityId(),
|
$message->getEntityId(),
|
||||||
$message->getContextGenerationData(),
|
$message->getContextGenerationData(),
|
||||||
@@ -122,20 +122,19 @@ class RequestGenerationHandler implements MessageHandlerInterface
|
|||||||
|
|
||||||
private function sendDataDump(StoredObject $destinationStoredObject, RequestGenerationMessage $message): void
|
private function sendDataDump(StoredObject $destinationStoredObject, RequestGenerationMessage $message): void
|
||||||
{
|
{
|
||||||
// Get the content of the document
|
$url = $this->tempUrlGenerator->generate('GET', $destinationStoredObject->getFilename(), 3600);
|
||||||
$content = $this->storedObjectManager->read($destinationStoredObject);
|
$parts = [];
|
||||||
$filename = $destinationStoredObject->getFilename();
|
parse_str(parse_url($url->url)['query'], $parts);
|
||||||
$contentType = $destinationStoredObject->getType();
|
$validity = \DateTimeImmutable::createFromFormat('U', $parts['temp_url_expires']);
|
||||||
|
|
||||||
// Create the email with the document as an attachment
|
|
||||||
$email = (new TemplatedEmail())
|
$email = (new TemplatedEmail())
|
||||||
->to($message->getSendResultToEmail())
|
->to($message->getSendResultToEmail())
|
||||||
->textTemplate('@ChillDocGenerator/Email/send_data_dump_to_admin.txt.twig')
|
->textTemplate('@ChillDocGenerator/Email/send_data_dump_to_admin.txt.twig')
|
||||||
->context([
|
->context([
|
||||||
'filename' => $filename,
|
'link' => $url->url,
|
||||||
|
'validity' => $validity,
|
||||||
])
|
])
|
||||||
->subject($this->translator->trans('docgen.data_dump_email.subject'))
|
->subject($this->translator->trans('docgen.data_dump_email.subject'));
|
||||||
->attach($content, $filename, $contentType);
|
|
||||||
|
|
||||||
$this->mailer->send($email);
|
$this->mailer->send($email);
|
||||||
}
|
}
|
||||||
|
@@ -1,132 +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\DocGeneratorBundle\Tests\Service\Messenger;
|
|
||||||
|
|
||||||
use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate;
|
|
||||||
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepositoryInterface;
|
|
||||||
use Chill\DocGeneratorBundle\Service\Generator\GeneratorInterface;
|
|
||||||
use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationHandler;
|
|
||||||
use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage;
|
|
||||||
use Chill\DocStoreBundle\Entity\StoredObject;
|
|
||||||
use Chill\DocStoreBundle\Repository\StoredObjectRepositoryInterface;
|
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
|
||||||
use Chill\MainBundle\Entity\User;
|
|
||||||
use Chill\MainBundle\Repository\UserRepositoryInterface;
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
use Doctrine\ORM\Query;
|
|
||||||
use PHPUnit\Framework\TestCase;
|
|
||||||
use Prophecy\Argument;
|
|
||||||
use Prophecy\PhpUnit\ProphecyTrait;
|
|
||||||
use Psr\Log\NullLogger;
|
|
||||||
use Symfony\Component\Mailer\MailerInterface;
|
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*
|
|
||||||
* @coversNothing
|
|
||||||
*/
|
|
||||||
class RequestGenerationHandlerTest extends TestCase
|
|
||||||
{
|
|
||||||
use ProphecyTrait;
|
|
||||||
|
|
||||||
public function testGenerationHappyScenario(): void
|
|
||||||
{
|
|
||||||
// Create entities
|
|
||||||
$template = new DocGeneratorTemplate();
|
|
||||||
$this->setPrivateProperty($template, 'id', 1);
|
|
||||||
|
|
||||||
$storedObject = new StoredObject();
|
|
||||||
$this->setPrivateProperty($storedObject, 'id', 2);
|
|
||||||
|
|
||||||
$creator = new User();
|
|
||||||
$creator->setEmail('test@example.com');
|
|
||||||
$this->setPrivateProperty($creator, 'id', 3);
|
|
||||||
|
|
||||||
$docGeneratorTemplateRepository = $this->prophesize(DocGeneratorTemplateRepositoryInterface::class);
|
|
||||||
$docGeneratorTemplateRepository->find(1)->willReturn($template);
|
|
||||||
|
|
||||||
$storedObjectRepository = $this->prophesize(StoredObjectRepositoryInterface::class);
|
|
||||||
$storedObjectRepository->find(2)->willReturn($storedObject);
|
|
||||||
|
|
||||||
$userRepository = $this->prophesize(UserRepositoryInterface::class);
|
|
||||||
$userRepository->find(3)->willReturn($creator);
|
|
||||||
|
|
||||||
// Create a mock for the Query object
|
|
||||||
$query = $this->prophesize(Query::class);
|
|
||||||
$query->setParameter('id', 2)->willReturn($query->reveal());
|
|
||||||
$query->execute()->shouldBeCalled();
|
|
||||||
|
|
||||||
// Create a mock for the EntityManager
|
|
||||||
$entityManager = $this->prophesize(EntityManagerInterface::class);
|
|
||||||
$entityManager->createQuery(Argument::containingString('UPDATE'))->willReturn($query->reveal());
|
|
||||||
$entityManager->flush()->shouldBeCalled();
|
|
||||||
|
|
||||||
$generator = $this->prophesize(GeneratorInterface::class);
|
|
||||||
$generator->generateDocFromTemplate(
|
|
||||||
$template,
|
|
||||||
123, // entityId
|
|
||||||
['key' => 'value'], // contextGenerationData
|
|
||||||
$storedObject,
|
|
||||||
$creator
|
|
||||||
)
|
|
||||||
->willReturn($storedObject)->shouldBeCalled();
|
|
||||||
|
|
||||||
$logger = new NullLogger();
|
|
||||||
|
|
||||||
$mailer = $this->prophesize(MailerInterface::class);
|
|
||||||
|
|
||||||
$translator = $this->prophesize(TranslatorInterface::class);
|
|
||||||
|
|
||||||
$storedObjectManager = $this->prophesize(StoredObjectManagerInterface::class);
|
|
||||||
|
|
||||||
// Create handler
|
|
||||||
$handler = new RequestGenerationHandler(
|
|
||||||
$docGeneratorTemplateRepository->reveal(),
|
|
||||||
$entityManager->reveal(),
|
|
||||||
$generator->reveal(),
|
|
||||||
$logger,
|
|
||||||
$storedObjectRepository->reveal(),
|
|
||||||
$userRepository->reveal(),
|
|
||||||
$mailer->reveal(),
|
|
||||||
$translator->reveal(),
|
|
||||||
$storedObjectManager->reveal()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Create message
|
|
||||||
$message = new RequestGenerationMessage(
|
|
||||||
$creator,
|
|
||||||
$template,
|
|
||||||
123, // entityId
|
|
||||||
$storedObject,
|
|
||||||
['key' => 'value'], // contextGenerationData
|
|
||||||
false, // isTest
|
|
||||||
null, // sendResultToEmail
|
|
||||||
false // dumpOnly
|
|
||||||
);
|
|
||||||
|
|
||||||
// Invoke handler
|
|
||||||
$handler->__invoke($message);
|
|
||||||
|
|
||||||
// Assertions
|
|
||||||
// The assertions are handled by the shouldBeCalled() expectations on the mocks
|
|
||||||
$this->assertTrue(true); // Just to have an assertion in the test
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setPrivateProperty(object $object, string $propertyName, $value): void
|
|
||||||
{
|
|
||||||
$reflection = new \ReflectionClass($object);
|
|
||||||
$property = $reflection->getProperty($propertyName);
|
|
||||||
$property->setAccessible(true);
|
|
||||||
$property->setValue($object, $value);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -31,36 +31,6 @@ final class DocGenEncoderTest extends TestCase
|
|||||||
$this->encoder = new DocGenEncoder();
|
$this->encoder = new DocGenEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEmbeddedLoopsThrowsException()
|
|
||||||
{
|
|
||||||
$this->expectException(UnexpectedValueException::class);
|
|
||||||
|
|
||||||
$data = [
|
|
||||||
'data' => [
|
|
||||||
['item' => 'one'],
|
|
||||||
[
|
|
||||||
'embedded' => [
|
|
||||||
[
|
|
||||||
['subitem' => 'two'],
|
|
||||||
['subitem' => 'three'],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$this->encoder->encode($data, 'docgen');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider generateEncodeData
|
|
||||||
*/
|
|
||||||
public function testEncode(mixed $expected, mixed $data, string $msg)
|
|
||||||
{
|
|
||||||
$generated = $this->encoder->encode($data, 'docgen');
|
|
||||||
$this->assertEquals($expected, $generated, $msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function generateEncodeData()
|
public static function generateEncodeData()
|
||||||
{
|
{
|
||||||
yield [['tests' => 'ok'], ['tests' => 'ok'], 'A simple test with a simple array'];
|
yield [['tests' => 'ok'], ['tests' => 'ok'], 'A simple test with a simple array'];
|
||||||
@@ -123,4 +93,34 @@ final class DocGenEncoderTest extends TestCase
|
|||||||
'a longer list, with near real data inside and embedded associative arrays',
|
'a longer list, with near real data inside and embedded associative arrays',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testEmbeddedLoopsThrowsException()
|
||||||
|
{
|
||||||
|
$this->expectException(UnexpectedValueException::class);
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'data' => [
|
||||||
|
['item' => 'one'],
|
||||||
|
[
|
||||||
|
'embedded' => [
|
||||||
|
[
|
||||||
|
['subitem' => 'two'],
|
||||||
|
['subitem' => 'three'],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
$this->encoder->encode($data, 'docgen');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider generateEncodeData
|
||||||
|
*/
|
||||||
|
public function testEncode(mixed $expected, mixed $data, string $msg)
|
||||||
|
{
|
||||||
|
$generated = $this->encoder->encode($data, 'docgen');
|
||||||
|
$this->assertEquals($expected, $generated, $msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,2 +1,4 @@
|
|||||||
docgen:
|
docgen:
|
||||||
# No ICU messages needed for data_dump_email anymore
|
data_dump_email:
|
||||||
|
link_valid_until: >-
|
||||||
|
Ce lien est valide jusqu'au {validity, date, full}, {validity, time, medium}
|
||||||
|
@@ -34,10 +34,8 @@ docgen:
|
|||||||
data_dump_email:
|
data_dump_email:
|
||||||
subject: Contenu des données de génération de document disponible
|
subject: Contenu des données de génération de document disponible
|
||||||
Dear: Cher
|
Dear: Cher
|
||||||
data_dump_ready_and_attached: >-
|
data_dump_ready_and_link: >-
|
||||||
Le contenu des données est disponible. Vous le trouverez en pièce jointe à cet email.
|
Le contenu des données est disponible. Vous pouvez le télécharger à l'aide du lien suivant:
|
||||||
filename: >-
|
|
||||||
Nom du fichier: %filename%
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,7 +18,6 @@ use Chill\DocStoreBundle\Exception\StoredObjectManagerException;
|
|||||||
use Chill\DocStoreBundle\Service\Cryptography\KeyGenerator;
|
use Chill\DocStoreBundle\Service\Cryptography\KeyGenerator;
|
||||||
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
use Chill\DocStoreBundle\Service\StoredObjectManagerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||||
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
|
|
||||||
use Symfony\Component\Filesystem\Filesystem;
|
use Symfony\Component\Filesystem\Filesystem;
|
||||||
use Symfony\Component\Filesystem\Path;
|
use Symfony\Component\Filesystem\Path;
|
||||||
|
|
||||||
@@ -148,11 +147,16 @@ class StoredObjectManager implements StoredObjectManagerInterface
|
|||||||
public function writeContent(string $filename, string $encryptedContent): void
|
public function writeContent(string $filename, string $encryptedContent): void
|
||||||
{
|
{
|
||||||
$fullPath = $this->buildPath($filename);
|
$fullPath = $this->buildPath($filename);
|
||||||
|
$dir = Path::getDirectory($fullPath);
|
||||||
|
|
||||||
try {
|
if (!$this->filesystem->exists($dir)) {
|
||||||
$this->filesystem->dumpFile($fullPath, $encryptedContent);
|
$this->filesystem->mkdir($dir);
|
||||||
} catch (IOExceptionInterface $exception) {
|
}
|
||||||
throw StoredObjectManagerException::unableToStoreDocumentOnDisk($exception);
|
|
||||||
|
$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 inputTitle = collectionEntry?.querySelector("input[type='text']");
|
||||||
|
|
||||||
const input_stored_object: HTMLInputElement | null = divElement.querySelector(
|
const input_stored_object: HTMLInputElement | null =
|
||||||
"input[data-stored-object]",
|
divElement.querySelector("input[data-stored-object]");
|
||||||
);
|
|
||||||
if (null === input_stored_object) {
|
if (null === input_stored_object) {
|
||||||
throw new Error("input to stored object not found");
|
throw new Error("input to stored object not found");
|
||||||
}
|
}
|
||||||
@@ -54,7 +53,9 @@ const startApp = (
|
|||||||
console.log("version added", stored_object_version);
|
console.log("version added", stored_object_version);
|
||||||
this.$data.existingDoc = stored_object;
|
this.$data.existingDoc = stored_object;
|
||||||
this.$data.existingDoc.currentVersion = stored_object_version;
|
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) {
|
||||||
if (!this.$data.inputTitle?.value) {
|
if (!this.$data.inputTitle?.value) {
|
||||||
this.$data.inputTitle.value = file_name;
|
this.$data.inputTitle.value = file_name;
|
||||||
|
@@ -49,7 +49,9 @@
|
|||||||
<li v-if="isHistoryViewable">
|
<li v-if="isHistoryViewable">
|
||||||
<history-button
|
<history-button
|
||||||
:stored-object="props.storedObject"
|
:stored-object="props.storedObject"
|
||||||
:can-edit="canEdit && props.storedObject._permissions.canEdit"
|
:can-edit="
|
||||||
|
canEdit && props.storedObject._permissions.canEdit
|
||||||
|
"
|
||||||
></history-button>
|
></history-button>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -127,7 +129,9 @@ const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
|
|||||||
canDownload: true,
|
canDownload: true,
|
||||||
canConvertPdf: true,
|
canConvertPdf: true,
|
||||||
returnPath:
|
returnPath:
|
||||||
window.location.pathname + window.location.search + window.location.hash,
|
window.location.pathname +
|
||||||
|
window.location.search +
|
||||||
|
window.location.hash,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -29,7 +29,9 @@
|
|||||||
</modal>
|
</modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
<div class="col-12 m-auto sticky-top">
|
<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">
|
<div class="col-5 text-center turn-page">
|
||||||
<select
|
<select
|
||||||
class="form-select form-select-sm"
|
class="form-select form-select-sm"
|
||||||
@@ -90,7 +92,10 @@
|
|||||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
class="col-5 p-0 text-center turnSignature"
|
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) }}
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -145,7 +150,10 @@
|
|||||||
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
:title="trans(SIGNATURES_ADD_SIGN_ZONE)"
|
||||||
>
|
>
|
||||||
<template v-if="canvasEvent === 'add'">
|
<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>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -199,7 +207,10 @@
|
|||||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
class="col-4 d-xl-none text-center turnSignature p-0"
|
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) }}
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -227,7 +238,10 @@
|
|||||||
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
v-if="signature.zones.length === 1 && signedState !== 'signed'"
|
||||||
class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
|
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) }}
|
{{ trans(SIGNATURES_GO_TO_SIGNATURE_UNIQUE) }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -285,7 +299,10 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ trans(SIGNATURES_CLICK_ON_DOCUMENT) }}
|
{{ 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>
|
<span class="visually-hidden">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -545,8 +562,14 @@ const addCanvasEvents = () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement;
|
const canvas = document.querySelectorAll(
|
||||||
canvas.addEventListener("pointerup", (e) => canvasClick(e, canvas), false);
|
"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) <
|
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
|
||||||
xy[1] &&
|
xy[1] &&
|
||||||
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;
|
zone.PDFPage.height * zoom.value;
|
||||||
|
|
||||||
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
|
||||||
@@ -598,7 +625,8 @@ const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
|
|||||||
signature.zones
|
signature.zones
|
||||||
.filter(
|
.filter(
|
||||||
(z) =>
|
(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),
|
(z.PDFPage.index + 1 === page.value && !multiPage.value),
|
||||||
)
|
)
|
||||||
.map((z) => {
|
.map((z) => {
|
||||||
|
@@ -153,10 +153,12 @@ const handleFile = async (file: File): Promise<void> => {
|
|||||||
</p>
|
</p>
|
||||||
<!-- todo i18n -->
|
<!-- todo i18n -->
|
||||||
<p v-if="has_existing_doc">
|
<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>
|
||||||
<p v-else>
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="waiting">
|
<div v-else class="waiting">
|
||||||
|
@@ -35,7 +35,9 @@ async function download_and_open(event: Event): Promise<void> {
|
|||||||
if (null === state.content) {
|
if (null === state.content) {
|
||||||
event.preventDefault();
|
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);
|
state.content = window.URL.createObjectURL(raw);
|
||||||
|
|
||||||
button.href = 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">
|
<modal v-if="state.modalOpened" @close="state.modalOpened = false">
|
||||||
<template v-slot:body>
|
<template v-slot:body>
|
||||||
<div class="desktop-edit">
|
<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>
|
<p>
|
||||||
<strong>{{ editionUntilFormatted }}</strong>
|
<strong>{{ editionUntilFormatted }}</strong>
|
||||||
</p>
|
</p>
|
||||||
@@ -55,21 +57,23 @@ const editionUntilFormatted = computed<string>(() => {
|
|||||||
|
|
||||||
<p>
|
<p>
|
||||||
<small
|
<small
|
||||||
>Le document peut être édité uniquement en utilisant Libre
|
>Le document peut être édité uniquement en utilisant
|
||||||
Office.</small
|
Libre Office.</small
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<small
|
<small
|
||||||
>En cas d'échec lors de l'enregistrement, sauver le document sur
|
>En cas d'échec lors de l'enregistrement, sauver le
|
||||||
le poste de travail avant de le déposer à nouveau ici.</small
|
document sur le poste de travail avant de le déposer
|
||||||
|
à nouveau ici.</small
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<small
|
<small
|
||||||
>Vous pouvez naviguez sur d'autres pages pendant l'édition.</small
|
>Vous pouvez naviguez sur d'autres pages pendant
|
||||||
|
l'édition.</small
|
||||||
>
|
>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -95,7 +95,10 @@ async function download_and_open(): Promise<void> {
|
|||||||
let raw;
|
let raw;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
raw = await download_and_decrypt_doc(props.storedObject, props.atVersion);
|
raw = await download_and_decrypt_doc(
|
||||||
|
props.storedObject,
|
||||||
|
props.atVersion,
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("error while downloading and decrypting document");
|
console.error("error while downloading and decrypting document");
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
@@ -49,7 +49,8 @@ const isRestored = computed<boolean>(
|
|||||||
);
|
);
|
||||||
|
|
||||||
const isDuplicated = 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<{
|
const classes = computed<{
|
||||||
@@ -69,9 +70,16 @@ const classes = computed<{
|
|||||||
<div :class="classes">
|
<div :class="classes">
|
||||||
<div
|
<div
|
||||||
class="col-12 tags"
|
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"
|
<span class="badge bg-info" v-if="isKeptBeforeConversion"
|
||||||
>Conservée avant conversion dans un autre format</span
|
>Conservée avant conversion dans un autre format</span
|
||||||
>
|
>
|
||||||
@@ -88,17 +96,21 @@ const classes = computed<{
|
|||||||
<span
|
<span
|
||||||
><strong> #{{ version.version + 1 }} </strong></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-if="version.version == 0">créé par</strong
|
||||||
><strong v-else>modifié par</strong>
|
><strong v-else>modifié par</strong>
|
||||||
<span class="badge-user"
|
<span class="badge-user"
|
||||||
><UserRenderBoxBadge :user="version.createdBy"></UserRenderBoxBadge
|
><UserRenderBoxBadge
|
||||||
|
:user="version.createdBy"
|
||||||
|
></UserRenderBoxBadge
|
||||||
></span>
|
></span>
|
||||||
<strong>à</strong>
|
<strong>à</strong>
|
||||||
{{
|
{{
|
||||||
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
||||||
}}</template
|
}}</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-if="version.version == 0">Créé le</strong
|
||||||
><strong v-else>modifié le</strong>
|
><strong v-else>modifié le</strong>
|
||||||
{{
|
{{
|
||||||
|
@@ -2,7 +2,9 @@
|
|||||||
<a
|
<a
|
||||||
:class="Object.assign(props.classes, { btn: true })"
|
:class="Object.assign(props.classes, { btn: true })"
|
||||||
@click="beforeLeave($event)"
|
@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>
|
<i class="fa fa-paragraph"></i>
|
||||||
Editer en ligne
|
Editer en ligne
|
||||||
|
@@ -145,7 +145,9 @@ async function download_info_link(
|
|||||||
function build_wopi_editor_link(uuid: string, returnPath?: string) {
|
function build_wopi_editor_link(uuid: string, returnPath?: string) {
|
||||||
if (returnPath === undefined) {
|
if (returnPath === undefined) {
|
||||||
returnPath =
|
returnPath =
|
||||||
window.location.pathname + window.location.search + window.location.hash;
|
window.location.pathname +
|
||||||
|
window.location.search +
|
||||||
|
window.location.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -184,7 +186,10 @@ async function download_and_decrypt_doc(
|
|||||||
) {
|
) {
|
||||||
downloadInfo = storedObject._links.downloadLink;
|
downloadInfo = storedObject._links.downloadLink;
|
||||||
} else {
|
} else {
|
||||||
downloadInfo = await download_info_link(storedObject, atVersionToDownload);
|
downloadInfo = await download_info_link(
|
||||||
|
storedObject,
|
||||||
|
atVersionToDownload,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawResponse = await window.fetch(downloadInfo.url);
|
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") {
|
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);
|
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()]),
|
'createdBy' => $this->normalizer->normalize($object->getCreatedBy(), $format, [...$context, UserNormalizer::AT_DATE => $object->getCreatedAt()]),
|
||||||
];
|
];
|
||||||
|
|
||||||
$normalizationGroups = $context[AbstractNormalizer::GROUPS] ?? [];
|
if (in_array(self::WITH_POINT_IN_TIMES_CONTEXT, $context[AbstractNormalizer::GROUPS] ?? [], true)) {
|
||||||
|
|
||||||
if (is_string($normalizationGroups)) {
|
|
||||||
$normalizationGroups = [$normalizationGroups];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_array(self::WITH_POINT_IN_TIMES_CONTEXT, $normalizationGroups, true)) {
|
|
||||||
$data['point-in-times'] = $this->normalizer->normalize($object->getPointInTimes(), $format, $context);
|
$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']]);
|
$data['from-restored'] = $this->normalizer->normalize($object->getCreatedFrom(), $format, [AbstractNormalizer::GROUPS => ['read']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -85,69 +85,6 @@ class TempUrlLocalStorageGeneratorTest extends TestCase
|
|||||||
self::assertEquals($expected, $urlGenerator->validateSignature($signature, $method, $objectName, $expiration), $message);
|
self::assertEquals($expected, $urlGenerator->validateSignature($signature, $method, $objectName, $expiration), $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateValidateSignatureData(): iterable
|
|
||||||
{
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
|
||||||
'GET',
|
|
||||||
$object_name,
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
|
||||||
true,
|
|
||||||
'Valid signature, not expired',
|
|
||||||
];
|
|
||||||
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('HEAD', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
|
||||||
'HEAD',
|
|
||||||
$object_name,
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
|
||||||
true,
|
|
||||||
'Valid signature, not expired',
|
|
||||||
];
|
|
||||||
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180).'A',
|
|
||||||
'GET',
|
|
||||||
$object_name,
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
|
||||||
false,
|
|
||||||
'Invalid signature',
|
|
||||||
];
|
|
||||||
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
|
||||||
'GET',
|
|
||||||
$object_name,
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration + 1)),
|
|
||||||
false,
|
|
||||||
'Signature expired',
|
|
||||||
];
|
|
||||||
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
|
||||||
'GET',
|
|
||||||
$object_name.'____',
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
|
||||||
false,
|
|
||||||
'Invalid object name',
|
|
||||||
];
|
|
||||||
|
|
||||||
yield [
|
|
||||||
TempUrlLocalStorageGeneratorTest::expectedSignature('POST', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
|
||||||
'POST',
|
|
||||||
$object_name,
|
|
||||||
$expiration,
|
|
||||||
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
|
||||||
false,
|
|
||||||
'Wrong method',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider generateValidateSignaturePostData
|
* @dataProvider generateValidateSignaturePostData
|
||||||
*/
|
*/
|
||||||
@@ -227,6 +164,69 @@ class TempUrlLocalStorageGeneratorTest extends TestCase
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function generateValidateSignatureData(): iterable
|
||||||
|
{
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
||||||
|
'GET',
|
||||||
|
$object_name,
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
||||||
|
true,
|
||||||
|
'Valid signature, not expired',
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('HEAD', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
||||||
|
'HEAD',
|
||||||
|
$object_name,
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
||||||
|
true,
|
||||||
|
'Valid signature, not expired',
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180).'A',
|
||||||
|
'GET',
|
||||||
|
$object_name,
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
||||||
|
false,
|
||||||
|
'Invalid signature',
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
||||||
|
'GET',
|
||||||
|
$object_name,
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration + 1)),
|
||||||
|
false,
|
||||||
|
'Signature expired',
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('GET', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
||||||
|
'GET',
|
||||||
|
$object_name.'____',
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
||||||
|
false,
|
||||||
|
'Invalid object name',
|
||||||
|
];
|
||||||
|
|
||||||
|
yield [
|
||||||
|
TempUrlLocalStorageGeneratorTest::expectedSignature('POST', $object_name = 'testABC', $expiration = 1734307200 + 180),
|
||||||
|
'POST',
|
||||||
|
$object_name,
|
||||||
|
$expiration,
|
||||||
|
\DateTimeImmutable::createFromFormat('U', (string) ($expiration - 10)),
|
||||||
|
false,
|
||||||
|
'Wrong method',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function buildGenerator(?UrlGeneratorInterface $urlGenerator = null, ?ClockInterface $clock = null): TempUrlLocalStorageGenerator
|
private function buildGenerator(?UrlGeneratorInterface $urlGenerator = null, ?ClockInterface $clock = null): TempUrlLocalStorageGenerator
|
||||||
{
|
{
|
||||||
return new TempUrlLocalStorageGenerator(
|
return new TempUrlLocalStorageGenerator(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user