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

This commit is contained in:
2025-02-19 10:57:59 +00:00
committed by Julien Fastré
parent c89e3785ef
commit d2fcb6945b
42 changed files with 924 additions and 9449 deletions

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,36 +44,38 @@
<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
v-for="action in socialActionsList"
:key="action.id"
:action="action"
:selection="socialActionsSelected"
@updateSelected="updateActionsSelected"
>
<check-social-action
v-for="action in socialActionsList"
:key="action.id"
:action="action"
:selection="socialActionsSelected"
@update-selected="updateActionsSelected"
/>
</div>
</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) => {
console.error(error.stack);
});
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,94 +33,55 @@
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
const props = defineProps({
entityWorkflowId: {
type: Number,
required: true,
},
props: {
entityWorkflowId: {
type: Number,
required: true,
},
subscriberStep: {
type: Boolean,
required: true,
},
subscriberFinal: {
type: Boolean,
required: true,
},
subscriberStep: {
type: Boolean,
required: true,
},
emits: ["subscriptionUpdated"],
methods: {
subscribeTo(step, to) {
let params = new URLSearchParams();
params.set("subscribe", to);
subscriberFinal: {
type: Boolean,
required: true,
},
});
const url =
`/api/1.0/main/workflow/${this.entityWorkflowId}/${step}?` +
params.toString();
//methods
const subscribeTo = (step, to) => {
let params = new URLSearchParams();
params.set("subscribe", to);
makeFetch("POST", url).then((response) => {
this.$emit("subscriptionUpdated", response);
});
},
},
const url =
`/api/1.0/main/workflow/${props.entityWorkflowId}/${step}?` +
params.toString();
makeFetch("POST", url).then((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,85 +79,65 @@
</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",
},
// props
const props = defineProps({
workflows: {
type: Array,
required: true,
},
});
// 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
? `<i class="fa fa-snowflake-o fa-sm me-1"></i>`
: ``;
return `${freezed}${step.transitionPrevious.text}`;
}
};
const getPopContent = (step) => {
if (step.transitionPrevious != null) {
if (step.transitionPreviousBy !== null) {
return `<ul class="small_in_title">
<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">${trans(WORKFLOW_AT)} : </span><b>${formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>`;
}
}
};
const formatDate = (datetime) =>
datetime.split("T")[0] + " " + datetime.split("T")[1].substring(0, 5);
const isUserSubscribedToStep = () => false;
const isUserSubscribedToFinal = () => false;
export default {
name: "ListWorkflow",
i18n: i18n,
props: {
workflows: {
type: Array,
required: true,
},
},
methods: {
goToUrl(w) {
return `/fr/main/workflow/${w.id}/show`;
},
getPopTitle(step) {
if (step.transitionPrevious != null) {
//console.log(step.transitionPrevious.text);
let freezed = step.isFreezed
? `<i class="fa fa-snowflake-o fa-sm me-1"></i>`
: ``;
return `${freezed}${step.transitionPrevious.text}`;
}
},
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>
</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>
</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 triggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]'),
);
const popoverList = triggerList.map(function (el) {
//console.log('popover', el)
return new Popover(el, {
html: true,
});
onMounted(() => {
const triggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]'),
);
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,103 +28,80 @@
<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,
// Define props
const props = defineProps({
workflows: {
type: Array,
required: true,
},
emits: ["goToGenerateWorkflow"],
props: {
workflows: {
type: Array,
required: true,
},
allowCreate: {
type: Boolean,
required: true,
},
relatedEntityClass: {
type: String,
required: true,
},
relatedEntityId: {
type: Number,
required: false,
},
workflowsAvailables: {
type: Array,
required: true,
},
preventDefaultMoveToGenerate: {
type: Boolean,
required: false,
default: false,
},
goToGenerateWorkflowPayload: {
required: false,
default: {},
},
allowCreate: {
type: Boolean,
required: true,
},
data() {
return {
modal: {
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
},
};
relatedEntityClass: {
type: String,
required: true,
},
computed: {
countWorkflows() {
return this.workflows.length;
},
hasWorkflow() {
return this.countWorkflows > 0;
},
relatedEntityId: {
type: Number,
required: false,
},
methods: {
openModal() {
this.modal.showModal = true;
},
goToGenerateWorkflow(data) {
console.log("go to generate workflow intercepted", data);
this.$emit("goToGenerateWorkflow", data);
},
workflowsAvailables: {
type: Array,
required: true,
},
i18n: {
messages: {
fr: {
workflow_list: "Liste des workflows associés",
workflow: " workflow associé",
workflows: " workflows associés",
},
},
preventDefaultMoveToGenerate: {
type: Boolean,
required: false,
default: false,
},
};
goToGenerateWorkflowPayload: {
required: false,
default: () => ({}),
},
});
// Define emits
const emit = defineEmits(["goToGenerateWorkflow"]);
// Reactive data
const modal = ref({
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
});
// 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: {
isRead: {
required: true,
type: Boolean,
},
notificationId: {
required: true,
type: Number,
},
// Optional
buttonClass: {
required: false,
type: String,
},
buttonNoText: {
required: false,
type: Boolean,
},
showUrl: {
required: false,
type: String,
},
// Props
const props = defineProps({
isRead: {
type: Boolean,
required: true,
},
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;
},
notificationId: {
type: Number,
required: true,
},
methods: {
markAsUnread() {
makeFetch(
"POST",
`/api/1.0/main/notification/${this.notificationId}/mark/unread`,
[],
).then(() => {
this.$emit("markRead", { notificationId: this.notificationId });
});
},
markAsRead() {
makeFetch(
"POST",
`/api/1.0/main/notification/${this.notificationId}/mark/read`,
[],
).then(() => {
this.$emit("markUnread", {
notificationId: this.notificationId,
});
});
},
markAllRead() {
makeFetch(
"POST",
`/api/1.0/main/notification/markallread`,
[],
).then(() => {
this.$emit("markAllRead");
});
},
buttonClass: {
type: String,
required: false,
},
i18n: {
messages: {
fr: {
markAsUnread: "Marquer comme non-lu",
markAsRead: "Marquer comme lu",
},
},
buttonNoText: {
type: Boolean,
required: false,
},
showUrl: {
type: String,
required: false,
},
});
// 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/${props.notificationId}/mark/unread`,
[],
).then(() => {
emit("markRead", { notificationId: props.notificationId });
});
};
const markAsRead = () => {
makeFetch(
"POST",
`/api/1.0/main/notification/${props.notificationId}/mark/read`,
[],
).then(() => {
emit("markUnread", { notificationId: props.notificationId });
});
};
</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,203 +28,164 @@
<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
const props = defineProps({
wopiUrl: {
type: String,
required: true,
},
props: {
wopiUrl: {
type: String,
required: true,
},
type: {
type: String,
required: true,
},
options: {
type: Object,
required: false,
},
type: {
type: String,
required: true,
},
data() {
return {
modal: {
showModal: false,
modalDialogClass: "modal-fullscreen", //modal-dialog-scrollable
},
logo: logo,
loading: false,
mime: [
// TODO temporary hardcoded. to be replaced by twig extension or a collabora server query
"application/clarisworks",
"application/coreldraw",
"application/macwriteii",
"application/msword",
"application/pdf",
"application/vnd.lotus-1-2-3",
"application/vnd.ms-excel",
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"application/vnd.ms-excel.sheet.macroEnabled.12",
"application/vnd.ms-excel.template.macroEnabled.12",
"application/vnd.ms-powerpoint",
"application/vnd.ms-powerpoint.presentation.macroEnabled.12",
"application/vnd.ms-powerpoint.template.macroEnabled.12",
"application/vnd.ms-visio.drawing",
"application/vnd.ms-word.document.macroEnabled.12",
"application/vnd.ms-word.template.macroEnabled.12",
"application/vnd.ms-works",
"application/vnd.oasis.opendocument.chart",
"application/vnd.oasis.opendocument.formula",
"application/vnd.oasis.opendocument.graphics",
"application/vnd.oasis.opendocument.graphics-flat-xml",
"application/vnd.oasis.opendocument.graphics-template",
"application/vnd.oasis.opendocument.presentation",
"application/vnd.oasis.opendocument.presentation-flat-xml",
"application/vnd.oasis.opendocument.presentation-template",
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.oasis.opendocument.spreadsheet-flat-xml",
"application/vnd.oasis.opendocument.spreadsheet-template",
"application/vnd.oasis.opendocument.text",
"application/vnd.oasis.opendocument.text-flat-xml",
"application/vnd.oasis.opendocument.text-master",
"application/vnd.oasis.opendocument.text-master-template",
"application/vnd.oasis.opendocument.text-template",
"application/vnd.oasis.opendocument.text-web",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"application/vnd.openxmlformats-officedocument.presentationml.template",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"application/vnd.sun.xml.calc",
"application/vnd.sun.xml.calc.template",
"application/vnd.sun.xml.chart",
"application/vnd.sun.xml.draw",
"application/vnd.sun.xml.draw.template",
"application/vnd.sun.xml.impress",
"application/vnd.sun.xml.impress.template",
"application/vnd.sun.xml.math",
"application/vnd.sun.xml.writer",
"application/vnd.sun.xml.writer.global",
"application/vnd.sun.xml.writer.template",
"application/vnd.visio",
"application/vnd.visio2013",
"application/vnd.wordperfect",
"application/x-abiword",
"application/x-aportisdoc",
"application/x-dbase",
"application/x-dif-document",
"application/x-fictionbook+xml",
"application/x-gnumeric",
"application/x-hwp",
"application/x-iwork-keynote-sffkey",
"application/x-iwork-numbers-sffnumbers",
"application/x-iwork-pages-sffpages",
"application/x-mspublisher",
"application/x-mswrite",
"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.",
},
},
options: {
type: Object,
required: false,
},
});
// data
const modal = ref({
showModal: false,
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",
"application/macwriteii",
"application/msword",
"application/pdf",
"application/vnd.lotus-1-2-3",
"application/vnd.ms-excel",
"application/vnd.ms-excel.sheet.binary.macroEnabled.12",
"application/vnd.ms-excel.sheet.macroEnabled.12",
"application/vnd.ms-excel.template.macroEnabled.12",
"application/vnd.ms-powerpoint",
"application/vnd.ms-powerpoint.presentation.macroEnabled.12",
"application/vnd.ms-powerpoint.template.macroEnabled.12",
"application/vnd.ms-visio.drawing",
"application/vnd.ms-word.document.macroEnabled.12",
"application/vnd.ms-word.template.macroEnabled.12",
"application/vnd.ms-works",
"application/vnd.oasis.opendocument.chart",
"application/vnd.oasis.opendocument.formula",
"application/vnd.oasis.opendocument.graphics",
"application/vnd.oasis.opendocument.graphics-flat-xml",
"application/vnd.oasis.opendocument.graphics-template",
"application/vnd.oasis.opendocument.presentation",
"application/vnd.oasis.opendocument.presentation-flat-xml",
"application/vnd.oasis.opendocument.presentation-template",
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.oasis.opendocument.spreadsheet-flat-xml",
"application/vnd.oasis.opendocument.spreadsheet-template",
"application/vnd.oasis.opendocument.text",
"application/vnd.oasis.opendocument.text-flat-xml",
"application/vnd.oasis.opendocument.text-master",
"application/vnd.oasis.opendocument.text-master-template",
"application/vnd.oasis.opendocument.text-template",
"application/vnd.oasis.opendocument.text-web",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"application/vnd.openxmlformats-officedocument.presentationml.template",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.openxmlformats-officedocument.spreadsheetml.template",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"application/vnd.sun.xml.calc",
"application/vnd.sun.xml.calc.template",
"application/vnd.sun.xml.chart",
"application/vnd.sun.xml.draw",
"application/vnd.sun.xml.draw.template",
"application/vnd.sun.xml.impress",
"application/vnd.sun.xml.impress.template",
"application/vnd.sun.xml.math",
"application/vnd.sun.xml.writer",
"application/vnd.sun.xml.writer.global",
"application/vnd.sun.xml.writer.template",
"application/vnd.visio",
"application/vnd.visio2013",
"application/vnd.wordperfect",
"application/x-abiword",
"application/x-aportisdoc",
"application/x-dbase",
"application/x-dif-document",
"application/x-fictionbook+xml",
"application/x-gnumeric",
"application/x-hwp",
"application/x-iwork-keynote-sffkey",
"application/x-iwork-numbers-sffnumbers",
"application/x-iwork-pages-sffpages",
"application/x-mspublisher",
"application/x-mswrite",
"application/x-pagemaker",
"application/x-sony-bbeb",
"application/x-t602",
];
// 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";
}