Compare commits

..

21 Commits

Author SHA1 Message Date
4028c020ee Release v4.12.0 2026-01-15 18:02:12 +01:00
0d4eef6a0c Merge branch '493-fix-stored-object-workflow-permission' into 'master'
Fix issues with permission for stored objects associated with workflows

Closes #493

See merge request Chill-Projet/chill-bundles!951
2026-01-15 16:54:37 +00:00
b6152d5356 Fix issues with permission for stored objects associated with workflows 2026-01-15 16:54:37 +00:00
8b708f8c73 fix CommentInput: replace deprecated value binding with model-value 2026-01-15 14:53:40 +01:00
8d5b200107 Restrict ux-translator version to 2.31.0 2026-01-15 14:44:05 +01:00
a9e9207d5a Update php-cs-fixer version 2026-01-15 13:41:00 +01:00
3915574ed4 phpstan error fix 2026-01-15 13:40:46 +01:00
f3217d22ef Fix: acc periods of which user is the referrer should not be included if when the list is filtered by center and none of the participations are part of the center 2026-01-15 13:25:54 +01:00
06c5affbe7 Increase delay for removing stale workflows from 90 to 180 days
- Updated `KEEP_INTERVAL` in `CancelStaleWorkflowCronJob` to `P180D`.
2026-01-15 10:08:40 +01:00
bf461a1211 Merge branch '473-display-bundles-version' into 'master'
Resolve "Afficher le numéro de version de Chill dans l'UX"

Closes #473

See merge request Chill-Projet/chill-bundles!947
2026-01-13 15:35:26 +00:00
3f0ad51114 Resolve "Afficher le numéro de version de Chill dans l'UX" 2026-01-13 15:35:26 +00:00
a4de8eaab3 Merge branch '489-fix-desactivation-date-goarls-results' into 'master'
Fix issue with goal/result deactivation date handling and improve formatting

Closes #489

See merge request Chill-Projet/chill-bundles!949
2026-01-13 15:32:08 +00:00
2feb137ac2 Fix issue with goal/result deactivation date handling and improve formatting 2026-01-13 15:32:07 +00:00
5ea74d118b Merge branch '490-fix-double-notification' into 'master'
Prevent notifications from being sent when the user signs a document he asked to himself

Closes #490

See merge request Chill-Projet/chill-bundles!950
2026-01-13 15:31:50 +00:00
8eb7a55ef5 Prevent notifications from being sent when the user signs a document he asked to himself 2026-01-13 15:31:49 +00:00
281887355f Fix calculation of budget balance 2026-01-12 10:34:30 +01:00
47b285b584 Fix export group by center for persons without a center in CenterAggregator.php 2025-12-30 13:01:56 +01:00
7c9b4d02f6 Fix ordering of social actions
Actions with a closing date in the future should be considered as 'still open'.
2025-12-18 11:08:18 +01:00
3ff9bba4de Fix the condition to display concerned persons in calendar list items. 2025-12-18 10:24:24 +01:00
c0f9e953fb Update to v4.11.0 2025-12-17 16:56:35 +01:00
a49ea2b6b9 Fix translation syntax
Cannot start with %, wrap translation value in double quotes
2025-12-17 16:54:33 +01:00
219 changed files with 1749 additions and 1414 deletions

View File

@@ -1,6 +0,0 @@
kind: Feature
body: 'Add filtering to admin lists: social actions, social issues, goals, results, and evaluations'
time: 2025-12-10T03:20:45.135973502+01:00
custom:
Issue: "478"
SchemaChange: No schema change

View File

@@ -1,7 +0,0 @@
kind: Fixed
body: |
Fix migration query after previous fix
time: 2025-12-11T21:49:08.899926492+01:00
custom:
Issue: "466"
SchemaChange: No schema change

9
.changes/v4.11.0.md Normal file
View File

