Merge branch '333-working-with-translations' into 'master'

Setup alias for use in standalone chill-bundles project and replace relative paths

Closes #333

See merge request Chill-Projet/chill-bundles!766
This commit is contained in:
Julien Fastré 2025-02-19 10:57:59 +00:00
commit 02f555efae
42 changed files with 924 additions and 9449 deletions

View File

@ -0,0 +1,6 @@
kind: DX
body: Create an unique source of trust for translations
time: 2025-01-31T13:18:01.239211506+01:00
custom:
Issue: "333"
SchemaChange: No schema change

1
.gitignore vendored
View File

@ -12,6 +12,7 @@ docker/rabbitmq/data
# in this development bundle, we want to ignore directories related to a real app
assets/*
!assets/translator.ts
migrations/*
templates/*
translations/*

View File

@ -113,7 +113,7 @@ lint:
- export PATH="./node_modules/.bin:$PATH"
script:
- yarn install --ignore-optional
- npx eslint-baseline "**/*.{js,vue}"
- npx eslint-baseline "src/**/*.{js,ts,vue}"
cache:
paths:
- node_modules/

9
assets/translator.ts Normal file
View File

@ -0,0 +1,9 @@
// @ts-ignore Cannot find module (when used within an app)
import { trans, getLocale, setLocale, setLocaleFallbacks } from "@symfony/ux-translator";
setLocaleFallbacks({"en": "fr", "nl": "fr", "fr": "en"});
setLocale('fr');
export { trans };
// @ts-ignore Cannot find module (when used within an app)
export * from '../var/translations';

View File

@ -75,6 +75,7 @@
"symfony/templating": "^5.4",
"symfony/translation": "^5.4",
"symfony/twig-bundle": "^5.4",
"symfony/ux-translator": "^2.22",
"symfony/validator": "^5.4",
"symfony/webpack-encore-bundle": "^1.11",
"symfony/workflow": "^5.4",

View File

@ -36,4 +36,5 @@ return [
Chill\BudgetBundle\ChillBudgetBundle::class => ['all' => true],
Chill\WopiBundle\ChillWopiBundle::class => ['all' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Symfony\UX\Translator\UxTranslatorBundle::class => ['all' => true],
];

View File

@ -0,0 +1,3 @@
ux_translator:
# The directory where the JavaScript translations are dumped
dump_directory: '%kernel.project_dir%/var/translations'

View File

@ -29,8 +29,7 @@ We strongly encourage you to initialize a git repository at this step, to track
# add the flex endpoints required for custom recipes
cat <<< "$(jq '.extra.symfony += {"endpoint": ["flex://defaults", "https://gitlab.com/api/v4/projects/57371968/repository/files/index.json/raw?ref=main"]}' composer.json)" > composer.json
# install chill and some dependencies
# TODO fix the suffix "alpha1" and replace by ^3.0.0 when version 3.0.0 will be released
symfony composer require chill-project/chill-bundles v3.0.0-RC3 champs-libres/wopi-lib dev-master@dev champs-libres/wopi-bundle dev-master@dev
symfony composer require chill-project/chill-bundles ^3.7.1 champs-libres/wopi-lib dev-master@dev champs-libres/wopi-bundle dev-master@dev symfony/amqp-messenger
We encourage you to accept the inclusion of the "Docker configuration from recipes": this is the documented way to run the database.
You must also accept to configure recipes from the contrib repository, unless you want to configure the bundles manually).
@ -48,7 +47,7 @@ You must also accept to configure recipes from the contrib repository, unless yo
If you encounter this error during assets compilation (:code:`yarn run encore production`) (repeated multiple times):
.. code-block:: txt
.. code-block::
[tsl] ERROR in /tmp/chill/v1/public/bundles/chillcalendar/types.ts(2,65)
TS2307: Cannot find module '../../../ChillMainBundle/Resources/public/types' or its corresponding type declarations.
@ -74,14 +73,22 @@ or in the :code:`.env.local` file, which should not be committed to the git repo
You do not need to set variables for the smtp server, redis server and relatorio server, as they are generated automatically
by the symfony server, from the docker compose services.
The only required variable is the :code:`ADMIN_PASSWORD`. You can generate a hashed and salted admin password using the command
:code:`symfony console security:hash-password <your password> 'Symfony\Component\Security\Core\User\User'`. Then,
The required variables are:
- the :code:`ADMIN_PASSWORD`;
- the :code:`OVHCLOUD_DSN` variable;
:code:`ADMIN_PASSWORD`
^^^^^^^^^^^^^^^^^^^^^^
You can generate a hashed and salted admin password using the command
:code:`symfony console security:hash-password <your password> 'Symfony\Component\Security\Core\User\User'`.Then,
you can either:
- add this password to the :code:`.env.local` file, you must escape the character :code:`$`: if the generated password
is :code:`$2y$13$iyvJLuT4YEa6iWXyQV4/N.hNHpNG8kXlYDkkt5MkYy4FXcSwYAwmm`, your :code:`.env.local` file will be:
.. code-block:: env
.. code-block:: bash
ADMIN_PASSWORD=\$2y\$13\$iyvJLuT4YEa6iWXyQV4/N.hNHpNG8kXlYDkkt5MkYy4FXcSwYAwmm
# note: if you copy-paste the line above, the password will be "admin".
@ -89,12 +96,24 @@ you can either:
- add the generated password to the secrets manager (**note**: you must add the generated hashed password to the secrets env,
not the password in clear text).
- set up the jwt authentication bundle
:code:`OVHCLOUD_DSN` and sending SMS messages
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is a temporary dependency, for ensuring compatibility for previous behaviour.
You can set it to :code:`null://null` if you do not plan to use sending SMS.
.. code-block:: bash
OVHCLOUD_DSN=null://null
If you plan to do it, you can configure the notifier component `as described in the symfony documentation <https://symfony.com/doc/current/notifier.html#notifier-sms-channel>`_.
Some environment variables are available for the JWT authentication bundle in the :code:`.env` file.
Prepare migrations and other tools
----------------------------------
Prepare database, messenger queue, and other configuration
----------------------------------------------------------
To continue the installation process, you will have to run migrations:
@ -114,14 +133,17 @@ To continue the installation process, you will have to run migrations:
# generate jwt token, required for some api features (webdav access, ...)
symfony console lexik:jwt:generate-keypair
.. warning::
.. note::
If you encounter an error while running :code:`symfony console messenger:setup-transports`, you can set up the messenger
transport to redis, by adding this in the :code:`.env.local` or :code:`.env` file:
If you encounter this error:
.. code-block::
No transport supports the given Messenger DSN.
Please check that you installed the package `symfony/amqp-messenger`.
.. code-block:: env
MESSENGER_TRANSPORT_DSN=redis://${REDIS_HOST}:${REDIS_PORT}/messages
Start your web server locally
-----------------------------

View File

@ -6,15 +6,11 @@
"@apidevtools/swagger-cli": "^4.0.4",
"@babel/core": "^7.20.5",
"@babel/preset-env": "^7.20.2",
"@ckeditor/ckeditor5-build-classic": "^41.4.2",
"@ckeditor/ckeditor5-dev-translations": "^40.2.0",
"@ckeditor/ckeditor5-dev-utils": "^40.2.0",
"@ckeditor/ckeditor5-dev-webpack-plugin": "^31.1.13",
"@ckeditor/ckeditor5-markdown-gfm": "^41.4.2",
"@ckeditor/ckeditor5-theme-lark": "^41.4.2",
"@ckeditor/ckeditor5-vue": "^5.1.0",
"@ckeditor/ckeditor5-vue": "^7.3.0",
"@eslint/js": "^9.14.0",
"@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",
@ -23,12 +19,14 @@
"bindings": "^1.5.0",
"bootstrap": "5.2.3",
"chokidar": "^3.5.1",
"ckeditor5": "^44.1.0",
"dompurify": "^3.1.0",
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.30.0",
"fork-awesome": "^1.1.7",
"intl-messageformat": "^10.5.11",
"jquery": "^3.6.0",
"node-sass": "^8.0.0",
"popper.js": "^1.16.1",
@ -54,6 +52,7 @@
"@fullcalendar/timegrid": "^6.1.4",
"@fullcalendar/vue3": "^6.1.4",
"@popperjs/core": "^2.9.2",
"@tsconfig/node20": "^20.1.4",
"@types/dompurify": "^3.0.5",
"@types/leaflet": "^1.9.3",
"bootstrap-icons": "^1.11.3",
@ -72,7 +71,7 @@
"vuex": "^4.0.0"
},
"browserslist": [
"Firefox ESR"
"defaults and fully supports es6-module and not dead"
],
"scripts": {
"dev-server": "encore dev-server",

View File

@ -30,13 +30,14 @@
<ul class="record_actions">
<li class="add-persons">
<add-persons
button-title="activity.add_persons"
modal-title="activity.add_persons"
:key="addPersons.key"
:options="addPersonsOptions"
@add-new-persons="addNewPersons"
:buttonTitle="trans(ACTIVITY_ADD_PERSONS)"
:modalTitle="trans(ACTIVITY_ADD_PERSONS)"
v-bind:key="addPersons.key"
v-bind:options="addPersonsOptions"
@addNewPersons="addNewPersons"
ref="addPersons"
/>
>
</add-persons>
</li>
</ul>
</teleport>
@ -47,6 +48,14 @@ import { mapState, mapGetters } from "vuex";
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
import PersonsBloc from "./ConcernedGroups/PersonsBloc.vue";
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
import {
ACTIVITY_BLOC_PERSONS,
ACTIVITY_BLOC_PERSONS_ASSOCIATED,
ACTIVITY_BLOC_THIRDPARTY,
ACTIVITY_BLOC_USERS,
ACTIVITY_ADD_PERSONS,
trans,
} from "translator";
export default {
name: "ConcernedGroups",
@ -55,18 +64,24 @@ export default {
PersonsBloc,
PersonText,
},
setup() {
return {
trans,
ACTIVITY_ADD_PERSONS,
};
},
data() {
return {
personsBlocs: [
{
key: "persons",
title: "activity.bloc_persons",
title: trans(ACTIVITY_BLOC_PERSONS),
persons: [],
included: false,
},
{
key: "personsAssociated",
title: "activity.bloc_persons_associated",
title: trans(ACTIVITY_BLOC_PERSONS_ASSOCIATED),
persons: [],
included: window.activity
? window.activity.activityType.personsVisible !== 0
@ -82,7 +97,7 @@ export default {
},
{
key: "thirdparty",
title: "activity.bloc_thirdparty",
title: trans(ACTIVITY_BLOC_THIRDPARTY),
persons: [],
included: window.activity
? window.activity.activityType.thirdPartiesVisible !== 0
@ -90,7 +105,7 @@ export default {
},
{
key: "users",
title: "activity.bloc_users",
title: trans(ACTIVITY_BLOC_USERS),
persons: [],
included: window.activity
? window.activity.activityType.usersVisible !== 0

View File

@ -2,7 +2,7 @@
<teleport to="#location">
<div class="mb-3 row">
<label :class="locationClassList">
{{ $t("activity.location") }}
{{ trans(ACTIVITY_LOCATION) }}
</label>
<div class="col-sm-8">
<VueMultiselect
@ -13,17 +13,17 @@
open-direction="top"
:multiple="false"
:searchable="true"
:placeholder="$t('activity.choose_location')"
:placeholder="trans(ACTIVITY_CHOOSE_LOCATION)"
:custom-label="customLabel"
:select-label="$t('multiselect.select_label')"
:deselect-label="$t('multiselect.deselect_label')"
:selected-label="$t('multiselect.selected_label')"
:select-label="trans(MULTISELECT_SELECT_LABEL)"
:deselect-label="trans(MULTISELECT_DESELECT_LABEL)"
:selected-label="trans(MULTISELECT_SELECTED_LABEL)"
:options="availableLocations"
group-values="locations"
group-label="locationGroup"
v-model="location"
/>
<new-location :available-locations="availableLocations" />
<new-location v-bind:available-locations="availableLocations" />
</div>
</div>
</teleport>
@ -33,6 +33,14 @@
import { mapState, mapGetters } from "vuex";
import VueMultiselect from "vue-multiselect";
import NewLocation from "./Location/NewLocation.vue";
import {
trans,
ACTIVITY_LOCATION,
ACTIVITY_CHOOSE_LOCATION,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
MULTISELECT_SELECTED_LABEL,
} from "translator";
export default {
name: "Location",
@ -40,6 +48,16 @@ export default {
NewLocation,
VueMultiselect,
},
setup() {
return {
trans,
ACTIVITY_LOCATION,
ACTIVITY_CHOOSE_LOCATION,
MULTISELECT_SELECT_LABEL,
MULTISELECT_DESELECT_LABEL,
MULTISELECT_SELECTED_LABEL,
};
},
data() {
return {
locationClassList: `col-form-label col-sm-4 ${document.querySelector("input#chill_activitybundle_activity_location").getAttribute("required") ? "required" : ""}`,

View File

@ -3,7 +3,7 @@
<ul class="record_actions">
<li>
<a class="btn btn-sm btn-create" @click="openModal">
{{ $t("activity.create_new_location") }}
{{ trans(ACTIVITY_CREATE_NEW_LOCATION) }}
</a>
</li>
</ul>
@ -11,12 +11,12 @@
<teleport to="body">
<modal
v-if="modal.showModal"
:modal-dialog-class="modal.modalDialogClass"
:modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false"
>
<template #header>
<h3 class="modal-title">
{{ $t("activity.create_new_location") }}
{{ trans(ACTIVITY_CREATE_NEW_LOCATION) }}
</h3>
</template>
<template #body>
@ -37,7 +37,7 @@
v-model="selectType"
>
<option selected disabled value="">
{{ $t("activity.choose_location_type") }}
{{ trans(ACTIVITY_CHOOSE_LOCATION_TYPE) }}
</option>
<option
v-for="t in locationTypes"
@ -48,7 +48,7 @@
</option>
</select>
<label>{{
$t("activity.location_fields.type")
trans(ACTIVITY_LOCATION_FIELDS_TYPE)
}}</label>
</div>
@ -60,14 +60,14 @@
placeholder
/>
<label for="name">{{
$t("activity.location_fields.name")
trans(ACTIVITY_LOCATION_FIELDS_NAME)
}}</label>
</div>
<add-address
:context="addAddress.context"
:options="addAddress.options"
:address-changed-callback="submitNewAddress"
:addressChangedCallback="submitNewAddress"
v-if="showAddAddress"
ref="addAddress"
/>
@ -80,7 +80,7 @@
placeholder
/>
<label for="phonenumber1">{{
$t("activity.location_fields.phonenumber1")
trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER1)
}}</label>
</div>
<div class="form-floating mb-3" v-if="hasPhonenumber1">
@ -91,7 +91,7 @@
placeholder
/>
<label for="phonenumber2">{{
$t("activity.location_fields.phonenumber2")
trans(ACTIVITY_LOCATION_FIELDS_PHONENUMBER2)
}}</label>
</div>
<div class="form-floating mb-3" v-if="showContactData">
@ -102,7 +102,7 @@
placeholder
/>
<label for="email">{{
$t("activity.location_fields.email")
trans(ACTIVITY_LOCATION_FIELDS_EMAIL)
}}</label>
</div>
</form>
@ -112,7 +112,7 @@
class="btn btn-save"
@click.prevent="saveNewLocation"
>
{{ $t("action.save") }}
{{ trans(SAVE) }}
</button>
</template>
</modal>
@ -126,6 +126,17 @@ import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue"
import { mapState } from "vuex";
import { getLocationTypes } from "../../api";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import {
SAVE,
ACTIVITY_LOCATION_FIELDS_EMAIL,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER1,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER2,
ACTIVITY_LOCATION_FIELDS_NAME,
ACTIVITY_LOCATION_FIELDS_TYPE,
ACTIVITY_CHOOSE_LOCATION_TYPE,
ACTIVITY_CREATE_NEW_LOCATION,
trans,
} from "translator";
export default {
name: "NewLocation",
@ -133,6 +144,19 @@ export default {
Modal,
AddAddress,
},
setup() {
return {
trans,
SAVE,
ACTIVITY_LOCATION_FIELDS_EMAIL,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER1,
ACTIVITY_LOCATION_FIELDS_PHONENUMBER2,
ACTIVITY_LOCATION_FIELDS_NAME,
ACTIVITY_LOCATION_FIELDS_TYPE,
ACTIVITY_CHOOSE_LOCATION_TYPE,
ACTIVITY_CREATE_NEW_LOCATION,
};
},
props: ["availableLocations"],
data() {
return {

View File

@ -3,7 +3,7 @@
<div class="mb-3 row">
<div class="col-4">
<label :class="socialIssuesClassList">{{
$t("activity.social_issues")
trans(ACTIVITY_SOCIAL_ISSUES)
}}</label>
</div>
<div class="col-8">
@ -12,8 +12,9 @@
:key="issue.id"
:issue="issue"
:selection="socialIssuesSelected"
@update-selected="updateIssuesSelected"
/>
@updateSelected="updateIssuesSelected"
>
</check-social-issue>
<div class="my-3">
<VueMultiselect
@ -31,10 +32,11 @@
:allow-empty="true"
:show-labels="false"
:loading="issueIsLoading"
:placeholder="$t('activity.choose_other_social_issue')"
:placeholder="trans(ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE)"
:options="socialIssuesOther"
@select="addIssueInList"
/>
>
</VueMultiselect>
</div>
</div>
</div>
@ -42,26 +44,28 @@
<div class="mb-3 row">
<div class="col-4">
<label :class="socialActionsClassList">{{
$t("activity.social_actions")
trans(ACTIVITY_SOCIAL_ACTIONS)
}}</label>
</div>
<div class="col-8">
<div v-if="actionIsLoading === true">
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg" />
<i
class="chill-green fa fa-circle-o-notch fa-spin fa-lg"
></i>
</div>
<span
v-else-if="socialIssuesSelected.length === 0"
class="inline-choice chill-no-data-statement mt-3"
>
{{ $t("activity.select_first_a_social_issue") }}
{{ trans(ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE) }}
</span>
<template v-else-if="socialActionsList.length > 0">
<div
v-if="
socialIssuesSelected.length ||
socialActionsSelected.length
<template
v-else-if="
socialActionsList.length > 0 &&
(socialIssuesSelected.length ||
socialActionsSelected.length)
"
>
<check-social-action
@ -69,9 +73,9 @@
:key="action.id"
:action="action"
:selection="socialActionsSelected"
@update-selected="updateActionsSelected"
/>
</div>
@updateSelected="updateActionsSelected"
>
</check-social-action>
</template>
<span
@ -80,7 +84,7 @@
"
class="inline-choice chill-no-data-statement mt-3"
>
{{ $t("activity.social_action_list_empty") }}
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
</span>
</div>
</div>
@ -92,6 +96,14 @@ import VueMultiselect from "vue-multiselect";
import CheckSocialIssue from "./SocialIssuesAcc/CheckSocialIssue.vue";
import CheckSocialAction from "./SocialIssuesAcc/CheckSocialAction.vue";
import { getSocialIssues, getSocialActionByIssue } from "../api.js";
import {
ACTIVITY_SOCIAL_ACTION_LIST_EMPTY,
ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE,
ACTIVITY_SOCIAL_ACTIONS,
ACTIVITY_SOCIAL_ISSUES,
ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE,
trans,
} from "translator";
export default {
name: "SocialIssuesAcc",
@ -100,6 +112,16 @@ export default {
CheckSocialAction,
VueMultiselect,
},
setup() {
return {
trans,
ACTIVITY_SOCIAL_ACTION_LIST_EMPTY,
ACTIVITY_SELECT_FIRST_A_SOCIAL_ISSUE,
ACTIVITY_SOCIAL_ACTIONS,
ACTIVITY_SOCIAL_ISSUES,
ACTIVITY_CHOOSE_OTHER_SOCIAL_ISSUE,
};
},
data() {
return {
issueIsLoading: false,
@ -133,7 +155,7 @@ export default {
this.actionAreLoaded = false;
getSocialIssues().then(
(response) =>
new Promise((resolve, reject) => {
new Promise((resolve) => {
this.$store.commit("updateIssuesOther", response.results);
/* Add in list the issues already associated (if not yet listed)
@ -208,7 +230,7 @@ export default {
this.actionIsLoading = true;
getSocialActionByIssue(item.id).then(
(actions) =>
new Promise((resolve, reject) => {
new Promise((resolve) => {
actions.results.forEach((action) => {
this.$store.commit("addActionInList", action);
}, this);
@ -235,7 +257,6 @@ export default {
};
</script>
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
<style lang="scss" scoped>
span.multiselect__single {
display: none !important;

View File

@ -102,6 +102,32 @@ activity:
Remove a document: Supprimer le document
comment: Commentaire
deleted: Échange supprimé
errors: Le formulaire contient des erreurs
social_issues: Problématiques sociales
choose_other_social_issue: Ajouter une autre problématique sociale...
social_actions: Actions d'accompagnement
select_first_a_social_issue: Sélectionnez d'abord une problématique sociale
social_action_list_empty: Aucune action sociale disponible
add_persons: Ajouter des personnes concernées
bloc_persons: Usagers
bloc_persons_associated: Usagers du parcours
bloc_persons_not_associated: Tiers non-pro.
bloc_thirdparty: Tiers professionnels
bloc_users: T(M)S
location: Localisation
choose_location: Choisissez une localisation
choose_location_type: Choisissez un type de localisation
create_new_location: Créer une nouvelle localisation
location_fields:
name: Nom
type: Type
phonenumber1: Téléphone
phonenumber2: Autre téléphone
email: Adresse courriel
create_address: Créer une adresse
edit_address: Modifier l'adresse
No documents: Aucun document
# activity filter in list page

View File

@ -1,9 +1,5 @@
#events
Name: Nom
Label: Nom
Date: Date
Event type : Type d'événement
See: Voir
Event: Événement
Events: Événements
'Event : %label%': Événement "%label%"
@ -123,7 +119,6 @@ Role: Rôles
Role creation: Nouveau rôle
Role edit: Modifier un rôle
'': ''
xlsx: xlsx
ods: ods
csv: csv

View File

@ -1,30 +1,32 @@
import ClassicEditorBase from "@ckeditor/ckeditor5-editor-classic/src/classiceditor";
import EssentialsPlugin from "@ckeditor/ckeditor5-essentials/src/essentials";
import MarkdownPlugin from "@ckeditor/ckeditor5-markdown-gfm/src/markdown";
import BoldPlugin from "@ckeditor/ckeditor5-basic-styles/src/bold";
import ItalicPlugin from "@ckeditor/ckeditor5-basic-styles/src/italic";
import BlockQuotePlugin from "@ckeditor/ckeditor5-block-quote/src/blockquote";
import HeadingPlugin from "@ckeditor/ckeditor5-heading/src/heading";
import LinkPlugin from "@ckeditor/ckeditor5-link/src/link";
import ListPlugin from "@ckeditor/ckeditor5-list/src/list";
import ParagraphPlugin from "@ckeditor/ckeditor5-paragraph/src/paragraph";
import {
Essentials,
Bold,
Italic,
Paragraph,
Markdown,
BlockQuote,
Heading,
Link,
List,
} from "ckeditor5";
import coreTranslations from "ckeditor5/translations/fr.js";
import "ckeditor5/ckeditor5.css";
import "./index.scss";
export default class ClassicEditor extends ClassicEditorBase {}
ClassicEditor.builtinPlugins = [
EssentialsPlugin,
MarkdownPlugin,
BoldPlugin,
ItalicPlugin,
BlockQuotePlugin,
HeadingPlugin,
LinkPlugin,
ListPlugin,
ParagraphPlugin,
];
ClassicEditor.defaultConfig = {
export default {
plugins: [
Essentials,
Markdown,
Bold,
Italic,
BlockQuote,
Heading,
Link,
List,
Paragraph,
],
toolbar: {
items: [
"heading",
@ -39,5 +41,6 @@ ClassicEditor.defaultConfig = {
"redo",
],
},
language: "fr",
translations: [coreTranslations],
licenseKey: "GPL",
};

View File

@ -1,14 +1,12 @@
import ClassicEditor from "./editor_config";
import config from "./editor_config";
import { ClassicEditor } from "ckeditor5";
const ckeditorFields: NodeListOf<HTMLTextAreaElement> =
document.querySelectorAll("textarea[ckeditor]");
ckeditorFields.forEach((field: HTMLTextAreaElement): void => {
ClassicEditor.create(field)
.then((editor) => {
//console.log( 'CkEditor was initialized', editor );
})
.catch((error) => {
ClassicEditor.create(field, config).catch((error) => {
console.error(error.stack);
throw error;
});
});
//Fields.push.apply(Fields, document.querySelectorAll('.cf-fields textarea'));

View File

@ -1,11 +1,10 @@
import { createApp } from "vue";
import NotificationReadToggle from "ChillMainAssets/vuejs/_components/Notification/NotificationReadToggle.vue";
import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
import NotificationReadAllToggle from "ChillMainAssets/vuejs/_components/Notification/NotificationReadAllToggle.vue";
const i18n = _createI18n({});
window.addEventListener("DOMContentLoaded", function (e) {
window.addEventListener("DOMContentLoaded", function () {
document
.querySelectorAll(".notification_toggle_read_status")
.forEach(function (el, i) {

View File

@ -70,7 +70,8 @@ const clickOnAddButton = () => {
<style scoped lang="scss">
.item-bloc {
&.isPicked {
background: linear-gradient(
background:
linear-gradient(
180deg,
rgba(25, 135, 84, 1) 0px,
rgba(25, 135, 84, 0) 9px

View File

@ -1,61 +1,65 @@
<template>
<span v-if="entity.type === 'person'" class="badge rounded-pill bg-person">
{{ $t("person") }}
<span
v-if="props.entity.type === 'person'"
class="badge rounded-pill bg-person"
>
{{ trans(PERSON) }}
</span>
<span
v-if="entity.type === 'thirdparty'"
v-if="props.entity.type === 'thirdparty'"
class="badge rounded-pill bg-thirdparty"
>
<template v-if="options.displayLong !== true">
{{ $t("thirdparty.thirdparty") }}
<template v-if="props.options.displayLong !== true">
{{ trans(THIRDPARTY) }}
</template>
<i class="fa fa-fw fa-user" v-if="entity.kind === 'child'" />
<i class="fa fa-fw fa-user" v-if="props.entity.kind === 'child'" />
<i
class="fa fa-fw fa-hospital-o"
v-else-if="entity.kind === 'company'"
v-else-if="props.entity.kind === 'company'"
/>
<i class="fa fa-fw fa-user-md" v-else />
<template v-if="options.displayLong === true">
<span v-if="entity.kind === 'child'">{{
$t("thirdparty.child")
<template v-if="props.options.displayLong === true">
<span v-if="props.entity.kind === 'child'">{{
trans(THIRDPARTY_CONTACT_OF)
}}</span>
<span v-else-if="entity.kind === 'company'">{{
$t("thirdparty.company")
<span v-else-if="props.entity.kind === 'company'">{{
trans(THIRDPARTY_A_CONTACT)
}}</span>
<span v-else>{{ $t("thirdparty.contact") }}</span>
</template>
</span>
<span v-if="entity.type === 'user'" class="badge rounded-pill bg-user">
{{ $t("user") }}
<span
v-if="props.entity.type === 'user'"
class="badge rounded-pill bg-user"
>
{{ trans(ACCEPTED_USERS) }}
</span>
<span v-if="entity.type === 'household'" class="badge rounded-pill bg-user">
{{ $t("household") }}
<span
v-if="props.entity.type === 'household'"
class="badge rounded-pill bg-user"
>
{{ trans(HOUSEHOLD) }}
</span>
</template>
<script>
export default {
name: "BadgeEntity",
props: ["options", "entity"],
i18n: {
messages: {
fr: {
person: "Usager",
thirdparty: {
thirdparty: "Tiers",
child: "Personne de contact",
company: "Personne morale",
contact: "Personne physique",
},
user: "TMS",
household: "Ménage",
},
},
},
};
<script setup>
import {
trans,
HOUSEHOLD,
ACCEPTED_USERS,
THIRDPARTY_A_CONTACT,
THIRDPARTY_CONTACT_OF,
PERSON,
THIRDPARTY,
} from "translator";
const props = defineProps({
options: Object,
entity: Object,
});
</script>

View File

@ -66,13 +66,13 @@
<div v-if="useDatePane === true" class="address-more">
<div v-if="address.validFrom">
<span class="validFrom">
<b>{{ $t("validFrom") }}</b
<b>{{ trans(ADDRESS_VALID_FROM) }}</b
>: {{ $d(address.validFrom.date) }}
</span>
</div>
<div v-if="address.validTo">
<span class="validTo">
<b>{{ $t("validTo") }}</b
<b>{{ trans(ADDRESS_VALID_TO) }}</b
>: {{ $d(address.validTo.date) }}
</span>
</div>
@ -83,6 +83,7 @@
<script>
import Confidential from "ChillMainAssets/vuejs/_components/Confidential.vue";
import AddressDetailsButton from "ChillMainAssets/vuejs/_components/AddressDetails/AddressDetailsButton.vue";
import { trans, ADDRESS_VALID_FROM, ADDRESS_VALID_TO } from "translator";
export default {
name: "AddressRenderBox",
@ -107,6 +108,9 @@ export default {
type: Boolean,
},
},
setup() {
return { trans, ADDRESS_VALID_FROM, ADDRESS_VALID_TO };
},
computed: {
component() {
return this.isMultiline === true ? "div" : "span";

View File

@ -6,8 +6,8 @@
v-if="!subscriberFinal"
@click="subscribeTo('subscribe', 'final')"
>
<i class="fa fa-check fa-fw" />
{{ $t("subscribe_final") }}
<i class="fa fa-check fa-fw"></i>
{{ trans(WORKFLOW_SUBSCRIBE_FINAL) }}
</button>
<button
class="btn btn-misc"
@ -15,8 +15,8 @@
v-if="subscriberFinal"
@click="subscribeTo('unsubscribe', 'final')"
>
<i class="fa fa-times fa-fw" />
{{ $t("unsubscribe_final") }}
<i class="fa fa-times fa-fw"></i>
{{ trans(WORKFLOW_UNSUBSCRIBE_FINAL) }}
</button>
<button
class="btn btn-misc"
@ -24,8 +24,8 @@
v-if="!subscriberStep"
@click="subscribeTo('subscribe', 'step')"
>
<i class="fa fa-check fa-fw" />
{{ $t("subscribe_all_steps") }}
<i class="fa fa-check fa-fw"></i>
{{ trans(WORKFLOW_SUBSCRIBE_ALL_STEPS) }}
</button>
<button
class="btn btn-misc"
@ -33,31 +33,25 @@
v-if="subscriberStep"
@click="subscribeTo('unsubscribe', 'step')"
>
<i class="fa fa-times fa-fw" />
{{ $t("unsubscribe_all_steps") }}
<i class="fa fa-times fa-fw"></i>
{{ trans(WORKFLOW_UNSUBSCRIBE_ALL_STEPS) }}
</button>
</div>
</template>
<script>
<script setup>
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods.ts";
import { defineProps, defineEmits } from "vue";
import {
trans,
WORKFLOW_SUBSCRIBE_FINAL,
WORKFLOW_UNSUBSCRIBE_FINAL,
WORKFLOW_SUBSCRIBE_ALL_STEPS,
WORKFLOW_UNSUBSCRIBE_ALL_STEPS,
} from "translator";
export default {
name: "EntityWorkflowVueSubscriber",
i18n: {
messages: {
fr: {
subscribe_final: "Recevoir une notification à l'étape finale",
unsubscribe_final:
"Ne plus recevoir de notification à l'étape finale",
subscribe_all_steps:
"Recevoir une notification à chaque étape du suivi",
unsubscribe_all_steps:
"Ne plus recevoir de notification à chaque étape du suivi",
},
},
},
props: {
// props
const props = defineProps({
entityWorkflowId: {
type: Number,
required: true,
@ -70,57 +64,24 @@ export default {
type: Boolean,
required: true,
},
},
emits: ["subscriptionUpdated"],
methods: {
subscribeTo(step, to) {
});
//methods
const subscribeTo = (step, to) => {
let params = new URLSearchParams();
params.set("subscribe", to);
const url =
`/api/1.0/main/workflow/${this.entityWorkflowId}/${step}?` +
`/api/1.0/main/workflow/${props.entityWorkflowId}/${step}?` +
params.toString();
makeFetch("POST", url).then((response) => {
this.$emit("subscriptionUpdated", response);
emit("subscriptionUpdated", response);
});
},
},
};
/*
* ALTERNATIVES
*
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="laststep">
<label class="form-check-label" for="laststep">{{ $t('subscribe_final') }}</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="allsteps">
<label class="form-check-label" for="allsteps">{{ $t('subscribe_all_steps') }}</label>
</div>
<div class="list-group my-3">
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
{{ $t('subscribe_final') }}
</label>
<label class="list-group-item">
<input class="form-check-input me-1" type="checkbox" value="">
{{ $t('subscribe_all_steps') }}
</label>
</div>
<div class="btn-group-vertical my-3" role="group">
<button type="button" class="btn btn-outline-primary">
<i class="fa fa-check fa-fw"></i>
{{ $t('subscribe_final') }}
</button>
<button type="button" class="btn btn-outline-primary">
<i class="fa fa-check fa-fw"></i>
{{ $t('subscribe_all_steps') }}
</button>
</div>
*/
// emit
const emit = defineEmits(["subscriptionUpdated"]);
</script>
<style scoped></style>

View File

@ -1,7 +1,7 @@
<template>
<div class="flex-table workflow" id="workflow-list">
<div
v-for="(w, i) in workflows"
v-for="(w, i) in props.workflows"
:key="`workflow-${i}`"
class="item-bloc"
>
@ -48,7 +48,7 @@
<span
v-if="w.isOnHoldAtCurrentStep"
class="badge bg-success rounded-pill"
>{{ $t("on_hold") }}</span
>{{ trans(WORKFLOW_ON_HOLD) }}</span
>
</div>
@ -56,11 +56,11 @@
<div class="item-col flex-grow-1">
<p v-if="isUserSubscribedToStep(w)">
<i class="fa fa-check fa-fw"></i>
{{ $t("you_subscribed_to_all_steps") }}
{{ trans(WORKFLOW_YOU_SUBSCRIBED_TO_ALL_STEPS) }}
</p>
<p v-if="isUserSubscribedToFinal(w)">
<i class="fa fa-check fa-fw"></i>
{{ $t("you_subscribed_to_final_step") }}
{{ trans(WORKFLOW_YOU_SUBSCRIBED_TO_FINAL_STEP) }}
</p>
</div>
<div class="item-col">
@ -69,7 +69,7 @@
<a
:href="goToUrl(w)"
class="btn btn-sm btn-show"
:title="$t('action.show')"
:title="trans(SEE)"
></a>
</li>
</ul>
@ -79,37 +79,30 @@
</div>
</template>
<script>
<script setup>
import Popover from "bootstrap/js/src/popover";
import { onMounted } from "vue";
import {
trans,
BY_USER,
SEE,
WORKFLOW_YOU_SUBSCRIBED_TO_ALL_STEPS,
WORKFLOW_YOU_SUBSCRIBED_TO_FINAL_STEP,
WORKFLOW_ON_HOLD,
WORKFLOW_AT,
} from "translator";
const i18n = {
messages: {
fr: {
you_subscribed_to_all_steps:
"Vous recevrez une notification à chaque étape",
you_subscribed_to_final_step:
"Vous recevrez une notification à l'étape finale",
by: "Par",
at: "Le",
on_hold: "En attente",
},
},
};
export default {
name: "ListWorkflow",
i18n: i18n,
props: {
// props
const props = defineProps({
workflows: {
type: Array,
required: true,
},
},
methods: {
goToUrl(w) {
return `/fr/main/workflow/${w.id}/show`;
},
getPopTitle(step) {
});
// methods
const goToUrl = (w) => `/fr/main/workflow/${w.id}/show`;
const getPopTitle = (step) => {
if (step.transitionPrevious != null) {
//console.log(step.transitionPrevious.text);
let freezed = step.isFreezed
@ -117,47 +110,34 @@ export default {
: ``;
return `${freezed}${step.transitionPrevious.text}`;
}
},
getPopContent(step) {
};
const getPopContent = (step) => {
if (step.transitionPrevious != null) {
if (step.transitionPreviousBy !== null) {
return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li>
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
<li><span class="item-key">${trans(BY_USER)} : </span><b>${step.transitionPreviousBy.text}</b></li>
<li><span class="item-key">${trans(WORKFLOW_AT)} : </span><b>${formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`;
} else {
return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
<li><span class="item-key">${trans(WORKFLOW_AT)} : </span><b>${formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`;
}
}
},
formatDate(datetime) {
return (
datetime.split("T")[0] +
" " +
datetime.split("T")[1].substring(0, 5)
);
},
isUserSubscribedToStep(w) {
// todo
return false;
},
isUserSubscribedToFinal(w) {
// todo
return false;
},
},
mounted() {
};
const formatDate = (datetime) =>
datetime.split("T")[0] + " " + datetime.split("T")[1].substring(0, 5);
const isUserSubscribedToStep = () => false;
const isUserSubscribedToFinal = () => false;
onMounted(() => {
const triggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]'),
);
const popoverList = triggerList.map(function (el) {
//console.log('popover', el)
triggerList.map(function (el) {
return new Popover(el, {
html: true,
});
});
},
};
});
</script>

View File

@ -1,23 +1,24 @@
<template>
<pick-workflow
:relatedEntityClass="this.relatedEntityClass"
:relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload"
<Pick-workflow
:relatedEntityClass="props.relatedEntityClass"
:relatedEntityId="props.relatedEntityId"
:workflowsAvailables="props.workflowsAvailables"
:preventDefaultMoveToGenerate="props.preventDefaultMoveToGenerate"
:goToGenerateWorkflowPayload="props.goToGenerateWorkflowPayload"
:countExistingWorkflows="countWorkflows"
:embedded-within-list-modal="false"
@go-to-generate-workflow="goToGenerateWorkflow"
@click-open-list="openModal"
></pick-workflow>
></Pick-workflow>
<teleport to="body">
<modal
<Modal
v-if="modal.showModal"
:modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false"
>
<template v-slot:header>
<h2 class="modal-title">{{ $t("workflow_list") }}</h2>
<h2 class="modal-title">{{ trans(WORKFLOW_LIST) }}</h2>
</template>
<template v-slot:body>
@ -27,38 +28,33 @@
<template v-slot:footer>
<pick-workflow
v-if="allowCreate"
:relatedEntityClass="this.relatedEntityClass"
:relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables"
:relatedEntityClass="props.relatedEntityClass"
:relatedEntityId="props.relatedEntityId"
:workflowsAvailables="props.workflowsAvailables"
:preventDefaultMoveToGenerate="
this.$props.preventDefaultMoveToGenerate
props.preventDefaultMoveToGenerate
"
:goToGenerateWorkflowPayload="
this.goToGenerateWorkflowPayload
props.goToGenerateWorkflowPayload
"
:countExistingWorkflows="countWorkflows"
:embedded-within-list-modal="true"
@go-to-generate-workflow="this.goToGenerateWorkflow"
@go-to-generate-workflow="goToGenerateWorkflow"
></pick-workflow>
</template>
</modal>
</Modal>
</teleport>
</template>
<script>
<script setup>
import { ref, computed, defineProps, defineEmits } from "vue";
import Modal from "ChillMainAssets/vuejs/_components/Modal";
import PickWorkflow from "ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue";
import ListWorkflowVue from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflow.vue";
import { trans, WORKFLOW_LIST } from "translator";
export default {
name: "ListWorkflowModal",
components: {
Modal,
PickWorkflow,
ListWorkflowVue,
},
emits: ["goToGenerateWorkflow"],
props: {
// Define props
const props = defineProps({
workflows: {
type: Array,
required: true,
@ -86,44 +82,26 @@ export default {
},
goToGenerateWorkflowPayload: {
required: false,
default: {},
default: () => ({}),
},
},
data() {
return {
modal: {
});
// Define emits
const emit = defineEmits(["goToGenerateWorkflow"]);
// Reactive data
const modal = ref({
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
},
};
},
computed: {
countWorkflows() {
return this.workflows.length;
},
hasWorkflow() {
return this.countWorkflows > 0;
},
},
methods: {
openModal() {
this.modal.showModal = true;
},
goToGenerateWorkflow(data) {
console.log("go to generate workflow intercepted", data);
this.$emit("goToGenerateWorkflow", data);
},
},
i18n: {
messages: {
fr: {
workflow_list: "Liste des workflows associés",
workflow: " workflow associé",
workflows: " workflows associés",
},
},
},
};
});
// Computed properties
const countWorkflows = computed(() => props.workflows.length);
// Methods
const openModal = () => (modal.value.showModal = true);
const goToGenerateWorkflow = (data) => emit("goToGenerateWorkflow", data);
</script>
<style scoped></style>

View File

@ -8,28 +8,28 @@
aria-modal="true"
role="dialog"
>
<div class="modal-dialog" :class="modalDialogClass">
<div class="modal-dialog" :class="props.modalDialogClass || {}">
<div class="modal-content">
<div class="modal-header">
<slot name="header" />
<button class="close btn" @click="$emit('close')">
<i class="fa fa-times" aria-hidden="true" />
<slot name="header"></slot>
<button class="close btn" @click="emits('close')">
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
<div class="modal-body">
<div class="body-head">
<slot name="body-head" />
<slot name="body-head"></slot>
</div>
<slot name="body" />
<slot name="body"></slot>
</div>
<div class="modal-footer" v-if="!hideFooter">
<button
class="btn btn-cancel"
@click="$emit('close')"
@click="emits('close')"
>
{{ $t("action.close") }}
{{ trans(MODAL_ACTION_CLOSE) }}
</button>
<slot name="footer" />
<slot name="footer"></slot>
</div>
</div>
</div>
@ -39,8 +39,7 @@
</transition>
</template>
<script lang="ts">
import { defineComponent } from "vue";
<script lang="ts" setup>
/*
* This Modal component is a mix between Vue3 modal implementation
* [+] with 'v-if:showModal' directive:parameter, html scope is added/removed not just shown/hidden
@ -50,22 +49,23 @@ import { defineComponent } from "vue";
* [+] using bootstrap css classes, the modal have a responsive behaviour,
* [+] modal design can be configured using css classes (size, scroll)
*/
export default defineComponent({
name: "Modal",
props: {
modalDialogClass: {
type: Object,
required: false,
default: {},
},
hideFooter: {
type: Boolean,
required: false,
default: false,
},
},
emits: ["close"],
import { trans, MODAL_ACTION_CLOSE } from "translator";
import { defineProps } from "vue";
export interface ModalProps {
modalDialogClass: object | null;
hideFooter: boolean;
}
// Define the props
const props = withDefaults(defineProps<ModalProps>(), {
hideFooter: false,
modalDialogClass: null,
});
const emits = defineEmits<{
close: [];
}>();
</script>
<style lang="scss">

View File

@ -9,12 +9,12 @@
class="btn"
:class="overrideClass"
type="button"
:title="$t('markAsUnread')"
:title="trans(NOTIFICATION_MARK_AS_UNREAD)"
@click="markAsUnread"
>
<i class="fa fa-sm fa-envelope-o" />
<span v-if="!buttonNoText" class="ps-2">
{{ $t("markAsUnread") }}
<i class="fa fa-sm fa-envelope-o"></i>
<span v-if="!props.buttonNoText" class="ps-2">
{{ trans(NOTIFICATION_MARK_AS_UNREAD) }}
</span>
</button>
@ -23,12 +23,12 @@
class="btn"
:class="overrideClass"
type="button"
:title="$t('markAsRead')"
:title="trans(NOTIFICATION_MARK_AS_READ)"
@click="markAsRead"
>
<i class="fa fa-sm fa-envelope-open-o" />
<i class="fa fa-sm fa-envelope-open-o"></i>
<span v-if="!buttonNoText" class="ps-2">
{{ $t("markAsRead") }}
{{ trans(NOTIFICATION_MARK_AS_READ) }}
</span>
</button>
@ -37,9 +37,9 @@
type="button"
class="btn btn-outline-primary"
:href="showUrl"
:title="$t('action.show')"
:title="trans(SEE)"
>
<i class="fa fa-sm fa-comment-o" />
<i class="fa fa-sm fa-comment-o"></i>
</a>
<!-- "Mark All Read" button -->
@ -51,7 +51,7 @@
:title="$t('markAllRead')"
@click="markAllRead"
>
<i class="fa fa-sm fa-envelope-o" />
<i class="fa fa-sm fa-envelope-o"></i>
<span v-if="!buttonNoText" class="ps-2">
{{ $t("markAllRead") }}
</span>
@ -59,89 +59,66 @@
</div>
</template>
<script>
<script setup>
import { computed } from "vue";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods.ts";
import {
trans,
NOTIFICATION_MARK_AS_READ,
NOTIFICATION_MARK_AS_UNREAD,
SEE,
} from "translator";
export default {
name: "NotificationReadToggle",
props: {
// Props
const props = defineProps({
isRead: {
required: true,
type: Boolean,
required: true,
},
notificationId: {
required: true,
type: Number,
required: true,
},
// Optional
buttonClass: {
required: false,
type: String,
required: false,
},
buttonNoText: {
required: false,
type: Boolean,
required: false,
},
showUrl: {
required: false,
type: String,
required: false,
},
},
emits: ["markRead", "markUnread"],
computed: {
/// [Option] override default button appearance (btn-misc)
overrideClass() {
return this.buttonClass ? this.buttonClass : "btn-misc";
},
/// [Option] don't display text on button
buttonHideText() {
return this.buttonNoText;
},
/// [Option] showUrl is href for show page second button.
// When passed, the component return a button-group with 2 buttons.
isButtonGroup() {
return this.showUrl;
},
},
methods: {
markAsUnread() {
});
// Emits
const emit = defineEmits(["markRead", "markUnread"]);
// Computed
const overrideClass = computed(() => props.buttonClass || "btn-misc");
const isButtonGroup = computed(() => props.showUrl);
// Methods
const markAsUnread = () => {
makeFetch(
"POST",
`/api/1.0/main/notification/${this.notificationId}/mark/unread`,
`/api/1.0/main/notification/${props.notificationId}/mark/unread`,
[],
).then(() => {
this.$emit("markRead", { notificationId: this.notificationId });
emit("markRead", { notificationId: props.notificationId });
});
},
markAsRead() {
};
const markAsRead = () => {
makeFetch(
"POST",
`/api/1.0/main/notification/${this.notificationId}/mark/read`,
`/api/1.0/main/notification/${props.notificationId}/mark/read`,
[],
).then(() => {
this.$emit("markUnread", {
notificationId: this.notificationId,
emit("markUnread", { notificationId: props.notificationId });
});
});
},
markAllRead() {
makeFetch(
"POST",
`/api/1.0/main/notification/markallread`,
[],
).then(() => {
this.$emit("markAllRead");
});
},
},
i18n: {
messages: {
fr: {
markAsUnread: "Marquer comme non-lu",
markAsRead: "Marquer comme lu",
},
},
},
};
</script>

View File

@ -8,10 +8,10 @@
]"
@click="openModal"
>
<i v-if="isChangeIcon" class="fa me-2" :class="options.changeIcon" />
<i v-if="isChangeIcon" class="fa me-2" :class="options.changeIcon"></i>
<span v-if="!noText">
{{ $t("online_edit_document") }}
{{ trans(WOPI_ONLINE_EDIT_DOCUMENT) }}
</span>
</a>
@ -19,8 +19,8 @@
<div class="wopi-frame" v-if="isOpenDocument">
<modal
v-if="modal.showModal"
:modal-dialog-class="modal.modalDialogClass"
:hide-footer="true"
:modalDialogClass="modal.modalDialogClass"
:hideFooter="true"
@close="modal.showModal = false"
>
<template #header>
@ -28,54 +28,51 @@
<span class="ms-auto me-3">
<span v-if="options.title">{{ options.title }}</span>
</span>
<!--
<a class="btn btn-outline-light">
<i class="fa fa-save fa-fw"></i>
{{ $t('save_and_quit') }}
</a>
-->
</template>
<template #body>
<div v-if="loading" class="loading">
<i
class="fa fa-circle-o-notch fa-spin fa-3x"
:title="$t('loading')"
/>
:title="trans(WOPI_LOADING)"
></i>
</div>
<iframe :src="this.wopiUrl" @load="loaded" />
<iframe :src="this.wopiUrl" @load="loaded"></iframe>
</template>
</modal>
</div>
<div v-else>
<modal
<Modal
v-if="modal.showModal"
modal-dialog-class="modal-sm"
modalDialogClass="modal-sm"
@close="modal.showModal = false"
>
<template #header>
<h3>{{ $t("invalid_title") }}</h3>
<template v-slot:header>
<h3>{{ trans(WOPI_INVALID_TITLE) }}</h3>
</template>
<template #body>
<template v-slot:body>
<div class="alert alert-warning">
{{ $t("invalid_message") }}
{{ trans(WOPI_ONLINE_EDIT_DOCUMENT) }}
</div>
</template>
</modal>
</Modal>
</div>
</teleport>
</template>
<script>
<script setup>
import { ref, computed } from "vue";
import {
trans,
WOPI_ONLINE_EDIT_DOCUMENT,
WOPI_INVALID_TITLE,
WOPI_LOADING,
} from "translator";
import Modal from "ChillMainAssets/vuejs/_components/Modal";
import logo from "ChillMainAssets/chill/img/logo-chill-sans-slogan_white.png";
export default {
name: "OpenWopiLink",
components: {
Modal,
},
props: {
// Props
const props = defineProps({
wopiUrl: {
type: String,
required: true,
@ -88,16 +85,17 @@ export default {
type: Object,
required: false,
},
},
data() {
return {
modal: {
});
// data
const modal = ref({
showModal: false,
modalDialogClass: "modal-fullscreen", //modal-dialog-scrollable
},
logo: logo,
loading: false,
mime: [
modalDialogClass: "modal-fullscreen",
});
const loading = ref(false);
// MIME types
const mime = [
// TODO temporary hardcoded. to be replaced by twig extension or a collabora server query
"application/clarisworks",
"application/coreldraw",
@ -169,62 +167,25 @@ export default {
"application/x-pagemaker",
"application/x-sony-bbeb",
"application/x-t602",
],
};
},
computed: {
isOpenDocument() {
if (this.mime.indexOf(this.type) !== -1) {
return true;
}
return false;
},
noText() {
if (typeof this.options.noText !== "undefined") {
return this.options.noText === true;
}
return false;
},
isChangeIcon() {
if (typeof this.options.changeIcon !== "undefined") {
return !(
this.options.changeIcon === null ||
this.options.changeIcon === ""
);
}
return false;
},
isChangeClass() {
if (typeof this.options.changeClass !== "undefined") {
return !(
this.options.changeClass === null ||
this.options.changeClass === ""
);
}
return false;
},
},
methods: {
openModal() {
this.loading = true;
this.modal.showModal = true;
},
loaded() {
this.loading = false;
},
},
i18n: {
messages: {
fr: {
online_edit_document: "Éditer en ligne",
save_and_quit: "Enregistrer et quitter",
loading: "Chargement de l'éditeur en ligne",
invalid_title: "Format incompatible",
invalid_message:
"Désolé, ce format de document n'est pas éditable en ligne.",
},
},
},
];
// Computed
const isOpenDocument = computed(() => mime.includes(props.type));
const noText = computed(() => props.options?.noText === true);
const isChangeIcon = computed(() => !!props.options?.changeIcon);
const isChangeClass = computed(() => !!props.options?.changeClass);
// Methods
const openModal = () => {
loading.value = true;
modal.value.showModal = true;
};
const loaded = () => {
loading.value = false;
};
</script>

View File

@ -1,45 +1,3 @@
const { styles } = require("@ckeditor/ckeditor5-dev-utils");
const {
CKEditorTranslationsPlugin,
} = require("@ckeditor/ckeditor5-dev-translations");
buildCKEditor = function (encore) {
encore
.addPlugin(
new CKEditorTranslationsPlugin({
language: "fr",
addMainLanguageTranslationsToAllAssets: true,
verbose: !encore.isProduction(),
strict: true,
}),
)
// Use raw-loader for CKEditor 5 SVG files.
.addRule({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/,
loader: "raw-loader",
})
// Configure other image loaders to exclude CKEditor 5 SVG files.
.configureLoaderRule("images", (loader) => {
loader.exclude =
/ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/;
})
// Configure PostCSS loader.
.addLoader({
test: /ckeditor5-[^/\\]+[/\\]theme[/\\].+\.css$/,
loader: "postcss-loader",
options: {
postcssOptions: styles.getPostCssConfig({
themeImporter: {
themePath: require.resolve("@ckeditor/ckeditor5-theme-lark"),
},
minify: true,
}),
},
});
};
// Compile and loads all assets from the Chill Main Bundle
module.exports = function (encore, entries) {
@ -79,8 +37,6 @@ module.exports = function (encore, entries) {
__dirname + "/Resources/public/page/export/download-export.js",
);
buildCKEditor(encore);
// Modules entrypoints
encore.addEntry(
"mod_collection",

View File

@ -44,6 +44,9 @@ address_fields: Données liées à l'adresse
Datas: Données
No title: Aucun titre
icon: icône
See: Voir
Name: Nom
Label: Nom
user:
profile:
@ -124,6 +127,49 @@ address:
address_homeless: L'adresse est-elle celle d'un domicile fixe ?
real address: Adresse d'un domicile
consider homeless: Cette adresse est incomplète
add_an_address_title: Créer une adresse
edit_an_address_title: Modifier une adresse
create_a_new_address: Créer une nouvelle adresse
edit_address: Modifier l'adresse
select_an_address_title: Sélectionner une adresse
fill_an_address: Compléter l'adresse
select_country: Choisir le pays
country: Pays
select_city: Choisir une localité
city: Localité
other_city: Autre localité
select_address: Choisir une adresse
address: Adresse
other_address: Autre adresse
create_address: Adresse inconnue. Cliquez ici pour créer une nouvelle adresse
isNoAddress: Pas d'adresse complète
isConfidential: Adresse confidentielle
street: Nom de rue
streetNumber: Numéro
floor: Étage
corridor: Couloir
steps: Escalier
flat: Appartement
buildingName: Résidence
extra: Complément d'adresse
distribution: Cedex
create_postal_code: Localité inconnue. Cliquez ici pour créer une nouvelle localité
postalCode_name: Nom
postalCode_code: Code postal
date: Date de la nouvelle adresse
valid_from: L'adresse est valable à partir du
valid_to: L'adresse est valable jusqu'au
back_to_the_list: Retour à la liste
loading: chargement en cours...
address_suggestions: Suggestion d'adresses
address_new_success: La nouvelle adresse est enregistrée.
address_edit_success: L'adresse a été mise à jour.
wait_redirection: La page est redirigée.
not_yet_address: Il n'y a pas encore d'adresse. Cliquez sur '+ Créer une adresse'
use_this_address: Utiliser cette adresse
household:
move_date: Date du déménagement
address more:
floor: ét
corridor: coul
@ -508,6 +554,8 @@ Follow workflow: Suivre la décision
Workflow history: Historique de la décision
workflow:
list: Liste des workflows associés
associated: workflow associé
deleted: Workflow supprimé
Created by: Créé par
My decision: Ma décision
@ -553,6 +601,7 @@ workflow:
Previous workflow transitionned help: Workflows où vous avez exécuté une action.
For: Pour
Cc: Cc
At: Le
You must select a next step, pick another decision if no next steps are available: Il faut une prochaine étape. Choissisez une autre décision si nécessaire.
An access key was also sent to those addresses: Un lien d'accès a été envoyé à ces adresses
Those users are also granted to apply a transition by using an access key: Ces utilisateurs ont obtenu l'accès grâce au lien reçu par email
@ -575,6 +624,12 @@ workflow:
public_views_by_ip: Visualisation par adresse IP
May not associate a document: Le workflow ne concerne pas un document
subscribe_final: Recevoir une notification à l'étape finale
unsubscribe_final: Ne plus recevoir de notification à l'étape finale
subscribe_all_steps: Recevoir une notification à chaque étape du suivi
unsubscribe_all_steps: Ne plus recevoir de notification à chaque étape du suivi
public_link:
expired_link_title: Lien expiré
expired_link_explanation: Le lien a expiré, vous ne pouvez plus visualiser ce document.
@ -656,6 +711,10 @@ notification:
Remove an email: Supprimer l'adresse email
Email with access link: Adresse email ayant reçu un lien d'accès
mark_as_read: Marquer comme lu
mark_as_unread: Marquer comme non-lu
export:
address_helper:
id: Identifiant de l'adresse
@ -795,4 +854,43 @@ gender:
Select gender translation: Traduction grammaticale
Select gender icon: Icône à utiliser
wopi:
online_edit_document: Éditer en ligne
save_and_quit: Enregistrer et quitter
loading: Chargement de l'éditeur en ligne
invalid_title: Format incompatible
invalid_message: Désolé, ce format de document n'est pas éditable en ligne.
onthefly:
show:
person: Détails de l'usager
thirdparty: Détails du tiers
file_person: Ouvrir la fiche de l'usager
file_thirdparty: Voir le Tiers
edit:
person: Modifier un usager
thirdparty: Modifier un tiers
create:
button: Créer {q}
title:
default: Création d'un nouvel usager ou d'un tiers professionnel
person: Création d'un nouvel usager
thirdparty: Création d'un nouveau tiers professionnel
person: un nouvel usager
thirdparty: un nouveau tiers professionnel
addContact:
title: Créer un contact pour {q}
resource_comment_title: Un commentaire est associé à cet interlocuteur
modal:
action:
close: Fermer
multiselect:
placeholder: Choisir
tag_placeholder: Créer un nouvel élément
select_label: Entrée ou cliquez pour sélectionner
deselect_label: Entrée ou cliquez pour désélectionner
select_group_label: Appuyer sur "Entrée" pour sélectionner ce groupe
deselect_group_label: Appuyer sur "Entrée" pour désélectionner ce groupe
selected_label: Sélectionné'

View File

@ -16,7 +16,8 @@
<ckeditor
name="content"
:placeholder="$t('comment.content')"
:editor="editor"
:editor="classicEditor"
:config="editorConfig"
v-model="content"
tag-name="textarea"
/>
@ -60,18 +61,18 @@
</template>
<script>
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "../../../../../../ChillMainBundle/Resources/public/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { mapState } from "vuex";
export default {
name: "Comment",
components: {
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
},
data() {
return {
editor: ClassicEditor,
loading: false,
lastRecordedContent: null,
};
@ -80,6 +81,8 @@ export default {
...mapState({
pinnedComment: (state) => state.accompanyingCourse.pinnedComment,
}),
classicEditor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
content: {
set(value) {
console.log("new comment value", value);

View File

@ -22,6 +22,7 @@
name="content"
:placeholder="$t('comment_placeholder')"
:editor="editor"
:config="editorConfig"
v-model="content"
tag-name="textarea"
/>
@ -38,14 +39,15 @@
<script>
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
export default {
name: "WriteComment",
components: {
Modal,
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
},
props: ["resource"],
emits: ["updateComment"],
@ -55,7 +57,6 @@ export default {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
},
editor: ClassicEditor,
formdata: {
content: this.resource.comment,
},
@ -71,6 +72,8 @@ export default {
},
},
computed: {
editor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
content: {
set(value) {
this.formdata.content = value;

View File

@ -36,14 +36,20 @@
<label class="col-form-label">{{ $t("private_comment") }}</label>
<ckeditor
v-model="privateComment"
:editor="editor"
:editor="classicEditor"
:config="editorConfig"
tag-name="textarea"
></ckeditor>
</div>
<div id="comment" class="action-row">
<label class="col-form-label">{{ $t("comments") }}</label>
<ckeditor v-model="note" :editor="editor" tag-name="textarea"></ckeditor>
<ckeditor
v-model="note"
:editor="classicEditor"
:config="editorConfig"
tag-name="textarea"
></ckeditor>
</div>
<div id="objectives" class="action-row">
@ -432,23 +438,16 @@
<script>
import { mapState, mapGetters } from "vuex";
import {
dateToISO,
ISOToDate,
ISOToDatetime,
} from "ChillMainAssets/chill/js/date";
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
import AddResult from "./components/AddResult.vue";
import AddEvaluation from "./components/AddEvaluation.vue";
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
import AddressRenderBox from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue";
import ThirdPartyRenderBox from "ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue";
import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue";
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
import { buildLinkCreate } from "ChillMainAssets/lib/entity-workflow/api";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
const i18n = {
@ -505,13 +504,11 @@ const i18n = {
export default {
name: "App",
components: {
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
AddResult,
AddEvaluation,
AddPersons,
AddressRenderBox,
ThirdPartyRenderBox,
PickTemplate,
ListWorkflowModal,
OnTheFly,
PersonText,
@ -521,7 +518,6 @@ export default {
return {
docAnchorId: null,
isExpanded: false,
editor: ClassicEditor,
showAddObjective: false,
showAddEvaluation: false,
handlingThirdPartyPicker: {
@ -588,6 +584,8 @@ export default {
"hasThirdParties",
"hasReferrers",
]),
classicEditor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
startDate: {
get() {
return this.$store.state.startDate;
@ -696,7 +694,7 @@ export default {
},
goToGenerateWorkflow({ link }) {
// console.log('save before leave to generate workflow')
const callback = (data) => {
const callback = () => {
window.location.assign(link);
};
@ -707,7 +705,7 @@ export default {
},
goToGenerateNotification(tos) {
console.log("save before leave to notification");
const callback = (data) => {
const callback = () => {
if (tos === true) {
window.location.assign(
`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&tos[0]=${this.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`,

View File

@ -89,7 +89,8 @@
}}</label>
<div class="col-sm-12">
<ckeditor
:editor="editor"
:editor="classicEditor"
:config="editorConfig"
:placeholder="$t('evaluation_comment_placeholder')"
v-model="comment"
tag-name="textarea"
@ -271,14 +272,11 @@
</template>
<script>
import {
dateToISO,
ISOToDate,
ISOToDatetime,
} from "ChillMainAssets/chill/js/date";
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import { mapGetters, mapState } from "vuex";
import { ISOToDatetime } from "ChillMainAssets/chill/js/date";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import { ClassicEditor } from "ckeditor5";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { mapState } from "vuex";
import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
import { buildLink } from "ChillDocGeneratorAssets/lib/document-generator";
import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue";
@ -325,7 +323,7 @@ export default {
props: ["evaluation", "docAnchorId"],
components: {
DropFileModal,
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
PickTemplate,
ListWorkflowModal,
DocumentActionButtonsGroup,
@ -333,7 +331,6 @@ export default {
i18n,
data() {
return {
editor: ClassicEditor,
template: null,
asyncUploadOptions: {
maxFiles: 1,
@ -374,6 +371,8 @@ export default {
},
computed: {
...mapState(["isPosting", "work", "me"]),
classicEditor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
AmIRefferer() {
return !(
this.$store.state.work.accompanyingPeriod.user &&
@ -596,12 +595,7 @@ export default {
newStatus: newStatus,
});
},
goToGenerateWorkflowEvaluationDocument({
event,
link,
workflowName,
payload,
}) {
goToGenerateWorkflowEvaluationDocument({ workflowName, payload }) {
const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(
(e) => e.key === this.evaluation.key,

View File

@ -29,7 +29,12 @@
</div>
<div class="item-row comment">
<ckeditor :editor="editor" v-model="comment" tag-name="textarea" />
<ckeditor
:editor="classicEditor"
:config="editorConfig"
v-model="comment"
tag-name="textarea"
/>
</div>
<div class="item-row participation-details">
@ -98,23 +103,21 @@ div.participation-details {
<script>
import { mapGetters } from "vuex";
import PersonRenderBox from "ChillPersonAssets/vuejs/_components/Entity/PersonRenderBox.vue";
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
export default {
name: "MemberDetails",
components: {
PersonRenderBox,
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
},
props: ["conc"],
data() {
return {
editor: ClassicEditor,
};
},
computed: {
...mapGetters(["concByPersonId"]),
classicEditor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
isHolder() {
return this.conc.holder;
},

View File

@ -5,27 +5,26 @@
$t('household_members_editor.positioning.comment_placeholder')
"
:editor="editor"
:config="editorConfig"
v-model="content"
tag-name="textarea"
/>
</template>
<script>
import CKEditor from "@ckeditor/ckeditor5-vue";
import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { ClassicEditor } from "ckeditor5";
export default {
name: "PersonComment.vue",
components: {
ckeditor: CKEditor.component,
ckeditor: Ckeditor,
},
props: ["conc"],
data() {
return {
editor: ClassicEditor,
};
},
computed: {
editor: () => ClassicEditor,
editorConfig: () => classicEditorConfig,
content: {
get() {
return this.$props.conc.comment || "";

View File

@ -43,7 +43,7 @@
</div>
</div>
<div class="item-row">
<div>
<div class="col-12">
<h6>{{ $t("household_members_editor.positioning.comment") }}</h6>
<person-comment :conc="conc" />
</div>

6
src/vuex.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
declare module "vuex" {
export * from "vuex/types/index.d.ts";
export * from "vuex/types/helpers.d.ts";
export * from "vuex/types/logger.d.ts";
export * from "vuex/types/vue.d.ts";
}

View File

@ -383,6 +383,21 @@
"templates/base.html.twig"
]
},
"symfony/ux-translator": {
"version": "2.22",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "2.9",
"ref": "bc396565cc4cab95692dd6df810553dc22e352e1"
},
"files": [
"assets/translator.js",
"config/packages/ux_translator.yaml",
"var/translations/configuration.js",
"var/translations/index.js"
]
},
"symfony/validator": {
"version": "5.4",
"recipe": {

28
ts-config-base.json Normal file
View File

@ -0,0 +1,28 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"target": "es2024",
"lib": [
"dom",
"esnext"
],
"module": "es6",
"moduleResolution": "bundler",
"isolatedModules": true,
"allowJs": false,
"checkJs": false,
"importHelpers": true,
"allowSyntheticDefaultImports": true,
"types": [
"node"
],
"sourceMap": true
},
"includes": [
"./src/**/*.ts",
"./src/**/*.vue"
],
"exclude": [
"./docs/*"
]
}

View File

@ -1,31 +1,13 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"extends": [
"./ts-config-base.json"
],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"translator": ["./assets/translator.ts"],
"ChillMainAssets/*": ["./src/Bundle/ChillMainBundle/Resources/public/*"],
"ChillDocStoreAssets/*": ["./src/Bundle/ChillDocStoreBundle/Resources/public/*"]
}
},
"lib": [
"es2020",
"dom"
],
"module": "es6",
"moduleResolution": "node",
"isolatedModules": true,
"allowJs": false,
"checkJs": false,
"importHelpers": true,
"allowSyntheticDefaultImports": true,
"types": [
"node"
],
"sourceMap": true
},
"includes": [
"./src/**/*.ts",
"./src/**/*.vue"
],
"exclude": [
"./docs/*"
]
}

View File

@ -1,5 +1,6 @@
const Encore = require("@symfony/webpack-encore");
const { resolve, parse } = require("path");
const {existsSync} = require("fs");
const { readdir } = require("fs").promises;
/**
@ -92,21 +93,15 @@ module.exports = (async () => {
.enableVersioning()
.enableSingleRuntimeChunk()
.splitEntryChunks();
// added when upgrading to symfony 5.4
// enables and configure @babel/preset-env polyfills
//.configureBabelPresetEnv((config) => {
// config.useBuiltIns = 'usage';
// config.corejs = '3.23';
//})
//.addLoader({ test: /\.pdf$/, loader: 'file-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'pdf/' } })
// populate config with chill entries
let chillEntries = [];
await populateConfig(Encore, chillEntries);
// configure Babel
// .configureBabel((config) => {
// config.plugins.push('@babel/a-babel-plugin');
// })
Encore.addAliases({
translator: resolve(__dirname, './assets/translator'),
"@symfony/ux-translator": resolve(__dirname, './vendor/symfony/ux-translator/assets'),
});
//getting the encore config and appending chill entries
config = Encore.getWebpackConfig();

8612
yarn.lock

File diff suppressed because it is too large Load Diff