@@ -0,0 +1,9 @@
## v4.11.0 - 2025-12-17
### Feature
* ([#478](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/478)) Add filtering to admin lists: social actions, social issues, goals, results, and evaluations
### Fixed
* ([#466](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/466)) Fix migration query after previous fix
* Fix translation key/value
Cannot start with % and should be wrapped in "".

16
.changes/v4.12.0.md Normal file
View File

@@ -0,0 +1,16 @@
## v4.12.0 - 2026-01-15
### Feature
* ([#473](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/473)) Display version of chill bundles in application footer
* Increase the delay before removing stale workflow from 90 days to 180 days.
### Fixed
* ([#480](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/480)) Fix the condition to display concerned persons in calendar list items.
* ([#481](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/481)) Fix ordering of social actions: actions with a closing date in the future should be considered as 'still open'.
* ([#477](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/477)) Fix export group by center for persons without a center in CenterAggregator.php
* Fix the calculation of budget balance to only take into account resources and charges that are still actual
* ([#489](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/489)) Fix desactivation date for Goals and results
* ([#490](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/490)) Prevent sending a notification when the user signs the document himself
* ([#491](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/491)) Fix: acc periods of which user is the referrer should not be included if when the list is filtered by center and none of the participations are part of the center
* ([#492](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/492)) fix CommentInput: replace deprecated value binding with model-value
* ([#493](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/493)) fix issue with stored object permissions associated with workflows (as attachment, or through a related entity)
BC: the constructor's signature of `\Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter` has changed.

13
.gitignore vendored
View File

@@ -50,12 +50,15 @@ phpstan.neon
###> symfony/phpunit-bridge ###
###< symfony/phpunit-bridge ###
###> symfony/webpack-encore-bundle ###
/node_modules/
/public/build/
npm-debug.log
yarn-error.log
###< symfony/webpack-encore-bundle ###
###> friendsofphp/php-cs-fixer ###
/.php-cs-fixer.php
/.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
###> pentatrion/vite-bundle ###
/node_modules/
/public/build/
###< pentatrion/vite-bundle ###

View File

@@ -6,6 +6,31 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
and is generated by [Changie](https://github.com/miniscruff/changie).
## v4.12.0 - 2026-01-15
### Feature
* ([#473](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/473)) Display version of chill bundles in application footer
* Increase the delay before removing stale workflow from 90 days to 180 days.
### Fixed
* ([#480](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/480)) Fix the condition to display concerned persons in calendar list items.
* ([#481](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/481)) Fix ordering of social actions: actions with a closing date in the future should be considered as 'still open'.
* ([#477](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/477)) Fix export group by center for persons without a center in CenterAggregator.php
* Fix the calculation of budget balance to only take into account resources and charges that are still actual
* ([#489](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/489)) Fix desactivation date for Goals and results
* ([#490](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/490)) Prevent sending a notification when the user signs the document himself
* ([#491](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/491)) Fix: acc periods of which user is the referrer should not be included if when the list is filtered by center and none of the participations are part of the center
* ([#492](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/492)) fix CommentInput: replace deprecated value binding with model-value
* ([#493](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/493)) fix issue with stored object permissions associated with workflows (as attachment, or through a related entity)
## v4.11.0 - 2025-12-17
### Feature
* ([#478](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/478)) Add filtering to admin lists: social actions, social issues, goals, results, and evaluations
### Fixed
* ([#466](https://gitlab.com/Chill-Projet/chill-bundles/-/issues/466)) Fix migration query after previous fix
* Fix translation key/value
Cannot start with % and should be wrapped in "".
## v4.10.1 - 2025-12-11
### Fixed
* Fix missing translation variable in NewLocation component

View File

@@ -21,6 +21,7 @@
"ext-openssl": "*",
"ext-redis": "*",
"ext-zlib": "*",
"composer-runtime-api": "*",
"champs-libres/wopi-bundle": "dev-symfony-v5@dev",
"champs-libres/wopi-lib": "dev-master@dev",
"doctrine/data-fixtures": "^1.8",
@@ -37,7 +38,6 @@
"ocramius/package-versions": "^1.10 || ^2",
"odolbeau/phone-number-bundle": "^3.6",
"ovh/ovh": "^3.0",
"pentatrion/vite-bundle": "^8.2",
"phpoffice/phpspreadsheet": "^1.16",
"ramsey/uuid-doctrine": "^1.7",
"sensio/framework-extra-bundle": "^5.5",
@@ -83,8 +83,9 @@
"symfony/templating": "^5.4",
"symfony/translation": "^5.4",
"symfony/twig-bundle": "^5.4",
"symfony/ux-translator": "^2.22",
"symfony/ux-translator": "2.31.0",
"symfony/validator": "^5.4",
"symfony/webpack-encore-bundle": "^1.11",
"symfony/workflow": "^5.4",
"symfony/yaml": "^5.4",
"thenetworg/oauth2-azure": "^2.0",
@@ -97,7 +98,7 @@
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3",
"fakerphp/faker": "^1.13",
"friendsofphp/php-cs-fixer": "3.65.0",
"friendsofphp/php-cs-fixer": "3.92.5",
"jangregor/phpstan-prophecy": "^1.0",
"nelmio/alice": "^3.8",
"nikic/php-parser": "^4.15",

View File

@@ -17,6 +17,7 @@ return [
Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Chill\ActivityBundle\ChillActivityBundle::class => ['all' => true],
@@ -36,5 +37,4 @@ return [
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
loophp\PsrHttpMessageBridgeBundle\PsrHttpMessageBridgeBundle::class => ['all' => true],
Pentatrion\ViteBundle\PentatrionViteBundle::class => ['all' => true],
];

View File

@@ -1,8 +1,6 @@
framework:
assets:
# Disable Encore-style manifest for default assets package. Vite (Pentatrion) uses public/build/.vite/manifest.json
# internally for vite_entry_* helpers; Symfony's asset() should not depend on a manifest.
json_manifest_path: null
json_manifest_path: '%kernel.project_dir%/public/build/manifest.json'
when@test:
framework:

View File

@@ -0,0 +1,41 @@
webpack_encore:
# The path where Encore is building the assets - i.e. Encore.setOutputPath()
output_path: '%kernel.project_dir%/public/build'
# If multiple builds are defined (as shown below), you can disable the default build:
# output_path: false
# Set attributes that will be rendered on all script and link tags
script_attributes:
defer: true
# Uncomment (also under link_attributes) if using Turbo Drive
# https://turbo.hotwired.dev/handbook/drive#reloading-when-assets-change
# 'data-turbo-track': reload
# link_attributes:
# Uncomment if using Turbo Drive
# 'data-turbo-track': reload
# If using Encore.enableIntegrityHashes() and need the crossorigin attribute (default: false, or use 'anonymous' or 'use-credentials')
# crossorigin: 'anonymous'
# Preload all rendered script and link tags automatically via the HTTP/2 Link header
# preload: true
# Throw an exception if the entrypoints.json file is missing or an entry is missing from the data
# strict_mode: false
# If you have multiple builds:
# builds:
# frontend: '%kernel.project_dir%/public/frontend/build'
# pass the build name as the 3rd argument to the Twig functions
# {{ encore_entry_script_tags('entry1', null, 'frontend') }}
#when@prod:
# webpack_encore:
# # Cache the entrypoints.json (rebuild Symfony's cache when entrypoints.json changes)
# # Available in version 1.2
# cache: true
when@test:
webpack_encore:
strict_mode: false

View File

@@ -1,9 +0,0 @@
when@dev:
_pentatrion_vite:
prefix: /build
resource: "@PentatrionViteBundle/Resources/config/routing.yaml"
_profiler_vite:
path: /_profiler/vite
defaults:
_controller: Pentatrion\ViteBundle\Controller\ProfilerController::info

View File

@@ -1,15 +1,6 @@
{
"name": "chill-bundles",
"private": true,
"name": "chill",
"version": "2.0.0",
"description": "Chill web application frontend (Vite build at repo root)",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"eslint": "eslint . --ext .js,.ts,.vue"
},
"devDependencies": {
"@alexlafroscia/yaml-merge": "^4.0.0",
"@apidevtools/swagger-cli": "^4.0.4",
@@ -20,11 +11,11 @@
"@hotwired/stimulus": "^3.0.0",
"@luminateone/eslint-baseline": "^1.0.9",
"@symfony/stimulus-bridge": "^3.2.0",
"@symfony/webpack-encore": "^4.1.0",
"@tsconfig/node20": "^20.1.4",
"@types/dompurify": "^3.0.5",
"@types/eslint__js": "^8.42.3",
"@typescript-eslint/parser": "^8.12.2",
"@vitejs/plugin-vue": "^5.1.4",
"bindings": "^1.5.0",
"bootstrap": "^5.3.6",
"chokidar": "^3.5.1",
@@ -49,9 +40,9 @@
"ts-loader": "^9.3.1",
"typescript": "^5.6.3",
"typescript-eslint": "^8.13.0",
"vite": "^5.4.8",
"vite-plugin-symfony": "^8",
"vue-loader": "^17.0.0"
"vue-loader": "^17.0.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
},
"dependencies": {
"@fullcalendar/core": "^6.1.4",
@@ -80,5 +71,21 @@
"vue-multiselect": "3.0.0-alpha.2",
"vue-toast-notification": "^3.1.2",
"vuex": "^4.0.0"
}
},
"browserslist": [
"defaults and fully supports es6-module and not dead"
],
"scripts": {
"dev-server": "encore dev-server",
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production --progress",
"specs-build": "yaml-merge src/Bundle/ChillMainBundle/chill.api.specs.yaml src/Bundle/ChillPersonBundle/chill.api.specs.yaml src/Bundle/ChillCalendarBundle/chill.api.specs.yaml src/Bundle/ChillThirdPartyBundle/chill.api.specs.yaml src/Bundle/ChillDocStoreBundle/chill.api.specs.yaml> templates/api/specs.yaml",
"specs-validate": "swagger-cli validate templates/api/specs.yaml",
"specs-create-dir": "mkdir -p templates/api",
"specs": "yarn run specs-create-dir && yarn run specs-build && yarn run specs-validate",
"version": "node --version",
"eslint": "npx eslint-baseline --fix \"src/**/*.{js,ts,vue}\""
},
"private": true
}

View File

@@ -1 +1 @@
import "./chillactivity.scss";
require("./chillactivity.scss");

View File

@@ -124,9 +124,9 @@
{# {{ form(delete_form) }} #}
{% block js %}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}

View File

@@ -15,7 +15,7 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', function (e) {
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
@@ -23,12 +23,12 @@
});
window.activity = {{ activity_json|json_encode|raw }};
</script>
{{ vite_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('vue_activity') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('vue_activity') }}
{{ vite_entry_link_tags('page_edit_activity') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('page_edit_activity') }}
{% endblock %}

View File

@@ -30,7 +30,7 @@
{% endblock %}
{% block js %}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', function (e) {
chill.displayAlertWhenLeavingModifiedForm('form[name="{{ edit_form.vars.form.vars.name }}"]',
@@ -38,10 +38,10 @@
});
window.activity = {{ activity_json|json_encode|raw }};
</script>
{{ vite_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('vue_activity') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }}
{% endblock %}

View File

@@ -7,14 +7,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}

View File

@@ -22,14 +22,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}

View File

@@ -121,9 +121,9 @@
{{ form_end(form) }}
{% block js %}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}

View File

@@ -15,16 +15,16 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
<script type="text/javascript">
window.activity = {{ activity_json|json_encode|raw }};
{% if default_location is not null %}window.default_location_id = {{ default_location.id }}{% endif %};
</script>
{{ vite_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('vue_activity') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }}
{% endblock %}

View File

@@ -14,7 +14,7 @@
{% endblock %}
{% block js %}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
<script type="text/javascript">
window.addEventListener('DOMContentLoaded', function (e) {
chill.displayAlertWhenLeavingUnsubmittedForm('form[name="{{ form.vars.form.vars.name }}"]',
@@ -22,10 +22,10 @@
});
window.activity = {{ activity_json|json_encode|raw }};
</script>
{{ vite_entry_script_tags('vue_activity') }}
{{ encore_entry_script_tags('vue_activity') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('vue_activity') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('vue_activity') }}
{% endblock %}

View File

@@ -6,16 +6,16 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% import '@ChillActivity/ActivityReason/macro.html.twig' as m %}

View File

@@ -6,14 +6,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_notification_toggle_read_status') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_notification_toggle_read_status') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% import '@ChillActivity/ActivityReason/macro.html.twig' as m %}

View File

@@ -16,7 +16,8 @@ use Chill\ActivityBundle\Repository\ActivityRepository;
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelperInterface;
use Symfony\Component\Security\Core\Security;
class ActivityStoredObjectVoter extends AbstractStoredObjectVoter
@@ -24,9 +25,10 @@ class ActivityStoredObjectVoter extends AbstractStoredObjectVoter
public function __construct(
private readonly ActivityRepository $repository,
Security $security,
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
WorkflowRelatedEntityPermissionHelperInterface $workflowDocumentService,
EntityWorkflowAttachmentRepository $attachmentRepository,
) {
parent::__construct($security, $workflowDocumentService);
parent::__construct($security, $attachmentRepository, $workflowDocumentService);
}
protected function getRepository(): AssociatedEntityToStoredObjectInterface

View File

@@ -0,0 +1,18 @@
// this file loads all assets from the Chill person bundle
module.exports = function (encore, entries) {
entries.push(__dirname + "/Resources/public/chill/index.js");
encore.addAliases({
ChillActivityAssets: __dirname + "/Resources/public",
});
encore.addEntry(
"page_edit_activity",
__dirname + "/Resources/public/page/edit_activity/index.scss",
);
encore.addEntry(
"vue_activity",
__dirname + "/Resources/public/vuejs/Activity/index.js",
);
};

View File

@@ -1,14 +0,0 @@
export default {
chillBase: [
"./src/Bundle/ChillActivityBundle/Resources/public/chill/index.js",
],
aliases: {
ChillActivityAssets: "./src/Bundle/ChillActivityBundle/Resources/public",
},
inputs: {
page_edit_activity:
"./src/Bundle/ChillActivityBundle/Resources/public/page/edit_activity/index.scss",
vue_activity:
"./src/Bundle/ChillActivityBundle/Resources/public/vuejs/Activity/index.js",
},
};

View File

@@ -2,12 +2,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block title %}

View File

@@ -1 +1 @@
import("./chillbudget.scss");
require("./chillbudget.scss");

View File

@@ -72,14 +72,20 @@
{% macro table_results(actualCharges, actualResources, results) %}
{% set now = date() %}
{% set totalCharges = 0 %}
{% for c in actualCharges %}
{% set totalCharges = totalCharges + c.amount %}
{% if c.startDate <= now and (c.endDate is null or c.endDate >= now) %}
{% set totalCharges = totalCharges + c.amount %}
{% endif %}
{% endfor %}
{% set totalResources = 0 %}
{% for r in actualResources %}
{% set totalResources = totalResources + r.amount %}
{% if r.startDate <= now and (r.endDate is null or r.endDate >= now) %}
{% set totalResources = totalResources + r.amount %}
{% endif %}
{% endfor %}
{% set result = (totalResources - totalCharges) %}

View File

@@ -7,11 +7,11 @@
{% block title title %}
{% block js %}
{{ vite_entry_script_tags('page_budget') }}
{{ encore_entry_script_tags('page_budget') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('page_budget') }}
{{ encore_entry_link_tags('page_budget') }}
{% endblock %}
{% block content %}

View File

@@ -7,11 +7,11 @@
{% block title title %}
{% block js %}
{{ vite_entry_script_tags('page_budget') }}
{{ encore_entry_script_tags('page_budget') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('page_budget') }}
{{ encore_entry_link_tags('page_budget') }}
{% endblock %}
{% block content %}

View File

@@ -0,0 +1,8 @@
// this file loads all assets from the Chill budget bundle
module.exports = function (encore, entries) {
encore.addAliases({
ChillBudgetAssets: __dirname + "/Resources/public",
});
encore.addEntry("page_budget", __dirname + "/Resources/public/page/index.js");
};

View File

@@ -1,8 +0,0 @@
export default {
aliases: {
ChillBudgetAssets: "./src/Bundle/ChillBudgetBundle/Resources/public",
},
inputs: {
page_budget: "./src/Bundle/ChillBudgetBundle/Resources/public/page/index.js",
},
};

View File

@@ -1 +1 @@
import("./scss/calendar.scss");
require("./scss/calendar.scss");

View File

@@ -255,3 +255,5 @@ export default {
},
};
</script>
<style src="vue-multiselect/dist/vue-multiselect.css"></style>

View File

@@ -75,7 +75,7 @@
</div>
{% if calendar.comment.comment is not empty
or calendar.users|length > 0
or calendar.persons|length > 0
or calendar.thirdParties|length > 0
or calendar.users|length > 0 %}
<div class="item-row details separator">

View File

@@ -20,13 +20,13 @@
window.endDate = {{ entity.endDate|date('Y-m-d H:i:s')|json_encode|raw }};
window.mainUser = {{ entity.mainUser.id }};
</script>
{{ vite_entry_script_tags('vue_calendar') }}
{{ encore_entry_script_tags('vue_calendar') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_calendar') }}
{{ vite_entry_link_tags('page_calendar') }}
{{ encore_entry_link_tags('vue_calendar') }}
{{ encore_entry_link_tags('page_calendar') }}
{% endblock %}
{% block block_post_menu %}

View File

@@ -20,13 +20,13 @@
window.endDate = {{ entity.endDate|date('Y-m-d H:i:s')|json_encode|raw }};
window.mainUser = {{ entity.mainUser.id }};
</script>
{{ vite_entry_script_tags('vue_calendar') }}
{{ encore_entry_script_tags('vue_calendar') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_calendar') }}
{{ vite_entry_link_tags('page_calendar') }}
{{ encore_entry_link_tags('vue_calendar') }}
{{ encore_entry_link_tags('page_calendar') }}
{% endblock %}
{% block block_post_menu %}

View File

@@ -23,10 +23,10 @@
window.endDate = {{ entity.endDate|date('Y-m-d H:i:s')|json_encode|raw }};
window.mainUser = {{ entity.mainUser.id }};
</script>
{{ vite_entry_script_tags('vue_calendar') }}
{{ encore_entry_script_tags('vue_calendar') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_calendar') }}
{{ encore_entry_link_tags('vue_calendar') }}
{% endblock %}

View File

@@ -9,14 +9,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_answer') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_answer') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_answer') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_answer') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}

View File

@@ -8,14 +8,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_answer') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_answer') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_answer') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_answer') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}

View File

@@ -16,10 +16,10 @@
<script type="text/javascript">
window.userId = {{ user.id }};
</script>
{{ vite_entry_script_tags('vue_mycalendarrange') }}
{{ encore_entry_script_tags('vue_mycalendarrange') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_mycalendarrange') }}
{{ encore_entry_link_tags('vue_mycalendarrange') }}
{% endblock %}

View File

@@ -15,18 +15,18 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript">
window.entity = {{ entity_json|json_encode|raw }};
{% if app.user.currentLocation is not null %}window.default_location_id = {{ app.user.currentLocation.id }};{% endif %};
</script>
{{ vite_entry_script_tags('vue_calendar') }}
{{ encore_entry_script_tags('vue_calendar') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_calendar') }}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('vue_calendar') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block block_post_menu %}

View File

@@ -15,18 +15,18 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript">
window.entity = {{ entity_json|json_encode|raw }};
{% if app.user.currentLocation is not null %}window.default_location_id = {{ app.user.currentLocation.id }};{% endif %};
</script>
{{ vite_entry_script_tags('vue_calendar') }}
{{ encore_entry_script_tags('vue_calendar') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('vue_calendar') }}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('vue_calendar') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block block_post_menu %}

View File

@@ -9,12 +9,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}
{% block content %}

View File

@@ -8,12 +8,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}
{% block content %}

View File

@@ -9,12 +9,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}
{% block content %}

View File

@@ -8,12 +8,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}
{% block content %}

View File

@@ -29,12 +29,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_answer') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_answer') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_answer') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_answer') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}

View File

@@ -0,0 +1,25 @@
// this file loads all assets from the Chill calendar bundle
module.exports = function (encore, entries) {
entries.push(__dirname + "/Resources/public/chill/chill.js");
encore.addAliases({
ChillCalendarAssets: __dirname + "/Resources/public",
});
encore.addEntry(
"vue_calendar",
__dirname + "/Resources/public/vuejs/Calendar/index.js",
);
encore.addEntry(
"vue_mycalendarrange",
__dirname + "/Resources/public/vuejs/MyCalendarRange/index2.ts",
);
encore.addEntry(
"page_calendar",
__dirname + "/Resources/public/chill/index.js",
);
encore.addEntry(
"mod_answer",
__dirname + "/Resources/public/module/Invite/answer.js",
);
};

View File

@@ -1,18 +0,0 @@
export default {
chillBase: [
"./src/Bundle/ChillCalendarBundle/Resources/public/chill/chill.js",
],
aliases: {
ChillCalendarAssets: "./src/Bundle/ChillCalendarBundle/Resources/public",
},
inputs: {
vue_calendar:
"./src/Bundle/ChillCalendarBundle/Resources/public/vuejs/Calendar/index.js",
vue_mycalendarrange:
"./src/Bundle/ChillCalendarBundle/Resources/public/vuejs/MyCalendarRange/index2.ts",
page_calendar:
"./src/Bundle/ChillCalendarBundle/Resources/public/chill/index.js",
mod_answer:
"./src/Bundle/ChillCalendarBundle/Resources/public/module/Invite/answer.js",
},
};

View File

@@ -17,9 +17,9 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -2,12 +2,12 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}

View File

@@ -17,9 +17,9 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -3,11 +3,11 @@
{% block title 'docgen.Generate a document'|trans %}
{% block js %}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block content %}

View File

@@ -0,0 +1,11 @@
// this file loads all assets from the Chill DocGenerator bundle
module.exports = function (encore, entries) {
encore.addAliases({
ChillDocGeneratorAssets: __dirname + "/Resources/public",
});
encore.addEntry(
"mod_docgen_picktemplate",
__dirname + "/Resources/public/module/PickTemplate/index.js",
);
};

View File

@@ -1,10 +0,0 @@
export default {
aliases: {
ChillDocGeneratorAssets:
"./src/Bundle/ChillDocGeneratorBundle/Resources/public",
},
inputs: {
mod_docgen_picktemplate:
"./src/Bundle/ChillDocGeneratorBundle/Resources/public/module/PickTemplate/index.js",
},
};

View File

@@ -1,2 +1,2 @@
import("./uploader.js");
import("./downloader.js");
require("./uploader.js");
require("./downloader.js");

View File

@@ -22,8 +22,8 @@ import { initializeButtons } from "./downloader.js";
// load css
//require('dropzone/dist/basic.css');
import("dropzone/dist/dropzone.css");
import("./index.scss");
require("dropzone/dist/dropzone.css");
require("./index.scss");
//
// disable dropzone autodiscover

View File

@@ -366,7 +366,7 @@ import {
} from "../../types";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import * as pdfjsLib from "pdfjs-dist";
import type {
import {
PDFDocumentProxy,
PDFPageProxy,
} from "pdfjs-dist/types/src/display/api";

View File

@@ -42,10 +42,10 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -38,10 +38,10 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -12,9 +12,9 @@
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('mod_entity_workflow_pick') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_entity_workflow_pick') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}
@@ -80,7 +80,7 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ vite_entry_script_tags('mod_entity_workflow_pick') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_entity_workflow_pick') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}

View File

@@ -3,14 +3,14 @@ activeRouteKey = '' %} {% block title %}
{{ "Documents" }}
{% endblock %} {% block js %}
{{ parent() }}
{{ vite_entry_script_tags("mod_docgen_picktemplate") }}
{{ vite_entry_script_tags("mod_entity_workflow_pick") }}
{{ vite_entry_script_tags("mod_document_action_buttons_group") }}
{{ encore_entry_script_tags("mod_docgen_picktemplate") }}
{{ encore_entry_script_tags("mod_entity_workflow_pick") }}
{{ encore_entry_script_tags("mod_document_action_buttons_group") }}
{% endblock %} {% block css %}
{{ parent() }}
{{ vite_entry_script_tags("mod_docgen_picktemplate") }}
{{ vite_entry_link_tags("mod_entity_workflow_pick") }}
{{ vite_entry_link_tags("mod_document_action_buttons_group") }}
{{ encore_entry_script_tags("mod_docgen_picktemplate") }}
{{ encore_entry_link_tags("mod_entity_workflow_pick") }}
{{ encore_entry_link_tags("mod_document_action_buttons_group") }}
{% endblock %} {% block content %}
<div class="document-list">
<h1>{{ "Documents" }}</h1>

View File

@@ -13,14 +13,14 @@ License * along with this program. If not, see <http://www.gnu.org/licenses/>.
{{ 'Documents for %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}
{% endblock %} {% block js %}
{{ parent() }}
{{ vite_entry_script_tags("mod_docgen_picktemplate") }}
{{ vite_entry_script_tags("mod_entity_workflow_pick") }}
{{ vite_entry_script_tags("mod_document_action_buttons_group") }}
{{ encore_entry_script_tags("mod_docgen_picktemplate") }}
{{ encore_entry_script_tags("mod_entity_workflow_pick") }}
{{ encore_entry_script_tags("mod_document_action_buttons_group") }}
{% endblock %} {% block css %}
{{ parent() }}
{{ vite_entry_link_tags("mod_docgen_picktemplate") }}
{{ vite_entry_link_tags("mod_entity_workflow_pick") }}
{{ vite_entry_link_tags("mod_document_action_buttons_group") }}
{{ encore_entry_link_tags("mod_docgen_picktemplate") }}
{{ encore_entry_link_tags("mod_entity_workflow_pick") }}
{{ encore_entry_link_tags("mod_document_action_buttons_group") }}
{% endblock %} {% block content %}
<div class="document-list">

View File

@@ -58,9 +58,9 @@
{% endblock %}
{% block js %}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -54,9 +54,9 @@
{% endblock %}
{% block js %}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{% endblock %}

View File

@@ -24,11 +24,11 @@
{% block title %}{{ 'Detail of document of %name%'|trans({ '%name%': person|chill_entity_render_string } ) }}{% endblock %}
{% block js %}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block content %}

View File

@@ -7,21 +7,21 @@
<link rel="shortcut icon" href="{{ asset('build/images/favicon.ico') }}" type="image/x-icon">
<title>Signature</title>
{{ vite_entry_link_tags('mod_bootstrap') }}
{{ vite_entry_link_tags('mod_forkawesome') }}
{{ vite_entry_link_tags('chill') }}
{{ vite_entry_link_tags('vue_document_signature') }}
{{ encore_entry_link_tags('mod_bootstrap') }}
{{ encore_entry_link_tags('mod_forkawesome') }}
{{ encore_entry_link_tags('chill') }}
{{ encore_entry_link_tags('vue_document_signature') }}
</head>
<body>
{% block js %}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
<script type="text/javascript">
window.signature = {{ signature|json_encode|raw }};
</script>
{{ vite_entry_script_tags('vue_document_signature') }}
{{ encore_entry_script_tags('vue_document_signature') }}
{% endblock %}
<div class="content" id="content">

View File

@@ -2,12 +2,12 @@
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_document_download_button') }}
{{ encore_entry_link_tags('mod_document_download_button') }}
{% endblock %}
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_document_download_button') }}
{{ encore_entry_script_tags('mod_document_download_button') }}
{% endblock %}
{% block title %}{{ 'workflow.public_link.title'|trans }} - {{ title }}{% endblock %}

View File

@@ -15,7 +15,10 @@ use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoterInterface;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Chill\MainBundle\Entity\Workflow\EntityWorkflow;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowAttachment;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelperInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
@@ -34,7 +37,8 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
public function __construct(
private readonly Security $security,
private readonly ?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null,
private readonly EntityWorkflowAttachmentRepository $entityWorkflowAttachmentRepository,
private readonly WorkflowRelatedEntityPermissionHelperInterface $workflowDocumentService,
) {}
public function supports(StoredObjectRoleEnum $attribute, StoredObject $subject): bool
@@ -46,16 +50,6 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
public function voteOnAttribute(StoredObjectRoleEnum $attribute, StoredObject $subject, TokenInterface $token): bool
{
// we first try to get the permission from the workflow, as attachement (this is the less intensive query)
$workflowPermissionAsAttachment = match ($attribute) {
StoredObjectRoleEnum::SEE => $this->workflowDocumentService->isAllowedByWorkflowForReadOperation($subject),
StoredObjectRoleEnum::EDIT => $this->workflowDocumentService->isAllowedByWorkflowForWriteOperation($subject),
};
if (WorkflowRelatedEntityPermissionHelper::FORCE_DENIED === $workflowPermissionAsAttachment) {
return false;
}
// Retrieve the related entity
$entity = $this->getRepository()->findAssociatedEntityToStoredObject($subject);
@@ -65,7 +59,7 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
$regularPermission = $this->security->isGranted($voterAttribute, $entity);
if (!$this->canBeAssociatedWithWorkflow()) {
return $regularPermission;
return $this->voteOnStoredObjectAsAttachementOfAWorkflow($attribute, $regularPermission, $subject);
}
$workflowPermission = match ($attribute) {
@@ -74,9 +68,41 @@ abstract class AbstractStoredObjectVoter implements StoredObjectVoterInterface
};
return match ($workflowPermission) {
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT => true,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED => false,
WorkflowRelatedEntityPermissionHelper::ABSTAIN => WorkflowRelatedEntityPermissionHelper::FORCE_GRANT === $workflowPermissionAsAttachment || $regularPermission,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT => true,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED => false,
WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN => $this->voteOnStoredObjectAsAttachementOfAWorkflow($attribute, $regularPermission, $subject),
};
}
private function voteOnStoredObjectAsAttachementOfAWorkflow(StoredObjectRoleEnum $attribute, bool $regularPermission, StoredObject $storedObject): bool
{
$attachments = $this->entityWorkflowAttachmentRepository->findByStoredObject($storedObject);
// we get all the entity workflows where the stored object is attached
$entityWorkflows = array_map(static fn (EntityWorkflowAttachment $attachment) => $attachment->getEntityWorkflow(), $attachments);
// we compute all the permission for each entity workflow
$permissions = array_map(fn (EntityWorkflow $entityWorkflow): string => match ($attribute) {
StoredObjectRoleEnum::SEE => $this->workflowDocumentService->isAllowedByWorkflowForReadOperation($entityWorkflow),
StoredObjectRoleEnum::EDIT => $this->workflowDocumentService->isAllowedByWorkflowForWriteOperation($entityWorkflow),
}, $entityWorkflows);
// now, we reduce the permissions: abstain are ignored. Between DENIED and and GRANT, DENIED takes precedence
$computedPermission = WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN;
foreach ($permissions as $permission) {
if (WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED === $permission) {
return false;
}
if (WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT === $permission) {
$computedPermission = WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT;
}
}
if (WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN === $computedPermission) {
return $regularPermission;
}
// this is the case where WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT is returned
return true;
}
}

View File

@@ -16,6 +16,7 @@ use Chill\DocStoreBundle\Repository\AccompanyingCourseDocumentRepository;
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Symfony\Component\Security\Core\Security;
@@ -25,8 +26,9 @@ final class AccompanyingCourseDocumentStoredObjectVoter extends AbstractStoredOb
private readonly AccompanyingCourseDocumentRepository $repository,
Security $security,
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
EntityWorkflowAttachmentRepository $attachmentRepository,
) {
parent::__construct($security, $workflowDocumentService);
parent::__construct($security, $attachmentRepository, $workflowDocumentService);
}
protected function getRepository(): AssociatedEntityToStoredObjectInterface

View File

@@ -16,6 +16,7 @@ use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Repository\PersonDocumentRepository;
use Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Symfony\Component\Security\Core\Security;
@@ -25,8 +26,9 @@ class PersonDocumentStoredObjectVoter extends AbstractStoredObjectVoter
private readonly PersonDocumentRepository $repository,
Security $security,
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
EntityWorkflowAttachmentRepository $attachmentRepository,
) {
parent::__construct($security, $workflowDocumentService);
parent::__construct($security, $attachmentRepository, $workflowDocumentService);
}
protected function getRepository(): AssociatedEntityToStoredObjectInterface

View File

@@ -16,8 +16,11 @@ use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Chill\MainBundle\Entity\Workflow\EntityWorkflowAttachment;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelperInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Security;
@@ -31,21 +34,31 @@ class AbstractStoredObjectVoterTest extends TestCase
{
use ProphecyTrait;
/**
* @param array<int, EntityWorkflowAttachment> $attachments
*
* @return void
*/
private function buildStoredObjectVoter(
bool $canBeAssociatedWithWorkflow,
AssociatedEntityToStoredObjectInterface $repository,
Security $security,
?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null,
?WorkflowRelatedEntityPermissionHelperInterface $workflowDocumentService = null,
array $attachments = [],
): AbstractStoredObjectVoter {
$attachmentsRepository = $this->prophesize(EntityWorkflowAttachmentRepository::class);
$attachmentsRepository->findByStoredObject(Argument::type(StoredObject::class))->willReturn($attachments);
// Anonymous class extending the abstract class
return new class ($canBeAssociatedWithWorkflow, $repository, $security, $workflowDocumentService) extends AbstractStoredObjectVoter {
return new class ($canBeAssociatedWithWorkflow, $repository, $security, $attachmentsRepository->reveal(), $workflowDocumentService) extends AbstractStoredObjectVoter {
public function __construct(
private readonly bool $canBeAssociatedWithWorkflow,
private readonly AssociatedEntityToStoredObjectInterface $repository,
Security $security,
?WorkflowRelatedEntityPermissionHelper $workflowDocumentService = null,
EntityWorkflowAttachmentRepository $attachmentRepository,
WorkflowRelatedEntityPermissionHelperInterface $workflowDocumentService,
) {
parent::__construct($security, $workflowDocumentService);
parent::__construct($security, $attachmentRepository, $workflowDocumentService);
}
protected function attributeToRole($attribute): string
@@ -72,28 +85,29 @@ class AbstractStoredObjectVoterTest extends TestCase
public function testSupportsOnAttribute(): void
{
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(new \stdClass()), $this->prophesize(Security::class)->reveal(), null);
$entityWorkflowService = $this->prophesize(WorkflowRelatedEntityPermissionHelperInterface::class);
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(new \stdClass()), $this->prophesize(Security::class)->reveal(), $entityWorkflowService->reveal());
self::assertTrue($voter->supports(StoredObjectRoleEnum::SEE, new StoredObject()));
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(new User()), $this->prophesize(Security::class)->reveal(), null);
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(new User()), $this->prophesize(Security::class)->reveal(), $entityWorkflowService->reveal());
self::assertFalse($voter->supports(StoredObjectRoleEnum::SEE, new StoredObject()));
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(null), $this->prophesize(Security::class)->reveal(), null);
$voter = $this->buildStoredObjectVoter(false, new DummyRepository(null), $this->prophesize(Security::class)->reveal(), $entityWorkflowService->reveal());
self::assertFalse($voter->supports(StoredObjectRoleEnum::SEE, new StoredObject()));
}
/**
* @dataProvider dataProviderVoteOnAttributeWithStoredObjectPermission
* @dataProvider dataProviderVoteOnAttributeWithWorkflow
*/
public function testVoteOnAttributeWithStoredObjectPermission(
public function testVoteOnAttributeWithWorkflow(
StoredObjectRoleEnum $attribute,
bool $expected,
bool $isGrantedRegularPermission,
string $isGrantedWorkflowPermission,
string $isGrantedStoredObjectAttachment,
): void {
$storedObject = new StoredObject();
$repository = new DummyRepository($related = new \stdClass());
@@ -102,31 +116,28 @@ class AbstractStoredObjectVoterTest extends TestCase
$security = $this->prophesize(Security::class);
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelper::class);
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelperInterface::class);
$security = $this->prophesize(Security::class);
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
$attachementRepository = $this->prophesize(EntityWorkflowAttachmentRepository::class);
$attachementRepository->findByStoredObject($storedObject)->willReturn([]);
if (StoredObjectRoleEnum::SEE === $attribute) {
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($storedObject)
->shouldBeCalled()
->willReturn($isGrantedStoredObjectAttachment);
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($related)
->willReturn($isGrantedWorkflowPermission);
} elseif (StoredObjectRoleEnum::EDIT === $attribute) {
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($storedObject)
->shouldBeCalled()
->willReturn($isGrantedStoredObjectAttachment);
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($related)
->willReturn($isGrantedWorkflowPermission);
} else {
throw new \LogicException('Invalid attribute for StoredObjectVoter');
}
$storedObjectVoter = new class ($repository, $workflowRelatedEntityPermissionHelper->reveal(), $security->reveal()) extends AbstractStoredObjectVoter {
public function __construct(private $repository, $helper, $security)
$storedObjectVoter = new class ($repository, $workflowRelatedEntityPermissionHelper->reveal(), $security->reveal(), $attachementRepository->reveal()) extends AbstractStoredObjectVoter {
public function __construct(private $repository, $helper, $security, EntityWorkflowAttachmentRepository $attachmentRepository)
{
parent::__construct($security, $helper);
parent::__construct($security, $attachmentRepository, $helper);
}
protected function getRepository(): AssociatedEntityToStoredObjectInterface
@@ -155,96 +166,64 @@ class AbstractStoredObjectVoterTest extends TestCase
self::assertEquals($expected, $actual);
}
public static function dataProviderVoteOnAttributeWithStoredObjectPermission(): iterable
public static function dataProviderVoteOnAttributeWithWorkflow(): iterable
{
foreach (['read' => StoredObjectRoleEnum::SEE, 'write' => StoredObjectRoleEnum::EDIT] as $action => $attribute) {
yield 'Not related to any workflow nor attachment ('.$action.')' => [
$attribute,
true,
true,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
];
yield 'Not related to any workflow nor attachment (refuse) ('.$action.')' => [
$attribute,
false,
false,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
];
yield 'Is granted by a workflow takes precedence (workflow) ('.$action.')' => [
$attribute,
false,
true,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
];
yield 'Is granted by a workflow takes precedence (stored object) ('.$action.')' => [
$attribute,
false,
true,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
];
yield 'Is granted by a workflow takes precedence (workflow) although grant ('.$action.')' => [
$attribute,
false,
true,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
];
yield 'Is granted by a workflow takes precedence (stored object) although grant ('.$action.')' => [
$attribute,
false,
true,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
true,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
];
yield 'Is granted by a workflow takes precedence (initially refused) (workflow) although grant ('.$action.')' => [
$attribute,
false,
false,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
];
yield 'Is granted by a workflow takes precedence (initially refused) (stored object) although grant ('.$action.')' => [
$attribute,
false,
false,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
WorkflowRelatedEntityPermissionHelper::FORCE_DENIED,
];
yield 'Force grant inverse the regular permission (workflow) ('.$action.')' => [
$attribute,
true,
false,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
];
yield 'Force grant inverse the regular permission (so) ('.$action.')' => [
$attribute,
true,
false,
WorkflowRelatedEntityPermissionHelper::ABSTAIN,
WorkflowRelatedEntityPermissionHelper::FORCE_GRANT,
];
}
}
/**
* @dataProvider dataProviderVoteOnAttributeWithoutStoredObjectPermission
* @dataProvider dataProviderVoteOnAttribute
*/
public function testVoteOnAttributeWithoutStoredObjectPermission(
public function testVoteOnAttribute(
StoredObjectRoleEnum $attribute,
bool $expected,
bool $canBeAssociatedWithWorkflow,
@@ -260,10 +239,7 @@ class AbstractStoredObjectVoterTest extends TestCase
$security = $this->prophesize(Security::class);
$security->isGranted('SOME_ROLE', $related)->willReturn($isGrantedRegularPermission);
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelper::class);
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($storedObject)->willReturn(WorkflowRelatedEntityPermissionHelper::ABSTAIN);
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForWriteOperation($storedObject)->willReturn(WorkflowRelatedEntityPermissionHelper::ABSTAIN);
$workflowRelatedEntityPermissionHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelperInterface::class);
if (null !== $isGrantedWorkflowPermissionRead) {
$workflowRelatedEntityPermissionHelper->isAllowedByWorkflowForReadOperation($related)
@@ -283,27 +259,155 @@ class AbstractStoredObjectVoterTest extends TestCase
self::assertEquals($expected, $voter->voteOnAttribute($attribute, $storedObject, $token), $message);
}
public static function dataProviderVoteOnAttributeWithoutStoredObjectPermission(): iterable
public static function dataProviderVoteOnAttribute(): iterable
{
// not associated on a workflow
yield [StoredObjectRoleEnum::SEE, true, false, true, null, null, 'not associated on a workflow, granted by regular access, must not rely on helper'];
yield [StoredObjectRoleEnum::SEE, false, false, false, null, null, 'not associated on a workflow, denied by regular access, must not rely on helper'];
// associated on a workflow, read operation
yield [StoredObjectRoleEnum::SEE, true, true, true, WorkflowRelatedEntityPermissionHelper::FORCE_GRANT, null, 'associated on a workflow, read by regular, force grant by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, true, true, true, WorkflowRelatedEntityPermissionHelper::ABSTAIN, null, 'associated on a workflow, read by regular, abstain by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, true, WorkflowRelatedEntityPermissionHelper::FORCE_DENIED, null, 'associated on a workflow, read by regular, force grant by workflow, ask for read, should be denied'];
yield [StoredObjectRoleEnum::SEE, true, true, false, WorkflowRelatedEntityPermissionHelper::FORCE_GRANT, null, 'associated on a workflow, denied read by regular, force grant by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, false, WorkflowRelatedEntityPermissionHelper::ABSTAIN, null, 'associated on a workflow, denied read by regular, abstain by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, false, WorkflowRelatedEntityPermissionHelper::FORCE_DENIED, null, 'associated on a workflow, denied read by regular, force grant by workflow, ask for read, should be denied'];
yield [StoredObjectRoleEnum::SEE, true, true, true, WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT, null, 'associated on a workflow, read by regular, force grant by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, true, true, true, WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN, null, 'associated on a workflow, read by regular, abstain by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, true, WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED, null, 'associated on a workflow, read by regular, force grant by workflow, ask for read, should be denied'];
yield [StoredObjectRoleEnum::SEE, true, true, false, WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT, null, 'associated on a workflow, denied read by regular, force grant by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, false, WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN, null, 'associated on a workflow, denied read by regular, abstain by workflow, ask for read, should be granted'];
yield [StoredObjectRoleEnum::SEE, false, true, false, WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED, null, 'associated on a workflow, denied read by regular, force grant by workflow, ask for read, should be denied'];
// association on a workflow, write operation
yield [StoredObjectRoleEnum::EDIT, true, true, true, null, WorkflowRelatedEntityPermissionHelper::FORCE_GRANT, 'associated on a workflow, write by regular, force grant by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, true, true, true, null, WorkflowRelatedEntityPermissionHelper::ABSTAIN, 'associated on a workflow, write by regular, abstain by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, true, null, WorkflowRelatedEntityPermissionHelper::FORCE_DENIED, 'associated on a workflow, write by regular, force grant by workflow, ask for write, should be denied'];
yield [StoredObjectRoleEnum::EDIT, true, true, false, null, WorkflowRelatedEntityPermissionHelper::FORCE_GRANT, 'associated on a workflow, denied write by regular, force grant by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, false, null, WorkflowRelatedEntityPermissionHelper::ABSTAIN, 'associated on a workflow, denied write by regular, abstain by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, false, null, WorkflowRelatedEntityPermissionHelper::FORCE_DENIED, 'associated on a workflow, denied write by regular, force grant by workflow, ask for write, should be denied'];
yield [StoredObjectRoleEnum::EDIT, true, true, true, null, WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT, 'associated on a workflow, write by regular, force grant by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, true, true, true, null, WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN, 'associated on a workflow, write by regular, abstain by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, true, null, WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED, 'associated on a workflow, write by regular, force grant by workflow, ask for write, should be denied'];
yield [StoredObjectRoleEnum::EDIT, true, true, false, null, WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT, 'associated on a workflow, denied write by regular, force grant by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, false, null, WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN, 'associated on a workflow, denied write by regular, abstain by workflow, ask for write, should be granted'];
yield [StoredObjectRoleEnum::EDIT, false, true, false, null, WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED, 'associated on a workflow, denied write by regular, force grant by workflow, ask for write, should be denied'];
}
/**
* @dataProvider dataProviderPrecedenceOfDirectAssociationOverWorkflowAttachments
*/
public function testPrecedenceOfDirectAssociationOverWorkflowAttachments(
StoredObjectRoleEnum $attribute,
bool $expected,
bool $regularPermission,
string $directWorkflowPermission,
string $attachmentWorkflowPermission,
string $message,
): void {
$storedObject = new StoredObject();
$repository = new DummyRepository($related = new \stdClass());
$token = new UsernamePasswordToken(new User(), 'dummy');
$security = $this->prophesize(Security::class);
$security->isGranted('SOME_ROLE', $related)->willReturn($regularPermission);
$workflowHelper = $this->prophesize(WorkflowRelatedEntityPermissionHelperInterface::class);
// Direct association permission
if (StoredObjectRoleEnum::SEE === $attribute) {
$workflowHelper->isAllowedByWorkflowForReadOperation($related)
->willReturn($directWorkflowPermission);
} else {
$workflowHelper->isAllowedByWorkflowForWriteOperation($related)
->willReturn($directWorkflowPermission);
}
// Attachment permission
$entityWorkflow = $this->prophesize(\Chill\MainBundle\Entity\Workflow\EntityWorkflow::class)->reveal();
$attachment = $this->prophesize(EntityWorkflowAttachment::class);
$attachment->getEntityWorkflow()->willReturn($entityWorkflow);
if (StoredObjectRoleEnum::SEE === $attribute) {
$workflowHelper->isAllowedByWorkflowForReadOperation($entityWorkflow)
->willReturn($attachmentWorkflowPermission);
} else {
$workflowHelper->isAllowedByWorkflowForWriteOperation($entityWorkflow)
->willReturn($attachmentWorkflowPermission);
}
$voter = $this->buildStoredObjectVoter(
true,
$repository,
$security->reveal(),
$workflowHelper->reveal(),
[$attachment->reveal()]
);
self::assertEquals($expected, $voter->voteOnAttribute($attribute, $storedObject, $token), $message);
}
public static function dataProviderPrecedenceOfDirectAssociationOverWorkflowAttachments(): iterable
{
$cases = [
[
'expected' => true,
'regular' => false,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
'message' => 'Direct FORCE_GRANT should win over attachment FORCE_DENIED',
],
[
'expected' => false,
'regular' => true,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
'message' => 'Direct FORCE_DENIED should win over attachment FORCE_GRANT',
],
[
'expected' => true,
'regular' => false,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'message' => 'Direct FORCE_GRANT should win over attachment ABSTAIN',
],
[
'expected' => false,
'regular' => true,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'message' => 'Direct FORCE_DENIED should win over attachment ABSTAIN',
],
[
'expected' => true,
'regular' => false,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_GRANT,
'message' => 'Direct ABSTAIN should let attachment FORCE_GRANT win',
],
[
'expected' => false,
'regular' => true,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::FORCE_DENIED,
'message' => 'Direct ABSTAIN should let attachment FORCE_DENIED win',
],
[
'expected' => true,
'regular' => true,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'message' => 'Both ABSTAIN should let regular permission (true) win',
],
[
'expected' => false,
'regular' => false,
'direct' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'attachment' => WorkflowRelatedEntityPermissionHelperInterface::ABSTAIN,
'message' => 'Both ABSTAIN should let regular permission (false) win',
],
];
foreach ([StoredObjectRoleEnum::SEE, StoredObjectRoleEnum::EDIT] as $attribute) {
foreach ($cases as $case) {
yield sprintf('%s - %s', $attribute->name, $case['message']) => [
$attribute,
$case['expected'],
$case['regular'],
$case['direct'],
$case['attachment'],
$case['message'],
];
}
}
}
}

View File

@@ -0,0 +1,21 @@
module.exports = function (encore) {
encore.addAliases({
ChillDocStoreAssets: __dirname + "/Resources/public",
});
encore.addEntry(
"mod_async_upload",
__dirname + "/Resources/public/module/async_upload/index.ts",
);
encore.addEntry(
"mod_document_action_buttons_group",
__dirname + "/Resources/public/module/document_action_buttons_group/index",
);
encore.addEntry(
"mod_document_download_button",
__dirname + "/Resources/public/module/button_download/index",
);
encore.addEntry(
"vue_document_signature",
__dirname + "/Resources/public/vuejs/DocumentSignature/index",
);
};

View File

@@ -1,15 +0,0 @@
export default {
aliases: {
ChillDocStoreAssets: "./src/Bundle/ChillDocStoreBundle/Resources/public",
},
inputs: {
mod_async_upload:
"./src/Bundle/ChillDocStoreBundle/Resources/public/module/async_upload/index.ts",
mod_document_action_buttons_group:
"./src/Bundle/ChillDocStoreBundle/Resources/public/module/document_action_buttons_group/index.ts",
mod_document_download_button:
"./src/Bundle/ChillDocStoreBundle/Resources/public/module/button_download/index.ts",
vue_document_signature:
"./src/Bundle/ChillDocStoreBundle/Resources/public/vuejs/DocumentSignature/index.ts",
},
};

View File

@@ -1 +1 @@
import("./chillevent.scss");
require("./chillevent.scss");

View File

@@ -1,10 +1,10 @@
{% extends '@ChillEvent/layout.html.twig' %} {% block js %}
{{ vite_entry_script_tags("mod_async_upload") }}
{{ vite_entry_script_tags("mod_pickentity_type") }}
{{ encore_entry_script_tags("mod_async_upload") }}
{{ encore_entry_script_tags("mod_pickentity_type") }}
{% endblock %} {% block css %}
{{ vite_entry_link_tags("mod_async_upload") }}
{{ vite_entry_link_tags("mod_pickentity_type") }}
{{ encore_entry_link_tags("mod_async_upload") }}
{{ encore_entry_link_tags("mod_pickentity_type") }}
{% endblock %} {% block title 'Event edit'|trans %} {% block event_content -%}
<div class="col-10">

View File

@@ -1,9 +1,9 @@
{% extends '@ChillEvent/layout.html.twig' %}
{% block css %}
{{ vite_entry_link_tags("mod_async_upload") }}
{{ vite_entry_link_tags("mod_pickentity_type") }}
{{ vite_entry_link_tags('vue_event') }}
{{ encore_entry_link_tags("mod_async_upload") }}
{{ encore_entry_link_tags("mod_pickentity_type") }}
{{ encore_entry_link_tags('vue_event') }}
{% endblock %}
{% block title 'Event creation'|trans %}
@@ -52,9 +52,9 @@
{% endblock %}
{% block js %}
{{ vite_entry_script_tags("mod_async_upload") }}
{{ vite_entry_script_tags("mod_pickentity_type") }}
{{ vite_entry_script_tags('vue_event') }}
{{ encore_entry_script_tags("mod_async_upload") }}
{{ encore_entry_script_tags("mod_pickentity_type") }}
{{ encore_entry_script_tags('vue_event') }}
<script type="text/javascript">
window.entity = {{ entity_json|json_encode|raw }};
{% if app.user.currentLocation is not null %}window.default_location_id = {{ app.user.currentLocation.id }};{% endif %}

View File

@@ -1,10 +1,10 @@
{% extends '@ChillEvent/layout.html.twig' %} {% block title 'Events'|trans %} {%
block js %}
{{ parent() }}
{{ vite_entry_script_tags("mod_pickentity_type") }}
{{ encore_entry_script_tags("mod_pickentity_type") }}
{% endblock %} {% block css %}
{{ parent() }}
{{ vite_entry_link_tags("mod_pickentity_type") }}
{{ encore_entry_link_tags("mod_pickentity_type") }}
{% endblock %} {% block content %}
<div class="col-10">
<h1>{{ block("title") }}</h1>

View File

@@ -6,14 +6,14 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock %}
{% macro insert_onthefly(type, entity, parent = null) %}

View File

@@ -14,6 +14,7 @@ namespace Chill\EventBundle\Security\Authorization;
use Chill\DocStoreBundle\Repository\AssociatedEntityToStoredObjectInterface;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectRoleEnum;
use Chill\DocStoreBundle\Security\Authorization\StoredObjectVoter\AbstractStoredObjectVoter;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowAttachmentRepository;
use Chill\MainBundle\Workflow\Helper\WorkflowRelatedEntityPermissionHelper;
use Chill\EventBundle\Entity\Event;
use Chill\EventBundle\Repository\EventRepository;
@@ -26,8 +27,9 @@ class EventStoredObjectVoter extends AbstractStoredObjectVoter
private readonly EventRepository $repository,
Security $security,
WorkflowRelatedEntityPermissionHelper $workflowDocumentService,
EntityWorkflowAttachmentRepository $attachmentRepository,
) {
parent::__construct($security, $workflowDocumentService);
parent::__construct($security, $attachmentRepository, $workflowDocumentService);
}
protected function getRepository(): AssociatedEntityToStoredObjectInterface

View File

@@ -0,0 +1,10 @@
module.exports = function (encore, entries) {
entries.push(__dirname + "/Resources/public/chill/index.js");
encore.addEntry(
"vue_event",
__dirname + "/Resources/public/vuejs/index.js",
);
};

View File

@@ -1,8 +0,0 @@
export default {
chillBase: [
"./src/Bundle/ChillEventBundle/Resources/public/chill/index.js",
],
inputs: {
vue_event: "./src/Bundle/ChillEventBundle/Resources/public/vuejs/index.js",
},
};

View File

@@ -1 +1 @@
import("./footer_bandeau.jpg");
require("./footer_bandeau.jpg");

View File

@@ -189,14 +189,14 @@ crud:
title_edit: Rapport "belemmering" bewerken
title_delete: Belemmering verwijderen
button_delete: Verwijderen
confirm_message_delete: %as_string% verwijderen?
confirm_message_delete: "%as_string% verwijderen?"
cscv:
title_new: Nieuw CV voor %person%
title_view: CV voor %person%
title_edit: CV bewerken
title_delete: CV verwijderen
button_delete: Verwijderen
confirm_message_delete: %as_string% verwijderen?
confirm_message_delete: "%as_string% verwijderen?"
no_date: Geen datum aangegeven
no_end_date: einddatum onbekend
no_start_date: startdatum onbekend
@@ -206,7 +206,7 @@ crud:
title_edit: Immersie bewerken
title_delete: Immersie verwijderen
button_delete: Verwijderen
confirm_message_delete: %as_string% verwijderen?
confirm_message_delete: "%as_string% verwijderen?"
projet_prof:
title_new: Nieuw professioneel project voor %person%
title_view: Professioneel project voor %person%

View File

@@ -1,7 +1,7 @@
{% extends '@ChillPerson/CRUD/edit.html.twig' %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block title 'Dispositifs de ' ~ entity.person.firstName ~ ' ' ~ entity.person.lastName %}
@@ -88,7 +88,7 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript" src="{{ asset('build/dispositifs_edit.js') }}"></script>
<script type="text/javascript">

View File

@@ -114,13 +114,13 @@
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock css %}
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript" src="{{ asset('build/personal_situation_edit.js') }}"></script>
{% endblock js %}

View File

@@ -274,12 +274,12 @@
{% block css %}
{{ parent() }}
{{ vite_entry_link_tags('mod_async_upload') }}
{{ vite_entry_script_tags('mod_document_action_buttons_group') }}
{{ encore_entry_link_tags('mod_async_upload') }}
{{ encore_entry_script_tags('mod_document_action_buttons_group') }}
{% endblock css %}
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_async_upload') }}
{{ vite_entry_link_tags('mod_document_action_buttons_group') }}
{{ encore_entry_script_tags('mod_async_upload') }}
{{ encore_entry_link_tags('mod_document_action_buttons_group') }}
{% endblock js %}

View File

@@ -4,7 +4,7 @@
{% set activeRouteKey = '' %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block title %}
@@ -66,6 +66,6 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript" src="{{ asset('build/immersion_edit.js') }}"></script>
{% endblock %}

View File

@@ -4,7 +4,7 @@
{% set activeRouteKey = '' %}
{% block css %}
{{ vite_entry_link_tags('mod_pickentity_type') }}
{{ encore_entry_link_tags('mod_pickentity_type') }}
{% endblock %}
{% block title %}
@@ -69,7 +69,7 @@
{% block js %}
{{ parent() }}
{{ vite_entry_script_tags('mod_pickentity_type') }}
{{ encore_entry_script_tags('mod_pickentity_type') }}
<script type="text/javascript" src="{{ asset('build/immersion_edit.js') }}"></script>
{% endblock %}

View File

@@ -0,0 +1,15 @@
module.exports = function (encore, chillEntries) {
let dispositif_edit_file =
__dirname + "/Resources/public/module/dispositif_edit/index.js",
personal_situation_edit_file =
__dirname + "/Resources/public/module/personal_situation/index.js",
cv_edit_file = __dirname + "/Resources/public/module/cv_edit/index.js",
immersion_edit_file =
__dirname + "/Resources/public/module/immersion_edit/index.js",
images = __dirname + "/Resources/public/images/index.js";
encore.addEntry("dispositifs_edit", dispositif_edit_file);
encore.addEntry("personal_situation_edit", personal_situation_edit_file);
encore.addEntry("immersion_edit", immersion_edit_file);
encore.addEntry("images", images);
encore.addEntry("cs_cv", cv_edit_file);
};

View File

@@ -1,13 +0,0 @@
export default {
inputs: {
dispositifs_edit:
"./src/Bundle/ChillJobBundle/src/Resources/public/module/dispositif_edit/index.js",
personal_situation_edit:
"./src/Bundle/ChillJobBundle/src/Resources/public/module/personal_situation/index.js",
immersion_edit:
"./src/Bundle/ChillJobBundle/src/Resources/public/module/immersion_edit/index.js",
images: "./src/Bundle/ChillJobBundle/src/Resources/public/images/index.js",
cs_cv:
"./src/Bundle/ChillJobBundle/src/Resources/public/module/cv_edit/index.js",
},
};

View File

@@ -1,12 +1,12 @@
@font-face {
/*font-family: 'open_sanssemibold';*/
font-family: 'Open Sans';
src: url('./opensans-semibold-webfont.eot');
src: url('./opensans-semibold-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-semibold-webfont.woff2') format('woff2'),
url('./opensans-semibold-webfont.woff') format('woff'),
url('./opensans-semibold-webfont.ttf') format('truetype'),
url('./opensans-semibold-webfont.svg#open_sanssemibold') format('svg');
src: url('opensans-semibold-webfont.eot');
src: url('opensans-semibold-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-semibold-webfont.woff2') format('woff2'),
url('opensans-semibold-webfont.woff') format('woff'),
url('opensans-semibold-webfont.ttf') format('truetype'),
url('opensans-semibold-webfont.svg#open_sanssemibold') format('svg');
font-weight: 600;
font-style: normal;
}
@@ -14,12 +14,12 @@
@font-face {
/*font-family: 'open_sanssemibold_italic';*/
font-family: 'Open Sans';
src: url('./opensans-semibolditalic-webfont.eot');
src: url('./opensans-semibolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-semibolditalic-webfont.woff2') format('woff2'),
url('./opensans-semibolditalic-webfont.woff') format('woff'),
url('./opensans-semibolditalic-webfont.ttf') format('truetype'),
url('./opensans-semibolditalic-webfont.svg#open_sanssemibold_italic') format('svg');
src: url('opensans-semibolditalic-webfont.eot');
src: url('opensans-semibolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-semibolditalic-webfont.woff2') format('woff2'),
url('opensans-semibolditalic-webfont.woff') format('woff'),
url('opensans-semibolditalic-webfont.ttf') format('truetype'),
url('opensans-semibolditalic-webfont.svg#open_sanssemibold_italic') format('svg');
font-weight: 600;
font-style: italic;
}
@@ -27,12 +27,12 @@
@font-face {
/*font-family: 'open_sansitalic';*/
font-family: 'Open Sans';
src: url('./opensans-italic-webfont.eot');
src: url('./opensans-italic-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-italic-webfont.woff2') format('woff2'),
url('./opensans-italic-webfont.woff') format('woff'),
url('./opensans-italic-webfont.ttf') format('truetype'),
url('./opensans-italic-webfont.svg#open_sansitalic') format('svg');
src: url('opensans-italic-webfont.eot');
src: url('opensans-italic-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-italic-webfont.woff2') format('woff2'),
url('opensans-italic-webfont.woff') format('woff'),
url('opensans-italic-webfont.ttf') format('truetype'),
url('opensans-italic-webfont.svg#open_sansitalic') format('svg');
font-weight: normal;
font-style: italic;
}
@@ -40,12 +40,12 @@
@font-face {
/*font-family: 'open_sanslight';*/
font-family: 'Open Sans';
src: url('./opensans-light-webfont.eot');
src: url('./opensans-light-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-light-webfont.woff2') format('woff2'),
url('./opensans-light-webfont.woff') format('woff'),
url('./opensans-light-webfont.ttf') format('truetype'),
url('./opensans-light-webfont.svg#open_sanslight') format('svg');
src: url('opensans-light-webfont.eot');
src: url('opensans-light-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-light-webfont.woff2') format('woff2'),
url('opensans-light-webfont.woff') format('woff'),
url('opensans-light-webfont.ttf') format('truetype'),
url('opensans-light-webfont.svg#open_sanslight') format('svg');
font-weight: 300;
font-style: normal;
}
@@ -53,12 +53,12 @@
@font-face {
/*font-family: 'open_sanslight_italic';*/
font-family: 'Open Sans';
src: url('./opensans-lightitalic-webfont.eot');
src: url('./opensans-lightitalic-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-lightitalic-webfont.woff2') format('woff2'),
url('./opensans-lightitalic-webfont.woff') format('woff'),
url('./opensans-lightitalic-webfont.ttf') format('truetype'),
url('./opensans-lightitalic-webfont.svg#open_sanslight_italic') format('svg');
src: url('opensans-lightitalic-webfont.eot');
src: url('opensans-lightitalic-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-lightitalic-webfont.woff2') format('woff2'),
url('opensans-lightitalic-webfont.woff') format('woff'),
url('opensans-lightitalic-webfont.ttf') format('truetype'),
url('opensans-lightitalic-webfont.svg#open_sanslight_italic') format('svg');
font-weight: 300;
font-style: italic;
}
@@ -66,12 +66,12 @@
@font-face {
/*font-family: 'open_sansregular';*/
font-family: 'Open Sans';
src: url('./opensans-regular-webfont.eot');
src: url('./opensans-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-regular-webfont.woff2') format('woff2'),
url('./opensans-regular-webfont.woff') format('woff'),
url('./opensans-regular-webfont.ttf') format('truetype'),
url('./opensans-regular-webfont.svg#open_sansregular') format('svg');
src: url('opensans-regular-webfont.eot');
src: url('opensans-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-regular-webfont.woff2') format('woff2'),
url('opensans-regular-webfont.woff') format('woff'),
url('opensans-regular-webfont.ttf') format('truetype'),
url('opensans-regular-webfont.svg#open_sansregular') format('svg');
font-weight: normal;
font-style: normal;
}
@@ -79,12 +79,12 @@
@font-face {
/*font-family: 'open_sansbold';*/
font-family: 'Open Sans';
src: url('./opensans-bold-webfont.eot');
src: url('./opensans-bold-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-bold-webfont.woff2') format('woff2'),
url('./opensans-bold-webfont.woff') format('woff'),
url('./opensans-bold-webfont.ttf') format('truetype'),
url('./opensans-bold-webfont.svg#open_sansbold') format('svg');
src: url('opensans-bold-webfont.eot');
src: url('opensans-bold-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-bold-webfont.woff2') format('woff2'),
url('opensans-bold-webfont.woff') format('woff'),
url('opensans-bold-webfont.ttf') format('truetype'),
url('opensans-bold-webfont.svg#open_sansbold') format('svg');
font-weight: bold;
font-style: normal;
}
@@ -92,12 +92,12 @@
@font-face {
/*font-family: 'open_sansbold_italic';*/
font-family: 'Open Sans';
src: url('./opensans-bolditalic-webfont.eot');
src: url('./opensans-bolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-bolditalic-webfont.woff2') format('woff2'),
url('./opensans-bolditalic-webfont.woff') format('woff'),
url('./opensans-bolditalic-webfont.ttf') format('truetype'),
url('./opensans-bolditalic-webfont.svg#open_sansbold_italic') format('svg');
src: url('opensans-bolditalic-webfont.eot');
src: url('opensans-bolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-bolditalic-webfont.woff2') format('woff2'),
url('opensans-bolditalic-webfont.woff') format('woff'),
url('opensans-bolditalic-webfont.ttf') format('truetype'),
url('opensans-bolditalic-webfont.svg#open_sansbold_italic') format('svg');
font-weight: bold;
font-style: italic;
@@ -106,12 +106,12 @@
@font-face {
/*font-family: 'open_sansextrabold';*/
font-family: 'Open Sans';
src: url('./opensans-extrabold-webfont.eot');
src: url('./opensans-extrabold-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-extrabold-webfont.woff2') format('woff2'),
url('./opensans-extrabold-webfont.woff') format('woff'),
url('./opensans-extrabold-webfont.ttf') format('truetype'),
url('./opensans-extrabold-webfont.svg#open_sansextrabold') format('svg');
src: url('opensans-extrabold-webfont.eot');
src: url('opensans-extrabold-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-extrabold-webfont.woff2') format('woff2'),
url('opensans-extrabold-webfont.woff') format('woff'),
url('opensans-extrabold-webfont.ttf') format('truetype'),
url('opensans-extrabold-webfont.svg#open_sansextrabold') format('svg');
font-weight: 800;
font-style: normal;
}
@@ -119,12 +119,12 @@
@font-face {
/*font-family: 'open_sansextrabold_italic';*/
font-family: 'Open Sans';
src: url('./opensans-extrabolditalic-webfont.eot');
src: url('./opensans-extrabolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('./opensans-extrabolditalic-webfont.woff2') format('woff2'),
url('./opensans-extrabolditalic-webfont.woff') format('woff'),
url('./opensans-extrabolditalic-webfont.ttf') format('truetype'),
url('./opensans-extrabolditalic-webfont.svg#open_sansextrabold_italic') format('svg');
src: url('opensans-extrabolditalic-webfont.eot');
src: url('opensans-extrabolditalic-webfont.eot?#iefix') format('embedded-opentype'),
url('opensans-extrabolditalic-webfont.woff2') format('woff2'),
url('opensans-extrabolditalic-webfont.woff') format('woff'),
url('opensans-extrabolditalic-webfont.ttf') format('truetype'),
url('opensans-extrabolditalic-webfont.svg#open_sansextrabold_italic') format('svg');
font-weight: 800;
font-style: italic;
}
}

View File

@@ -4,49 +4,44 @@
*/
/// import jQuery
import $ from "jquery";
// expose jQuery globally for plugins expecting it
window.$ = window.jQuery = $;
const $ = require("jquery");
global.$ = global.jQuery = $;
/// import select2 (relies on global jQuery)
import "select2/dist/js/select2.full";
window.select2 = window.select2 || window.$?.fn?.select2;
/// import select2
const select2 = require("select2");
global.select2 = select2;
import "select2/dist/css/select2.css";
import "select2-bootstrap-theme/dist/select2-bootstrap.css";
// Global vendor styles
import "vue-multiselect/dist/vue-multiselect.css";
import "vis-network/dist/dist/vis-network.min.css";
require("select2/dist/css/select2.css");
require("select2-bootstrap-theme/dist/select2-bootstrap.css");
/*
* Load Chill themes assets
*/
import "./chillmain.scss";
require("./chillmain.scss");
import { chill } from "./js/chill.js";
// expose chill helper globally for legacy inline scripts
window.chill = chill;
global.chill = chill;
import "./js/date";
import "./js/counter.js";
require("./js/date");
require("./js/counter.js");
/// Load fonts
import "./fonts/OpenSans/OpenSans.scss";
require("./fonts/OpenSans/OpenSans.scss");
/// Load images
import "./img/favicon.ico";
import "./img/logo-chill-sans-slogan_white.png";
import "./img/logo-chill-outil-accompagnement_white.png";
require("./img/favicon.ico");
require("./img/logo-chill-sans-slogan_white.png");
require("./img/logo-chill-outil-accompagnement_white.png");
/*
* Load local libs
* Some libs are only used in a few pages, they are loaded on a case by case basis
*/
import "../lib/breadcrumb/index.js";
import "../lib/download-report/index.js";
import "../lib/select_interactive_loading/index.js";
require("../lib/breadcrumb/index.js");
require("../lib/download-report/index.js");
require("../lib/select_interactive_loading/index.js");
//require('../lib/show_hide/index.js');
//require('../lib/tabs/index.js');

View File

@@ -1 +1 @@
import "./layout.scss";
require("./layout.scss");

View File

@@ -14,8 +14,5 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { download_report } from "./download-report.js";
// Ensure global namespace exists, then expose for legacy usage
window.chill = window.chill || {};
window.chill.download_report = download_report;
chill.download_report = require("./download-report.js");

View File

@@ -1,2 +1,2 @@
import "./tabs.js";
import "./tabs.scss";
require("./tabs.js");
require("./tabs.scss");

View File

@@ -1,4 +1,4 @@
import "./blur.scss";
require("./blur.scss");
document.querySelectorAll(".confidential").forEach(function (el) {
let i = document.createElement("i");

View File

@@ -1,8 +1,8 @@
// Compile all bootstrap assets from nodes-modules
//require('bootstrap/scss/bootstrap.scss')
// Or compile bootstrap only enabled assets (use ESM import so Vite processes CSS in dev)
import "./bootstrap.scss";
// Or compile bootstrap only enabled assets
require("./bootstrap.scss");
// You can specify which plugins you need
import Dropdown from "bootstrap/js/src/dropdown";

Some files were not shown because too many files have changed in this diff Show More